Commit a0d574ad2020539a2b8a3f6b78dca670912c778b

Authored by kemengkai
1 parent d43006dc

增加任务流程预测功能,预测未审批等待审批的任务流程。

yudao-dependencies/pom.xml
... ... @@ -65,7 +65,6 @@
65 65 <tencentcloud-sdk-java.version>3.1.471</tencentcloud-sdk-java.version>
66 66 <yunpian-java-sdk.version>1.2.7</yunpian-java-sdk.version>
67 67 <justauth.version>1.4.0</justauth.version>
68   - <dom4j.version>2.1.3</dom4j.version>
69 68 </properties>
70 69  
71 70 <dependencyManagement>
... ... @@ -579,13 +578,6 @@
579 578 <artifactId>justauth-spring-boot-starter</artifactId> <!-- 社交登陆(例如说,个人微信、企业微信等等) -->
580 579 <version>${justauth.version}</version>
581 580 </dependency>
582   - <!-- https://mvnrepository.com/artifact/org.dom4j/dom4j -->
583   - <!-- XML读写框架 -->
584   - <dependency>
585   - <groupId>org.dom4j</groupId>
586   - <artifactId>dom4j</artifactId>
587   - <version>${dom4j.version}</version>
588   - </dependency>
589 581 </dependencies>
590 582 </dependencyManagement>
591 583  
... ...
yudao-module-bpm/yudao-module-bpm-biz/pom.xml
... ... @@ -10,10 +10,6 @@
10 10 <modelVersion>4.0.0</modelVersion>
11 11 <artifactId>yudao-module-bpm-biz</artifactId>
12 12  
13   - <properties>
14   - <dom4j.version>2.1.3</dom4j.version>
15   - </properties>
16   -
17 13 <name>${project.artifactId}</name>
18 14 <description>
19 15 bpm-base 模块,实现公用的工作流的逻辑,提供给 bpm-activiti 和 bpm-flowable 复用
... ... @@ -30,6 +26,11 @@
30 26 <artifactId>yudao-module-system-api</artifactId>
31 27 <version>${revision}</version>
32 28 </dependency>
  29 + <dependency>
  30 + <groupId>cn.iocoder.boot</groupId>
  31 + <artifactId>yudao-module-system-biz</artifactId>
  32 + <version>${revision}</version>
  33 + </dependency>
33 34  
34 35 <!-- 业务组件 -->
35 36 <dependency>
... ... @@ -85,11 +86,10 @@
85 86 <version>1.4.196</version>
86 87 <scope>test</scope>
87 88 </dependency>
88   - <!-- https://mvnrepository.com/artifact/org.dom4j/dom4j -->
89   - <!-- XML读写框架 -->
90 89 <dependency>
91 90 <groupId>org.dom4j</groupId>
92 91 <artifactId>dom4j</artifactId>
  92 + <version>2.1.3</version>
93 93 </dependency>
94 94 </dependencies>
95 95 </project>
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java
... ... @@ -7,9 +7,6 @@ import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
7 7 import io.swagger.annotations.Api;
8 8 import io.swagger.annotations.ApiImplicitParam;
9 9 import io.swagger.annotations.ApiOperation;
10   -import org.apache.ibatis.annotations.Param;
11   -import org.flowable.bpmn.model.BpmnModel;
12   -import org.flowable.engine.TaskService;
13 10 import org.springframework.security.access.prepost.PreAuthorize;
14 11 import org.springframework.validation.annotation.Validated;
15 12 import org.springframework.web.bind.annotation.*;
... ... @@ -18,7 +15,6 @@ import javax.annotation.Resource;
18 15 import javax.validation.Valid;
19 16  
20 17 import java.util.List;
21   -import java.util.Objects;
22 18  
23 19 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
24 20 import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId;
... ... @@ -55,13 +51,6 @@ public class BpmTaskController {
55 51 return success(taskService.getTaskListByProcessInstanceId(processInstanceId));
56 52 }
57 53  
58   - @GetMapping("/get")
59   - @ApiOperation(value = "获取审批单详情", notes = "包括完成的、未完成的")
60   - @ApiImplicitParam(name = "taskId", value = "任务Id", required = true, dataTypeClass = String.class)
61   - public CommonResult<Object> getTask(@Param("taskId") String processInstanceId) {
62   - return success(taskService.getTaskInfo(processInstanceId));
63   - }
64   -
65 54 @PutMapping("/approve")
66 55 @ApiOperation("通过任务")
67 56 @PreAuthorize("@ss.hasPermission('bpm:task:update')")
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmTaskAssignRuleMapper.java
... ... @@ -32,4 +32,6 @@ public interface BpmTaskAssignRuleMapper extends BaseMapperX&lt;BpmTaskAssignRuleDO
32 32 .eq("task_definition_key", taskDefinitionKey));
33 33 }
34 34  
  35 +
  36 +
