入伍保留学籍申请、外宿申请-上一级审批结束之后,给下一级发送审批提醒

This commit is contained in:
2025-12-22 17:39:08 +08:00
parent 27efd6a39d
commit 095aff7183
4 changed files with 378 additions and 5 deletions

View File

@@ -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查询节点名称兼容所有版本的核心方法
*/

View File

@@ -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);
}
}
}

View File

@@ -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 "审批已完成";
}
}
/**

View File

@@ -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);
}
}
}