|
|
|
|
package com.project.interaction.utils;
|
|
|
|
|
|
|
|
|
|
import cn.hutool.core.date.DateUtil;
|
|
|
|
|
import com.github.tingyugetc520.ali.dingtalk.api.DtService;
|
|
|
|
|
import com.github.tingyugetc520.ali.dingtalk.bean.message.DtCorpConversationMessage;
|
|
|
|
|
import com.github.tingyugetc520.ali.dingtalk.bean.message.DtCorpConversationMsgSendResult;
|
|
|
|
|
import com.github.tingyugetc520.ali.dingtalk.bean.message.DtMessage;
|
|
|
|
|
import com.google.common.collect.Lists;
|
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
import org.redisson.api.RedissonClient;
|
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.Date;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
|
|
|
|
@Slf4j
|
|
|
|
|
@Component
|
|
|
|
|
public class NotifyUtil {
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
private DtService dtService;
|
|
|
|
|
@Autowired
|
|
|
|
|
private RedissonClient redissonClient;
|
|
|
|
|
|
|
|
|
|
// 钉钉通知相关配置
|
|
|
|
|
private final List<String> WARN_USER_LIST = Lists.newArrayList(
|
|
|
|
|
"283712335120874575",
|
|
|
|
|
"01231011386731976125",
|
|
|
|
|
"590204300932000212"
|
|
|
|
|
);
|
|
|
|
|
// 防重复缓存key前缀
|
|
|
|
|
private static final String WARN_LOCK_KEY_PREFIX = "question:gen:warn:lock:";
|
|
|
|
|
// 重复发送间隔:1小时(3600秒)
|
|
|
|
|
private static final long WARN_LOCK_EXPIRE_SECONDS = 3600L;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void notify(Long taskId,Long clusterId) {
|
|
|
|
|
|
|
|
|
|
// 构建Redis缓存key(按taskId唯一)
|
|
|
|
|
String cacheKey = WARN_LOCK_KEY_PREFIX + taskId;
|
|
|
|
|
|
|
|
|
|
// 核心逻辑:检查Redis缓存,存在则直接返回(1小时内已发送过)
|
|
|
|
|
boolean isCached = redissonClient.getBucket(cacheKey).isExists();
|
|
|
|
|
if (isCached) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
String now = DateUtil.now();
|
|
|
|
|
String markdown = String.format("### 【告警】算法生题API调用失败通知 \n\n") +
|
|
|
|
|
String.format("## 核心信息\n") +
|
|
|
|
|
String.format("- 考试任务ID:%d\n", taskId) +
|
|
|
|
|
String.format("- 知识点簇ID:%d\n", clusterId) +
|
|
|
|
|
String.format("- 当前时间:%s\n\n", now) +
|
|
|
|
|
String.format("## 异常说明\n") +
|
|
|
|
|
String.format("算法服务生成题目时调用失败,可能导致考试题目不完整或无法正常作答,请尽快排查以下问题:\n") +
|
|
|
|
|
String.format("- 算法服务是否正常运行\n");
|
|
|
|
|
DtCorpConversationMessage corpConversationMessage = DtCorpConversationMessage.builder()
|
|
|
|
|
.agentId(dtService.getDtConfigStorage().getAgentId())
|
|
|
|
|
.userIds(WARN_USER_LIST)
|
|
|
|
|
.msg(DtMessage.MARKDOWN()
|
|
|
|
|
.content("算法生题API调用失败通知")
|
|
|
|
|
.text(markdown)
|
|
|
|
|
.build())
|
|
|
|
|
.build();
|
|
|
|
|
DtCorpConversationMsgSendResult result = dtService.getCorpConversationMsgService().send(corpConversationMessage);
|
|
|
|
|
if (result.getErrCode() == 0) {
|
|
|
|
|
log.info(">>> [算法生题API调用失败通知] 成功发送通知 ,考试任务ID:{} ,知识点簇ID:{}", taskId, clusterId);
|
|
|
|
|
} else {
|
|
|
|
|
log.error(">>> [算法生题API调用失败通知] 发送失败.考试任务ID:{} ,知识点簇ID:{}, 错误码: {}, 错误信息: {}", taskId, clusterId,
|
|
|
|
|
result.getErrCode(), result.getErrMsg());
|
|
|
|
|
}
|
|
|
|
|
redissonClient.getBucket(cacheKey).set("SEND_SUCCESS", WARN_LOCK_EXPIRE_SECONDS, TimeUnit.SECONDS);
|
|
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error(">>> [算法生题API调用失败通知] 钉钉接口调用异常, 考试任务ID:{} ,知识点簇ID:{}, 原因: {}",taskId, clusterId, e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|