补全AfterImplDeptLeaderApproveFeedbackListener监听器

This commit is contained in:
wsm
2026-05-22 16:28:55 +08:00
parent e3be62749d
commit 286659dd6b
@@ -2,21 +2,26 @@ package org.jeecg.xispeakfb.listener;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.flowable.engine.delegate.TaskListener; import org.flowable.engine.delegate.TaskListener;
import org.flowable.task.service.delegate.DelegateTask; import org.flowable.task.service.delegate.DelegateTask;
import org.jeecg.common.api.vo.Result; import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.bg.xispeak.entity.BgXiSpeak;
import org.jeecg.modules.bg.xispeak.entity.BgXiSpeakFeedback; import org.jeecg.modules.bg.xispeak.entity.BgXiSpeakFeedback;
import org.jeecg.modules.bg.xispeak.entity.DeptApproveDetail;
import org.jeecg.modules.bg.xispeak.entity.DeptApproveDetailMap;
import org.jeecg.modules.bg.xispeak.service.IBgXiSpeakFeedbackService; import org.jeecg.modules.bg.xispeak.service.IBgXiSpeakFeedbackService;
import org.jeecg.modules.bg.xispeak.service.IBgXiSpeakService;
import org.jeecg.modules.tasktask.constant.FlowConstants; import org.jeecg.modules.tasktask.constant.FlowConstants;
import org.jeecg.modules.tasktask.entity.TaskTask; import org.jeecg.modules.tasktask.entity.TaskTask;
import org.jeecg.modules.tasktask.service.ITaskTaskService; import org.jeecg.modules.tasktask.service.ITaskTaskService;
import org.jeecg.xispeak.XiSpeakConfig;
import org.jeecg.xispeakfb.XiSpeakFeedbackConfig; import org.jeecg.xispeakfb.XiSpeakFeedbackConfig;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.HashMap; import java.util.*;
import java.util.Map;
@Slf4j @Slf4j
@Component("AfterImplDeptLeaderApproveFeedbackListener") @Component("AfterImplDeptLeaderApproveFeedbackListener")
@@ -24,13 +29,96 @@ import java.util.Map;
public class AfterImplDeptLeaderApproveListener implements TaskListener { public class AfterImplDeptLeaderApproveListener implements TaskListener {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final XiSpeakFeedbackConfig xiSpeakFeedbackConfig; private final XiSpeakFeedbackConfig xiSpeakFeedbackConfig;
private final IBgXiSpeakFeedbackService bgXiSpeakFeedbackService; private final IBgXiSpeakFeedbackService bgXiSpeakFeedbackService;
private final ITaskTaskService taskTaskService; private final ITaskTaskService taskTaskService;
private final XiSpeakConfig xiSpeakConfig;
private final IBgXiSpeakService bgXiSpeakService;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void notify(DelegateTask delegateTask) { public void notify(DelegateTask delegateTask) {
String currentWorkerName = delegateTask.getAssignee();
Object rawBusinessKey = delegateTask.getVariable(xiSpeakConfig.getXiSpeak().getBusinessKey());
String taskId = delegateTask.getId();
// 1. 基础边界防御性校验
if (StringUtils.isEmpty(currentWorkerName) || rawBusinessKey == null) {
log.warn("【任务通知】无法获取有效的审批人或业务ID,略过处理。TaskId: {}, Assignee: {}, BusinessKey: {}",
taskId, currentWorkerName, rawBusinessKey);
return;
}
String businessKeyStr = rawBusinessKey.toString();
try {
// 2. 🎯 架构优化:移除 FOR UPDATE 悲观锁,改用普通查询,预防工作流交叉死锁
BgXiSpeak xiSpeak = bgXiSpeakService.getById(businessKeyStr);
if (xiSpeak == null) {
log.error("【任务通知】业务数据不存在,终止处理。BusinessKey: {}", businessKeyStr);
return;
}
// 3. 部门变量安全解析
String implDeptKey = xiSpeakConfig.getXiSpeak().getImplDeptCollectionUsedKey();
Object rawDeptVar = delegateTask.getVariableLocal(implDeptKey);
if (rawDeptVar == null) {
rawDeptVar = delegateTask.getVariable(implDeptKey);
}
if (rawDeptVar == null) {
log.error("【任务通知】流程数据异常:未找到实施部门ID变量: {}, BusinessKey: {}", implDeptKey, businessKeyStr);
return;
}
// 🎯 优化:更安全的解析机制
String cleanDeptId = parseDeptId(rawDeptVar);
// 4. 安全获取或创建部门审批详情
DeptApproveDetailMap approveMap = xiSpeak.getApproveInfo();
if (approveMap == null) {
approveMap = new DeptApproveDetailMap();
}
DeptApproveDetail detail = approveMap.get(cleanDeptId);
if (detail == null) {
detail = new DeptApproveDetail();
detail.setDeptId(cleanDeptId);
detail.setImplUserNameList(new ArrayList<>());
approveMap.put(cleanDeptId, detail);
}
// 5. 状态比对与幂等更新
if (!Objects.equals(detail.getApproverName(), currentWorkerName)) {
detail.setApproverName(currentWorkerName);
// 写回并更新
xiSpeak.setApproveInfo(approveMap);
bgXiSpeakService.updateById(xiSpeak);
log.info("【任务通知】业务单据 [{}] 部门 [{}] 经办人审批记录成功更新为: {}",
businessKeyStr, cleanDeptId, currentWorkerName);
} else {
log.info("【任务通知】业务单据 [{}] 部门 [{}] 经办人未发生变化 [{}], 跳过数据库更新",
businessKeyStr, cleanDeptId, currentWorkerName);
}
} catch (Exception e) {
// 6. 异常全上下文捕获,方便线上无缝排查
log.error(String.format("【任务通知】处理任务结束监听器异常。TaskId: %s, BusinessKey: %s", taskId, businessKeyStr), e);
throw e; // 抛出异常以触发 Spring 事务和 Flowable 流程回滚
}
}
/**
* 辅助方法:安全解析部门ID,支持 Collection 和 String 表现形式
*/
private String parseDeptId(Object rawDeptVar) {
if (rawDeptVar instanceof Collection) {
Collection<?> collection = (Collection<?>) rawDeptVar;
if (!collection.isEmpty()) {
return Objects.toString(collection.iterator().next(), "").trim();
}
}
return rawDeptVar.toString().replace("[", "").replace("]", "").trim();
} }
} }