|
|
@@ -7,6 +7,7 @@ import com.qqflow.engine.domain.ewechat.config.EnterpriseWechatProperties;
|
|
|
import com.qqflow.engine.domain.ewechat.mapper.EnterpriseWechatCorpMapper;
|
|
|
import com.qqflow.engine.domain.ewechat.model.enterprise.req.EnterpriseWechatSendTextCardMsgReq;
|
|
|
import com.qqflow.engine.domain.ewechat.model.enterprise.req.EnterpriseWechatSendTextMsgReq;
|
|
|
+import com.qqflow.engine.domain.ewechat.model.enterprise.rsp.EnterpriseWechatSendTextMsgRsp;
|
|
|
import com.qqflow.engine.domain.ewechat.po.EnterpriseWechatCorp;
|
|
|
import com.qqflow.engine.domain.system.entity.SysUser;
|
|
|
import com.qqflow.engine.domain.system.entity.SysUserRole;
|
|
|
@@ -40,42 +41,62 @@ public class EnterpriseWechatMsgService {
|
|
|
/** access_token 有效期 7200 秒,缓存 7000 秒留余量 */
|
|
|
private static final Duration ACCESS_TOKEN_TTL = Duration.ofSeconds(7000);
|
|
|
|
|
|
- /** 给指定企微用户ID列表发送文本消息 */
|
|
|
- public void sendTextToUsers(List<String> wecomUserIds, String content) {
|
|
|
- if (wecomUserIds == null || wecomUserIds.isEmpty()) return;
|
|
|
+ /** 给指定企微用户ID列表发送文本消息;返回是否被企微接口成功接收 */
|
|
|
+ public boolean sendTextToUsers(List<String> wecomUserIds, String content) {
|
|
|
+ if (wecomUserIds == null || wecomUserIds.isEmpty()) return false;
|
|
|
String accessToken = this.getCorpAccessToken();
|
|
|
if (accessToken == null) {
|
|
|
log.warn("[企微消息] 无法获取 access_token");
|
|
|
- return;
|
|
|
+ return false;
|
|
|
}
|
|
|
try {
|
|
|
EnterpriseWechatSendTextMsgReq req = EnterpriseWechatSendTextMsgReq.toUsers(
|
|
|
wecomUserIds, wechatProperties.getAgentId(), content);
|
|
|
- enterpriseWechatApi.sendTextMsg(accessToken, req);
|
|
|
- log.info("[企微消息] 已发送 | 接收人数:{}", wecomUserIds.size());
|
|
|
+ EnterpriseWechatSendTextMsgRsp rsp = enterpriseWechatApi.sendTextMsg(accessToken, req);
|
|
|
+ return logSendResult(rsp, "文本消息", wecomUserIds.size());
|
|
|
} catch (Exception e) {
|
|
|
log.error("[企微消息] 发送失败", e);
|
|
|
+ return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /** 给指定企微用户ID列表发送文本卡片消息(可点击跳转,用于审批待办/催办) */
|
|
|
- public void sendTextCardToUsers(List<String> wecomUserIds, String title, String description, String url, String btnText) {
|
|
|
- if (wecomUserIds == null || wecomUserIds.isEmpty()) return;
|
|
|
+ /** 给指定企微用户ID列表发送文本卡片消息(可点击跳转,用于审批待办/催办);返回是否发送成功 */
|
|
|
+ public boolean sendTextCardToUsers(List<String> wecomUserIds, String title, String description, String url, String btnText) {
|
|
|
+ if (wecomUserIds == null || wecomUserIds.isEmpty()) return false;
|
|
|
String accessToken = this.getCorpAccessToken();
|
|
|
if (accessToken == null) {
|
|
|
log.warn("[企微消息] 无法获取 access_token");
|
|
|
- return;
|
|
|
+ return false;
|
|
|
}
|
|
|
try {
|
|
|
EnterpriseWechatSendTextCardMsgReq req = EnterpriseWechatSendTextCardMsgReq.toUsers(
|
|
|
wecomUserIds, wechatProperties.getAgentId(), title, description, url, btnText);
|
|
|
- enterpriseWechatApi.sendTextCardMsg(accessToken, req);
|
|
|
- log.info("[企微消息] 已发送文本卡片 | 接收人数:{} | {}", wecomUserIds.size(), title);
|
|
|
+ EnterpriseWechatSendTextMsgRsp rsp = enterpriseWechatApi.sendTextCardMsg(accessToken, req);
|
|
|
+ return logSendResult(rsp, "文本卡片", wecomUserIds.size());
|
|
|
} catch (Exception e) {
|
|
|
log.error("[企微消息] 文本卡片发送失败", e);
|
|
|
+ return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 记录企微接口真实返回码:errcode=0 才算成功。
|
|
|
+ * 之前只看 HTTP 异常,errcode 非 0(如 60020 IP 不在白名单)会被当成发送成功。
|
|
|
+ */
|
|
|
+ private boolean logSendResult(EnterpriseWechatSendTextMsgRsp rsp, String scene, int userCount) {
|
|
|
+ if (rsp == null) {
|
|
|
+ log.error("[企微消息] {}无响应 | 接收人数:{}", scene, userCount);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (rsp.getErrcode() == null || rsp.getErrcode() == 0) {
|
|
|
+ log.info("[企微消息] {}已发送 | 接收人数:{} | msgid:{}", scene, userCount, rsp.getMsgid());
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ log.error("[企微消息] {}发送失败 | 接收人数:{} | errcode={} errmsg={} invaliduser={}",
|
|
|
+ scene, userCount, rsp.getErrcode(), rsp.getErrmsg(), rsp.getInvaliduser());
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
/** 给指定角色下的所有企微用户发送文本消息 */
|
|
|
public void sendTextToRole(Long roleId, String content) {
|
|
|
List<String> wecomUserIds = this.getRoleWecomUserIds(roleId);
|