Commit df5d75d5 by 王志超

feat: 子执行项工单流转

parent 650cf755
package com.netease.mail.yanxuan.change.biz.biz;
import com.alibaba.fastjson.JSON;
import com.netease.mail.yanxuan.change.biz.meta.exception.ExceptionFactory;
import com.netease.mail.yanxuan.change.biz.service.ChangeFlowExecService;
import com.netease.mail.yanxuan.change.biz.service.ChangeSubFlowService;
import com.netease.mail.yanxuan.change.biz.service.rpc.FlowService;
import com.netease.mail.yanxuan.change.common.bean.CommonConstants;
import com.netease.mail.yanxuan.change.common.bean.RequestLocalBean;
import com.netease.mail.yanxuan.change.common.bean.ResponseCode;
import com.netease.mail.yanxuan.change.common.enums.ChangeFlowEnum;
import com.netease.mail.yanxuan.change.common.enums.FlowOperationTypeEnum;
import com.netease.mail.yanxuan.change.common.enums.FlowxOperationEnum;
import com.netease.mail.yanxuan.change.common.util.DateUtils;
import com.netease.mail.yanxuan.change.dal.entity.ChangeExecRecord;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeSubFlowCreateReq;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeSubFlowSubmitReq;
import com.netease.yanxuan.flowx.sdk.meta.dto.base.FlowDataDTO;
import com.netease.yanxuan.flowx.sdk.meta.dto.flow.FlowCreateReqDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import javax.validation.Valid;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
......@@ -32,6 +40,9 @@ public class ChangeSubFlowBiz {
@Autowired
private FlowService flowService;
@Autowired
private ChangeFlowExecService changeFlowExecService;
public String createAndSubmit(@Valid ChangeSubFlowCreateReq changeSubFlowCreateReq) {
String uid = RequestLocalBean.getUid();
......@@ -70,4 +81,126 @@ public class ChangeSubFlowBiz {
public List<ChangeExecRecord> list(Integer page, Integer pageSize) {
return changeSubFlowService.query((page - 1) * pageSize, pageSize);
}
/**
* 子流程提交
* @param changeSubFlowSubmitReq 子流程提交请求
* @return 下一节点ID
*/
public String submitSubFlow(ChangeSubFlowSubmitReq changeSubFlowSubmitReq) {
log.info("[submitSubFlow] changeSubFlowSubmitReq:{}", JSON.toJSONString(changeSubFlowSubmitReq));
String subFlowId = changeSubFlowSubmitReq.getSubFlowId();
// 通过子流程工单ID查询行动项记录
ChangeExecRecord execRecord = changeFlowExecService.getBySubFlowId(subFlowId);
Assert.notNull(execRecord, "行动项记录不存在");
// 检查工单节点
String currentNode = execRecord.getSubFlowNode();
this.checkNode(currentNode, Collections.singletonList(changeSubFlowSubmitReq.getCurrentNodeId()));
String uid = RequestLocalBean.getUid();
// 验证执行人权限
if (!uid.equals(execRecord.getChangeExecUserEmail())) {
throw ExceptionFactory.createBiz(ResponseCode.NO_AUTH, ResponseCode.NO_AUTH.getMsg());
}
// 获取工单详情
FlowDataDTO flowDataDTO = flowService.flowDetail(subFlowId);
if (flowDataDTO == null) {
throw ExceptionFactory.createBiz(ResponseCode.DETAIL_FLOW_ERROR, "子流程工单查询错误,不存在");
}
return checkUpdateAndSubmit(subFlowId, flowDataDTO, uid, execRecord, currentNode, changeSubFlowSubmitReq);
}
/**
* 检查并提交子流程节点
*/
private String checkUpdateAndSubmit(String subFlowId, FlowDataDTO flowDataDTO, String uid,
ChangeExecRecord execRecord, String currentNode,
ChangeSubFlowSubmitReq changeSubFlowSubmitReq) {
ChangeFlowEnum node = ChangeFlowEnum.getByNodeId(currentNode);
Assert.notNull(node, "节点配置不存在");
log.debug("[checkUpdateAndSubmit] subFlowId:{}, nodeEnum:{}, changeSubFlowSubmitReq:{}",
subFlowId, node, JSON.toJSONString(changeSubFlowSubmitReq));
// 构建工单内容
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());
switch (node) {
case CHANGE_SUB_FLOW_START:
// 确认行动方案节点,直接提交到下一节点
String nextNodeId = flowService.submitFlow(subFlowId, flowDataDTO, uid,
ChangeFlowEnum.CHANGE_SUB_FLOW.getTopoId(), JSON.toJSONString(content), true,
FlowxOperationEnum.SUBMIT.getName(), "提交工单", execRecord.getCreateTime());
// 更新节点ID
execRecord.setSubFlowNode(nextNodeId);
execRecord.setUpdateTime(DateUtils.getCurrentTime());
changeFlowExecService.update(execRecord);
return nextNodeId;
case CHANGE_SUB_FLOW_SUBMIT:
// 审批行动方案节点,直接提交到执行节点
String execNodeId = flowService.submitFlow(subFlowId, flowDataDTO, uid,
ChangeFlowEnum.CHANGE_SUB_FLOW.getTopoId(), JSON.toJSONString(content), true,
FlowxOperationEnum.SUBMIT.getName(), "提交工单", execRecord.getCreateTime());
// 更新节点ID
execRecord.setSubFlowNode(execNodeId);
execRecord.setUpdateTime(DateUtils.getCurrentTime());
changeFlowExecService.update(execRecord);
return execNodeId;
case CHANGE_SUB_FLOW_EXE:
// 执行行动方案节点,直接提交到提交执行结果节点
String confirmNodeId = flowService.submitFlow(subFlowId, flowDataDTO, uid,
ChangeFlowEnum.CHANGE_SUB_FLOW.getTopoId(), JSON.toJSONString(content), true,
FlowxOperationEnum.SUBMIT.getName(), "提交工单", execRecord.getCreateTime());
// 更新节点ID
execRecord.setSubFlowNode(confirmNodeId);
execRecord.setUpdateTime(DateUtils.getCurrentTime());
changeFlowExecService.update(execRecord);
return confirmNodeId;
case CHANGE_SUB_FLOW_CONFIRM:
// 提交执行结果节点,需要填写完成时间和完成情况
Long finishTime = changeSubFlowSubmitReq.getChangeExecFinishTime();
String finishDesc = changeSubFlowSubmitReq.getChangeExecFinishDesc();
Assert.notNull(finishTime, "行动完成时间不可为空");
Assert.isTrue(StringUtils.isNotBlank(finishDesc), "行动完成情况不可为空");
// 更新完成信息
execRecord.setChangeExecFinishTime(finishTime);
execRecord.setChangeExecFinishDesc(finishDesc);
// 提交到结束节点
String endNodeId = flowService.submitFlow(subFlowId, flowDataDTO, uid,
ChangeFlowEnum.CHANGE_SUB_FLOW.getTopoId(), JSON.toJSONString(content), true,
FlowxOperationEnum.SUBMIT.getName(), "提交工单", execRecord.getCreateTime());
// 更新节点ID
execRecord.setSubFlowNode(endNodeId);
execRecord.setUpdateTime(DateUtils.getCurrentTime());
changeFlowExecService.update(execRecord);
// TODO: 子流程完成后,检查主流程是否可以进入确认节点
log.info("[CHANGE_SUB_FLOW_CONFIRM] 子流程完成,subFlowId:{}, changeExecId:{}", subFlowId, execRecord.getId());
return endNodeId;
default:
throw ExceptionFactory.createBiz(ResponseCode.BAD_REQUEST, "不支持的子流程节点类型");
}
}
/**
* 检查节点是否匹配
*/
private void checkNode(String currentNode, List<String> expectedNodes) {
if (!expectedNodes.contains(currentNode)) {
throw ExceptionFactory.createBiz(ResponseCode.BAD_REQUEST,
String.format("当前节点[%s]与预期节点[%s]不匹配", currentNode, expectedNodes));
}
}
}
......@@ -49,4 +49,18 @@ public interface ChangeFlowExecService {
* @return
*/
List<Long> queryByExecUser(String changeExecUser);
/**
* 根据id查询行动项记录
* @param id
* @return
*/
ChangeExecRecord getById(Long id);
/**
* 根据子流程工单ID查询行动项记录
* @param subFlowId
* @return
*/
ChangeExecRecord getBySubFlowId(String subFlowId);
}
\ No newline at end of file
......@@ -75,4 +75,9 @@ public class ChangeFlowExecServiceImpl implements ChangeFlowExecService {
public List<Long> queryByExecUser(String changeExecUser) {
return changeExecRecordMapper.queryByUser("%" + changeExecUser + "%");
}
@Override
public ChangeExecRecord getBySubFlowId(String subFlowId) {
return changeExecRecordMapper.selectBySubFlowId(subFlowId);
}
}
......@@ -42,4 +42,7 @@ public interface ChangeExecRecordMapper extends tk.mybatis.mapper.common.Mapper<
@Select("SELECT * FROM TB_YX_QC_CHANGE_EXEC_RECORD ORDER BY id DESC LIMIT #{limit},#{offset}")
List<ChangeExecRecord> queryList(@Param("limit") int limit, @Param("offset") Integer offset);
@Select("SELECT * FROM TB_YX_QC_CHANGE_EXEC_RECORD WHERE sub_flow_id = #{subFlowId} LIMIT 1")
ChangeExecRecord selectBySubFlowId(@Param("subFlowId") String subFlowId);
}
/**
* @(#)ChangeSubFlowSubmitReq.java, 2025/01/18.
* <p/>
* Copyright 2025 Netease, Inc. All rights reserved.
* NETEASE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.netease.mail.yanxuan.change.dal.meta.model.req;
import javax.validation.constraints.NotBlank;
import lombok.Data;
/**
* 子流程提交请求
* @Author zcwang
* @Date 2025/01/18
*/
@Data
public class ChangeSubFlowSubmitReq {
/**
* 子流程工单id
*/
@NotBlank(message = "子流程工单id不能为空")
private String subFlowId;
/**
* 当前节点id
*/
@NotBlank(message = "当前节点不能为空")
private String currentNodeId;
/**
* 行动完成时间(提交执行结果时必填)
*/
private Long changeExecFinishTime;
/**
* 行动完成情况(提交执行结果时必填)
*/
private String changeExecFinishDesc;
}
......@@ -10,6 +10,7 @@ import com.netease.mail.yanxuan.change.biz.biz.ChangeSubFlowBiz;
import com.netease.mail.yanxuan.change.common.bean.AjaxResult;
import com.netease.mail.yanxuan.change.dal.entity.ChangeExecRecord;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeSubFlowCreateReq;
import com.netease.mail.yanxuan.change.dal.meta.model.req.ChangeSubFlowSubmitReq;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
......@@ -49,4 +50,14 @@ public class ChangeSubFlowController {
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
return AjaxResult.success(changeSubFlowBiz.list(page, pageSize));
}
/**
* 子流程提交
*
* @return
*/
@PostMapping("/submit")
public AjaxResult<String> submit(@RequestBody @Valid ChangeSubFlowSubmitReq changeSubFlowSubmitReq) {
return AjaxResult.success(changeSubFlowBiz.submitSubFlow(changeSubFlowSubmitReq));
}
}
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