Commit 5443ba39 by 王志超

feat: 子工单分批流转逻辑处理

parent 5e45ca3d
......@@ -704,24 +704,9 @@ public class ChangeFlowBiz {
buildAndSendEmail.buildAndSendEmailSubmit(changeRecord, changeExecRecords);
return submitNode;
case NEW_CHANGE_FLOW_CONFIRM_EXEC_PLAN:
// 确认变更方案节点:检查所有子单是否都已审批通过
if (!checkAllSubFlowsApprovedForMainFlow(changeRecord.getId())) {
// 确认变更方案节点:由子单审批通过后自动触发,不应该由前端主动调用
throw ExceptionFactory.createBiz(ResponseCode.BAD_REQUEST,
"存在子单未审批通过,无法流转主工单");
}
// 所有子单都已审批通过,流转主工单到部门负责人审批节点
String ownerApproveNodeId = flowService.submitFlow(flowId.toString(), flowDataDTO, uid,
ChangeFlowEnum.NEW_CHANGE_FLOW.getTopoId(), JSON.toJSONString(content), true,
FlowxOperationEnum.SUBMIT.getName(), "所有子单审批通过,主工单流转", changeRecord.getCreateTime());
changeRecord.setFlowNode(ownerApproveNodeId);
changeRecord.setState(ChangeStatusEnum.WAIT_DEPT_LEADER_APPROVE.getStatus());
changeRecord.setUpdateTime(DateUtils.getCurrentTime());
changeFlowService.updateRecord(changeRecord);
log.info("[NEW_CHANGE_FLOW_CONFIRM_EXEC_PLAN] 主工单流转成功,flowId:{}, nextNodeId:{}",
flowId, ownerApproveNodeId);
return ownerApproveNodeId;
"该节点不允许主动提交,需等待所有子单审批通过后自动流转");
case NEW_CHANGE_FLOW_OWNER_APPROVE:
case NEW_CHANGE_FLOW_ADMIN_APPROVE:
case NEW_CHANGE_FLOW_QUALITY_APPROVE:
......@@ -1739,24 +1724,58 @@ public class ChangeFlowBiz {
}
/**
* 检查主工单下所有子单是否都已审批通过(供主工单流转时调用)
* 条件:节点是 CHANGE_SUB_FLOW_EXE 且 changePlanApproved=true
* 所有子单审批通过后,流转主工单到部门负责人审批节点
* 从 NEW_CHANGE_FLOW_CONFIRM_EXEC_PLAN 流转到 NEW_CHANGE_FLOW_OWNER_APPROVE
*
* @param changeRecordId 主工单ID
* @return true 表示所有子单都已审批通过
*/
public boolean checkAllSubFlowsApprovedForMainFlow(Long changeRecordId) {
// 查询该主工单下所有子单
List<ChangeSubFlowRecord> allSubFlows = changeSubFlowRecordMapper.selectByChangeRecordId(changeRecordId);
if (CollectionUtils.isEmpty(allSubFlows)) {
return false;
void submitMainFlowAfterAllSubFlowsApproved(Long changeRecordId) {
// 查询主工单
ChangeRecord changeRecord = changeRecordMapper.selectByPrimaryKey(changeRecordId);
if (changeRecord == null) {
log.error("[submitMainFlowAfterAllSubFlowsApproved] 主工单不存在,changeRecordId:{}", changeRecordId);
throw ExceptionFactory.createBiz(ResponseCode.BAD_REQUEST, "主工单不存在");
}
// 检查是否所有子单都满足条件:节点是 CHANGE_SUB_FLOW_EXE 且 changePlanApproved=true
return allSubFlows.stream().allMatch(subFlow ->
ChangeFlowEnum.CHANGE_SUB_FLOW_EXE.getNodeId().equals(subFlow.getSubFlowNode())
&& Boolean.TRUE.equals(subFlow.getChangePlanApproved())
);
// 验证主工单当前节点
String currentNode = changeRecord.getFlowNode();
if (!ChangeFlowEnum.NEW_CHANGE_FLOW_CONFIRM_EXEC_PLAN.getNodeId().equals(currentNode)) {
throw ExceptionFactory.createBiz(ResponseCode.NODE_ERROR,
String.format("主工单当前节点不是确认变更方案节点,无法流转。当前节点:%s", currentNode));
}
try {
Long flowId = changeRecord.getFlowId();
String uid = RequestLocalBean.getUid();
// 获取工单详情
FlowDataDTO flowDataDTO = flowService.flowDetail(flowId.toString());
if (flowDataDTO == null) {
throw ExceptionFactory.createBiz(ResponseCode.DETAIL_FLOW_ERROR, "工单查询错误,不存在");
}
// 构建提交内容
Map<String, Object> content = new HashMap<>(CommonConstants.INIT_HASH_MAP_SIZE);
content.put("updateTime", System.currentTimeMillis());
content.put(CommonConstants.FLOW_OPERATION_KEY, FlowOperationTypeEnum.PASS.getValue());
// 流转主工单到部门负责人审批节点
String ownerApproveNodeId = flowService.submitFlow(flowId.toString(), flowDataDTO, uid,
ChangeFlowEnum.NEW_CHANGE_FLOW.getTopoId(), JSON.toJSONString(content), true,
FlowxOperationEnum.SUBMIT.getName(), "所有子单审批通过,主工单流转", changeRecord.getCreateTime());
changeRecord.setFlowNode(ownerApproveNodeId);
changeRecord.setState(ChangeStatusEnum.WAIT_DEPT_LEADER_APPROVE.getStatus());
changeRecord.setUpdateTime(DateUtils.getCurrentTime());
changeFlowService.updateRecord(changeRecord);
log.info("[submitMainFlowAfterAllSubFlowsApproved] 主工单流转成功,flowId:{}, nextNodeId:{}",
flowId, ownerApproveNodeId);
} catch (Exception e) {
log.error("[submitMainFlowAfterAllSubFlowsApproved] 主工单流转失败,changeRecordId:{}", changeRecordId, e);
throw ExceptionFactory.createBiz(ResponseCode.BAD_REQUEST,
String.format("主工单流转失败:%s", e.getMessage()));
}
}
/**
......
......@@ -33,7 +33,6 @@ import com.netease.mail.yanxuan.change.dal.mapper.ChangeSubFlowRecordMapper;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeExecConfigReq;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeFlowFile;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeFlowListQueryReq;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeFlowSubmitReq;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeSubFlowCreateReq;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeSubFlowListQueryReq;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeSubFlowSubmitReq;
......@@ -299,28 +298,17 @@ public class ChangeSubFlowBiz {
changeSubFlowRecordService.update(subFlowRecord);
log.info("[CHANGE_SUB_FLOW_EXE] 审批不通过,subFlowId:{}, rejectReason:{}", subFlowId, execRejectReason);
} else {
// 审批通过,只标记 changePlanApproved=true,暂不更新状态和流转工单
// 审批通过,只标记 changePlanApproved=true,子单不流转
subFlowRecord.setChangePlanApproved(true);
subFlowRecord.setUpdateTime(DateUtils.getCurrentTime());
changeSubFlowRecordService.update(subFlowRecord);
log.info("[CHANGE_SUB_FLOW_EXE] 审批通过,subFlowId:{}, 标记changePlanApproved=true", subFlowId);
// 检查该主工单下所有子单是否都已审批通过
if (changeFlowBiz.checkAllSubFlowsApprovedForMainFlow(subFlowRecord.getChangeRecordId())) {
// 所有子单都通过,批量流转所有子单并更新状态
batchSubmitAllSubFlows(subFlowRecord.getChangeRecordId(), flowDataDTO, uid, content);
log.info("[CHANGE_SUB_FLOW_EXE] 所有子单均已审批通过,批量流转子单到下一节点");
// 所有子单流转完成后,流转主工单
ChangeRecord mainRecord = changeRecordMapper.selectByPrimaryKey(subFlowRecord.getChangeRecordId());
if (mainRecord != null) {
ChangeFlowSubmitReq mainFlowSubmitReq = new ChangeFlowSubmitReq();
mainFlowSubmitReq.setFlowId(mainRecord.getFlowId());
mainFlowSubmitReq.setCurrentNodeId(mainRecord.getFlowNode());
changeFlowBiz.submit(mainFlowSubmitReq);
log.info("[CHANGE_SUB_FLOW_EXE] 主工单流转成功,changeRecordId:{}, flowId:{}",
subFlowRecord.getChangeRecordId(), mainRecord.getFlowId());
}
if (checkAllSubFlowsApproved(subFlowRecord.getChangeRecordId())) {
// 所有子单都通过,流转主工单
changeFlowBiz.submitMainFlowAfterAllSubFlowsApproved(subFlowRecord.getChangeRecordId());
log.info("[CHANGE_SUB_FLOW_EXE] 所有子单均已审批通过,主工单已流转");
}
}
......@@ -502,42 +490,24 @@ public class ChangeSubFlowBiz {
}
/**
* 批量流转所有子单到下一节点,并流转主工单
* 检查主工单下所有子单是否都已审批通过
* 条件:节点是 CHANGE_SUB_FLOW_EXE 且 changePlanApproved=true
*
* @param changeRecordId 主工单ID
* @param flowDataDTO 流程数据
* @param uid 操作人
* @param content 内容
* @return true 表示所有子单都已审批通过
*/
private void batchSubmitAllSubFlows(Long changeRecordId, FlowDataDTO flowDataDTO, String uid, Object content) {
private boolean checkAllSubFlowsApproved(Long changeRecordId) {
// 查询该主工单下所有子单
List<ChangeSubFlowRecord> allSubFlows = changeSubFlowRecordMapper.selectByChangeRecordId(changeRecordId);
if (CollectionUtils.isEmpty(allSubFlows)) {
return;
return false;
}
// 批量流转所有子单
for (ChangeSubFlowRecord subFlow : allSubFlows) {
try {
// 提交子单流程到下一节点
String nextNodeId = flowService.submitFlow(subFlow.getSubFlowId(), flowDataDTO, uid,
ChangeFlowEnum.CHANGE_SUB_FLOW.getTopoId(), JSON.toJSONString(content), true,
FlowxOperationEnum.SUBMIT.getName(), "所有子单审批通过,自动流转", subFlow.getCreateTime());
// 更新子单节点和状态
subFlow.setSubFlowNode(nextNodeId);
subFlow.setStatus(ChangeSubFlowStatusEnum.WAIT_SUBMIT_RESULT.getStatus());
subFlow.setUpdateTime(DateUtils.getCurrentTime());
changeSubFlowRecordService.update(subFlow);
log.info("[batchSubmitAllSubFlows] 子单流转成功,subFlowId:{}, nextNodeId:{}",
subFlow.getSubFlowId(), nextNodeId);
} catch (Exception e) {
log.error("[batchSubmitAllSubFlows] 子单流转失败,subFlowId:{}", subFlow.getSubFlowId(), e);
throw ExceptionFactory.createBiz(ResponseCode.BAD_REQUEST,
String.format("子单[%s]流转失败:%s", subFlow.getSubFlowId(), e.getMessage()));
}
}
// 检查是否所有子单都满足条件:节点是 CHANGE_SUB_FLOW_EXE 且 changePlanApproved=true
return allSubFlows.stream().allMatch(subFlow ->
ChangeFlowEnum.CHANGE_SUB_FLOW_EXE.getNodeId().equals(subFlow.getSubFlowNode())
&& Boolean.TRUE.equals(subFlow.getChangePlanApproved())
);
}
/**
......
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