35 37 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmTaskExtMapper.java
... ... @@ -22,6 +22,16 @@ public interface BpmTaskExtMapper extends BaseMapperX&lt;BpmTaskExtDO&gt; {
22 22 }
23 23  
24 24 /**
  25 + * 查询全部任务
  26 + *
  27 + * @return 返回任务
  28 + */
  29 + @TenantIgnore
  30 + default List<BpmTaskExtDO> listAll() {
  31 + return selectList();
  32 + }
  33 +
  34 + /**
25 35 * 查询任务
26 36 *
27 37 * @param procInstId 流程id
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java
... ... @@ -68,15 +68,6 @@ public interface BpmTaskService {
68 68 List<BpmTaskRespVO> getTaskListByProcessInstanceId(String processInstanceId);
69 69  
70 70 /**
71   - * 获取任务详情
72   - *
73   - * @param processInstanceId 流程实例的编号
74   - *
75   - * @return 流程任务列表
76   - */
77   - List<BpmTaskRespVO> getTaskInfo(String processInstanceId);
78   -
79   - /**
80 71 * 通过任务
81 72 *
82 73 * @param userId 用户编号
... ... @@ -95,7 +86,6 @@ public interface BpmTaskService {
95 86 /**
96 87 * 回退任务
97 88 *
98   - * @param userId 用户id
99 89 * @param reqVO 回退任务信息
100 90 */
101 91 CommonResult<Boolean> backTask(BpmTaskBackReqVO reqVO);
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java
... ... @@ -18,8 +18,8 @@ import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmTaskExtMapper;
18 18 import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmTaskAssignRuleTypeEnum;
19 19 import cn.iocoder.yudao.module.bpm.domain.enums.task.BpmProcessInstanceResultEnum;
20 20 import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService;
  21 +import cn.iocoder.yudao.module.business.hi.task.inst.service.HiTaskInstService;
21 22 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
22   -import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
23 23 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
24 24 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
25 25 import lombok.extern.slf4j.Slf4j;
... ... @@ -45,7 +45,6 @@ import java.util.stream.Collectors;
45 45 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
46 46 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
47 47 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
48   -import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId;
49 48 import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
50 49  
51 50 /**
... ... @@ -79,6 +78,8 @@ public class BpmTaskServiceImpl implements BpmTaskService {
79 78 private BpmTaskAssignRuleMapper taskAssignRuleMapper;
80 79 @Resource
81 80 private BpmActivityMapper bpmActivityMapper;
  81 + @Resource
  82 + private HiTaskInstService hiTaskInstService;
82 83  
83 84 @Override
84 85 public PageResult<BpmTaskTodoPageItemRespVO> getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageVO) {
... ... @@ -160,22 +161,22 @@ public class BpmTaskServiceImpl implements BpmTaskService {
160 161 @Override
161 162 public List<BpmTaskRespVO> getTaskListByProcessInstanceId(String processInstanceId) {
162 163 // 获得任务列表
163   - List<HistoricTaskInstance> tasks =
  164 + /* List<HistoricTaskInstance> tasks =
164 165 historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId)
165 166 .orderByHistoricTaskInstanceStartTime().desc() // 创建时间倒序
166 167 .list();
167 168 if (CollUtil.isEmpty(tasks)) {
168 169 return Collections.emptyList();
169   - }
  170 + }*/
170 171 // 获得 TaskExtDO Map
171 172 // List<BpmTaskExtDO> bpmTaskExtDOList =
172 173 // taskExtMapper.selectListByTaskIds(convertSet(tasks, HistoricTaskInstance::getId));
173 174  
174   - List<BpmTaskExtDO> bpmTaskExtDOList = taskExtMapper.listByProcInstId(processInstanceId);
  175 +// List<BpmTaskExtDO> bpmTaskExtDOList = taskExtMapper.listByProcInstId(processInstanceId);
175 176 // List<BpmTaskExtDO> bpmTaskExtDOList = BpmTaskConvert.INSTANCE.distinct(tmpBpmTaskExtDOList);
176 177 // bpmTaskExtDOList.forEach(var -> log.info("var = " + var));
177 178  
178   - Map<String, BpmTaskExtDO> bpmTaskExtDoMap = convertMap(bpmTaskExtDOList, BpmTaskExtDO::getTaskId);
  179 + /*Map<String, BpmTaskExtDO> bpmTaskExtDoMap = convertMap(bpmTaskExtDOList, BpmTaskExtDO::getTaskId);
179 180 // 获得 ProcessInstance Map
180 181 HistoricProcessInstance processInstance = processInstanceService.getHistoricProcessInstance(processInstanceId);
181 182 // 获得 User Map
... ... @@ -183,28 +184,11 @@ public class BpmTaskServiceImpl implements BpmTaskService {
183 184 userIds.add(NumberUtils.parseLong(processInstance.getStartUserId()));
184 185 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);
185 186 // 获得 Dept Map
186   - Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
187   -
188   - // 拼接数据
189   - return BpmTaskConvert.INSTANCE.convertList3(tasks, bpmTaskExtDoMap, processInstance, userMap, deptMap);
190   - }
191   -
192   - @Override
193   - public List<BpmTaskRespVO> getTaskInfo(String processInstanceId) {
194   -
195   - List<BpmTaskExtDO> bpmTaskExtDOList = taskExtMapper.listByProcInstId(processInstanceId);
196   -
197   - Map<String, BpmTaskExtDO> bpmTaskExtDoMap = convertMap(bpmTaskExtDOList, BpmTaskExtDO::getTaskId);
198   - // 获得 ProcessInstance Map
199   - HistoricProcessInstance processInstance = processInstanceService.getHistoricProcessInstance(processInstanceId);
200   - // 获得 User Map
201   - Set<Long> userIds = bpmTaskExtDOList.stream().map(BpmTaskExtDO::getAssigneeUserId).collect(Collectors.toSet());
202   - userIds.add(NumberUtils.parseLong(processInstance.getStartUserId()));
203   - Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);
204   -
  187 + Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));*/
205 188  
206 189 // 拼接数据
207   - return new ArrayList<>();
  190 + List<BpmTaskExtDO> tmpBpmTaskExtDOList = taskExtMapper.listByProcInstId(processInstanceId);
  191 + return hiTaskInstService.taskGetComment(tmpBpmTaskExtDOList, "");
