Commit d467bfc5 by 王志超

feat: 行动工单流程流转

parent 5cb06801
Pipeline #86538 passed with stages
in 1 minute 29 seconds
......@@ -58,7 +58,6 @@ import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;
......@@ -221,19 +220,26 @@ public class ChangeSubFlowBiz {
subFlowRecord.getChangeRecordId(), changeExecProjectList, subFlowId, subFlowRecord.getId());
newExecRecords.forEach(changeFlowExecService::saveRecord);
// 提交到下一节点
String nextNodeId = flowService.submitFlow(subFlowId, flowDataDTO, uid,
ChangeFlowEnum.CHANGE_SUB_FLOW.getTopoId(), JSON.toJSONString(content), true,
FlowxOperationEnum.SUBMIT.getName(), "提交工单", subFlowRecord.getCreateTime());
// 检查是否需要审批,通过paramMap控制流转方向
Map<String, Object> paramMap = new HashMap<>();
String nextNodeId;
// 检查是否需要审批
if (needApprove(expectedDepartment)) {
// 需要审批:流转到审批行动方案节点,设置上级领导为审批人
log.info("[CHANGE_SUB_FLOW_START] 部门[{}]需要审批,等待上级审批", expectedDepartment);
// 需要审批:设置上级领导为审批人,停留在审批节点
paramMap.put("type", 1);
// 提交到审批行动方案节点
nextNodeId = flowService.submitFlowWithParamMap(subFlowId, flowDataDTO, uid,
ChangeFlowEnum.CHANGE_SUB_FLOW.getTopoId(), JSON.toJSONString(content), paramMap,
FlowxOperationEnum.SUBMIT.getName(), "提交工单", subFlowRecord.getCreateTime());
// 更新子单记录
subFlowRecord.setSubFlowNode(nextNodeId);
subFlowRecord.setStatus(ChangeSubFlowStatusEnum.WAIT_APPROVE_ACTION_PLAN.getStatus());
subFlowRecord.setUpdateTime(DateUtils.getCurrentTime());
// 获取上级领导并设置为审批人
String execUserEmail = subFlowRecord.getChangeExecUserEmail();
if (StringUtils.isBlank(execUserEmail)) {
throw ExceptionFactory.createBiz(ResponseCode.BAD_REQUEST, "行动人邮箱不能为空");
......@@ -243,39 +249,33 @@ public class ChangeSubFlowBiz {
throw ExceptionFactory.createBiz(ResponseCode.BAD_REQUEST,
String.format("行动人[%s]的部门上级领导不存在", execUserEmail));
}
// 设置审批人为上级领导(JSON 数组格式)
subFlowRecord.setApprover(JSON.toJSONString(Collections.singletonList(leaderEmail)));
changeSubFlowRecordService.update(subFlowRecord);
log.info("[checkUpdateAndSubmit] 子单流转完成 <<< subFlowId:{}, 原节点:{}-{}, 新节点:{}-审批行动方案",
subFlowId, oldNodeId, oldNodeName, nextNodeId);
return nextNodeId;
} else {
// 不需要审批,自动提交到下一节点(审批人保持为行动人自己)
// 不需要审批:直接跳到审批变更方案节点,审批人保持为行动人自己
log.info("[CHANGE_SUB_FLOW_START] 部门[{}]不需要审批,自动跳过审批", expectedDepartment);
paramMap.put("type", 2);
// 重新查询最新的flowDataDTO,因为第一次submitFlow已经改变了flow状态
FlowDataDTO latestFlowDataDTO = flowService.flowDetail(subFlowId);
if (latestFlowDataDTO == null) {
throw ExceptionFactory.createBiz(ResponseCode.DETAIL_FLOW_ERROR, "子流程工单查询错误,不存在");
}
// 使用paramMap控制流转方向(type=1表示审批通过)
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("type", 1);
String autoNextNodeId = flowService.submitFlowWithParamMap(subFlowId, latestFlowDataDTO, uid,
// 提交到审批变更方案节点
nextNodeId = flowService.submitFlowWithParamMap(subFlowId, flowDataDTO, uid,
ChangeFlowEnum.CHANGE_SUB_FLOW.getTopoId(), JSON.toJSONString(content), paramMap,
FlowxOperationEnum.SUBMIT.getName(), "自动审批通过", subFlowRecord.getCreateTime());
subFlowRecord.setSubFlowNode(autoNextNodeId);
FlowxOperationEnum.SUBMIT.getName(), "提交工单", subFlowRecord.getCreateTime());
// 更新子单记录
subFlowRecord.setSubFlowNode(nextNodeId);
subFlowRecord.setStatus(ChangeSubFlowStatusEnum.WAIT_APPROVE_CHANGE_PLAN.getStatus());
subFlowRecord.setUpdateTime(DateUtils.getCurrentTime());
changeSubFlowRecordService.update(subFlowRecord);
// todo:非名单中部门无需审批,行动人确认提交后邮件同步负责人上级对应变更信息
log.info("[checkUpdateAndSubmit] 子单流转完成 <<< subFlowId:{}, 原节点:{}-{}, 新节点:{}-审批变更方案 (自动跳过审批)",
subFlowId, oldNodeId, oldNodeName, autoNextNodeId);
return autoNextNodeId;
subFlowId, oldNodeId, oldNodeName, nextNodeId);
}
changeSubFlowRecordService.update(subFlowRecord);
return nextNodeId;
case CHANGE_SUB_FLOW_SUBMIT:
// 审批行动方案节点
Boolean approved = changeSubFlowSubmitReq.getApproved();
......@@ -293,10 +293,13 @@ public class ChangeSubFlowBiz {
log.info("[CHANGE_SUB_FLOW_SUBMIT] 审批不通过,subFlowId:{}, rejectReason:{}", subFlowId, rejectReason);
}
// 提交工单(根据审批结果流转到不同节点)
// 使用paramMap控制流转方向(type=1通过,type=2不通过)
Map<String, Object> approveParamMap = new HashMap<>();
approveParamMap.put("type", approved ? 1 : 2);
String remark = approved ? "审批通过" : "审批不通过";
String approveNodeId = flowService.submitFlow(subFlowId, flowDataDTO, uid,
ChangeFlowEnum.CHANGE_SUB_FLOW.getTopoId(), JSON.toJSONString(content), approved,
String approveNodeId = flowService.submitFlowWithParamMap(subFlowId, flowDataDTO, uid,
ChangeFlowEnum.CHANGE_SUB_FLOW.getTopoId(), JSON.toJSONString(content), approveParamMap,
FlowxOperationEnum.SUBMIT.getName(), remark, subFlowRecord.getCreateTime());
// 更新行动工单
......@@ -318,36 +321,60 @@ public class ChangeSubFlowBiz {
throw ExceptionFactory.createBiz(ResponseCode.BAD_REQUEST, "审批结果不能为空");
}
if (!execApproved) {
// 审批不通过,拒绝原因必填
// 使用paramMap控制流转方向
Map<String, Object> execParamMap = new HashMap<>();
String execNodeId;
if (execApproved) {
// 审批通过:流转到提交执行结果节点
log.info("[CHANGE_SUB_FLOW_EXE] 审批通过,subFlowId:{}", subFlowId);
execParamMap.put("type", 1);
// 提交到提交执行结果节点
execNodeId = flowService.submitFlowWithParamMap(subFlowId, flowDataDTO, uid,
ChangeFlowEnum.CHANGE_SUB_FLOW.getTopoId(), JSON.toJSONString(content), execParamMap,
FlowxOperationEnum.SUBMIT.getName(), "审批通过", subFlowRecord.getCreateTime());
// 更新子单记录
subFlowRecord.setSubFlowNode(execNodeId);
subFlowRecord.setStatus(ChangeSubFlowStatusEnum.WAIT_SUBMIT_RESULT.getStatus());
subFlowRecord.setUpdateTime(DateUtils.getCurrentTime());
changeSubFlowRecordService.update(subFlowRecord);
log.info("[checkUpdateAndSubmit] 子单流转完成 <<< subFlowId:{}, 原节点:{}-{}, 新节点:{}-提交执行结果, 审批结果:通过",
subFlowId, oldNodeId, oldNodeName, execNodeId);
// 检查所有子单是否都已到达提交执行结果节点,如果是则流转主工单
if (checkAllSubFlowsApproved(subFlowRecord.getChangeRecordId())) {
changeFlowBiz.submitMainFlowAfterAllSubFlowsApproved(subFlowRecord.getChangeRecordId());
log.info("[CHANGE_SUB_FLOW_EXE] 所有子单均已到达提交执行结果节点,主工单已流转");
}
} else {
// 审批不通过:回退到确认行动方案节点,拒绝原因必填
String execRejectReason = changeSubFlowSubmitReq.getRejectReason();
if (StringUtils.isBlank(execRejectReason)) {
throw ExceptionFactory.createBiz(ResponseCode.BAD_REQUEST, "拒绝原因不能为空");
}
subFlowRecord.setChangePlanApproved(false);
subFlowRecord.setRejectReason(execRejectReason);
subFlowRecord.setStatus(ChangeSubFlowStatusEnum.CANCELLED.getStatus());
subFlowRecord.setUpdateTime(DateUtils.getCurrentTime());
changeSubFlowRecordService.update(subFlowRecord);
log.info("[CHANGE_SUB_FLOW_EXE] 审批不通过,subFlowId:{}, rejectReason:{}", subFlowId, execRejectReason);
} else {
// 审批通过,只标记 changePlanApproved=true,子单不流转
subFlowRecord.setChangePlanApproved(true);
execParamMap.put("type", 2);
// 提交到确认行动方案节点
execNodeId = flowService.submitFlowWithParamMap(subFlowId, flowDataDTO, uid,
ChangeFlowEnum.CHANGE_SUB_FLOW.getTopoId(), JSON.toJSONString(content), execParamMap,
FlowxOperationEnum.SUBMIT.getName(), "审批不通过", subFlowRecord.getCreateTime());
// 更新子单记录
subFlowRecord.setSubFlowNode(execNodeId);
subFlowRecord.setStatus(ChangeSubFlowStatusEnum.CANCELLED.getStatus());
subFlowRecord.setUpdateTime(DateUtils.getCurrentTime());
changeSubFlowRecordService.update(subFlowRecord);
log.info("[CHANGE_SUB_FLOW_EXE] 审批通过,subFlowId:{}, 标记changePlanApproved=true", subFlowId);
// 检查该主工单下所有子单是否都已审批通过
if (checkAllSubFlowsApproved(subFlowRecord.getChangeRecordId())) {
// 所有子单都通过,流转主工单
changeFlowBiz.submitMainFlowAfterAllSubFlowsApproved(subFlowRecord.getChangeRecordId());
log.info("[CHANGE_SUB_FLOW_EXE] 所有子单均已审批通过,主工单已流转");
}
log.info("[checkUpdateAndSubmit] 子单流转完成 <<< subFlowId:{}, 原节点:{}-{}, 新节点:{}-确认行动方案, 审批结果:不通过",
subFlowId, oldNodeId, oldNodeName, execNodeId);
}
log.info("[checkUpdateAndSubmit] 子单流转完成 <<< subFlowId:{}, 节点保持:{}-{}, 审批结果:{}",
subFlowId, oldNodeId, oldNodeName, execApproved ? "通过" : "不通过");
return subFlowRecord.getSubFlowNode();
return execNodeId;
case CHANGE_SUB_FLOW_CONFIRM:
// 提交执行结果节点,填写变更结论
......@@ -543,11 +570,11 @@ public class ChangeSubFlowBiz {
}
/**
* 检查主工单下所有子单是否都已审批通过
* 条件:节点是 CHANGE_SUB_FLOW_EXE 且 changePlanApproved=true
* 检查主工单下所有子单是否都已到达提交执行结果节点
* 条件:status = WAIT_SUBMIT_RESULT 且 subFlowNode = CHANGE_SUB_FLOW_CONFIRM
*
* @param changeRecordId 主工单ID
* @return true 表示所有子单都已审批通过
* @return true 表示所有子单都已到达提交执行结果节点
*/
private boolean checkAllSubFlowsApproved(Long changeRecordId) {
// 查询该主工单下所有子单
......@@ -556,10 +583,10 @@ public class ChangeSubFlowBiz {
return false;
}
// 检查是否所有子单都满足条件:节点是 CHANGE_SUB_FLOW_EXE 且 changePlanApproved=true
// 检查是否所有子单都满足条件:status = WAIT_SUBMIT_RESULT 且 subFlowNode = CHANGE_SUB_FLOW_CONFIRM
return allSubFlows.stream().allMatch(subFlow ->
ChangeFlowEnum.CHANGE_SUB_FLOW_EXE.getNodeId().equals(subFlow.getSubFlowNode())
&& Boolean.TRUE.equals(subFlow.getChangePlanApproved())
ChangeSubFlowStatusEnum.WAIT_SUBMIT_RESULT.getStatus().equals(subFlow.getStatus())
&& ChangeFlowEnum.CHANGE_SUB_FLOW_CONFIRM.getNodeId().equals(subFlow.getSubFlowNode())
);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment