|
@@ -1,5 +1,6 @@
|
|
|
package com.qqflow.engine.domain.flow.service.impl;
|
|
package com.qqflow.engine.domain.flow.service.impl;
|
|
|
|
|
|
|
|
|
|
+import com.qqflow.engine.domain.ewechat.service.EnterpriseWechatMsgService;
|
|
|
import com.qqflow.engine.domain.flow.po.ApprovalTask;
|
|
import com.qqflow.engine.domain.flow.po.ApprovalTask;
|
|
|
import com.qqflow.engine.domain.flow.service.NotificationService;
|
|
import com.qqflow.engine.domain.flow.service.NotificationService;
|
|
|
import com.qqflow.engine.domain.system.dto.WeComConfigDTO;
|
|
import com.qqflow.engine.domain.system.dto.WeComConfigDTO;
|
|
@@ -12,22 +13,9 @@ import lombok.RequiredArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
|
|
+import java.util.Collections;
|
|
|
import java.util.List;
|
|
import java.util.List;
|
|
|
|
|
|
|
|
-/**
|
|
|
|
|
- * 企业微信通知服务(预留实现)
|
|
|
|
|
- * <p>
|
|
|
|
|
- * 本服务仅负责收集通知事件、读取企微配置、定位接收人的企微账号,并通过日志输出待发送内容。
|
|
|
|
|
- * 实际的企业微信应用消息推送由外部对接系统完成,对接方可选择以下方式消费:
|
|
|
|
|
- * 1. 监听本系统发布的 TaskAssignedEvent / TaskCompletedEvent / ProcessCompletedEvent;
|
|
|
|
|
- * 2. 调用本系统预留的查询接口(如 {@link com.qqflow.engine.domain.system.service.SysNotificationConfigService#getWeComConfig()})读取配置;
|
|
|
|
|
- * 3. 读取 sys_user.wecom_user_id 或 sys_role.wecom_user_id 获取接收人企微账号。
|
|
|
|
|
- * <p>
|
|
|
|
|
- * 对接时需要:
|
|
|
|
|
- * - 企业微信 corpId, agentId, secret(存储在 sys_notification_config 表)
|
|
|
|
|
- * - 用户/角色企微账号映射(sys_user.wecom_user_id / sys_role.wecom_user_id)
|
|
|
|
|
- * - 调用企微消息推送 API: POST https://qyapi.weixin.qq.com/cgi-bin/message/send
|
|
|
|
|
- */
|
|
|
|
|
@Slf4j
|
|
@Slf4j
|
|
|
@Service
|
|
@Service
|
|
|
@RequiredArgsConstructor
|
|
@RequiredArgsConstructor
|
|
@@ -38,77 +26,48 @@ public class WeComNotificationService implements NotificationService {
|
|
|
private final SysUserMapper sysUserMapper;
|
|
private final SysUserMapper sysUserMapper;
|
|
|
private final SysRoleMapper sysRoleMapper;
|
|
private final SysRoleMapper sysRoleMapper;
|
|
|
private final SysNotificationConfigService sysNotificationConfigService;
|
|
private final SysNotificationConfigService sysNotificationConfigService;
|
|
|
|
|
+ private final EnterpriseWechatMsgService wechatMsgService;
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public void notifyTaskAssigned(List<Long> assigneeIds, String assigneeType, String processName, String instanceTitle, String nodeName) {
|
|
public void notifyTaskAssigned(List<Long> assigneeIds, String assigneeType, String processName, String instanceTitle, String nodeName) {
|
|
|
- WeComConfigDTO config = this.sysNotificationConfigService.getWeComConfig();
|
|
|
|
|
- if (!isEnabled(config)) {
|
|
|
|
|
- log.debug("[企微通知-预留] 企业微信通知未启用,跳过待办提醒");
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (!this.isEnabled()) return;
|
|
|
for (Long assigneeId : assigneeIds) {
|
|
for (Long assigneeId : assigneeIds) {
|
|
|
String wecomUserId = resolveWeComUserId(assigneeId, assigneeType);
|
|
String wecomUserId = resolveWeComUserId(assigneeId, assigneeType);
|
|
|
- String receiverName = resolveReceiverName(assigneeId, assigneeType);
|
|
|
|
|
- if (!hasReminderEnabled(assigneeId, assigneeType) || wecomUserId == null) {
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
- log.info("[企微通知-预留] 待办提醒 | 接收人:{} | 企微账号:{} | 流程:{} | 标题:{} | 节点:{} | corpId:{} | agentId:{}",
|
|
|
|
|
- receiverName, wecomUserId, processName, instanceTitle, nodeName,
|
|
|
|
|
- mask(config.getCorpId()), mask(config.getAgentId()));
|
|
|
|
|
- // TODO: 生产环境由企业微信对接后端调用企微 API 发送应用消息
|
|
|
|
|
|
|
+ if (wecomUserId == null) continue;
|
|
|
|
|
+ String content = String.format("【待办提醒】\n流程:%s\n标题:%s\n节点:%s\n请及时处理。",
|
|
|
|
|
+ processName, instanceTitle, nodeName);
|
|
|
|
|
+ wechatMsgService.sendTextToUsers(Collections.singletonList(wecomUserId), content);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public void notifyTaskCompleted(Long instanceId, String processName, String instanceTitle,
|
|
public void notifyTaskCompleted(Long instanceId, String processName, String instanceTitle,
|
|
|
String nodeName, String operatorName, String action) {
|
|
String nodeName, String operatorName, String action) {
|
|
|
- WeComConfigDTO config = this.sysNotificationConfigService.getWeComConfig();
|
|
|
|
|
- if (!isEnabled(config)) {
|
|
|
|
|
- log.debug("[企微通知-预留] 企业微信通知未启用,跳过审批结果通知");
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
- log.info("[企微通知-预留] 审批结果 | 实例ID:{} | 流程:{} | 标题:{} | 节点:{} | 操作人:{} | 操作:{} | corpId:{} | agentId:{}",
|
|
|
|
|
- instanceId, processName, instanceTitle, nodeName, operatorName, action,
|
|
|
|
|
- mask(config.getCorpId()), mask(config.getAgentId()));
|
|
|
|
|
- // TODO: 生产环境由企业微信对接后端调用企微 API 发送审批结果通知(通知发起人或相关人)
|
|
|
|
|
|
|
+ // 审批完成通知:目前仅记录日志,后续可扩展
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public void notifyProcessCompleted(Long applicantId, String processName, String instanceTitle, String result) {
|
|
public void notifyProcessCompleted(Long applicantId, String processName, String instanceTitle, String result) {
|
|
|
- WeComConfigDTO config = this.sysNotificationConfigService.getWeComConfig();
|
|
|
|
|
- if (!isEnabled(config)) {
|
|
|
|
|
- log.debug("[企微通知-预留] 企业微信通知未启用,跳过流程结束通知");
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (!this.isEnabled()) return;
|
|
|
SysUser applicant = sysUserMapper.selectById(applicantId);
|
|
SysUser applicant = sysUserMapper.selectById(applicantId);
|
|
|
- if (applicant == null || !isUserRemindEnabled(applicant)) {
|
|
|
|
|
- return;
|
|
|
|
|
|
|
+ if (applicant != null && applicant.getWecomUserId() != null && !applicant.getWecomUserId().isBlank()) {
|
|
|
|
|
+ String content = String.format("【流程结束】\n流程:%s\n标题:%s\n结果:%s",
|
|
|
|
|
+ processName, instanceTitle, result);
|
|
|
|
|
+ wechatMsgService.sendTextToUsers(Collections.singletonList(applicant.getWecomUserId()), content);
|
|
|
}
|
|
}
|
|
|
- log.info("[企微通知-预留] 流程结束 | 接收人:{} | 企微账号:{} | 流程:{} | 标题:{} | 结果:{} | corpId:{} | agentId:{}",
|
|
|
|
|
- applicant.getRealName(), applicant.getWecomUserId(), processName, instanceTitle, result,
|
|
|
|
|
- mask(config.getCorpId()), mask(config.getAgentId()));
|
|
|
|
|
- // TODO: 生产环境由企业微信对接后端调用企微 API 发送流程结束通知
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public void notifyTaskOverdue(ApprovalTask task, String processName, String instanceTitle, String nodeName, boolean overdue) {
|
|
public void notifyTaskOverdue(ApprovalTask task, String processName, String instanceTitle, String nodeName, boolean overdue) {
|
|
|
- WeComConfigDTO config = this.sysNotificationConfigService.getWeComConfig();
|
|
|
|
|
- if (!isEnabled(config)) {
|
|
|
|
|
- log.debug("[企微通知-预留] 企业微信通知未启用,跳过超时催办通知");
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
- Long assigneeId = task.getAssigneeId();
|
|
|
|
|
- String assigneeType = task.getAssigneeType();
|
|
|
|
|
- String wecomUserId = resolveWeComUserId(assigneeId, assigneeType);
|
|
|
|
|
- String receiverName = resolveReceiverName(assigneeId, assigneeType);
|
|
|
|
|
- if (!hasReminderEnabled(assigneeId, assigneeType) || wecomUserId == null) {
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (!this.isEnabled()) return;
|
|
|
String type = overdue ? "已超时催办" : "即将超时提醒";
|
|
String type = overdue ? "已超时催办" : "即将超时提醒";
|
|
|
- log.info("[企微通知-预留] {} | 接收人:{} | 企微账号:{} | 流程:{} | 标题:{} | 节点:{} | corpId:{} | agentId:{}",
|
|
|
|
|
- type, receiverName, wecomUserId, processName, instanceTitle, nodeName,
|
|
|
|
|
- mask(config.getCorpId()), mask(config.getAgentId()));
|
|
|
|
|
- // TODO: 生产环境由企业微信对接后端调用企微 API 发送超时/催办通知
|
|
|
|
|
|
|
+ String content = String.format("【%s】\n流程:%s\n标题:%s\n节点:%s\n请及时处理。",
|
|
|
|
|
+ type, processName, instanceTitle, nodeName);
|
|
|
|
|
+ if (ASSIGNEE_TYPE_ROLE.equalsIgnoreCase(task.getAssigneeType())) {
|
|
|
|
|
+ wechatMsgService.sendTextToRole(task.getAssigneeId(), content);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ wechatMsgService.sendTextToUser(task.getAssigneeId(), content);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private String resolveWeComUserId(Long assigneeId, String assigneeType) {
|
|
private String resolveWeComUserId(Long assigneeId, String assigneeType) {
|
|
@@ -120,40 +79,8 @@ public class WeComNotificationService implements NotificationService {
|
|
|
return user != null ? user.getWecomUserId() : null;
|
|
return user != null ? user.getWecomUserId() : null;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private String resolveReceiverName(Long assigneeId, String assigneeType) {
|
|
|
|
|
- if (ASSIGNEE_TYPE_ROLE.equalsIgnoreCase(assigneeType)) {
|
|
|
|
|
- SysRole role = sysRoleMapper.selectById(assigneeId);
|
|
|
|
|
- return role != null ? role.getRoleName() : "";
|
|
|
|
|
- }
|
|
|
|
|
- SysUser user = sysUserMapper.selectById(assigneeId);
|
|
|
|
|
- return user != null ? user.getRealName() : "";
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- private boolean hasReminderEnabled(Long assigneeId, String assigneeType) {
|
|
|
|
|
- if (ASSIGNEE_TYPE_ROLE.equalsIgnoreCase(assigneeType)) {
|
|
|
|
|
- SysRole role = sysRoleMapper.selectById(assigneeId);
|
|
|
|
|
- return role != null && isRoleRemindEnabled(role);
|
|
|
|
|
- }
|
|
|
|
|
- SysUser user = sysUserMapper.selectById(assigneeId);
|
|
|
|
|
- return user != null && isUserRemindEnabled(user);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- private boolean isEnabled(WeComConfigDTO config) {
|
|
|
|
|
|
|
+ private boolean isEnabled() {
|
|
|
|
|
+ WeComConfigDTO config = sysNotificationConfigService.getWeComConfig();
|
|
|
return config != null && config.getEnabled() != null && config.getEnabled() == 1;
|
|
return config != null && config.getEnabled() != null && config.getEnabled() == 1;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- private boolean isUserRemindEnabled(SysUser user) {
|
|
|
|
|
- return user.getWecomRemindEnabled() == null || user.getWecomRemindEnabled() == 1;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- private boolean isRoleRemindEnabled(SysRole role) {
|
|
|
|
|
- return role.getWecomRemindEnabled() == null || role.getWecomRemindEnabled() == 1;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- private String mask(String value) {
|
|
|
|
|
- if (value == null || value.length() <= 4) {
|
|
|
|
|
- return value;
|
|
|
|
|
- }
|
|
|
|
|
- return value.substring(0, 2) + "****" + value.substring(value.length() - 2);
|
|
|
|
|
- }
|
|
|
|
|
}
|
|
}
|