208 192 }
209 193  
210 194 @Override
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/business/hi/task/inst/domain/HistoricApproveTaskDTO.java
1   -package net.lab1024.smartadmin.module.business.approve.camunda.hi.task.inst.domain;
  1 +package cn.iocoder.yudao.module.business.hi.task.inst.domain;
2 2  
3 3 import lombok.AllArgsConstructor;
4 4 import lombok.Data;
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/business/hi/task/inst/domain/vo/HiTaskinstVO.java
1   -package net.lab1024.smartadmin.module.business.approve.camunda.hi.task.inst.domain.vo;
  1 +package cn.iocoder.yudao.module.business.hi.task.inst.domain.vo;
2 2  
3 3 import lombok.Data;
4 4 import java.util.Date;
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/business/hi/task/inst/service/HiTaskInstService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.business.hi.task.inst.service;
  2 +
  3 +import cn.hutool.core.bean.BeanUtil;
  4 +import cn.hutool.core.collection.CollUtil;
  5 +import cn.hutool.core.util.ObjectUtil;
  6 +import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
  7 +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
  8 +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskTodoPageItemRespVO;
  9 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
  10 +import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO;
  11 +import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmTaskAssignRuleMapper;
  12 +import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmTaskAssignRuleTypeEnum;
  13 +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
  14 +import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
  15 +import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
  16 +import cn.iocoder.yudao.module.system.dal.mysql.dept.DeptMapper;
  17 +import cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper;
  18 +import lombok.extern.slf4j.Slf4j;
  19 +import org.flowable.bpmn.model.*;
  20 +import org.flowable.common.engine.impl.de.odysseus.el.ExpressionFactoryImpl;
  21 +import org.flowable.common.engine.impl.de.odysseus.el.util.SimpleContext;
  22 +import org.flowable.common.engine.impl.javax.el.ExpressionFactory;
  23 +import org.flowable.common.engine.impl.javax.el.ValueExpression;
  24 +import org.flowable.engine.*;
  25 +import org.flowable.engine.history.HistoricProcessInstance;
  26 +import org.flowable.task.api.history.HistoricTaskInstance;
  27 +import org.flowable.variable.api.history.HistoricVariableInstance;
  28 +import org.springframework.stereotype.Service;
  29 +
  30 +import javax.annotation.Resource;
  31 +import java.util.*;
  32 +import java.util.function.Function;
  33 +import java.util.stream.Collectors;
  34 +
  35 +/**
  36 + * [ ]
  37 + *
  38 + * @author 孟凯
  39 + * @version 1.0
  40 + */
  41 +@Slf4j
  42 +@Service
  43 +public class HiTaskInstService {
  44 +
  45 + @Resource
  46 + private HistoryService historyService;
  47 + @Resource
  48 + private RepositoryService repositoryService;
  49 + @Resource
  50 + private BpmTaskAssignRuleMapper bpmTaskAssignRuleMapper;
  51 + @Resource
  52 + private BpmProcessInstanceService processInstanceService;
  53 + @Resource
  54 + private AdminUserMapper adminUserApi;
  55 + @Resource
  56 + private DeptMapper deptMapper;
  57 +
  58 + /**
  59 + * 获取任务具体流程信息
  60 + *
  61 + * @param taskList 任务信息
  62 + * @param approved 任意选择条件
  63 + *
  64 + * @return 返回流程信息
  65 + */
  66 + @TenantIgnore
  67 + public List<BpmTaskRespVO> taskGetComment(List<BpmTaskExtDO> taskList, Object approved) {
  68 + BpmTaskExtDO task = taskList.get(taskList.size() - 1);
  69 + Map<String, BpmTaskExtDO> bpmTaskMap =
  70 + taskList.stream().collect(Collectors.toMap(BpmTaskExtDO::getTaskId, Function.identity()));
  71 + // 获得 ProcessInstance Map
  72 + HistoricProcessInstance procInst =
  73 + processInstanceService.getHistoricProcessInstance(task.getProcessInstanceId());
  74 + Map<Long, AdminUserDO> userDoMap =
  75 + adminUserApi.selectList().stream().collect(Collectors.toMap(AdminUserDO::getId, Function.identity()));
  76 + Map<Long, DeptDO> deptMap =
  77 + deptMapper.selectList().stream().collect(Collectors.toMap(DeptDO::getId, Function.identity()));
  78 + List<HistoricTaskInstance> hisTaskInstList =
  79 + historyService.createHistoricTaskInstanceQuery().processInstanceId(task.getProcessInstanceId())
  80 + .orderByHistoricTaskInstanceStartTime().desc().list();
  81 + LinkedList<BpmTaskRespVO> bpmTaskRespVOList =
  82 + nowTaskFormat(procInst, hisTaskInstList, bpmTaskMap, userDoMap, deptMap);
  83 +
  84 + //ProcessInstanceId流程实例
  85 + String procInstId = task.getProcessInstanceId();
  86 + List<BpmTaskAssignRuleDO> tmpBpmTaskAssignRuleDOList =
  87 + bpmTaskAssignRuleMapper.selectListByProcessDefinitionId(task.getProcessDefinitionId(), null);
  88 + List<HistoricVariableInstance> hisVarInstList =
  89 + historyService.createHistoricVariableInstanceQuery().processInstanceId(procInstId).list();
  90 + Map<String, Object> hisVarInstMap = new HashMap<>();
  91 + for (HistoricVariableInstance hisVarInst : hisVarInstList) {
  92 + hisVarInstMap.put(hisVarInst.getVariableName(), hisVarInst.getValue());
  93 + }
  94 + hisVarInstMap.put("approved", approved);
  95 + //获取bpm(模型)对象
  96 + BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
  97 + getFlow(bpmnModel, task.getTaskDefKey(), tmpBpmTaskAssignRuleDOList, bpmTaskRespVOList, userDoMap, deptMap,
  98 + hisVarInstMap);
  99 + return bpmTaskRespVOList;
  100 + }
  101 +
  102 + /**
  103 + * 格式化任务信息
  104 + */
  105 + private LinkedList<BpmTaskRespVO> nowTaskFormat(HistoricProcessInstance procInst, List<HistoricTaskInstance> taskList,
  106 + Map<String, BpmTaskExtDO> bpmTaskExtDoMap, Map<Long, AdminUserDO> userMap, Map<Long, DeptDO> deptMap) {
  107 + LinkedList<BpmTaskRespVO> bpmTaskRespVOList = new LinkedList<>();
  108 + for (HistoricTaskInstance hisTaskInst : taskList) {
  109 + BpmTaskRespVO respVO = initRespVo(hisTaskInst, bpmTaskExtDoMap, procInst, userMap);
  110 + AdminUserDO user = userMap.get(Long.valueOf(hisTaskInst.getAssignee()));
  111 + if (BeanUtil.isNotEmpty(user)) {
  112 + respVO.setAssigneeUser(setUser(user));
  113 + DeptDO dept = deptMap.get(user.getDeptId());
  114 + if (BeanUtil.isNotEmpty(dept)) {
  115 + respVO.getAssigneeUser().setDeptName(dept.getName());
  116 + }
  117 + }
  118 + bpmTaskRespVOList.addFirst(respVO);
  119 + }
  120 + return bpmTaskRespVOList;
  121 + }
  122 +
  123 + private BpmTaskRespVO initRespVo(Object taskInst, Map<String, BpmTaskExtDO> bpmTaskExtDoMap,
  124 + HistoricProcessInstance procInst, Map<Long, AdminUserDO> userMap) {
  125 + BpmTaskRespVO respVO = new BpmTaskRespVO();
  126 + if (taskInst instanceof HistoricTaskInstance) {
  127 + respVO = setBpmnTaskRespVo((HistoricTaskInstance)taskInst);
  128 + BeanUtil.copyProperties(taskInst, respVO);
  129 + BpmTaskExtDO bpmTaskExtDO = bpmTaskExtDoMap.get(respVO.getId());
  130 + if (ObjectUtil.isNotEmpty(bpmTaskExtDO)) {
  131 + BeanUtil.copyProperties(bpmTaskExtDO, respVO);
  132 + respVO.setId(bpmTaskExtDO.getTaskId());
  133 + }
  134 + }
  135 + if (taskInst instanceof BpmTaskExtDO) {
  136 + respVO = setBpmnTaskRespVo((BpmTaskExtDO)taskInst);
  137 + BeanUtil.copyProperties(taskInst, respVO);
  138 + }
  139 + // copyTo(bpmTaskExtDO, respVO);
  140 + if (procInst != null) {
  141 + AdminUserDO startUser = userMap.get(Long.valueOf(procInst.getStartUserId()));
  142 + if (BeanUtil.isEmpty(startUser)) {
  143 + throw new RuntimeException("查找不到审批用户!!!");
  144 + }
  145 + respVO.setProcessInstance(setProcInst(procInst, startUser));
  146 + }
  147 + return respVO;
  148 + }
  149 +
  150 + private BpmTaskRespVO.User setUser(AdminUserDO bean) {
  151 + if (bean == null) {
  152 + return null;
  153 + }
  154 +
  155 + BpmTaskRespVO.User user = new BpmTaskRespVO.User();
  156 +
  157 + user.setId(bean.getId());
  158 + user.setNickname(bean.getNickname());
  159 + user.setDeptId(bean.getDeptId());
  160 +
  161 + return user;
  162 +
  163 + }
  164 +
  165 + private BpmTaskRespVO setBpmnTaskRespVo(BpmTaskExtDO bean) {
  166 + if (bean == null) {
  167 + return null;
  168 + }
  169 +
  170 + BpmTaskRespVO bpmTaskRespVO = new BpmTaskRespVO();
  171 +
  172 + bpmTaskRespVO.setDefinitionKey(bean.getTaskDefKey());
  173 + bpmTaskRespVO.setId(bean.getTaskId());
  174 + bpmTaskRespVO.setName(bean.getName());
  175 + bpmTaskRespVO.setCreateTime(bean.getCreateTime());
  176 +
  177 + return bpmTaskRespVO;
  178 + }
  179 +
  180 + public BpmTaskRespVO setBpmnTaskRespVo(HistoricTaskInstance bean) {
  181 + if (bean == null) {
  182 + return null;
  183 + }
  184 +
  185 + BpmTaskRespVO bpmTaskRespVO = new BpmTaskRespVO();
  186 +
  187 + bpmTaskRespVO.setDefinitionKey(bean.getTaskDefinitionKey());
  188 + bpmTaskRespVO.setId(bean.getId());
  189 + bpmTaskRespVO.setName(bean.getName());
  190 + bpmTaskRespVO.setClaimTime(bean.getClaimTime());
  191 + bpmTaskRespVO.setCreateTime(bean.getCreateTime());
  192 + bpmTaskRespVO.setEndTime(bean.getEndTime());
  193 + bpmTaskRespVO.setDurationInMillis(bean.getDurationInMillis());
  194 +
  195 + return bpmTaskRespVO;
  196 + }
  197 +
  198 + public BpmTaskTodoPageItemRespVO.ProcessInstance setProcInst(HistoricProcessInstance processInstance,
  199 + AdminUserDO startUser) {
  200 + if (processInstance == null && startUser == null) {
  201 + return null;
  202 + }
  203 +
  204 + BpmTaskTodoPageItemRespVO.ProcessInstance processInstanceResult =
  205 + new BpmTaskTodoPageItemRespVO.ProcessInstance();
  206 +
  207 + if (processInstance != null) {
  208 + processInstanceResult.setId(processInstance.getId());
  209 + processInstanceResult.setName(processInstance.getName());
  210 + if (processInstance.getStartUserId() != null) {
  211 + processInstanceResult.setStartUserId(Long.parseLong(processInstance.getStartUserId()));
  212 + }
  213 + processInstanceResult.setProcessDefinitionId(processInstance.getProcessDefinitionId());
  214 + }
  215 + if (startUser != null) {
  216 + processInstanceResult.setStartUserNickname(startUser.getNickname());
  217 + }
  218 +
  219 + return processInstanceResult;
  220 + }
  221 +
  222 + private void getFlow(BpmnModel bpmnModel, String taskDefKey, List<BpmTaskAssignRuleDO> tmpBpmTaskAssignRuleDOList,
  223 + LinkedList<BpmTaskRespVO> bpmTaskRespVOList, Map<Long, AdminUserDO> userDoMap, Map<Long, DeptDO> deptMap,
  224 + Map<String, Object> taskVarMap) {
  225 + //传节点定义key获取当前节点
  226 + FlowNode flowNode = (FlowNode)bpmnModel.getFlowElement(taskDefKey);
  227 + //输出连线
  228 + List<SequenceFlow> outgoingFlows = flowNode.getOutgoingFlows();
  229 + //遍历返回下一个节点信息
  230 + for (SequenceFlow outgoingFlow : outgoingFlows) {
  231 + //类型自己判断(获取下个节点是网关还是节点)
  232 + FlowElement targetFlowElement = outgoingFlow.getTargetFlowElement();
  233 + getFlow(bpmnModel, targetFlowElement, tmpBpmTaskAssignRuleDOList, bpmTaskRespVOList, userDoMap, deptMap,
  234 + taskVarMap);
  235 + }
  236 + }
  237 +
  238 + private void getFlow(BpmnModel bpmnModel, FlowElement targetFlowElement,
  239 + List<BpmTaskAssignRuleDO> tmpBpmTaskAssignRuleDOList, LinkedList<BpmTaskRespVO> bpmTaskRespVOList,
  240 + Map<Long, AdminUserDO> userDoMap, Map<Long, DeptDO> deptMap, Map<String, Object> taskVarMap) {
  241 + // 下一个taskDefKey
  242 + String nextTaskDefKey = null;
  243 + //下个是节点
  244 + if (targetFlowElement instanceof UserTask) {
  245 + // 判断是否是为并行任务
  246 + List<BpmTaskAssignRuleDO> bpmTaskAssignRuleDOList = tmpBpmTaskAssignRuleDOList.stream().filter(
  247 + bpmTaskAssignRuleDO -> bpmTaskAssignRuleDO.getTaskDefinitionKey().equals(targetFlowElement.getId()))
  248 + .collect(Collectors.toList());
  249 + if (CollUtil.isEmpty(bpmTaskAssignRuleDOList)) {
  250 + throw new RuntimeException("任务key不存在!!!");
  251 + }
  252 + for (BpmTaskAssignRuleDO bpmTaskAssignRuleDO : bpmTaskAssignRuleDOList) {
  253 + nextTaskDefKey = bpmTaskAssignRuleDO.getTaskDefinitionKey();
  254 + for (Long userId : bpmTaskAssignRuleDO.getOptions()) {
  255 + BpmTaskRespVO bpmTaskRespVO =
  256 + (BpmTaskRespVO)new BpmTaskRespVO().setName(targetFlowElement.getName());
  257 + bpmTaskRespVOList.addFirst(bpmTaskRespVO);
  258 + AdminUserDO adminUserDO = userDoMap.get(userId);
  259 + DeptDO deptDO = deptMap.get(adminUserDO.getDeptId());
  260 + bpmTaskRespVO.setAssigneeUser(setUser(adminUserDO));
  261 + bpmTaskRespVO.getAssigneeUser().setDeptName(deptDO.getName());
  262 + if (!bpmTaskAssignRuleDO.getType().equals(BpmTaskAssignRuleTypeEnum.USER_OR_SIGN.getType())
  263 + && !bpmTaskAssignRuleDO.getType().equals(BpmTaskAssignRuleTypeEnum.USER_SIGN.getType())) {
  264 + break;
  265 + }
  266 + }
  267 + }
  268 + getFlow(bpmnModel, nextTaskDefKey, tmpBpmTaskAssignRuleDOList, bpmTaskRespVOList, userDoMap, deptMap,
  269 + taskVarMap);
  270 + // 下个节点是网关(调用下面的方法)
  271 + } else if (targetFlowElement instanceof ExclusiveGateway) {
  272 + String defaultFlow = ((ExclusiveGateway)targetFlowElement).getDefaultFlow();
  273 + FlowElement nexFlowElement = getExclusiveGateway(targetFlowElement, taskVarMap, defaultFlow);
  274 + getFlow(bpmnModel, nexFlowElement, tmpBpmTaskAssignRuleDOList, bpmTaskRespVOList, userDoMap, deptMap,
  275 + taskVarMap);
  276 + }
  277 + }
  278 +
  279 + /**
  280 + * 获取排他网关分支名称、分支表达式、下一级任务节点
  281 + *
  282 + * @param flowElement 任务节点
  283 + * @param taskVarMap 审批数据
  284 + */
  285 + private FlowElement getExclusiveGateway(FlowElement flowElement, Map<String, Object> taskVarMap,
  286 + String defaultFlow) {
  287 + // 获取所有网关分支
  288 + List<SequenceFlow> targetFlows = ((ExclusiveGateway)flowElement).getOutgoingFlows();
  289 + Boolean elExpressionFlag = Boolean.FALSE;
  290 + FlowElement sequenceFlowResult = null;
  291 + FlowElement defaultSequenceFlow = null;
  292 + // 循环每个网关分支
  293 + for (SequenceFlow sequenceFlow : targetFlows) {
  294 + if (defaultFlow.equals(sequenceFlow.getId())) {
  295 + defaultSequenceFlow = sequenceFlow.getTargetFlowElement();
  296 + continue;
  297 + }
  298 + elExpressionFlag = elExpression(sequenceFlow.getConditionExpression(), taskVarMap);
  299 + if (elExpressionFlag) {
  300 + // 获取下一个网关和节点数据
  301 + FlowElement targetFlowElement = sequenceFlow.getTargetFlowElement();
  302 + // 网关的下个节点是用户节点
  303 + if (targetFlowElement instanceof UserTask) {
  304 + sequenceFlowResult = targetFlowElement;
  305 + break;
  306 + } else if (targetFlowElement instanceof EndEvent) {
  307 + log.info("排他网关的下一节点是EndEvent: 结束节点");
  308 + } else if (targetFlowElement instanceof ServiceTask) {
  309 + log.info("排他网关的下一节点是ServiceTask: 内部方法");
  310 + } else if (targetFlowElement instanceof ExclusiveGateway) {
  311 + defaultFlow = ((ExclusiveGateway)targetFlowElement).getDefaultFlow();
  312 + return getExclusiveGateway(targetFlowElement, taskVarMap, defaultFlow);
  313 + } else if (targetFlowElement instanceof SubProcess) {
  314 + log.info("排他网关的下一节点是SubProcess: 内部子流程");
  315 + }
  316 + }
  317 + }
  318 + if (!elExpressionFlag) {
  319 + if (defaultSequenceFlow instanceof UserTask) {
  320 + sequenceFlowResult = defaultSequenceFlow;
  321 + } else if (defaultSequenceFlow instanceof ExclusiveGateway) {
  322 + defaultFlow = ((ExclusiveGateway)defaultSequenceFlow).getDefaultFlow();
  323 + return getExclusiveGateway(defaultSequenceFlow, taskVarMap, defaultFlow);
  324 + }
  325 + }
  326 + return sequenceFlowResult;
  327 + }
  328 +
  329 + /**
  330 + * 网关分叉条件判断,网关分叉,必须要有默认出口
  331 + *
  332 + * @param elExpression el表达式
  333 + * @param variableMap 流程所有变量
  334 + *
  335 + * @return 返回true或false
  336 + */
  337 + private Boolean elExpression(String elExpression, Map<String, Object> variableMap) {
  338 + ExpressionFactory factory = new ExpressionFactoryImpl();
  339 + SimpleContext context = new SimpleContext();
  340 + for (String k : variableMap.keySet()) {
  341 + if (variableMap.get(k) != null) {
  342 + context.setVariable(k,
  343 + factory.createValueExpression(variableMap.get(k), variableMap.get(k).getClass()));
  344 + }
  345 + }
  346 + ValueExpression e = factory.createValueExpression(context, elExpression, Boolean.class);
  347 + //el表达式和variables得到的结果
  348 + return (Boolean)e.getValue(context);
  349 + }
  350 +}
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/business/hi/task/inst/service/HiTaskinstService.java deleted
1   -package cn.iocoder.yudao.module.business.hi.task.inst.service;
2   -
3   -import cn.hutool.core.bean.BeanUtil;
4   -import cn.hutool.core.collection.CollUtil;
5   -import cn.hutool.core.util.BooleanUtil;
6   -import cn.hutool.json.JSONUtil;
7   -import cn.iocoder.yudao.module.bpm.domain.vo.ApproveProcInstVO;
8   -import lombok.extern.slf4j.Slf4j;
9   -import org.flowable.common.engine.impl.de.odysseus.el.util.SimpleContext;
10   -import org.flowable.engine.HistoryService;
11   -import org.flowable.engine.RepositoryService;
12   -import org.flowable.engine.TaskService;
13   -import org.flowable.variable.api.history.HistoricVariableInstance;
14   -import org.springframework.beans.factory.annotation.Autowired;
15   -import org.springframework.stereotype.Service;
16   -
17   -import java.util.*;
18   -
19   -/**
20   - * [ ]
21   - *
22   - * @author 孟凯
23   - * @version 1.0
24   - * @company 1024创新实验室(www.1024lab.net)
25   - * @copyright (c) 1024创新实验室( www.1024lab.net )Inc. All rights reserved.
26   - * @date 2022-01-17 15:14:27
27   - * @since JDK1.8
28   - */
29   -@Slf4j
30   -@Service
31   -public class HiTaskinstService {
32   -
33   -
34   - @Autowired
35   - private TaskService taskService;
36   - @Autowired
37   - private HistoryService historyService;
38   - @Autowired
39   - private RepositoryService repositoryService;
40   -
41   - /**
42   - * 获取任务具体流程信息
43   - *
44   - * @param procInstId 流程id
45   - * @param procDefId 流程部署id
46   - *
47   - * @return 返回流程信息
48   - */
49   - public List<ApproveProcInstVO> taskGetComment(String procInstId, String procDefId) {
50   - Map<String, Object> variableMap = new HashMap<>(50);
51   - List<HistoricVariableInstance> hisVarInstList =
52   - historyService.createHistoricVariableInstanceQuery().processInstanceId(procInstId).list();
53   - hisVarInstList.forEach(hisVarInst -> {
54   - variableMap.put(hisVarInst.getName(), hisVarInst.getValue());
55   - });
56   -
57   - List<ApproveProcInstVO> procInstVOList = hiTaskinstDao.listByProcInstIdAndNotDelete(procInstId);
58   -
59   - BpmnModelInstance bpmnModelInstance = repositoryService.getBpmnModel(procDefId);
60   - DomElement document1 = bpmnModelInstance.getDocument().getElementById(procDefId.split(":")[0]);
61   - LinkedHashMap<String, DomElement> domElementMap = new LinkedHashMap<>(50);
62   - getChildElementToMap(document1, domElementMap);
63   - getChildNode(procInstVOList, domElementMap, variableMap);
64   - return procInstVOList;
65   - }
66   -
67   - /**
68   - * 获取子节点信息,存储到map中
69   - *
70   - * @param domElement 父节点
71   - * @param domElementMap 节点map
72   - */
73   - private void getChildElementToMap(DomElement domElement, LinkedHashMap<String, DomElement> domElementMap) {
74   - List<DomElement> childElements = domElement.getChildElements();
75   - for (DomElement childElement : childElements) {
76   - if ("BPMNDiagram".equals(childElement.getLocalName())) {
77   - break;
78   - }
79   - if ("extensionElements".equals(childElement.getLocalName())) {
80   - break;
81   - }
82   - if (!"outgoing".equals(childElement.getLocalName()) && !"incoming".equals(childElement.getLocalName())) {
83   - domElementMap.put(childElement.getAttribute("id"), childElement);
84   - }
85   - getChildElementToMap(childElement, domElementMap);
86   - }
87   - }
88   -
89   - /**
90   - * 获取子节点信息
91   - *
92   - * @param procInstVOList 流程VO列表
93   - * @param domElementMap 节点map
94   - * @param variableMap 流程所有的变量
95   - */
96   - private void getChildNode(List<ApproveProcInstVO> procInstVOList, LinkedHashMap<String, DomElement> domElementMap,
97   - Map<String, Object> variableMap) {
98   - DomElement domElement = domElementMap.get(procInstVOList.get(procInstVOList.size() - 1).getTaskDefKey());
99   - for (DomElement childElement : domElement.getChildElements()) {
100   - if ("outgoing".equals(childElement.getLocalName())) {
101   - DomElement tmpDomElement = domElementMap.get(childElement.getTextContent());
102   - getChildNode(procInstVOList, domElementMap, variableMap, tmpDomElement);
103   - }
104   - }
105   - }
106   -
107   - /**
108   - * 获取子节点信息
109   - *
110   - * @param procInstVOList 流程VO列表
111   - * @param domElementMap 节点map
112   - * @param variableMap 流程所有的变量
113   - * @param domElement 父节点信息
114   - */
115   - private void getChildNode(List<ApproveProcInstVO> procInstVOList, LinkedHashMap<String, DomElement> domElementMap,
116   - Map<String, Object> variableMap, DomElement domElement) {
117   - if ("exclusiveGateway".equals(domElement.getLocalName())) {
118   - DomElement domElementChild = getNodeExclusiveGateway(domElementMap, variableMap, domElement);
119   - getChildNode(procInstVOList, domElementMap, variableMap, domElementChild);
120   - } else if ("userTask".equals(domElement.getLocalName())) {
121   - getProcInstVO(procInstVOList, domElement, variableMap);
122   - for (DomElement childElement : domElement.getChildElements()) {
123   - if ("outgoing".equals(childElement.getLocalName())) {
124   - DomElement tmpDomElement = domElementMap.get(childElement.getTextContent());
125   - DomElement domElementChild = getNodeBySequenceFlow(domElementMap, tmpDomElement);
126   - if ("endEvent".equals(domElementChild.getLocalName())) {
127   - return;
128   - }
129   - getChildNode(procInstVOList, domElementMap, variableMap, domElementChild);
130   - }
131   - }
132   - } else {
133   - DomElement domElementChild = getNodeBySequenceFlow(domElementMap, domElement);
134   - if (BeanUtil.isEmpty(domElementChild)) {
135   - throw new RuntimeException("无流程可执行!!!");
136   - }
137   - if ("endEvent".equals(domElementChild.getLocalName())) {
138   - return;
139   - }
140   - getChildNode(procInstVOList, domElementMap, variableMap, domElementChild);
141   - }
142   - }
143   -
144   - /**
145   - * 获取网关节点的子节点
146   - *
147   - * @param domElementMap 流程所有的节点
148   - * @param variableMap 流程所有的变量
149   - * @param domElement 父节点信息
150   - *
151   - * @return 返回子节点信息
152   - */
153   - private DomElement getNodeExclusiveGateway(LinkedHashMap<String, DomElement> domElementMap,
154   - Map<String, Object> variableMap, DomElement domElement) {
155   - Boolean elExpressionFlag = Boolean.FALSE;
156   - ArrayList<DomElement> nullChildSequenceFlowList = new ArrayList<>();
157   - for (DomElement exclusiveGatewayChild : domElement.getChildElements()) {
158   - if ("outgoing".equals(exclusiveGatewayChild.getLocalName()) && BooleanUtil.isFalse(elExpressionFlag)) {
159   - DomElement sequenceFlowDomElement = domElementMap.get(exclusiveGatewayChild.getTextContent());
160   - if (CollUtil.isNotEmpty(sequenceFlowDomElement.getChildElements())
161   - && sequenceFlowDomElement.getChildElements().size() > 0) {
162   - for (DomElement conditionExpression : sequenceFlowDomElement.getChildElements()) {
163   - if ("conditionExpression".equals(conditionExpression.getLocalName())) {
164   - elExpressionFlag = elExpression(conditionExpression.getTextContent(), variableMap);
165   - if (BooleanUtil.isTrue(elExpressionFlag)) {
166   - break;
167   - }
168   - }
169   - }
170   - } else {
171   - nullChildSequenceFlowList.add(sequenceFlowDomElement);
172   - }
173   - if (elExpressionFlag) {
174   - return getNodeBySequenceFlow(domElementMap, sequenceFlowDomElement);
175   - }
176   - }
177   - }
178   - if (CollUtil.isEmpty(nullChildSequenceFlowList) && nullChildSequenceFlowList.size() < 1) {
179   - throw new RuntimeException("网关缺少无条件流程可执行!!!");
180   - }
181   - if (nullChildSequenceFlowList.size() > 1) {
182   - throw new RuntimeException("无条件流程大于1条!!!");
183   - }
184   - return getNodeBySequenceFlow(domElementMap, nullChildSequenceFlowList.get(0));
185   - }
186   -
187   - /**
188   - * 获取流程序列流的子节点
189   - *
190   - * @param domElementMap 流程所有节点
191   - * @param domElement 父节点信息
192   - *
193   - * @return 返回子节点
194   - */
195   - private DomElement getNodeBySequenceFlow(LinkedHashMap<String, DomElement> domElementMap, DomElement domElement) {
196   - String targetRef = domElement.getAttribute("targetRef");
197   - return domElementMap.get(targetRef);
198   - }
199   -
200   - /**
201   - * 设置节点信息进ApproveProcInstVO
202   - *
203   - * @param procInstVOList ApproveProcInstVOList
204   - * @param domElement 节点信息
205   - * @param variableMap 流程所有变量
206   - */
207   - private void getProcInstVO(List<ApproveProcInstVO> procInstVOList, DomElement domElement,
208   - Map<String, Object> variableMap) {
209   - String camundaNameSpaceUri = "http://camunda.org/schema/1.0/bpmn";
210   - boolean userListFlag = false;
211   - List<Object> approveProcInstVOList = new ArrayList<>();
212   - for (DomElement childElement : domElement.getChildElements()) {
213   - if ("multiInstanceLoopCharacteristics".equals(childElement.getLocalName())) {
214   - userListFlag = true;
215   - String collectionVar = childElement.getAttribute(camundaNameSpaceUri, "collection");
216   - Object taskUserList = variableMap.get(collectionVar);
217   - approveProcInstVOList = JSONUtil.parseArray(taskUserList);
218   - }
219   - }
220   -
221   - if (userListFlag) {
222   - approveProcInstVOList.forEach(tmpAssignee -> {
223   - String assignee = String.valueOf(tmpAssignee);
224   - ApproveProcInstVO approveProcInstVO = new ApproveProcInstVO();
225   - approveProcInstVO.setName(domElement.getAttribute("name"));
226   - approveProcInstVO.setTaskDefKey(domElement.getAttribute("id"));
227   - approveProcInstVO.setAssignee(assignee);
228   - approveProcInstVO.setAssigneeName(employeeDao.getByLoginName(assignee, 0).getActualName());
229   - procInstVOList.add(approveProcInstVO);
230   - });
231   - } else {
232   - ApproveProcInstVO approveProcInstVO = new ApproveProcInstVO();
233   - approveProcInstVO.setName(domElement.getAttribute("name"));
234   - approveProcInstVO.setTaskDefKey(domElement.getAttribute("id"));
235   - approveProcInstVO.setAssignee(domElement.getAttribute(camundaNameSpaceUri, "assignee"));
236   - approveProcInstVO.setAssigneeName(
237   - employeeDao.getByLoginName(approveProcInstVO.getAssignee(), 0).getActualName());
238   - procInstVOList.add(approveProcInstVO);
239   - }
240   - }
241   -
242   - /**
243   - * 网关分叉条件判断,网关分叉,必须要有默认出口
244   - *
245   - * @param elExpression el表达式
246   - * @param variableMap 流程所有变量
247   - *
248   - * @return 返回true或false
249   - */
250   - private Boolean elExpression(String elExpression, Map<String, Object> variableMap) {
251   - ExpressionFactory factory = new ExpressionFactoryImpl();
252   - SimpleContext context = new SimpleContext();
253   - for (String k : variableMap.keySet()) {
254   - if (variableMap.get(k) != null) {
255   - context.setVariable(k,
256   - factory.createValueExpression(variableMap.get(k), variableMap.get(k).getClass()));
257   - }
258   - }
259   - ValueExpression e = factory.createValueExpression(context, elExpression, Boolean.class);
260   - //el表达式和variables得到的结果
261   - return (Boolean)e.getValue(context);
262   - }
263   -}