feat:(REQ-2699) 临时支持app端语音助手功能,菜单更新编码时发送钉钉事件
This commit is contained in:
parent
ec757f3ed1
commit
7a3bb207e0
@ -138,6 +138,12 @@
|
||||
<artifactId>apisix-plat-api</artifactId>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>alibaba-dingtalk-service-sdk</artifactId>
|
||||
<version>2.0.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
@ -0,0 +1,68 @@
|
||||
package cn.axzo.tyr.server.common.util;
|
||||
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.dingtalk.api.DefaultDingTalkClient;
|
||||
import com.dingtalk.api.DingTalkClient;
|
||||
import com.dingtalk.api.request.OapiRobotSendRequest;
|
||||
import com.dingtalk.api.response.OapiRobotSendResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* @author wangsiqian
|
||||
* @since 2024/07/30
|
||||
*/
|
||||
@Slf4j
|
||||
public class DingTalkUtil {
|
||||
|
||||
/**
|
||||
* 发送消息
|
||||
*
|
||||
* @author wangsiqian
|
||||
* @date 2024-07-30
|
||||
*/
|
||||
public static void sendMessage(String content, String accessToken, String secret) {
|
||||
Long timestamp = System.currentTimeMillis();
|
||||
String sign = getSign(timestamp, secret);
|
||||
if (StrUtil.isBlank(sign)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String url = StrUtil.format("https://oapi.dingtalk.com/robot/send?access_token={}&sign={}×tamp={}",
|
||||
accessToken, sign, String.valueOf(timestamp));
|
||||
DingTalkClient client = new DefaultDingTalkClient(url);
|
||||
|
||||
OapiRobotSendRequest req = new OapiRobotSendRequest();
|
||||
OapiRobotSendRequest.Text text = new OapiRobotSendRequest.Text();
|
||||
text.setContent(content);
|
||||
OapiRobotSendRequest.At at = new OapiRobotSendRequest.At();
|
||||
at.setIsAtAll(false);
|
||||
req.setMsgtype("text");
|
||||
req.setText(text);
|
||||
req.setAt(at);
|
||||
try {
|
||||
OapiRobotSendResponse response = client.execute(req);
|
||||
log.info("发送钉钉消息结果:{}", response);
|
||||
} catch (Exception error) {
|
||||
log.info("发送钉钉消息失败:{}", error.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private static String getSign(Long timestamp, String secret) {
|
||||
try {
|
||||
String stringToSign = timestamp + "\n" + secret;
|
||||
Mac mac = Mac.getInstance("HmacSHA256");
|
||||
mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
|
||||
byte[] signData = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
|
||||
return URLEncoder.encode(new String(Base64.encodeBase64(signData)), "UTF-8");
|
||||
} catch (Exception ignored) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -25,7 +25,9 @@ import cn.axzo.tyr.client.model.res.SaasRoleRes;
|
||||
import cn.axzo.tyr.client.model.roleuser.req.ListRoleUserRelationParam;
|
||||
import cn.axzo.tyr.client.model.vo.SaasRoleGroupVO;
|
||||
import cn.axzo.tyr.client.model.vo.SaveOrUpdateRoleVO;
|
||||
import cn.axzo.tyr.server.event.inner.SendDingTalkHandler;
|
||||
import cn.axzo.tyr.server.event.outer.CacheWorkspaceProductHandler;
|
||||
import cn.axzo.tyr.server.event.payload.SaasFeatureResourceUpsertPayload;
|
||||
import cn.axzo.tyr.server.event.payload.ServicePkgProductCreatedPayload;
|
||||
import cn.axzo.tyr.server.job.CacheProductFeatureResourceJob;
|
||||
import cn.axzo.tyr.server.job.CacheProductPermissionJob;
|
||||
@ -176,6 +178,8 @@ public class PrivateController {
|
||||
private CacheWorkspaceProductJob cacheWorkspaceProductJob;
|
||||
@Autowired
|
||||
private RoleSaasFeatureResourceCacheService roleSaasFeatureResourceCacheService;
|
||||
@Autowired
|
||||
private SendDingTalkHandler sendDingTalkHandler;
|
||||
|
||||
/**
|
||||
* 统一层级的roleGroup按照id升序,sort从1递增
|
||||
@ -1360,6 +1364,15 @@ public class PrivateController {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@PostMapping("/api/private/dingtalk/send")
|
||||
public Object sendUpsertDingTalk(@RequestBody SaasFeatureResourceUpsertPayload request) {
|
||||
Event event = Event.builder()
|
||||
.data(request)
|
||||
.build();
|
||||
sendDingTalkHandler.onFeatureResourceUpsert(event, null);
|
||||
return "ok";
|
||||
}
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
|
||||
@ -0,0 +1,63 @@
|
||||
package cn.axzo.tyr.server.event.inner;
|
||||
|
||||
import cn.axzo.framework.rocketmq.Event;
|
||||
import cn.axzo.framework.rocketmq.EventConsumer;
|
||||
import cn.axzo.tyr.server.common.util.DingTalkUtil;
|
||||
import cn.axzo.tyr.server.event.payload.SaasFeatureResourceUpsertPayload;
|
||||
import cn.axzo.tyr.server.repository.entity.SaasFeatureResource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class SendDingTalkHandler implements InitializingBean {
|
||||
|
||||
@Autowired
|
||||
private EventConsumer eventConsumer;
|
||||
@Value("${spring.profiles.active}")
|
||||
private String env;
|
||||
|
||||
// 语音助手菜单变更通知,@沈尚只是临时的方案,所以没改成配置
|
||||
private static final String ACCESS_TOKEN = "11cdf26d77211ee887184844910bf249b94aa2675c7ce36d75a7aa87d619490f";
|
||||
private static final String SECRET = "SEC3c1be9e4fe4cc09f16eb4b2eebf91659f21d5bdfb1d764b52f3e47825e6bed3f";
|
||||
|
||||
|
||||
public void onFeatureResourceUpsert(Event event, EventConsumer.Context context) {
|
||||
log.info("begin send dingTalk rocketmq event: {}", event);
|
||||
SaasFeatureResourceUpsertPayload payload = event.normalizedData(SaasFeatureResourceUpsertPayload.class);
|
||||
|
||||
if (Objects.isNull(payload.getAction())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Objects.equals(payload.getAction(), SaasFeatureResource.Action.UPDATE) &&
|
||||
Objects.equals(payload.getNewValue().getUniCode(), payload.getOldValue().getUniCode())) {
|
||||
return;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("环境:" + env + "\n");
|
||||
sb.append("操作:" + payload.getAction() + "\n");
|
||||
if (Objects.equals(payload.getAction(), SaasFeatureResource.Action.CREATE)) {
|
||||
sb.append("新code:" + payload.getNewValue().getUniCode());
|
||||
} else if (Objects.equals(payload.getAction(), SaasFeatureResource.Action.UPDATE)) {
|
||||
sb.append("新code:" + payload.getNewValue().getUniCode() + "\n");
|
||||
sb.append("旧code:" + payload.getOldValue().getUniCode());
|
||||
} else if (Objects.equals(payload.getAction(), SaasFeatureResource.Action.DELETE)) {
|
||||
sb.append("旧code:" + payload.getOldValue().getUniCode());
|
||||
}
|
||||
|
||||
DingTalkUtil.sendMessage(sb.toString(), ACCESS_TOKEN, SECRET);
|
||||
log.info("end send dingTalk rocketmq event: {}", event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
eventConsumer.registerHandler(EventTypeEnum.SAAS_FEATURE_RESOURCE_UPSERT.getEventCode(), this::onFeatureResourceUpsert);
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
package cn.axzo.tyr.server.event.payload;
|
||||
|
||||
import cn.axzo.tyr.server.repository.entity.SaasFeatureResource;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
@ -14,5 +15,12 @@ import java.util.Set;
|
||||
@AllArgsConstructor
|
||||
public class SaasFeatureResourceUpsertPayload implements Serializable {
|
||||
|
||||
// 只有tyr消费,触发更新缓存,同步等很多批量操作要全部重构收口代码后,才能好修改这个payload
|
||||
private Set<String> terminals;
|
||||
|
||||
private SaasFeatureResource oldValue;
|
||||
|
||||
private SaasFeatureResource newValue;
|
||||
|
||||
private SaasFeatureResource.Action action;
|
||||
}
|
||||
|
||||
@ -198,4 +198,14 @@ public class SaasFeatureResource extends BaseEntity<SaasFeatureResource> {
|
||||
return Objects.equals(ALL_ROLE.getValue(), authType);
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum Action {
|
||||
DELETE( "删除操作"),
|
||||
CREATE( "创建操作"),
|
||||
UPDATE( "更新操作");
|
||||
|
||||
private String desc;
|
||||
}
|
||||
}
|
||||
|
||||
@ -241,6 +241,16 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic
|
||||
baseResource.setCreateBy(operatorId);
|
||||
baseResource.setUpdateBy(operatorId);
|
||||
newResource(baseResource, parent);
|
||||
|
||||
Event event = Event.builder()
|
||||
.targetType(SAAS_FEATURE_RESOURCE_TARGET_TYPE)
|
||||
.eventCode(SAAS_FEATURE_RESOURCE_UPSERT.getEventCode())
|
||||
.data(SaasFeatureResourceUpsertPayload.builder()
|
||||
.newValue(featureResourceDao.getById(baseResource.getId()))
|
||||
.action(SaasFeatureResource.Action.CREATE)
|
||||
.build())
|
||||
.build();
|
||||
mqProducer.send(event);
|
||||
} else {
|
||||
//更新 - 恢复不能变更的数据
|
||||
baseResource.setId(resource.getId());
|
||||
@ -251,6 +261,17 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic
|
||||
baseResource.setUpdateBy(operatorId);
|
||||
baseResource.setAppItemId(resource.getAppItemId());
|
||||
featureResourceDao.updateById(baseResource);
|
||||
|
||||
Event event = Event.builder()
|
||||
.targetType(SAAS_FEATURE_RESOURCE_TARGET_TYPE)
|
||||
.eventCode(SAAS_FEATURE_RESOURCE_UPSERT.getEventCode())
|
||||
.data(SaasFeatureResourceUpsertPayload.builder()
|
||||
.newValue(featureResourceDao.getById(baseResource.getId()))
|
||||
.oldValue(resource)
|
||||
.action(SaasFeatureResource.Action.UPDATE)
|
||||
.build())
|
||||
.build();
|
||||
mqProducer.send(event);
|
||||
}
|
||||
|
||||
// 处理资源关联的权限
|
||||
|
||||
@ -32,7 +32,6 @@ import cn.axzo.tyr.client.model.res.PageElementResp;
|
||||
import cn.axzo.tyr.client.model.res.SaasFeatureResourceResp;
|
||||
import cn.axzo.tyr.server.common.util.Throws;
|
||||
import cn.axzo.tyr.server.config.MqProducer;
|
||||
import cn.axzo.tyr.server.event.payload.RolePermissionCreatedPayload;
|
||||
import cn.axzo.tyr.server.event.payload.SaasFeatureResourceUpsertPayload;
|
||||
import cn.axzo.tyr.server.model.ResourcePermission;
|
||||
import cn.axzo.tyr.server.model.ResourcePermissionQueryDTO;
|
||||
@ -89,7 +88,6 @@ import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.axzo.tyr.server.config.exception.BizResultCode.FEATURE_RESOURCE_NOT_FOUND;
|
||||
import static cn.axzo.tyr.server.event.inner.EventTypeEnum.ROLE_PERMISSION_CREATED;
|
||||
import static cn.axzo.tyr.server.event.inner.EventTypeEnum.SAAS_FEATURE_RESOURCE_UPSERT;
|
||||
import static cn.axzo.tyr.server.repository.entity.SaasFeatureResource.DEFAULT_WORKSPACE_TYPE;
|
||||
import static cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation.NEW_FEATURE;
|
||||
@ -272,12 +270,33 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl<SaasFeatureResou
|
||||
// 生成唯一编码,用于pre菜单同步
|
||||
baseResource.setFeatureCode(req.getUniCode());
|
||||
newResource(baseResource, parent == null ? "" : parent.getPath());
|
||||
|
||||
Event event = Event.builder()
|
||||
.targetType(TARGET_TYPE)
|
||||
.eventCode(SAAS_FEATURE_RESOURCE_UPSERT.getEventCode())
|
||||
.data(SaasFeatureResourceUpsertPayload.builder()
|
||||
.newValue(featureResourceDao.getById(baseResource.getId()))
|
||||
.action(SaasFeatureResource.Action.CREATE)
|
||||
.build())
|
||||
.build();
|
||||
mqProducer.send(event);
|
||||
} else {
|
||||
//补充path
|
||||
SaasFeatureResource newValue = featureResourceDao.getById(baseResource.getId());
|
||||
SaasFeatureResource dbResource = featureResourceDao.getById(req.getId());
|
||||
baseResource.setPath(dbResource.getPath());
|
||||
baseResource.setFeatureCode(req.getUniCode());
|
||||
featureResourceDao.updateById(baseResource);
|
||||
|
||||
Event event = Event.builder()
|
||||
.targetType(TARGET_TYPE)
|
||||
.eventCode(SAAS_FEATURE_RESOURCE_UPSERT.getEventCode())
|
||||
.data(SaasFeatureResourceUpsertPayload.builder()
|
||||
.oldValue(featureResourceDao.getById(baseResource.getId()))
|
||||
.newValue(newValue)
|
||||
.build())
|
||||
.build();
|
||||
mqProducer.send(event);
|
||||
}
|
||||
// 保存组件与页面元素关系,如果是页面,改的是默认路由
|
||||
ModifyPageElementRelationDTO modifyPageElementRelation = ModifyPageElementRelationDTO.builder()
|
||||
@ -714,6 +733,8 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl<SaasFeatureResou
|
||||
.eventCode(SAAS_FEATURE_RESOURCE_UPSERT.getEventCode())
|
||||
.data(SaasFeatureResourceUpsertPayload.builder()
|
||||
.terminals(Sets.newHashSet(featureResource.getTerminal()))
|
||||
.oldValue(featureResource)
|
||||
.action(SaasFeatureResource.Action.DELETE)
|
||||
.build())
|
||||
.build();
|
||||
mqProducer.send(event);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user