Commit f47f6d934ee23cc98c440cfb62246b9c4fa8802f

Authored by YunaiV
1 parent f8d6f1e2

【代码评审】Bpm:数据报表

yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/simple/BpmSimpleModelNodeVO.java
... ... @@ -362,6 +362,7 @@ public class BpmSimpleModelNodeVO {
362 362 @Valid
363 363 private List<HttpRequestParam> body;
364 364  
  365 + // TODO @json:可能未来看情况,搞个 HttpResponseParam;得看看有没别的业务需要,抽象统一
365 366 /**
366 367 * 请求返回处理设置,用于修改流程表单值
367 368 *
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstancePageReqVO.java
... ... @@ -8,7 +8,6 @@ import lombok.Data;
8 8 import org.springframework.format.annotation.DateTimeFormat;
9 9  
10 10 import java.time.LocalDateTime;
11   -import java.util.Map;
12 11  
13 12 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
14 13  
... ... @@ -40,7 +39,7 @@ public class BpmProcessInstancePageReqVO extends PageParam {
40 39 @Schema(description = "发起用户编号", example = "1024")
41 40 private Long startUserId; // 注意,只有在【流程实例】菜单,才使用该参数
42 41  
43   - @Schema(description = "动态表单字段查询JSON Str", example = "{}")
44   - private String formFieldsParams;
  42 + @Schema(description = "动态表单字段查询 JSON Str", example = "{}")
  43 + private String formFieldsParams; // SpringMVC 在 get 请求下,无法方便的定义 Map 类型的参数,所以通过 String 接收后,逻辑里面转换
45 44  
46 45 }
... ...
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 import cn.hutool.core.util.ArrayUtil;
8 8 import cn.hutool.core.util.ObjectUtil;
9 9 import cn.hutool.core.util.StrUtil;
10   -import cn.hutool.json.JSONObject;
11 10 import cn.iocoder.yudao.framework.common.pojo.PageResult;
12 11 import cn.iocoder.yudao.framework.common.util.date.DateUtils;
13 12 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
... ... @@ -134,69 +133,18 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
134 133  
135 134 @Override
136 135 public HistoricProcessInstance getHistoricProcessInstance(String id) {
137   - return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).includeProcessVariables().singleResult();
  136 + return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).includeProcessVariables()
  137 + .singleResult();
138 138 }
139 139  
140 140 @Override
141 141 public List<HistoricProcessInstance> getHistoricProcessInstances(Set<String> ids) {
142   - return historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids).includeProcessVariables().list();
143   - }
144   -
145   - @Override
146   - public PageResult<HistoricProcessInstance> getProcessInstancePage(Long userId,
147   - BpmProcessInstancePageReqVO pageReqVO) {
148   - // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页
149   - HistoricProcessInstanceQuery processInstanceQuery = historyService.createHistoricProcessInstanceQuery()
150   - .includeProcessVariables()
151   - .processInstanceTenantId(FlowableUtils.getTenantId())
152   - .orderByProcessInstanceStartTime().desc();
153   - if (userId != null) { // 【我的流程】菜单时,需要传递该字段
154   - processInstanceQuery.startedBy(String.valueOf(userId));
155   - } else if (pageReqVO.getStartUserId() != null) { // 【管理流程】菜单时,才会传递该字段
156   - processInstanceQuery.startedBy(String.valueOf(pageReqVO.getStartUserId()));
157   - }
158   - if (StrUtil.isNotEmpty(pageReqVO.getName())) {
159   - processInstanceQuery.processInstanceNameLike("%" + pageReqVO.getName() + "%");
160   - }
161   - if (StrUtil.isNotEmpty(pageReqVO.getProcessDefinitionKey())) {
162   - processInstanceQuery.processDefinitionKey(pageReqVO.getProcessDefinitionKey());
163   - }
164   - if (StrUtil.isNotEmpty(pageReqVO.getCategory())) {
165   - processInstanceQuery.processDefinitionCategory(pageReqVO.getCategory());
166   - }
167   - if (pageReqVO.getStatus() != null) {
168   - processInstanceQuery.variableValueEquals(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS, pageReqVO.getStatus());
169   - }
170   - if (ArrayUtil.isNotEmpty(pageReqVO.getCreateTime())) {
171   - processInstanceQuery.startedAfter(DateUtils.of(pageReqVO.getCreateTime()[0]));
172   - processInstanceQuery.startedBefore(DateUtils.of(pageReqVO.getCreateTime()[1]));
173   - }
174   - if (ArrayUtil.isNotEmpty(pageReqVO.getEndTime())) {
175   - processInstanceQuery.finishedAfter(DateUtils.of(pageReqVO.getEndTime()[0]));
176   - processInstanceQuery.finishedBefore(DateUtils.of(pageReqVO.getEndTime()[1]));
177   - }
178   - // 表单字段查询
179   - // TODO 应支持多种类型的查询方式,目前只有字符串全等
180   - if (StrUtil.isNotEmpty(pageReqVO.getFormFieldsParams())) {
181   - JSONObject formFieldsParams = new JSONObject(pageReqVO.getFormFieldsParams());
182   - for (Map.Entry<String, Object> field : formFieldsParams.entrySet()) {
183   - if (StrUtil.isNotEmpty(field.getValue().toString())) {
184   - processInstanceQuery.variableValueEquals(field.getKey(), field.getValue());
185   - }
186   - }
187   - }
188   - // 查询数量
189   - long processInstanceCount = processInstanceQuery.count();
190   - if (processInstanceCount == 0) {
191   - return PageResult.empty(processInstanceCount);
192   - }
193   - // 查询列表
194   - List<HistoricProcessInstance> processInstanceList = processInstanceQuery.listPage(PageUtils.getStart(pageReqVO), pageReqVO.getPageSize());
195   - return new PageResult<>(processInstanceList, processInstanceCount);
  142 + return historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids).includeProcessVariables()
  143 + .list();
196 144 }
197 145  
198 146 private Map<String, String> getFormFieldsPermission(BpmnModel bpmnModel,
199   - String activityId, String taskId) {
  147 + String activityId, String taskId) {
200 148 // 1. 获取流程活动编号。流程活动 Id 为空事,从流程任务中获取流程活动 Id
201 149 if (StrUtil.isEmpty(activityId) && StrUtil.isNotEmpty(taskId)) {
202 150 activityId = Optional.ofNullable(taskService.getHistoricTask(taskId))
... ... @@ -229,8 +177,10 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
229 177 }
230 178 // 1.3 读取其它相关数据
231 179 ProcessDefinition processDefinition = processDefinitionService.getProcessDefinition(
232   - historicProcessInstance != null ? historicProcessInstance.getProcessDefinitionId() : reqVO.getProcessDefinitionId());
233   - BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.getProcessDefinitionInfo(processDefinition.getId());
  180 + historicProcessInstance != null ? historicProcessInstance.getProcessDefinitionId()
  181 + : reqVO.getProcessDefinitionId());
  182 + BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService
  183 + .getProcessDefinitionInfo(processDefinition.getId());
234 184 BpmnModel bpmnModel = processDefinitionService.getProcessDefinitionBpmnModel(processDefinition.getId());
235 185  
236 186 // 2.1 已结束 + 进行中的活动节点
... ... @@ -239,24 +189,29 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
239 189 List<HistoricActivityInstance> activities = null; // 流程实例列表
240 190 if (reqVO.getProcessInstanceId() != null) {
241 191 activities = taskService.getActivityListByProcessInstanceId(reqVO.getProcessInstanceId());
242   - List<HistoricTaskInstance> tasks = taskService.getTaskListByProcessInstanceId(reqVO.getProcessInstanceId(), true);
  192 + List<HistoricTaskInstance> tasks = taskService.getTaskListByProcessInstanceId(reqVO.getProcessInstanceId(),
  193 + true);
243 194 endActivityNodes = getEndActivityNodeList(startUserId, bpmnModel, processDefinitionInfo,
244 195 historicProcessInstance, processInstanceStatus, activities, tasks);
245   - runActivityNodes = getRunApproveNodeList(startUserId, bpmnModel, processDefinition, processVariables, activities, tasks);
  196 + runActivityNodes = getRunApproveNodeList(startUserId, bpmnModel, processDefinition, processVariables,
  197 + activities, tasks);
246 198 }
247 199  
248 200 // 2.2 流程已经结束,直接 return,无需预测
249 201 if (BpmProcessInstanceStatusEnum.isProcessEndStatus(processInstanceStatus)) {
250   - return buildApprovalDetail(reqVO, bpmnModel, processDefinition, processDefinitionInfo, historicProcessInstance,
  202 + return buildApprovalDetail(reqVO, bpmnModel, processDefinition, processDefinitionInfo,
  203 + historicProcessInstance,
251 204 processInstanceStatus, endActivityNodes, runActivityNodes, null, null);
252 205 }
253 206  
254 207 // 3.1 计算当前登录用户的待办任务
255   - // TODO @jason:有一个极端情况,如果一个用户有 2 个 task A 和 B,A 已经通过,B 需要审核。这个时,通过 A 进来,todo 拿到 B,会不会表单权限不一致哈。
  208 + // TODO @jason:有一个极端情况,如果一个用户有 2 个 task A 和 B,A 已经通过,B 需要审核。这个时,通过 A 进来,todo 拿到
  209 + // B,会不会表单权限不一致哈。
256 210 BpmTaskRespVO todoTask = taskService.getFirstTodoTask(loginUserId, reqVO.getProcessInstanceId());
257 211  
258 212 // 3.2 预测未运行节点的审批信息
259   - List<ActivityNode> simulateActivityNodes = getSimulateApproveNodeList(startUserId, bpmnModel, processDefinitionInfo,
  213 + List<ActivityNode> simulateActivityNodes = getSimulateApproveNodeList(startUserId, bpmnModel,
  214 + processDefinitionInfo,
260 215 processVariables, activities);
261 216  
262 217 // 4. 拼接最终数据
... ... @@ -264,34 +219,93 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
264 219 processInstanceStatus, endActivityNodes, runActivityNodes, simulateActivityNodes, todoTask);
265 220 }
266 221  
  222 + @Override
  223 + @SuppressWarnings("unchecked")
  224 + public PageResult<HistoricProcessInstance> getProcessInstancePage(Long userId,
  225 + BpmProcessInstancePageReqVO pageReqVO) {
  226 + // 1. 构建查询条件
  227 + HistoricProcessInstanceQuery processInstanceQuery = historyService.createHistoricProcessInstanceQuery()
  228 + .includeProcessVariables()
  229 + .processInstanceTenantId(FlowableUtils.getTenantId())
  230 + .orderByProcessInstanceStartTime().desc();
  231 + if (userId != null) { // 【我的流程】菜单时,需要传递该字段
  232 + processInstanceQuery.startedBy(String.valueOf(userId));
  233 + } else if (pageReqVO.getStartUserId() != null) { // 【管理流程】菜单时,才会传递该字段
  234 + processInstanceQuery.startedBy(String.valueOf(pageReqVO.getStartUserId()));
  235 + }
  236 + if (StrUtil.isNotEmpty(pageReqVO.getName())) {
  237 + processInstanceQuery.processInstanceNameLike("%" + pageReqVO.getName() + "%");
  238 + }
  239 + if (StrUtil.isNotEmpty(pageReqVO.getProcessDefinitionKey())) {
  240 + processInstanceQuery.processDefinitionKey(pageReqVO.getProcessDefinitionKey());
  241 + }
  242 + if (StrUtil.isNotEmpty(pageReqVO.getCategory())) {
  243 + processInstanceQuery.processDefinitionCategory(pageReqVO.getCategory());
  244 + }
  245 + if (pageReqVO.getStatus() != null) {
  246 + processInstanceQuery.variableValueEquals(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS,
  247 + pageReqVO.getStatus());
  248 + }
  249 + if (ArrayUtil.isNotEmpty(pageReqVO.getCreateTime())) {
  250 + processInstanceQuery.startedAfter(DateUtils.of(pageReqVO.getCreateTime()[0]));
  251 + processInstanceQuery.startedBefore(DateUtils.of(pageReqVO.getCreateTime()[1]));
  252 + }
  253 + if (ArrayUtil.isNotEmpty(pageReqVO.getEndTime())) {
  254 + processInstanceQuery.finishedAfter(DateUtils.of(pageReqVO.getEndTime()[0]));
  255 + processInstanceQuery.finishedBefore(DateUtils.of(pageReqVO.getEndTime()[1]));
  256 + }
  257 + // 表单字段查询
  258 + Map<String, Object> formFieldsParams = JsonUtils.parseObject(pageReqVO.getFormFieldsParams(), Map.class);
  259 + if (CollUtil.isNotEmpty(formFieldsParams)) {
  260 + formFieldsParams.forEach((key, value) -> {
  261 + if (StrUtil.isEmpty(String.valueOf(value))) {
  262 + return;
  263 + }
  264 + // TODO @lesan:应支持多种类型的查询方式,目前只有字符串全等
  265 + processInstanceQuery.variableValueEquals(key, value);
  266 + });
  267 + }
  268 +
  269 + // 2.1 查询数量
  270 + long processInstanceCount = processInstanceQuery.count();
  271 + if (processInstanceCount == 0) {
  272 + return PageResult.empty(processInstanceCount);
  273 + }
  274 + // 2.2 查询列表
  275 + List<HistoricProcessInstance> processInstanceList = processInstanceQuery.listPage(PageUtils.getStart(pageReqVO),
  276 + pageReqVO.getPageSize());
  277 + return new PageResult<>(processInstanceList, processInstanceCount);
  278 + }
  279 +
267 280 /**
268 281 * 拼接审批详情的最终数据
269 282 * <p>
270 283 * 主要是,拼接审批人的用户信息、部门信息
271 284 */
272 285 private BpmApprovalDetailRespVO buildApprovalDetail(BpmApprovalDetailReqVO reqVO,
273   - BpmnModel bpmnModel,
274   - ProcessDefinition processDefinition,
275   - BpmProcessDefinitionInfoDO processDefinitionInfo,
276   - HistoricProcessInstance processInstance,
277   - Integer processInstanceStatus,
278   - List<ActivityNode> endApprovalNodeInfos,
279   - List<ActivityNode> runningApprovalNodeInfos,
280   - List<ActivityNode> simulateApprovalNodeInfos,
281   - BpmTaskRespVO todoTask) {
  286 + BpmnModel bpmnModel,
  287 + ProcessDefinition processDefinition,
  288 + BpmProcessDefinitionInfoDO processDefinitionInfo,
  289 + HistoricProcessInstance processInstance,
  290 + Integer processInstanceStatus,
  291 + List<ActivityNode> endApprovalNodeInfos,
  292 + List<ActivityNode> runningApprovalNodeInfos,
  293 + List<ActivityNode> simulateApprovalNodeInfos,
  294 + BpmTaskRespVO todoTask) {
282 295 // 1. 获取所有需要读取用户信息的 userIds
283   - List<ActivityNode> approveNodes = newArrayList(asList(endApprovalNodeInfos, runningApprovalNodeInfos, simulateApprovalNodeInfos));
  296 + List<ActivityNode> approveNodes = newArrayList(
  297 + asList(endApprovalNodeInfos, runningApprovalNodeInfos, simulateApprovalNodeInfos));
284 298 Set<Long> userIds = BpmProcessInstanceConvert.INSTANCE.parseUserIds(processInstance, approveNodes, todoTask);
285 299 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);
286 300 Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
287 301  
288   -
289 302 // 2. 表单权限
290 303 String taskId = reqVO.getTaskId() == null && todoTask != null ? todoTask.getId() : reqVO.getTaskId();
291 304 Map<String, String> formFieldsPermission = getFormFieldsPermission(bpmnModel, reqVO.getActivityId(), taskId);
292 305  
293 306 // 3. 拼接数据
294   - return BpmProcessInstanceConvert.INSTANCE.buildApprovalDetail(bpmnModel, processDefinition, processDefinitionInfo, processInstance,
  307 + return BpmProcessInstanceConvert.INSTANCE.buildApprovalDetail(bpmnModel, processDefinition,
  308 + processDefinitionInfo, processInstance,
295 309 processInstanceStatus, approveNodes, todoTask, formFieldsPermission, userMap, deptMap);
296 310 }
297 311  
... ... @@ -299,17 +313,19 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
299 313 * 获得【已结束】的活动节点们
300 314 */
301 315 private List<ActivityNode> getEndActivityNodeList(Long startUserId, BpmnModel bpmnModel,
302   - BpmProcessDefinitionInfoDO processDefinitionInfo,
303   - HistoricProcessInstance historicProcessInstance, Integer processInstanceStatus,
304   - List<HistoricActivityInstance> activities, List<HistoricTaskInstance> tasks) {
  316 + BpmProcessDefinitionInfoDO processDefinitionInfo,
  317 + HistoricProcessInstance historicProcessInstance, Integer processInstanceStatus,
  318 + List<HistoricActivityInstance> activities, List<HistoricTaskInstance> tasks) {
305 319 // 遍历 tasks 列表,只处理已结束的 UserTask
306   - // 为什么不通过 activities 呢?因为,加签场景下,它只存在于 tasks,没有 activities,导致如果遍历 activities 的话,它无法成为一个节点
  320 + // 为什么不通过 activities 呢?因为,加签场景下,它只存在于 tasks,没有 activities,导致如果遍历 activities
  321 + // 的话,它无法成为一个节点
307 322 List<HistoricTaskInstance> endTasks = filterList(tasks, task -> task.getEndTime() != null);
308 323 List<ActivityNode> approvalNodes = convertList(endTasks, task -> {
309 324 FlowElement flowNode = BpmnModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey());
310 325 ActivityNode activityNode = new ActivityNode().setId(task.getTaskDefinitionKey()).setName(task.getName())
311   - .setNodeType(START_USER_NODE_ID.equals(task.getTaskDefinitionKey()) ?
312   - BpmSimpleModelNodeTypeEnum.START_USER_NODE.getType() : BpmSimpleModelNodeTypeEnum.APPROVE_NODE.getType())
  326 + .setNodeType(START_USER_NODE_ID.equals(task.getTaskDefinitionKey())
  327 + ? BpmSimpleModelNodeTypeEnum.START_USER_NODE.getType()
  328 + : BpmSimpleModelNodeTypeEnum.APPROVE_NODE.getType())
313 329 .setStatus(FlowableUtils.getTaskStatus(task))
314 330 .setCandidateStrategy(BpmnModelUtils.parseCandidateStrategy(flowNode))
315 331 .setStartTime(DateUtils.of(task.getCreateTime())).setEndTime(DateUtils.of(task.getEndTime()))
... ... @@ -334,7 +350,8 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
334 350 .setName(BpmSimpleModelNodeTypeEnum.START_USER_NODE.getName())
335 351 .setNodeType(BpmSimpleModelNodeTypeEnum.START_USER_NODE.getType())
336 352 .setStatus(startTask.getStatus()).setTasks(ListUtil.of(startTask))
337   - .setStartTime(DateUtils.of(activity.getStartTime())).setEndTime(DateUtils.of(activity.getEndTime()));
  353 + .setStartTime(DateUtils.of(activity.getStartTime()))
  354 + .setEndTime(DateUtils.of(activity.getEndTime()));
338 355 approvalNodes.add(0, startNode);
339 356 return;
340 357 }
... ... @@ -347,7 +364,8 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
347 364 ActivityNode endNode = new ActivityNode().setId(activity.getId())
348 365 .setName(BpmSimpleModelNodeTypeEnum.END_NODE.getName())
349 366 .setNodeType(BpmSimpleModelNodeTypeEnum.END_NODE.getType()).setStatus(processInstanceStatus)
350   - .setStartTime(DateUtils.of(activity.getStartTime())).setEndTime(DateUtils.of(activity.getEndTime()));
  367 + .setStartTime(DateUtils.of(activity.getStartTime()))
  368 + .setEndTime(DateUtils.of(activity.getEndTime()));
351 369 String reason = FlowableUtils.getProcessInstanceReason(historicProcessInstance);
352 370 if (StrUtil.isNotEmpty(reason)) {
353 371 endNode.setTasks(singletonList(new ActivityNodeTask().setId(endNode.getId())
... ... @@ -363,15 +381,16 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
363 381 * 获得【进行中】的活动节点们
364 382 */
365 383 private List<ActivityNode> getRunApproveNodeList(Long startUserId,
366   - BpmnModel bpmnModel,
367   - ProcessDefinition processDefinition,
368   - Map<String, Object> processVariables,
369   - List<HistoricActivityInstance> activities,
370   - List<HistoricTaskInstance> tasks) {
  384 + BpmnModel bpmnModel,
  385 + ProcessDefinition processDefinition,
  386 + Map<String, Object> processVariables,
  387 + List<HistoricActivityInstance> activities,
  388 + List<HistoricTaskInstance> tasks) {
371 389 // 构建运行中的任务,基于 activityId 分组
372 390 List<HistoricActivityInstance> runActivities = filterList(activities, activity -> activity.getEndTime() == null
373 391 && (StrUtil.equalsAny(activity.getActivityType(), ELEMENT_TASK_USER)));
374   - Map<String, List<HistoricActivityInstance>> runningTaskMap = convertMultiMap(runActivities, HistoricActivityInstance::getActivityId);
  392 + Map<String, List<HistoricActivityInstance>> runningTaskMap = convertMultiMap(runActivities,
  393 + HistoricActivityInstance::getActivityId);
375 394  
376 395 // 按照 activityId 分组,构建 ApprovalNodeInfo 节点
377 396 Map<String, HistoricTaskInstance> taskMap = convertMap(tasks, HistoricTaskInstance::getId);
... ... @@ -381,8 +400,10 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
381 400 // 构建活动节点
382 401 FlowElement flowNode = BpmnModelUtils.getFlowElementById(bpmnModel, activityId);
383 402 HistoricActivityInstance firstActivity = CollUtil.getFirst(taskActivities); // 取第一个任务,会签/或签的任务,开始时间相同
384   - ActivityNode activityNode = new ActivityNode().setId(firstActivity.getActivityId()).setName(firstActivity.getActivityName())
385   - .setNodeType(BpmSimpleModelNodeTypeEnum.APPROVE_NODE.getType()).setStatus(BpmTaskStatusEnum.RUNNING.getStatus())
  403 + ActivityNode activityNode = new ActivityNode().setId(firstActivity.getActivityId())
  404 + .setName(firstActivity.getActivityName())
  405 + .setNodeType(BpmSimpleModelNodeTypeEnum.APPROVE_NODE.getType())
  406 + .setStatus(BpmTaskStatusEnum.RUNNING.getStatus())
386 407 .setCandidateStrategy(BpmnModelUtils.parseCandidateStrategy(flowNode))
387 408 .setStartTime(DateUtils.of(CollUtil.getFirst(taskActivities).getStartTime()))
388 409 .setTasks(new ArrayList<>());
... ... @@ -395,7 +416,8 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
395 416 taskService.getAllChildrenTaskListByParentTaskId(activity.getTaskId(), tasks),
396 417 childTask -> childTask.getEndTime() == null);
397 418 if (CollUtil.isNotEmpty(childrenTasks)) {
398   - activityNode.getTasks().addAll(convertList(childrenTasks, BpmProcessInstanceConvert.INSTANCE::buildApprovalTaskInfo));
  419 + activityNode.getTasks().addAll(
  420 + convertList(childrenTasks, BpmProcessInstanceConvert.INSTANCE::buildApprovalTaskInfo));
399 421 }
400 422 }
401 423 // 处理每个任务的 candidateUsers 属性:如果是依次审批,需要预测它的后续审批人。因为 Task 是审批完一个,创建一个新的 Task
... ... @@ -405,8 +427,9 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
405 427 // 截取当前审批人位置后面的候选人,不包含当前审批人
406 428 ActivityNodeTask approvalTaskInfo = CollUtil.getFirst(activityNode.getTasks());
407 429 Assert.notNull(approvalTaskInfo, "任务不能为空");
408   - int index = CollUtil.indexOf(candidateUserIds, userId -> ObjectUtils.equalsAny(userId, approvalTaskInfo.getOwner(),
409   - approvalTaskInfo.getAssignee())); // 委派或者向前加签情况,需要先比较 owner
  430 + int index = CollUtil.indexOf(candidateUserIds,
  431 + userId -> ObjectUtils.equalsAny(userId, approvalTaskInfo.getOwner(),
  432 + approvalTaskInfo.getAssignee())); // 委派或者向前加签情况,需要先比较 owner
410 433 activityNode.setCandidateUserIds(CollUtil.sub(candidateUserIds, index + 1, candidateUserIds.size()));
411 434 }
412 435 return activityNode;
... ... @@ -417,10 +440,11 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
417 440 * 获得【预测(未来)】的活动节点们
418 441 */
419 442 private List<ActivityNode> getSimulateApproveNodeList(Long startUserId, BpmnModel bpmnModel,
420   - BpmProcessDefinitionInfoDO processDefinitionInfo,
421   - Map<String, Object> processVariables,
422   - List<HistoricActivityInstance> activities) {
423   - // TODO @芋艿:【可优化】在驳回场景下,未来的预测准确性不高。原因是,驳回后,HistoricActivityInstance 包括了历史的操作,不是只有 startEvent 到当前节点的记录
  443 + BpmProcessDefinitionInfoDO processDefinitionInfo,
  444 + Map<String, Object> processVariables,
  445 + List<HistoricActivityInstance> activities) {
  446 + // TODO @芋艿:【可优化】在驳回场景下,未来的预测准确性不高。原因是,驳回后,HistoricActivityInstance
  447 + // 包括了历史的操作,不是只有 startEvent 到当前节点的记录
424 448 Set<String> runActivityIds = convertSet(activities, HistoricActivityInstance::getActivityId);
425 449 // 情况一:BPMN 设计器
426 450 if (Objects.equals(BpmModelTypeEnum.BPMN.getType(), processDefinitionInfo.getModelType())) {
... ... @@ -430,7 +454,8 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
430 454 }
431 455 // 情况二:SIMPLE 设计器
432 456 if (Objects.equals(BpmModelTypeEnum.SIMPLE.getType(), processDefinitionInfo.getModelType())) {
433   - BpmSimpleModelNodeVO simpleModel = JsonUtils.parseObject(processDefinitionInfo.getSimpleModel(), BpmSimpleModelNodeVO.class);
  457 + BpmSimpleModelNodeVO simpleModel = JsonUtils.parseObject(processDefinitionInfo.getSimpleModel(),
  458 + BpmSimpleModelNodeVO.class);
434 459 List<BpmSimpleModelNodeVO> simpleNodes = SimpleModelUtils.simulateProcess(simpleModel, processVariables);
435 460 return convertList(simpleNodes, simpleNode -> buildNotRunApproveNodeForSimple(startUserId, bpmnModel,
436 461 processDefinitionInfo, processVariables, simpleNode, runActivityIds));
... ... @@ -439,9 +464,10 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
439 464 }
440 465  
441 466 private ActivityNode buildNotRunApproveNodeForSimple(Long startUserId, BpmnModel bpmnModel,
442   - BpmProcessDefinitionInfoDO processDefinitionInfo, Map<String, Object> processVariables,
443   - BpmSimpleModelNodeVO node, Set<String> runActivityIds) {
444   - // TODO @芋艿:【可优化】在驳回场景下,未来的预测准确性不高。原因是,驳回后,HistoricActivityInstance 包括了历史的操作,不是只有 startEvent 到当前节点的记录
  467 + BpmProcessDefinitionInfoDO processDefinitionInfo, Map<String, Object> processVariables,
  468 + BpmSimpleModelNodeVO node, Set<String> runActivityIds) {
  469 + // TODO @芋艿:【可优化】在驳回场景下,未来的预测准确性不高。原因是,驳回后,HistoricActivityInstance
  470 + // 包括了历史的操作,不是只有 startEvent 到当前节点的记录
445 471 if (runActivityIds.contains(node.getId())) {
446 472 return null;
447 473 }
... ... @@ -474,12 +500,13 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
474 500 }
475 501  
476 502 private ActivityNode buildNotRunApproveNodeForBpmn(Long startUserId, BpmnModel bpmnModel,
477   - BpmProcessDefinitionInfoDO processDefinitionInfo, Map<String, Object> processVariables,
478   - FlowElement node, Set<String> runActivityIds) {
  503 + BpmProcessDefinitionInfoDO processDefinitionInfo, Map<String, Object> processVariables,
  504 + FlowElement node, Set<String> runActivityIds) {
479 505 if (runActivityIds.contains(node.getId())) {
480 506 return null;
481 507 }
482   - ActivityNode activityNode = new ActivityNode().setId(node.getId()).setStatus(BpmTaskStatusEnum.NOT_START.getStatus());
  508 + ActivityNode activityNode = new ActivityNode().setId(node.getId())
  509 + .setStatus(BpmTaskStatusEnum.NOT_START.getStatus());
483 510  
484 511 // 1. 开始节点
485 512 if (node instanceof StartEvent) {
... ... @@ -505,7 +532,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
505 532 }
506 533  
507 534 private List<Long> getTaskCandidateUserList(BpmnModel bpmnModel, String activityId,
508   - Long startUserId, String processDefinitionId, Map<String, Object> processVariables) {
  535 + Long startUserId, String processDefinitionId, Map<String, Object> processVariables) {
509 536 Set<Long> userIds = taskCandidateInvoker.calculateUsersByActivity(bpmnModel, activityId,
510 537 startUserId, processDefinitionId, processVariables);
511 538 return new ArrayList<>(userIds);
... ... @@ -519,14 +546,16 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
519 546 return null;
520 547 }
521 548 // 1.2 获得流程定义
522   - BpmnModel bpmnModel = processDefinitionService.getProcessDefinitionBpmnModel(processInstance.getProcessDefinitionId());
  549 + BpmnModel bpmnModel = processDefinitionService
  550 + .getProcessDefinitionBpmnModel(processInstance.getProcessDefinitionId());
523 551 if (bpmnModel == null) {
524 552 return null;
525 553 }
526 554 BpmSimpleModelNodeVO simpleModel = null;
527 555 BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.getProcessDefinitionInfo(
528 556 processInstance.getProcessDefinitionId());
529   - if (processDefinitionInfo != null && BpmModelTypeEnum.SIMPLE.getType().equals(processDefinitionInfo.getModelType())) {
  557 + if (processDefinitionInfo != null
  558 + && BpmModelTypeEnum.SIMPLE.getType().equals(processDefinitionInfo.getModelType())) {
530 559 simpleModel = JsonUtils.parseObject(processDefinitionInfo.getSimpleModel(), BpmSimpleModelNodeVO.class);
531 560 }
532 561 // 1.3 获得流程实例对应的活动实例列表 + 任务列表
... ... @@ -538,10 +567,12 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
538 567 activityInstance -> activityInstance.getEndTime() == null);
539 568 Set<String> finishedTaskActivityIds = convertSet(activities, HistoricActivityInstance::getActivityId,
540 569 activityInstance -> activityInstance.getEndTime() != null
541   - && ObjectUtil.notEqual(activityInstance.getActivityType(), BpmnXMLConstants.ELEMENT_SEQUENCE_FLOW));
  570 + && ObjectUtil.notEqual(activityInstance.getActivityType(),
  571 + BpmnXMLConstants.ELEMENT_SEQUENCE_FLOW));
542 572 Set<String> finishedSequenceFlowActivityIds = convertSet(activities, HistoricActivityInstance::getActivityId,
543 573 activityInstance -> activityInstance.getEndTime() != null
544   - && ObjectUtil.equals(activityInstance.getActivityType(), BpmnXMLConstants.ELEMENT_SEQUENCE_FLOW));
  574 + && ObjectUtil.equals(activityInstance.getActivityType(),
  575 + BpmnXMLConstants.ELEMENT_SEQUENCE_FLOW));
545 576 // 特殊:会签情况下,会有部分已完成(审批)、部分未完成(待审批),此时需要 finishedTaskActivityIds 移除掉
546 577 finishedTaskActivityIds.removeAll(unfinishedTaskActivityIds);
547 578 // 特殊:如果流程实例被拒绝,则需要计算是哪个活动节点。
... ... @@ -559,8 +590,10 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
559 590 Set<Long> userIds = BpmProcessInstanceConvert.INSTANCE.parseUserIds02(processInstance, tasks);
560 591 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);
561 592 Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
562   - return BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceBpmnModelView(processInstance, tasks, bpmnModel, simpleModel,
563   - unfinishedTaskActivityIds, finishedTaskActivityIds, finishedSequenceFlowActivityIds, rejectTaskActivityIds,
  593 + return BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceBpmnModelView(processInstance, tasks, bpmnModel,
  594 + simpleModel,
  595 + unfinishedTaskActivityIds, finishedTaskActivityIds, finishedSequenceFlowActivityIds,
  596 + rejectTaskActivityIds,
564 597 userMap, deptMap);
565 598 }
566 599  
... ... @@ -570,7 +603,8 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
570 603 @Transactional(rollbackFor = Exception.class)
571 604 public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO) {
572 605 // 获得流程定义
573   - ProcessDefinition definition = processDefinitionService.getProcessDefinition(createReqVO.getProcessDefinitionId());
  606 + ProcessDefinition definition = processDefinitionService
  607 + .getProcessDefinition(createReqVO.getProcessDefinitionId());
574 608 // 发起流程
575 609 return createProcessInstance0(userId, definition, createReqVO.getVariables(), null,
576 610 createReqVO.getStartUserSelectAssignees());
... ... @@ -580,16 +614,18 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
580 614 public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO createReqDTO) {
581 615 return FlowableUtils.executeAuthenticatedUserId(userId, () -> {
582 616 // 获得流程定义
583   - ProcessDefinition definition = processDefinitionService.getActiveProcessDefinition(createReqDTO.getProcessDefinitionKey());
  617 + ProcessDefinition definition = processDefinitionService
  618 + .getActiveProcessDefinition(createReqDTO.getProcessDefinitionKey());
584 619 // 发起流程
585   - return createProcessInstance0(userId, definition, createReqDTO.getVariables(), createReqDTO.getBusinessKey(),
  620 + return createProcessInstance0(userId, definition, createReqDTO.getVariables(),
  621 + createReqDTO.getBusinessKey(),
586 622 createReqDTO.getStartUserSelectAssignees());
587 623 });
588 624 }
589 625  
590 626 private String createProcessInstance0(Long userId, ProcessDefinition definition,
591   - Map<String, Object> variables, String businessKey,
592   - Map<String, List<Long>> startUserSelectAssignees) {
  627 + Map<String, Object> variables, String businessKey,
  628 + Map<String, List<Long>> startUserSelectAssignees) {
593 629 // 1.1 校验流程定义
594 630 if (definition == null) {
595 631 throw exception(PROCESS_DEFINITION_NOT_EXISTS);
... ... @@ -597,7 +633,8 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
597 633 if (definition.isSuspended()) {
598 634 throw exception(PROCESS_DEFINITION_IS_SUSPENDED);
599 635 }
600   - BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.getProcessDefinitionInfo(definition.getId());
  636 + BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService
  637 + .getProcessDefinitionInfo(definition.getId());
601 638 if (processDefinitionInfo == null) {
602 639 throw exception(PROCESS_DEFINITION_NOT_EXISTS);
603 640 }
... ... @@ -616,9 +653,12 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
616 653 variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_ID, userId); // 设置流程变量,发起人 ID
617 654 variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS, // 流程实例状态:审批中
618 655 BpmProcessInstanceStatusEnum.RUNNING.getStatus());
619   - variables.put(BpmnVariableConstants.PROCESS_INSTANCE_SKIP_EXPRESSION_ENABLED, true); // 跳过表达式需要添加此变量为 true,不影响没配置 skipExpression 的节点
  656 + variables.put(BpmnVariableConstants.PROCESS_INSTANCE_SKIP_EXPRESSION_ENABLED, true); // 跳过表达式需要添加此变量为
  657 + // true,不影响没配置
  658 + // skipExpression 的节点
620 659 if (CollUtil.isNotEmpty(startUserSelectAssignees)) {
621   - variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_SELECT_ASSIGNEES, startUserSelectAssignees);
  660 + variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_SELECT_ASSIGNEES,
  661 + startUserSelectAssignees);
622 662 }
623 663  
624 664 // 3. 创建流程
... ... @@ -648,7 +688,8 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
648 688 return instance.getId();
649 689 }
650 690  
651   - private void validateStartUserSelectAssignees(ProcessDefinition definition, Map<String, List<Long>> startUserSelectAssignees) {
  691 + private void validateStartUserSelectAssignees(ProcessDefinition definition,
  692 + Map<String, List<Long>> startUserSelectAssignees) {
652 693 // 1. 获得发起人自选审批人的 UserTask/ServiceTask 列表
653 694 BpmnModel bpmnModel = processDefinitionService.getProcessDefinitionBpmnModel(definition.getId());
654 695 List<Task> tasks = BpmTaskCandidateStartUserSelectStrategy.getStartUserSelectTaskList(bpmnModel);
... ... @@ -683,7 +724,8 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
683 724 throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF);
684 725 }
685 726 // 1.3 校验允许撤销审批中的申请
686   - BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.getProcessDefinitionInfo(instance.getProcessDefinitionId());
  727 + BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService
  728 + .getProcessDefinitionInfo(instance.getProcessDefinitionId());
