入伍保留学籍申请、外宿申请-上一级审批结束之后,给下一级发送审批提醒
This commit is contained in:
@@ -5,12 +5,15 @@ import com.srs.common.core.domain.entity.SysUser;
|
||||
|
||||
import com.srs.common.doman.vo.TeacherVo;
|
||||
import com.srs.common.utils.SecurityUtils;
|
||||
import com.srs.common.utils.WeChatUtil;
|
||||
import com.srs.common.utils.spring.SpringUtils;
|
||||
import com.srs.flowable.domain.EnlistmentReserve;
|
||||
import com.srs.flowable.domain.EnlistmentReserveApproval;
|
||||
import com.srs.flowable.mapper.EnlistmentReserveApprovalMapper;
|
||||
import com.srs.flowable.mapper.EnlistmentReserveMapper;
|
||||
import com.srs.flowable.mapper.RelieveMapper;
|
||||
import com.srs.system.service.ISysUserService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.bpmn.model.BpmnModel;
|
||||
import org.flowable.bpmn.model.FlowNode;
|
||||
import org.flowable.engine.HistoryService;
|
||||
@@ -28,9 +31,10 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* 审批流程负责人自动流转监听器
|
||||
* 用于节点审批通过时,添加审批记录
|
||||
* 用于节点审批通过时,添加审批记录 + 给学生发送企业微信通知
|
||||
*/
|
||||
@Component("approvalAssigneeListener") // Spring Bean名称,与BPMN表达式对应
|
||||
@Slf4j
|
||||
public class ApprovalAssigneeListener implements ExecutionListener {
|
||||
|
||||
@Autowired
|
||||
@@ -103,8 +107,89 @@ public class ApprovalAssigneeListener implements ExecutionListener {
|
||||
// 改变申请表中的审核状态(审核通过)
|
||||
enlistmentReserve.setApplyStatus(status);
|
||||
rtEnlistmentReserveMapper.updateRtEnlistmentReserve(enlistmentReserve);
|
||||
// ========== 给学生发送入伍保留学籍审批通知 ==========
|
||||
sendStudentWeChatNotification(execution, enlistmentReserve, currentNodeName, approvalResult, approvalOpinion);
|
||||
}
|
||||
|
||||
/**
|
||||
* 给学生发送入伍保留学籍审批结果的企业微信通知
|
||||
*/
|
||||
private void sendStudentWeChatNotification(DelegateExecution execution, EnlistmentReserve enlistmentReserve,
|
||||
String currentNodeName, Long approvalResult, String approvalOpinion) {
|
||||
try {
|
||||
// 1. 获取需要的Mapper和工具类
|
||||
RelieveMapper relieveMapper = (RelieveMapper) SpringUtils.getBean("relieveMapper");
|
||||
WeChatUtil weChatUtil = SpringUtils.getBean(WeChatUtil.class);
|
||||
|
||||
// 2. 获取学生基础信息
|
||||
String studentNo = enlistmentReserve.getStudentNo();
|
||||
String studentName = enlistmentReserve.getStudentName();
|
||||
|
||||
// 3. 获取学生userId(优先从流程变量取)
|
||||
Long stuUserId = null;
|
||||
if (execution.hasVariable("stuUserId")) {
|
||||
stuUserId = Long.valueOf(execution.getVariable("stuUserId").toString());
|
||||
} else {
|
||||
// 兜底:通过申请表获取学生id
|
||||
stuUserId = enlistmentReserve.getStudentId();
|
||||
}
|
||||
|
||||
if (stuUserId == null) {
|
||||
log.warn("⚠ 未找到学生(学号:{},姓名:{})对应的用户ID,无法发送通知", studentNo, studentName);
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. 查询学生的企业微信账号
|
||||
String stuUserName = relieveMapper.getUserNameByUserId(stuUserId);
|
||||
|
||||
if (stuUserName != null && !stuUserName.isEmpty()) {
|
||||
// 5. 拼接审批结果描述
|
||||
String approveResultDesc = getApprovalResultDesc(approvalResult, currentNodeName);
|
||||
|
||||
// 6. 构造通知内容
|
||||
String content = String.format("您的入伍保留学籍申请有新的审批进展:%s(%s),%s,<a href='https://zhxg.gxsdxy.cn/wab/#/pages/Approval/index'>点此查看详情</a>",
|
||||
currentNodeName,
|
||||
approveResultDesc,
|
||||
(approvalOpinion != null && !approvalOpinion.isEmpty()) ? "审批意见:" + approvalOpinion : "");
|
||||
|
||||
// 7. 发送企业微信消息
|
||||
weChatUtil.sendTextMessage(stuUserName, content);
|
||||
log.info("✅ 已成功向学生(姓名:{},学号:{},userName:{})发送入伍保留学籍审批通知。审批节点:{},结果:{}",
|
||||
studentName, studentNo, stuUserName, currentNodeName, approveResultDesc);
|
||||
|
||||
} else {
|
||||
// 发送日志
|
||||
log.warn("⚠ 找到了学生(学号:{},姓名:{},userId:{}),但其对应的企业微信账号为空,无法发送通知。",
|
||||
studentNo, studentName, stuUserId);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 异常处理:记录日志+不影响主流程
|
||||
String studentNo = enlistmentReserve.getStudentNo();
|
||||
log.error("❌ 向学生(学号:{})发送入伍保留学籍审批通知时出现异常,但流程将继续。错误详情:", studentNo, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换审批结果为可读描述(适配入伍保留学籍审批状态)
|
||||
*/
|
||||
private String getApprovalResultDesc(Long approvalResult, String currentNodeName) {
|
||||
if (approvalResult == null) {
|
||||
return "审批已处理";
|
||||
}
|
||||
// 匹配项目中实际的审批状态值(0=驳回/1=通过/2=审批中)
|
||||
switch (approvalResult.intValue()) {
|
||||
case 0:
|
||||
return currentNodeName + "驳回";
|
||||
case 1:
|
||||
return currentNodeName + "通过";
|
||||
case 2:
|
||||
return "审批中";
|
||||
default:
|
||||
return "审批已完成";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据节点ID和流程定义ID,查询节点名称(兼容所有版本的核心方法)
|
||||
*/
|
||||
|
||||
@@ -4,13 +4,18 @@ import com.srs.common.core.domain.entity.SysUser;
|
||||
|
||||
|
||||
import com.srs.common.doman.vo.TeacherVo;
|
||||
import com.srs.common.utils.DateUtils;
|
||||
import com.srs.common.utils.SecurityUtils;
|
||||
import com.srs.common.utils.WeChatUtil;
|
||||
import com.srs.common.utils.spring.SpringUtils;
|
||||
import com.srs.flowable.domain.EnlistmentReserve;
|
||||
import com.srs.flowable.domain.EnlistmentReserveApproval;
|
||||
import com.srs.flowable.domain.NotificationManage;
|
||||
import com.srs.flowable.mapper.EnlistmentReserveApprovalMapper;
|
||||
import com.srs.flowable.mapper.EnlistmentReserveMapper;
|
||||
import com.srs.flowable.mapper.LeaveMapper;
|
||||
import com.srs.system.service.ISysUserService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.bpmn.model.BpmnModel;
|
||||
import org.flowable.bpmn.model.FlowNode;
|
||||
import org.flowable.engine.HistoryService;
|
||||
@@ -31,6 +36,7 @@ import java.util.List;
|
||||
* 用于节点审批之前时,更新下一个节点的负责人变量(approval)
|
||||
*/
|
||||
@Component("startApprovalAssigneeListener") // Spring Bean名称,与BPMN表达式对应
|
||||
@Slf4j
|
||||
public class StartApprovalAssigneeListener implements ExecutionListener {
|
||||
|
||||
@Autowired
|
||||
@@ -46,7 +52,7 @@ public class StartApprovalAssigneeListener implements ExecutionListener {
|
||||
String currentActivityId = execution.getCurrentActivityId(); // 当前节点ID(兼容所有版本)
|
||||
String processDefinitionId = execution.getProcessDefinitionId(); // 流程定义ID
|
||||
|
||||
// 2. 根据节点ID查询节点名称(核心修正:通过流程定义获取名称)
|
||||
// 2. 根据节点ID查询节点名称(通过流程定义获取名称)
|
||||
String currentNodeName = getNodeNameByActivityId(processDefinitionId, currentActivityId);
|
||||
if (currentNodeName == null) {
|
||||
throw new RuntimeException("未找到节点ID=" + currentActivityId + "的名称");
|
||||
@@ -61,6 +67,8 @@ public class StartApprovalAssigneeListener implements ExecutionListener {
|
||||
if (nextAssigneeId != null) {
|
||||
execution.setVariable("approval", nextAssigneeId);
|
||||
execution.setVariable("currentNode", currentNodeName);
|
||||
// ========== 发送通知逻辑 ==========
|
||||
sendApprovalNotification(execution, currentNodeName, nextAssigneeId, enlistmentId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,4 +182,99 @@ public class StartApprovalAssigneeListener implements ExecutionListener {
|
||||
throw new RuntimeException("未配置节点[" + currentNodeName + "]的当前负责人规则");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送审批通知(系统通知+企业微信通知)
|
||||
*/
|
||||
private void sendApprovalNotification(DelegateExecution execution, String currentNodeName,
|
||||
Long nextAssigneeId, Long enlistmentId) {
|
||||
try {
|
||||
// 获取需要的Mapper和工具类
|
||||
EnlistmentReserveMapper enlistmentReserveMapper = (EnlistmentReserveMapper) SpringUtils.getBean(EnlistmentReserveMapper.class);
|
||||
LeaveMapper leaveMapper = (LeaveMapper) SpringUtils.getBean("leaveMapper");
|
||||
WeChatUtil weChatUtil = SpringUtils.getBean(WeChatUtil.class);
|
||||
|
||||
// 1. 查询入伍保留学籍申请详情
|
||||
EnlistmentReserve enlistmentReserve = enlistmentReserveMapper.selectRtEnlistmentReserveById(enlistmentId);
|
||||
if (enlistmentReserve == null) {
|
||||
log.warn("未找到入伍保留学籍申请记录,ID:{}", enlistmentId);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 查询下一个审批人的信息(获取用户名/工号)
|
||||
SysUser nextApprover = sysUserService.selectUserById(nextAssigneeId);
|
||||
if (nextApprover == null) {
|
||||
log.warn("未找到审批人信息,用户ID:{}", nextAssigneeId);
|
||||
return;
|
||||
}
|
||||
String approverUserName = nextApprover.getUserName(); // 审批人工号/用户名
|
||||
String approverName = nextApprover.getNickName(); // 审批人姓名
|
||||
|
||||
log.info("开始发送【入伍保留学籍审批】通知,审批节点:{},审批人:{}({})",
|
||||
currentNodeName, approverName, approverUserName);
|
||||
|
||||
// 3. 处理系统通知(先删后加,避免重复通知)
|
||||
NotificationManage notificationManage = new NotificationManage();
|
||||
notificationManage.setContent(String.format("您有一条【入伍保留学籍审批】待处理(节点:%s)", currentNodeName));
|
||||
notificationManage.setReceiver(nextAssigneeId); // 接收人:下一个审批人
|
||||
|
||||
// 3.1 查询是否已有相同通知,有则删除
|
||||
NotificationManage existNotify = leaveMapper.selectCphMsgListForFlowable(notificationManage);
|
||||
if (existNotify != null) {
|
||||
int delRes = leaveMapper.deleteCphMsgById(existNotify.getId());
|
||||
log.info("删除重复的系统通知,通知ID:{},删除结果:{}", existNotify.getId(), delRes);
|
||||
}
|
||||
|
||||
// 3.2 添加新的系统通知
|
||||
notificationManage.setSender(SecurityUtils.getUserId()); // 发送人:当前操作人
|
||||
notificationManage.setCreateTime(DateUtils.getNowDate()); // 创建时间
|
||||
int addRes = leaveMapper.insertCphMsg(notificationManage);
|
||||
log.info("新增系统通知成功,接收人ID:{},添加结果:{}", nextAssigneeId, addRes);
|
||||
|
||||
// 4. 企业微信推送消息
|
||||
if (approverUserName != null && !approverUserName.isEmpty()) {
|
||||
// 构造带超链接的消息内容
|
||||
String weChatContent = String.format(
|
||||
"您有一条【入伍保留学籍审批】待处理(节点:%s),<a href='https://zhxg.gxsdxy.cn/wab/#/pages/Approval/index'>请点击前往处理</a>",
|
||||
currentNodeName
|
||||
);
|
||||
|
||||
// 发送企业微信文本消息
|
||||
weChatUtil.sendTextMessage(approverUserName, weChatContent);
|
||||
log.info("企业微信通知发送成功,接收人工号:{},节点:{}", approverUserName, currentNodeName);
|
||||
} else {
|
||||
log.warn("审批人工号为空,无法发送企业微信通知,用户ID:{}", nextAssigneeId);
|
||||
}
|
||||
|
||||
// ========== 删除当前审批人的待处理通知 ==========
|
||||
// 4.1 获取当前审批人ID(当前操作人=已完成审批的人)
|
||||
Long currentApproverId = SecurityUtils.getUserId();
|
||||
if (currentApproverId == null) {
|
||||
log.warn("当前审批人ID为空,无法删除其待处理通知");
|
||||
return;
|
||||
}
|
||||
|
||||
// 4.2 构造当前审批人的待处理通知查询条件
|
||||
NotificationManage currentNotifyQuery = new NotificationManage();
|
||||
// 内容匹配:当前节点的待处理通知(关键词+节点名称)
|
||||
currentNotifyQuery.setContent(String.format("您有一条【入伍保留学籍审批】待处理(节点:%s)", currentNodeName));
|
||||
currentNotifyQuery.setReceiver(currentApproverId); // 接收人=当前审批人
|
||||
|
||||
// 4.3 查询当前审批人的该节点待处理通知
|
||||
NotificationManage currentExistNotify = leaveMapper.selectCphMsgListForFlowable(currentNotifyQuery);
|
||||
if (currentExistNotify != null) {
|
||||
// 4.4 删除该通知(清理已处理的待办)
|
||||
int currentDelRes = leaveMapper.deleteCphMsgById(currentExistNotify.getId());
|
||||
log.info("删除当前审批人({})的【{}】待处理通知,通知ID:{},删除结果:{}",
|
||||
currentApproverId, currentNodeName, currentExistNotify.getId(), currentDelRes);
|
||||
} else {
|
||||
log.info("当前审批人({})无【{}】节点的待处理通知,无需删除", currentApproverId, currentNodeName);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
// 捕获所有异常,仅记录日志,不影响主流程
|
||||
log.error("发送入伍保留学籍审批通知失败,节点:{},审批人ID:{},错误信息:{}",
|
||||
currentNodeName, nextAssigneeId, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,12 +2,15 @@ package com.srs.flowable.listener.outsideAccommodation;
|
||||
|
||||
|
||||
import com.srs.common.utils.SecurityUtils;
|
||||
import com.srs.common.utils.WeChatUtil;
|
||||
import com.srs.common.utils.spring.SpringUtils;
|
||||
import com.srs.flowable.domain.DormitoryStudent;
|
||||
import com.srs.flowable.domain.OutsideAccommodationApply;
|
||||
import com.srs.flowable.domain.OutsideAccommodationApproval;
|
||||
import com.srs.flowable.mapper.OutsideAccommodationApplyMapper;
|
||||
import com.srs.flowable.mapper.OutsideAccommodationApprovalMapper;
|
||||
import com.srs.flowable.mapper.RelieveMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.bpmn.model.BpmnModel;
|
||||
import org.flowable.bpmn.model.FlowNode;
|
||||
import org.flowable.engine.RepositoryService;
|
||||
@@ -21,9 +24,10 @@ import java.util.Date;
|
||||
|
||||
/**
|
||||
* 审批流程负责人自动流转监听器
|
||||
* 用于节点审批通过时,添加审批记录
|
||||
* 用于节点审批通过时,添加审批记录 + 给学生发送企业微信通知
|
||||
*/
|
||||
@Component("OutsideAccommodationEndListener") // Spring Bean名称,与BPMN表达式对应
|
||||
@Slf4j
|
||||
public class OutsideAccommodationEndListener implements ExecutionListener {
|
||||
|
||||
// 用于查询流程定义中的节点信息
|
||||
@@ -36,7 +40,7 @@ public class OutsideAccommodationEndListener implements ExecutionListener {
|
||||
String currentActivityId = execution.getCurrentActivityId(); // 当前节点ID(兼容所有版本)
|
||||
String processDefinitionId = execution.getProcessDefinitionId(); // 流程定义ID
|
||||
|
||||
// 2. 根据节点ID查询节点名称(核心修正:通过流程定义获取名称)
|
||||
// 2. 根据节点ID查询节点名称(通过流程定义获取名称)
|
||||
String currentNodeName = getNodeNameByActivityId(processDefinitionId, currentActivityId);
|
||||
if (currentNodeName == null) {
|
||||
throw new RuntimeException("未找到节点ID=" + currentActivityId + "的名称");
|
||||
@@ -88,6 +92,84 @@ public class OutsideAccommodationEndListener implements ExecutionListener {
|
||||
}
|
||||
outsideAccommodationApply.setStatus(status);
|
||||
outsideAccommodationApplyMapper.updateDmsOutsideAccommodationApply(outsideAccommodationApply);
|
||||
// ========== 给学生发送企业微信通知 ==========
|
||||
sendStudentWeChatNotification(execution, outsideAccommodationApply, currentNodeName, approvalResult, approvalOpinion);
|
||||
}
|
||||
|
||||
/**
|
||||
* 给学生发送外宿申请审批结果的企业微信通知
|
||||
*/
|
||||
private void sendStudentWeChatNotification(DelegateExecution execution, OutsideAccommodationApply outsideAccommodationApply,
|
||||
String currentNodeName, Long approvalResult, String approvalOpinion) {
|
||||
try {
|
||||
// 1. 获取需要的Mapper和工具类
|
||||
RelieveMapper relieveMapper = (RelieveMapper) SpringUtils.getBean("relieveMapper");
|
||||
WeChatUtil weChatUtil = SpringUtils.getBean(WeChatUtil.class);
|
||||
|
||||
// 2. 获取学生学号和姓名(从外宿申请对象中获取)
|
||||
String studentNo = outsideAccommodationApply.getStudentNo();
|
||||
String studentName = outsideAccommodationApply.getStudentName();
|
||||
|
||||
// 3. 先尝试从流程变量获取学生userId
|
||||
Long stuUserId = null;
|
||||
if (execution.hasVariable("stuUserId")) {
|
||||
stuUserId = Long.valueOf(execution.getVariable("stuUserId").toString());
|
||||
} else {
|
||||
// 补充逻辑:如果流程变量中没有stuUserId,通过申请表获取
|
||||
stuUserId = outsideAccommodationApply.getStudentId();
|
||||
}
|
||||
|
||||
if (stuUserId == null) {
|
||||
log.warn("⚠ 未找到学生(学号:{},姓名:{})对应的用户ID,无法发送通知", studentNo, studentName);
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. 使用userId查询对应的企业微信账号
|
||||
String stuUserName = relieveMapper.getUserNameByUserId(stuUserId);
|
||||
|
||||
if (stuUserName != null && !stuUserName.isEmpty()) {
|
||||
// 5. 拼接审批结果提示信息(适配外宿申请场景)
|
||||
String approveResultDesc = getApprovalResultDesc(approvalResult, currentNodeName);
|
||||
|
||||
// 6. 拼接最终通知内容
|
||||
String content = String.format("您的外宿申请有新的审批进展:%s(%s),%s,<a href='https://zhxg.gxsdxy.cn/wab/#/pages/Approval/index'>点此查看详情</a>",
|
||||
currentNodeName,
|
||||
approveResultDesc,
|
||||
(approvalOpinion != null && !approvalOpinion.isEmpty()) ? "审批意见:" + approvalOpinion : "");
|
||||
|
||||
// 7. 发送企业微信消息
|
||||
weChatUtil.sendTextMessage(stuUserName, content);
|
||||
log.info("✅ 已成功向学生(姓名:{},学号:{},userName:{})发送外宿申请审批通知。审批节点:{},结果:{}",
|
||||
studentName, studentNo, stuUserName, currentNodeName, approveResultDesc);
|
||||
|
||||
} else {
|
||||
log.warn("⚠ 找到了学生(学号:{},姓名:{},userId:{}),但其对应的企业微信账号为空,无法发送通知。",
|
||||
studentNo, studentName, stuUserId);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 捕获所有异常,仅记录日志,不影响主流程
|
||||
String studentNo = outsideAccommodationApply.getStudentNo();
|
||||
log.error("❌ 向学生(学号:{})发送外宿申请审批通知时出现异常,但流程将继续。错误详情:", studentNo, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换审批结果为可读描述(适配外宿申请的审批状态)
|
||||
*/
|
||||
private String getApprovalResultDesc(Long approvalResult, String currentNodeName) {
|
||||
if (approvalResult == null) {
|
||||
return "审批已处理";
|
||||
}
|
||||
switch (approvalResult.intValue()) {
|
||||
case 0:
|
||||
return currentNodeName + "驳回";
|
||||
case 1:
|
||||
return currentNodeName + "通过";
|
||||
case 2:
|
||||
return "审批中";
|
||||
default:
|
||||
return "审批已完成";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,13 +2,19 @@ package com.srs.flowable.listener.outsideAccommodation;
|
||||
|
||||
import com.srs.common.core.domain.entity.SysUser;
|
||||
import com.srs.common.doman.vo.TeacherVo;
|
||||
import com.srs.common.utils.DateUtils;
|
||||
import com.srs.common.utils.SecurityUtils;
|
||||
import com.srs.common.utils.WeChatUtil;
|
||||
import com.srs.common.utils.spring.SpringUtils;
|
||||
import com.srs.dormitory.domain.DmsOutsideAccommodationApply;
|
||||
import com.srs.flowable.domain.EnlistmentReserve;
|
||||
import com.srs.flowable.domain.NotificationManage;
|
||||
import com.srs.flowable.domain.OutsideAccommodationApply;
|
||||
import com.srs.flowable.mapper.EnlistmentReserveMapper;
|
||||
import com.srs.flowable.mapper.LeaveMapper;
|
||||
import com.srs.flowable.mapper.OutsideAccommodationApplyMapper;
|
||||
import com.srs.system.service.ISysUserService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.bpmn.model.BpmnModel;
|
||||
import org.flowable.bpmn.model.FlowNode;
|
||||
import org.flowable.engine.RepositoryService;
|
||||
@@ -25,6 +31,7 @@ import java.util.List;
|
||||
* 用于节点审批之前时,更新下一个节点的负责人变量(approval)
|
||||
*/
|
||||
@Component("OutsideAccommodationStartListener") // Spring Bean名称,与BPMN表达式对应
|
||||
@Slf4j
|
||||
public class OutsideAccommodationStartListener implements ExecutionListener {
|
||||
|
||||
@Autowired
|
||||
@@ -40,7 +47,7 @@ public class OutsideAccommodationStartListener implements ExecutionListener {
|
||||
String currentActivityId = execution.getCurrentActivityId(); // 当前节点ID(兼容所有版本)
|
||||
String processDefinitionId = execution.getProcessDefinitionId(); // 流程定义ID
|
||||
|
||||
// 2. 根据节点ID查询节点名称(核心修正:通过流程定义获取名称)
|
||||
// 2. 根据节点ID查询节点名称(通过流程定义获取名称)
|
||||
String currentNodeName = getNodeNameByActivityId(processDefinitionId, currentActivityId);
|
||||
if (currentNodeName == null) {
|
||||
throw new RuntimeException("未找到节点ID=" + currentActivityId + "的名称");
|
||||
@@ -55,6 +62,8 @@ public class OutsideAccommodationStartListener implements ExecutionListener {
|
||||
if (nextAssigneeId != null) {
|
||||
execution.setVariable("approval", nextAssigneeId);
|
||||
execution.setVariable("currentNode", currentNodeName);
|
||||
// ========== 外宿申请审批通知逻辑 ==========
|
||||
sendOutsideAccommodationNotification(execution, currentNodeName, nextAssigneeId, accommodationId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,4 +177,98 @@ public class OutsideAccommodationStartListener implements ExecutionListener {
|
||||
throw new RuntimeException("未配置节点[" + currentNodeName + "]的当前负责人规则");
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 发送外宿申请审批通知(系统通知+企业微信通知)
|
||||
*/
|
||||
private void sendOutsideAccommodationNotification(DelegateExecution execution, String currentNodeName,
|
||||
Long nextAssigneeId, Long accommodationId) {
|
||||
try {
|
||||
// 获取需要的Mapper和工具类
|
||||
OutsideAccommodationApplyMapper outsideAccommodationApplyMapper = SpringUtils.getBean(OutsideAccommodationApplyMapper.class);
|
||||
LeaveMapper leaveMapper = (LeaveMapper) SpringUtils.getBean("leaveMapper");
|
||||
WeChatUtil weChatUtil = SpringUtils.getBean(WeChatUtil.class);
|
||||
|
||||
// 1. 查询外宿申请详情
|
||||
com.srs.flowable.domain.OutsideAccommodationApply outsideAccommodationApply = outsideAccommodationApplyMapper.selectDmsOutsideAccommodationApplyById(accommodationId);
|
||||
if (outsideAccommodationApply == null) {
|
||||
log.warn("未找到外宿申请记录,ID:{}", accommodationId);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 查询下一个审批人的信息(获取用户名/工号)
|
||||
SysUser nextApprover = sysUserService.selectUserById(nextAssigneeId);
|
||||
if (nextApprover == null) {
|
||||
log.warn("未找到审批人信息,用户ID:{}", nextAssigneeId);
|
||||
return;
|
||||
}
|
||||
String approverUserName = nextApprover.getUserName(); // 审批人工号/用户名
|
||||
String approverName = nextApprover.getNickName(); // 审批人姓名
|
||||
|
||||
log.info("开始发送【外宿申请审批】通知,审批节点:{},审批人:{}({})",
|
||||
currentNodeName, approverName, approverUserName);
|
||||
|
||||
// 3. 处理系统通知(先删后加,避免重复通知)
|
||||
NotificationManage notificationManage = new NotificationManage();
|
||||
notificationManage.setContent(String.format("您有一条【外宿申请审批】待处理(节点:%s)", currentNodeName));
|
||||
notificationManage.setReceiver(nextAssigneeId); // 接收人:下一个审批人
|
||||
|
||||
// 3.1 查询是否已有相同通知,有则删除
|
||||
NotificationManage existNotify = leaveMapper.selectCphMsgListForFlowable(notificationManage);
|
||||
if (existNotify != null) {
|
||||
int delRes = leaveMapper.deleteCphMsgById(existNotify.getId());
|
||||
log.info("删除重复的系统通知,通知ID:{},删除结果:{}", existNotify.getId(), delRes);
|
||||
}
|
||||
|
||||
// 3.2 添加新的系统通知
|
||||
notificationManage.setSender(SecurityUtils.getUserId() != null ? SecurityUtils.getUserId() : 0L); // 发送人:当前操作人(兜底处理)
|
||||
notificationManage.setCreateTime(DateUtils.getNowDate()); // 创建时间
|
||||
int addRes = leaveMapper.insertCphMsg(notificationManage);
|
||||
log.info("新增系统通知成功,接收人ID:{},添加结果:{}", nextAssigneeId, addRes);
|
||||
|
||||
// 4. 企业微信推送消息
|
||||
if (approverUserName != null && !approverUserName.isEmpty()) {
|
||||
// 构造带超链接的消息内容
|
||||
String weChatContent = String.format(
|
||||
"您有一条【外宿申请审批】待处理(节点:%s),<a href='https://zhxg.gxsdxy.cn/wab/#/pages/Approval/index'>请点击前往处理</a>",
|
||||
currentNodeName
|
||||
);
|
||||
|
||||
// 发送企业微信文本消息
|
||||
weChatUtil.sendTextMessage(approverUserName, weChatContent);
|
||||
log.info("企业微信通知发送成功,接收人工号:{},节点:{}", approverUserName, currentNodeName);
|
||||
} else {
|
||||
log.warn("审批人工号为空,无法发送企业微信通知,用户ID:{}", nextAssigneeId);
|
||||
}
|
||||
|
||||
// ========== 删除当前审批人的待处理通知 ==========
|
||||
// 4.1 获取当前审批人ID(当前操作人=已完成审批的人)
|
||||
Long currentApproverId = SecurityUtils.getUserId();
|
||||
if (currentApproverId == null) {
|
||||
log.warn("当前审批人ID为空,无法删除其待处理通知");
|
||||
return;
|
||||
}
|
||||
|
||||
// 4.2 构造当前审批人的待处理通知查询条件
|
||||
NotificationManage currentNotifyQuery = new NotificationManage();
|
||||
// 内容匹配:当前节点的待处理通知(关键词+节点名称)
|
||||
currentNotifyQuery.setContent(String.format("您有一条【外宿申请审批】待处理(节点:%s)", currentNodeName));
|
||||
currentNotifyQuery.setReceiver(currentApproverId); // 接收人=当前审批人
|
||||
|
||||
// 4.3 查询当前审批人的该节点待处理通知
|
||||
NotificationManage currentExistNotify = leaveMapper.selectCphMsgListForFlowable(currentNotifyQuery);
|
||||
if (currentExistNotify != null) {
|
||||
// 4.4 删除该通知(清理已处理的待办)
|
||||
int currentDelRes = leaveMapper.deleteCphMsgById(currentExistNotify.getId());
|
||||
log.info("删除当前审批人({})的【{}】待处理通知,通知ID:{},删除结果:{}",
|
||||
currentApproverId, currentNodeName, currentExistNotify.getId(), currentDelRes);
|
||||
} else {
|
||||
log.info("当前审批人({})无【{}】节点的待处理通知,无需删除", currentApproverId, currentNodeName);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
// 捕获所有异常,仅记录日志,不影响主流程
|
||||
log.error("发送外宿申请审批通知失败,节点:{},审批人ID:{},错误信息:{}",
|
||||
currentNodeName, nextAssigneeId, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user