Commit cb3467ada2bd8d07a17699e950147b9333896c39

Authored by lizhixian
1 parent 9a83515c

review: 代码审查

yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java
1 package cn.iocoder.yudao.module.bpm.controller.admin.task; 1 package cn.iocoder.yudao.module.bpm.controller.admin.task;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.util.StrUtil;
4 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 5 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
6 import cn.iocoder.yudao.framework.common.util.number.NumberUtils; 8 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
  9 +import cn.iocoder.yudao.framework.common.util.string.StrUtils;
7 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*; 10 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*;
8 import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert; 11 import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert;
9 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO; 12 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
@@ -163,6 +166,9 @@ public class BpmProcessInstanceController { @@ -163,6 +166,9 @@ public class BpmProcessInstanceController {
163 @Parameter(name = "id", description = "流程实例的编号", required = true) 166 @Parameter(name = "id", description = "流程实例的编号", required = true)
164 @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')") 167 @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
165 public CommonResult<BpmApprovalDetailRespVO> getApprovalDetail(@Valid BpmApprovalDetailReqVO reqVO) { 168 public CommonResult<BpmApprovalDetailRespVO> getApprovalDetail(@Valid BpmApprovalDetailReqVO reqVO) {
  169 + if (StrUtil.isNotEmpty(reqVO.getProcessVariablesStr())){
  170 + reqVO.setProcessVariables(JsonUtils.parseObject(reqVO.getProcessVariablesStr(),Map.class));
  171 + }
166 return success(processInstanceService.getApprovalDetail(getLoginUserId(), reqVO)); 172 return success(processInstanceService.getApprovalDetail(getLoginUserId(), reqVO));
167 } 173 }
168 174
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmApprovalDetailReqVO.java
@@ -19,7 +19,7 @@ public class BpmApprovalDetailReqVO { @@ -19,7 +19,7 @@ public class BpmApprovalDetailReqVO {
19 private Map<String, Object> processVariables; // 使用场景:同 processDefinitionId,用于流程预测 19 private Map<String, Object> processVariables; // 使用场景:同 processDefinitionId,用于流程预测
20 20
21 @Schema(description = "流程变量") 21 @Schema(description = "流程变量")
22 - private String processVariablesStr; // 使用场景:同 processDefinitionId,用于流程预测 22 + private String processVariablesStr; //解决 GET 无法传递对象的问题,最终转换成 processVariables 变量
23 23
24 @Schema(description = "流程实例的编号", example = "1024") 24 @Schema(description = "流程实例的编号", example = "1024")
25 private String processInstanceId; // 使用场景:流程已发起时候传流程实例 ID 25 private String processInstanceId; // 使用场景:流程已发起时候传流程实例 ID
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java
@@ -778,16 +778,9 @@ public class BpmnModelUtils { @@ -778,16 +778,9 @@ public class BpmnModelUtils {
778 if (currentElement instanceof ExclusiveGateway) { 778 if (currentElement instanceof ExclusiveGateway) {
779 // 查找满足条件的 SequenceFlow 路径 779 // 查找满足条件的 SequenceFlow 路径
780 Gateway gateway = (Gateway) currentElement; 780 Gateway gateway = (Gateway) currentElement;
781 - SequenceFlow matchSequenceFlow;  
782 - //流程首次发起时,variables值一定为空,会导致条件表达式解析错误导致预测节点缺失  
783 - if (null == variables) {  
784 - matchSequenceFlow = CollUtil.findOne(gateway.getOutgoingFlows(),  
785 - flow -> ObjUtil.notEqual(gateway.getDefaultFlow(), flow.getId()));  
786 - } else {  
787 - matchSequenceFlow = CollUtil.findOne(gateway.getOutgoingFlows(),  
788 - flow -> ObjUtil.notEqual(gateway.getDefaultFlow(), flow.getId())  
789 - && (evalConditionExpress(variables, flow.getConditionExpression())));  
790 - } 781 + SequenceFlow matchSequenceFlow = CollUtil.findOne(gateway.getOutgoingFlows(),
  782 + flow -> ObjUtil.notEqual(gateway.getDefaultFlow(), flow.getId())
  783 + && (evalConditionExpress(variables, flow.getConditionExpression())));
791 if (matchSequenceFlow == null) { 784 if (matchSequenceFlow == null) {
792 matchSequenceFlow = CollUtil.findOne(gateway.getOutgoingFlows(), 785 matchSequenceFlow = CollUtil.findOne(gateway.getOutgoingFlows(),
793 flow -> ObjUtil.equal(gateway.getDefaultFlow(), flow.getId())); 786 flow -> ObjUtil.equal(gateway.getDefaultFlow(), flow.getId()));
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java
@@ -7,7 +7,6 @@ import cn.hutool.core.lang.Assert; @@ -7,7 +7,6 @@ import cn.hutool.core.lang.Assert;
7 import cn.hutool.core.util.ArrayUtil; 7 import cn.hutool.core.util.ArrayUtil;
8 import cn.hutool.core.util.ObjectUtil; 8 import cn.hutool.core.util.ObjectUtil;
9 import cn.hutool.core.util.StrUtil; 9 import cn.hutool.core.util.StrUtil;
10 -import cn.hutool.json.JSONUtil;  
11 import cn.iocoder.yudao.framework.common.pojo.PageResult; 10 import cn.iocoder.yudao.framework.common.pojo.PageResult;
12 import cn.iocoder.yudao.framework.common.util.date.DateUtils; 11 import cn.iocoder.yudao.framework.common.util.date.DateUtils;
13 import cn.iocoder.yudao.framework.common.util.json.JsonUtils; 12 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
@@ -29,7 +28,6 @@ import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum; @@ -29,7 +28,6 @@ import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum;
29 import cn.iocoder.yudao.module.bpm.enums.task.BpmReasonEnum; 28 import cn.iocoder.yudao.module.bpm.enums.task.BpmReasonEnum;
30 import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum; 29 import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
31 import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateInvoker; 30 import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateInvoker;
32 -import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.dept.BpmTaskCandidateStartUserSelectStrategy;  
33 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum; 31 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
34 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants; 32 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants;
35 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants; 33 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants;
@@ -167,9 +165,6 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService @@ -167,9 +165,6 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
167 HistoricProcessInstance historicProcessInstance = null; // 流程实例 165 HistoricProcessInstance historicProcessInstance = null; // 流程实例
168 Integer processInstanceStatus = BpmProcessInstanceStatusEnum.NOT_START.getStatus(); // 流程状态 166 Integer processInstanceStatus = BpmProcessInstanceStatusEnum.NOT_START.getStatus(); // 流程状态
169 Map<String, Object> processVariables = reqVO.getProcessVariables(); // 流程变量 167 Map<String, Object> processVariables = reqVO.getProcessVariables(); // 流程变量
170 - if (reqVO.getProcessVariablesStr() != null){  
171 - processVariables = JSONUtil.parseObj(reqVO.getProcessVariablesStr());  
172 - }  
173 // 1.2 如果是流程已发起的场景,则使用流程实例的数据 168 // 1.2 如果是流程已发起的场景,则使用流程实例的数据
174 if (reqVO.getProcessInstanceId() != null) { 169 if (reqVO.getProcessInstanceId() != null) {
175 historicProcessInstance = getHistoricProcessInstance(reqVO.getProcessInstanceId()); 170 historicProcessInstance = getHistoricProcessInstance(reqVO.getProcessInstanceId());
@@ -213,8 +208,11 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService @@ -213,8 +208,11 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
213 // TODO @jason:有一个极端情况,如果一个用户有 2 个 task A 和 B,A 已经通过,B 需要审核。这个时,通过 A 进来,todo 拿到 208 // TODO @jason:有一个极端情况,如果一个用户有 2 个 task A 和 B,A 已经通过,B 需要审核。这个时,通过 A 进来,todo 拿到
214 // B,会不会表单权限不一致哈。 209 // B,会不会表单权限不一致哈。
215 BpmTaskRespVO todoTask = taskService.getFirstTodoTask(loginUserId, reqVO.getProcessInstanceId()); 210 BpmTaskRespVO todoTask = taskService.getFirstTodoTask(loginUserId, reqVO.getProcessInstanceId());
216 -  
217 - // 3.2 预测未运行节点的审批信息 211 + // 3.2 流程首次发起时,variables值一定为空,会导致条件表达式解析错误导致预测节点缺失
  212 + if (null == processVariables) {
  213 + processVariables = new HashMap<>();
  214 + }
  215 + // 3.3 预测未运行节点的审批信息
218 List<ActivityNode> simulateActivityNodes = getSimulateApproveNodeList(startUserId, bpmnModel, 216 List<ActivityNode> simulateActivityNodes = getSimulateApproveNodeList(startUserId, bpmnModel,
219 processDefinitionInfo, 217 processDefinitionInfo,
220 processVariables, activities); 218 processVariables, activities);
@@ -697,17 +695,16 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService @@ -697,17 +695,16 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
697 private void validateStartUserSelectAssignees(Long userId, ProcessDefinition definition, 695 private void validateStartUserSelectAssignees(Long userId, ProcessDefinition definition,
698 Map<String, List<Long>> startUserSelectAssignees, Map<String,Object> variables) { 696 Map<String, List<Long>> startUserSelectAssignees, Map<String,Object> variables) {
699 // 1.获取预测的节点信息 697 // 1.获取预测的节点信息
700 - BpmApprovalDetailReqVO detailReqVO = new BpmApprovalDetailReqVO();  
701 - detailReqVO.setProcessVariables(variables);  
702 - detailReqVO.setProcessDefinitionId(definition.getId());  
703 - BpmApprovalDetailRespVO respVO = getApprovalDetail(userId, detailReqVO);  
704 - List<ActivityNode> activityNodes = respVO.getActivityNodes(); 698 + BpmApprovalDetailRespVO detailRespVO = getApprovalDetail(userId, new BpmApprovalDetailReqVO()
  699 + .setProcessDefinitionId(definition.getId())
  700 + .setProcessVariables(variables));
  701 + List<ActivityNode> activityNodes = detailRespVO.getActivityNodes();
705 if (CollUtil.isEmpty(activityNodes)){ 702 if (CollUtil.isEmpty(activityNodes)){
706 return; 703 return;
707 } 704 }
708 - //移除掉不是发起人自选审批人节点  
709 - activityNodes.removeIf(task -> null == task.getCandidateStrategy() || !task.getCandidateStrategy().equals(BpmTaskCandidateStrategyEnum.START_USER_SELECT.getStrategy()));  
710 - // 2. 流程发起时要先获取当前流程的预测走向节点,发起时只校验预测的节点发起人自选审批人的审批人和抄送人是否都配置了 705 + // 2.移除掉不是发起人自选审批人节点
  706 + activityNodes.removeIf(task -> Objects.equals(BpmTaskCandidateStrategyEnum.START_USER_SELECT.getStrategy(), task. getCandidateStrategy()));
  707 + // 3.流程发起时要先获取当前流程的预测走向节点,发起时只校验预测的节点发起人自选审批人的审批人和抄送人是否都配置了
711 activityNodes.forEach(task -> { 708 activityNodes.forEach(task -> {
712 List<Long> assignees = startUserSelectAssignees != null ? startUserSelectAssignees.get(task.getId()) : null; 709 List<Long> assignees = startUserSelectAssignees != null ? startUserSelectAssignees.get(task.getId()) : null;
713 if (CollUtil.isEmpty(assignees)) { 710 if (CollUtil.isEmpty(assignees)) {