687 729 Assert.notNull(processDefinitionInfo, "流程定义({})不存在", processDefinitionInfo);
688 730 if (processDefinitionInfo.getAllowCancelRunningProcess() != null // 防止未配置 AllowCancelRunningProcess , 默认为可取消
689 731 && Boolean.FALSE.equals(processDefinitionInfo.getAllowCancelRunningProcess())) {
... ... @@ -721,9 +763,11 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
721 763  
722 764 @Override
723 765 public void updateProcessInstanceReject(ProcessInstance processInstance, String reason) {
724   - runtimeService.setVariable(processInstance.getProcessInstanceId(), BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS,
  766 + runtimeService.setVariable(processInstance.getProcessInstanceId(),
  767 + BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS,
725 768 BpmProcessInstanceStatusEnum.REJECT.getStatus());
726   - runtimeService.setVariable(processInstance.getProcessInstanceId(), BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_REASON,
  769 + runtimeService.setVariable(processInstance.getProcessInstanceId(),
  770 + BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_REASON,
727 771 BpmReasonEnum.REJECT_TASK.format(reason));
728 772 }
729 773  
... ... @@ -734,18 +778,22 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
734 778 // 注意:需要基于 instance 设置租户编号,避免 Flowable 内部异步时,丢失租户编号
735 779 FlowableUtils.execute(instance.getTenantId(), () -> {
736 780 // 1.1 获取当前状态
737   - Integer status = (Integer) instance.getProcessVariables().get(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS);
738   - String reason = (String) instance.getProcessVariables().get(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_REASON);
  781 + Integer status = (Integer) instance.getProcessVariables()
  782 + .get(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS);
  783 + String reason = (String) instance.getProcessVariables()
  784 + .get(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_REASON);
739 785 // 1.2 当流程状态还是审批状态中,说明审批通过了,则变更下它的状态
740 786 // 为什么这么处理?因为流程完成,并且完成了,说明审批通过了
741 787 if (Objects.equals(status, BpmProcessInstanceStatusEnum.RUNNING.getStatus())) {
742 788 status = BpmProcessInstanceStatusEnum.APPROVE.getStatus();
743   - runtimeService.setVariable(instance.getId(), BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS, status);
  789 + runtimeService.setVariable(instance.getId(), BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS,
  790 + status);
744 791 }
745 792  
746 793 // 2. 发送对应的消息通知
747 794 if (Objects.equals(status, BpmProcessInstanceStatusEnum.APPROVE.getStatus())) {
748   - messageService.sendMessageWhenProcessInstanceApprove(BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceApproveMessage(instance));
  795 + messageService.sendMessageWhenProcessInstanceApprove(
  796 + BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceApproveMessage(instance));
749 797 } else if (Objects.equals(status, BpmProcessInstanceStatusEnum.REJECT.getStatus())) {
750 798 messageService.sendMessageWhenProcessInstanceReject(
751 799 BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceRejectMessage(instance, reason));
... ...