Browse Source

撤回、驳回删除节点,下达再重新建节点

ecss-tx
han\hanst 1 month ago
parent
commit
f6a04c55a6
  1. 12
      src/main/java/com/xujie/sys/modules/erf/service/ErfFlowEngineService.java
  2. 40
      src/main/java/com/xujie/sys/modules/erf/service/impl/ErfExpApplyServiceImpl.java
  3. 99
      src/main/java/com/xujie/sys/modules/erf/service/impl/ErfFlowEngineServiceImpl.java

12
src/main/java/com/xujie/sys/modules/erf/service/ErfFlowEngineService.java

@ -33,19 +33,13 @@ public interface ErfFlowEngineService {
void startFlowWithApprovers(String applyNo, String buCode, Long creatorUserId, Map<String, Object> approverInfo); void startFlowWithApprovers(String applyNo, String buCode, Long creatorUserId, Map<String, Object> approverInfo);
/** /**
* 重新启动流程驳回后重新下达
* 删除申请单的所有流程节点实例
* *
* <p> startFlowWithApprovers 的区别</p>
* <ul>
* <li>不创建新的流程实例重用已有的</li>
* <li>更新流程实例的审批人信息</li>
* <li>创建新的节点实例attempt_no 递增</li>
* </ul>
* <p>撤回操作时调用清空节点记录下次下达时重新创建</p>
* *
* @param applyNo 申请单号 * @param applyNo 申请单号
* @param approverInfo 审批人信息techManagerId, prodManagerIds, qualityManagerIds
*/ */
void restartFlowWithApprovers(String applyNo, Map<String, Object> approverInfo);
void deleteFlowNodes(String applyNo);
/** /**
* 流转到下一个节点 * 流转到下一个节点

40
src/main/java/com/xujie/sys/modules/erf/service/impl/ErfExpApplyServiceImpl.java

@ -140,19 +140,9 @@ public class ErfExpApplyServiceImpl extends ServiceImpl<ErfExpApplyMapper, ErfEx
throw new XJException("质量经理未指定"); throw new XJException("质量经理未指定");
} }
// 修复漏洞检查是否已存在流程实例判断是首次下达还是重新下达
// 正确的判断方式查询流程实例表而不是只看申请单状态
// 因为撤回后状态也是"草稿"但流程实例已经存在
QueryWrapper<ErfFlowInstance> flowQuery = new QueryWrapper<>();
flowQuery.eq("apply_no", data.getApplyNo());
ErfFlowInstance existingFlow = erfFlowInstanceMapper.selectOne(flowQuery);
boolean isFirstSubmit = (existingFlow == null);
String action = isFirstSubmit ? "首次下达" :
("已驳回".equals(entity.getStatus()) ? "驳回后重新下达" : "撤回后重新下达");
String action = "已驳回".equals(entity.getStatus()) ? "驳回后重新下达" : "下达";
log.info("申请单: {}, 流程实例存在: {}, 当前状态: {}, 操作: {}",
data.getApplyNo(), existingFlow != null, entity.getStatus(), action);
log.info("申请单: {}, 当前状态: {}, 操作: {}", data.getApplyNo(), entity.getStatus(), action);
// 更新申请单状态updateTime由MyBatis-Plus自动填充 // 更新申请单状态updateTime由MyBatis-Plus自动填充
entity.setStatus("已下达"); entity.setStatus("已下达");
@ -166,22 +156,13 @@ public class ErfExpApplyServiceImpl extends ServiceImpl<ErfExpApplyMapper, ErfEx
approverInfo.put("prodManagerIds", data.getProdManagerIds()); approverInfo.put("prodManagerIds", data.getProdManagerIds());
approverInfo.put("qualityManagerIds", data.getQualityManagerIds()); approverInfo.put("qualityManagerIds", data.getQualityManagerIds());
if (isFirstSubmit) {
// 首次下达创建新的流程实例
log.info("首次下达,创建流程实例");
erfFlowEngineService.startFlowWithApprovers(
entity.getApplyNo(),
entity.getBuNo(),
entity.getCreatorUserId(),
approverInfo
);
} else {
// 重新下达驳回后或撤回后重用已有流程实例不创建新的
erfFlowEngineService.restartFlowWithApprovers(
entity.getApplyNo(),
approverInfo
);
}
// 无论首次还是重新下达都新建节点startFlowWithApprovers 内部会先删除旧节点
erfFlowEngineService.startFlowWithApprovers(
entity.getApplyNo(),
entity.getBuNo(),
entity.getCreatorUserId(),
approverInfo
);
// 记录操作日志 - 获取审批人用户名 // 记录操作日志 - 获取审批人用户名
String techManagerName = getUserDisplayById(data.getTechManagerId()); String techManagerName = getUserDisplayById(data.getTechManagerId());
@ -333,6 +314,9 @@ public class ErfExpApplyServiceImpl extends ServiceImpl<ErfExpApplyMapper, ErfEx
entity.setStatus("草稿"); entity.setStatus("草稿");
this.updateById(entity); this.updateById(entity);
// 撤回时删除所有流程节点下次下达时重新创建
erfFlowEngineService.deleteFlowNodes(applyNo);
log.info("撤回工程实验申请单: {}", applyNo); log.info("撤回工程实验申请单: {}", applyNo);
} }

99
src/main/java/com/xujie/sys/modules/erf/service/impl/ErfFlowEngineServiceImpl.java

@ -107,102 +107,61 @@ public class ErfFlowEngineServiceImpl implements ErfFlowEngineService {
log.info("审批人信息 - 技术经理: {}, 生产经理: {}, 质量经理: {}", log.info("审批人信息 - 技术经理: {}, 生产经理: {}, 质量经理: {}",
techManagerId, prodManagerIds, qualityManagerIds); techManagerId, prodManagerIds, qualityManagerIds);
// 创建流程实例保存审批人信息到remark字段
ErfFlowInstance flowInstance = new ErfFlowInstance();
flowInstance.setApplyNo(applyNo);
flowInstance.setFlowCode("EXP_APPLY_" + buCode);
flowInstance.setFlowVersion(1);
flowInstance.setStatus("运行中");
flowInstance.setStartTime(new Date());
flowInstance.setCurrentNodeCode("技术经理审批");
// 1. 删除该申请单已有的所有节点实例确保每次下达都是全新的节点
deleteFlowNodes(applyNo);
// 将审批人信息序列化保存到remark字段方便后续节点读取
// 2. 将审批人信息序列化保存到remark字段方便后续节点读取
String approverJson = String.format( String approverJson = String.format(
"{\"techManagerId\":%d,\"prodManagerIds\":[%s],\"qualityManagerIds\":[%s]}", "{\"techManagerId\":%d,\"prodManagerIds\":[%s],\"qualityManagerIds\":[%s]}",
techManagerId, techManagerId,
prodManagerIds.stream().map(String::valueOf).collect(Collectors.joining(",")), prodManagerIds.stream().map(String::valueOf).collect(Collectors.joining(",")),
qualityManagerIds.stream().map(String::valueOf).collect(Collectors.joining(",")) qualityManagerIds.stream().map(String::valueOf).collect(Collectors.joining(","))
); );
flowInstance.setRemark(approverJson);
erfFlowInstanceMapper.insert(flowInstance);
// 创建第一个审批节点实例技术经理审批
ErfFlowNodeInstance nodeInstance = new ErfFlowNodeInstance();
nodeInstance.setApplyNo(applyNo);
nodeInstance.setNodeCode("技术经理审批");
nodeInstance.setAttemptNo(1);
nodeInstance.setStatus("待审核");
nodeInstance.setReceiveTime(new Date());
nodeInstance.setAssigneeUserId(techManagerId); // 使用传入的技术经理ID
// 根据审批人id查询审批人名称并设置到节点实例冗余存储方便查询和展示
nodeInstance.setAssigneeName(sysUserDao.getUserDisplayById(techManagerId));
erfFlowNodeInstanceMapper.insert(nodeInstance);
log.info("流程启动成功,当前节点:技术经理审批,审批人ID:{}", techManagerId);
}
@Override
public void restartFlowWithApprovers(String applyNo, Map<String, Object> approverInfo) {
log.info("=== 重新启动流程(驳回后重新下达)=== 申请单号: {}", applyNo);
Long techManagerId = (Long) approverInfo.get("techManagerId");
@SuppressWarnings("unchecked")
List<Long> prodManagerIds = (List<Long>) approverInfo.get("prodManagerIds");
@SuppressWarnings("unchecked")
List<Long> qualityManagerIds = (List<Long>) approverInfo.get("qualityManagerIds");
log.info("审批人信息 - 技术经理: {}, 生产经理: {}, 质量经理: {}",
techManagerId, prodManagerIds, qualityManagerIds);
// 1. 查询已有的流程实例
// 3. 创建或更新流程实例
QueryWrapper<ErfFlowInstance> flowQuery = new QueryWrapper<>(); QueryWrapper<ErfFlowInstance> flowQuery = new QueryWrapper<>();
flowQuery.eq("apply_no", applyNo); flowQuery.eq("apply_no", applyNo);
ErfFlowInstance flowInstance = erfFlowInstanceMapper.selectOne(flowQuery); ErfFlowInstance flowInstance = erfFlowInstanceMapper.selectOne(flowQuery);
boolean isNewInstance = (flowInstance == null);
if (flowInstance == null) { if (flowInstance == null) {
throw new XJException("流程实例不存在,无法重新下达");
flowInstance = new ErfFlowInstance();
flowInstance.setApplyNo(applyNo);
flowInstance.setFlowCode("EXP_APPLY_" + buCode);
flowInstance.setFlowVersion(1);
flowInstance.setStartTime(new Date());
} }
// 2. 更新流程实例的审批人信息和状态
flowInstance.setStatus("运行中"); flowInstance.setStatus("运行中");
flowInstance.setCurrentNodeCode("技术经理审批"); flowInstance.setCurrentNodeCode("技术经理审批");
// 更新审批人信息到remark字段
String approverJson = String.format(
"{\"techManagerId\":%d,\"prodManagerIds\":[%s],\"qualityManagerIds\":[%s]}",
techManagerId,
prodManagerIds.stream().map(String::valueOf).collect(Collectors.joining(",")),
qualityManagerIds.stream().map(String::valueOf).collect(Collectors.joining(","))
);
flowInstance.setRemark(approverJson); flowInstance.setRemark(approverJson);
erfFlowInstanceMapper.updateById(flowInstance);
log.info("更新流程实例,当前节点:技术经理审批");
// 3. 查询技术经理审批节点的最大attempt_no
QueryWrapper<ErfFlowNodeInstance> nodeQuery = new QueryWrapper<>();
nodeQuery.eq("apply_no", applyNo)
.eq("node_code", "技术经理审批")
.orderByDesc("attempt_no")
.last("OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY");
ErfFlowNodeInstance lastInstance = erfFlowNodeInstanceMapper.selectOne(nodeQuery);
int nextAttemptNo = (lastInstance != null) ? lastInstance.getAttemptNo() + 1 : 1;
if (isNewInstance) {
erfFlowInstanceMapper.insert(flowInstance);
log.info("新建流程实例");
} else {
erfFlowInstanceMapper.updateById(flowInstance);
log.info("更新已有流程实例");
}
// 4. 创建新的技术经理审批节点实例attempt_no递增
// 4. 创建第一个审批节点实例技术经理审批
ErfFlowNodeInstance nodeInstance = new ErfFlowNodeInstance(); ErfFlowNodeInstance nodeInstance = new ErfFlowNodeInstance();
nodeInstance.setApplyNo(applyNo); nodeInstance.setApplyNo(applyNo);
nodeInstance.setNodeCode("技术经理审批"); nodeInstance.setNodeCode("技术经理审批");
nodeInstance.setAttemptNo(nextAttemptNo);
nodeInstance.setAttemptNo(1);
nodeInstance.setStatus("待审核"); nodeInstance.setStatus("待审核");
nodeInstance.setReceiveTime(new Date()); nodeInstance.setReceiveTime(new Date());
nodeInstance.setAssigneeUserId(techManagerId); // 使用新的技术经理ID
// 根据审批人id查询审批人名称并设置到节点实例冗余存储方便查询和展示
nodeInstance.setAssigneeUserId(techManagerId);
nodeInstance.setAssigneeName(sysUserDao.getUserDisplayById(techManagerId)); nodeInstance.setAssigneeName(sysUserDao.getUserDisplayById(techManagerId));
erfFlowNodeInstanceMapper.insert(nodeInstance); erfFlowNodeInstanceMapper.insert(nodeInstance);
log.info("流程重新启动成功,当前节点:技术经理审批,尝试次数:{},审批人ID:{}",
nextAttemptNo, techManagerId);
log.info("流程启动成功,当前节点:技术经理审批,审批人ID:{}", techManagerId);
}
@Override
public void deleteFlowNodes(String applyNo) {
int deletedCount = erfFlowNodeInstanceMapper.delete(
new QueryWrapper<ErfFlowNodeInstance>().eq("apply_no", applyNo)
);
log.info("删除申请单 {} 的流程节点实例,共 {} 条", applyNo, deletedCount);
} }
@Override @Override

Loading…
Cancel
Save