001/* 002 * Copyright 2024-2025, Warm-Flow (290631660@qq.com). 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.dromara.warm.flow.core.service.impl; 017 018import org.dromara.warm.flow.core.FlowFactory; 019import org.dromara.warm.flow.core.constant.ExceptionCons; 020import org.dromara.warm.flow.core.dao.FlowTaskDao; 021import org.dromara.warm.flow.core.dto.FlowParams; 022import org.dromara.warm.flow.core.dto.ModifyHandler; 023import org.dromara.warm.flow.core.entity.*; 024import org.dromara.warm.flow.core.enums.*; 025import org.dromara.warm.flow.core.listener.Listener; 026import org.dromara.warm.flow.core.listener.ListenerVariable; 027import org.dromara.warm.flow.core.orm.service.impl.WarmServiceImpl; 028import org.dromara.warm.flow.core.service.TaskService; 029import org.dromara.warm.flow.core.utils.*; 030 031import java.math.BigDecimal; 032import java.math.RoundingMode; 033import java.util.*; 034 035/** 036 * 待办任务Service业务层处理 037 * 038 * @author warm 039 * @since 2023-03-29 040 */ 041public class TaskServiceImpl extends WarmServiceImpl<FlowTaskDao<Task>, Task> implements TaskService { 042 043 @Override 044 public TaskService setDao(FlowTaskDao<Task> warmDao) { 045 this.warmDao = warmDao; 046 return this; 047 } 048 049 @Override 050 public Instance skip(Long taskId, FlowParams flowParams) { 051 AssertUtil.isTrue(StringUtils.isNotEmpty(flowParams.getMessage()) 052 && flowParams.getMessage().length() > 500, ExceptionCons.MSG_OVER_LENGTH); 053 // 获取待办任务 054 Task task = getById(taskId); 055 return skip(flowParams, task); 056 } 057 058 @Override 059 public Instance skip(FlowParams flowParams, Task task) { 060 // TODO min 后续考虑并发问题,待办任务和实例表不同步,可给待办任务id加锁,抽取所接口,方便后续兼容分布式锁 061 // 流程开启前正确性校验 062 R r = getAndCheck(task); 063 064 // 非第一个记得跳转类型必传 065 if (!NodeType.isStart(task.getNodeType())) { 066 AssertUtil.isFalse(StringUtils.isNotEmpty(flowParams.getSkipType()), ExceptionCons.NULL_CONDITIONVALUE); 067 } 068 069 // 执行开始监听器 070 task.setUserList(FlowFactory.userService().listByAssociatedAndTypes(task.getId())); 071 ListenerUtil.executeListener(new ListenerVariable(r.definition, r.instance, r.nowNode, flowParams.getVariable() 072 , task).setFlowParams(flowParams), Listener.LISTENER_START); 073 074 // 如果是受托人在处理任务,需要处理一条委派记录,并且更新委托人,回到计划审批人,然后直接返回流程实例 075 if (handleDepute(task, flowParams)) { 076 return r.instance; 077 } 078 079 // 判断当前处理人是否有权限处理 080 checkAuth(r.nowNode, task, flowParams); 081 082 //或签、会签、票签逻辑处理 083 if (cooperate(r.nowNode, task, flowParams)) { 084 return r.instance; 085 } 086 087 // 获取关联的节点,判断当前处理人是否有权限处理 088 Node nextNode = FlowFactory.nodeService().getNextNode(task.getDefinitionId(), r.nowNode.getNodeCode() 089 , flowParams.getNodeCode(), flowParams.getSkipType()); 090 091 // 如果是网关节点,则重新获取后续节点 092 List<Node> nextNodes = FlowFactory.nodeService().getNextByCheckGateway(flowParams.getVariable(), nextNode); 093 094 // 不能退回,未完成过任务 095 if (SkipType.isReject(flowParams.getSkipType())) { 096 List<HisTask> rejectHisTasks = FlowFactory.hisTaskService() 097 .getByInsAndNodeCodes(task.getInstanceId(), StreamUtils.toList(nextNodes, Node::getNodeCode)); 098 AssertUtil.isEmpty(rejectHisTasks, ExceptionCons.BACK_TASK_NOT_EXECUTED); 099 } 100 101 // 判断下一结点是否有权限监听器,有执行权限监听器nextNode.setPermissionFlag,无走数据库的权限标识符 102 ListenerUtil.executeGetNodePermission(new ListenerVariable(r.definition, r.instance, r.nowNode 103 , flowParams.getVariable(), task, nextNodes).setFlowParams(flowParams)); 104 105 // 构建增待办任务和设置结束任务历史记录 106 List<Task> addTasks = buildAddTasks(flowParams, task, r.instance, nextNodes, nextNode, r.definition); 107 108 // 办理人变量替换 109 if (CollUtil.isNotEmpty(addTasks)) { 110 addTasks.forEach(addTask -> addTask.getPermissionList().replaceAll(s -> VariableUtil.eval(s, flowParams.getVariable()))); 111 } 112 // 执行分派监听器 113 ListenerUtil.executeListener(new ListenerVariable(r.definition, r.instance, r.nowNode, flowParams.getVariable() 114 , task, nextNodes, addTasks).setFlowParams(flowParams), Listener.LISTENER_ASSIGNMENT); 115 116 // 更新流程信息 117 updateFlowInfo(task, r.instance, addTasks, flowParams, nextNodes); 118 119 // 一票否决(谨慎使用),如果退回,退回指向节点后还存在其他正在执行的待办任务,转历史任务,状态都为失效,重走流程。 120 oneVoteVeto(task, flowParams, nextNode.getNodeCode()); 121 122 // 处理未完成的任务,当流程完成,还存在待办任务未完成,转历史任务,状态完成。 123 handUndoneTask(r.instance, flowParams); 124 125 // 最后判断是否存在节点监听器,存在执行节点监听器 126 ListenerUtil.endCreateListener(new ListenerVariable(r.definition, r.instance, r.nowNode 127 , flowParams.getVariable(), task, nextNodes, addTasks).setFlowParams(flowParams)); 128 129 return r.instance; 130 } 131 132 @Override 133 public Instance termination(Long taskId, FlowParams flowParams) { 134 return termination(getById(taskId), flowParams); 135 } 136 137 @Override 138 public Instance termination(Task task, FlowParams flowParams) { 139 R r = getAndCheck(task); 140 ListenerUtil.executeListener(new ListenerVariable(r.definition, r.instance, r.nowNode, flowParams.getVariable() 141 , task).setFlowParams(flowParams), Listener.LISTENER_START); 142 143 // 判断当前处理人是否有权限处理 144 task.setUserList(FlowFactory.userService().listByAssociatedAndTypes(task.getId())); 145 checkAuth(r.nowNode, task, flowParams); 146 147 // 所有待办转历史 148 Node endNode = FlowFactory.nodeService().getOne(FlowFactory.newNode() 149 .setDefinitionId(r.instance.getDefinitionId()).setNodeType(NodeType.END.getKey())); 150 151 // 流程实例完成 152 r.instance.setNodeType(endNode.getNodeType()) 153 .setNodeCode(endNode.getNodeCode()) 154 .setNodeName(endNode.getNodeName()) 155 .setFlowStatus(ObjectUtil.isNotNull(flowParams.getFlowStatus()) ? flowParams.getFlowStatus() 156 : FlowStatus.TERMINATE.getKey()); 157 158 // 待办任务转历史 159 flowParams.setSkipType(SkipType.PASS.getKey()).flowStatus(r.instance.getFlowStatus()); 160 List<HisTask> insHisList = FlowFactory.hisTaskService().setSkipInsHis(task, Collections.singletonList(endNode) 161 , flowParams); 162 FlowFactory.hisTaskService().saveBatch(insHisList); 163 FlowFactory.insService().updateById(r.instance); 164 165 // 删除流程相关办理人 166 FlowFactory.userService().deleteByTaskIds(Collections.singletonList(task.getId())); 167 // 处理未完成的任务,当流程完成,还存在待办任务未完成,转历史任务,状态完成。 168 handUndoneTask(r.instance, flowParams); 169 // 最后判断是否存在节点监听器,存在执行节点监听器 170 ListenerUtil.executeListener(new ListenerVariable(r.definition, r.instance, r.nowNode, flowParams.getVariable() 171 , task), Listener.LISTENER_END); 172 return r.instance; 173 } 174 175 @Override 176 public boolean deleteByInsIds(List<Long> instanceIds) { 177 List<Instance> instanceList = FlowFactory.insService().getByIds(instanceIds); 178 Definition definition; 179 for (Instance instance : instanceList) { 180 definition = FlowFactory.defService().getById(instance.getDefinitionId()); 181 AssertUtil.isFalse(judgeActivityStatus(definition, instance), ExceptionCons.NOT_ACTIVITY); 182 } 183 return SqlHelper.retBool(getDao().deleteByInsIds(instanceIds)); 184 } 185 186 @Override 187 public boolean transfer(Long taskId, FlowParams flowParams) { 188 List<User> users = FlowFactory.userService().getByProcessedBys(taskId, flowParams.getAddHandlers(), UserType.TRANSFER.getKey()); 189 AssertUtil.isNotEmpty(users, ExceptionCons.IS_ALREADY_TRANSFER); 190 flowParams.cooperateType(CooperateType.TRANSFER.getKey()) 191 .reductionHandlers(Collections.singletonList(flowParams.getHandler())); 192 193 return updateHandler(taskId, flowParams); 194 } 195 196 @Override 197 public boolean transfer(Long taskId, String curUser, List<String> permissionFlag, List<String> addHandlers, String message) { 198 List<User> users = FlowFactory.userService().getByProcessedBys(taskId, addHandlers, UserType.TRANSFER.getKey()); 199 AssertUtil.isNotEmpty(users, ExceptionCons.IS_ALREADY_TRANSFER); 200 201 ModifyHandler modifyHandler = ModifyHandler.build() 202 .taskId(taskId) 203 .addHandlers(addHandlers) 204 .reductionHandlers(Collections.singletonList(curUser)) 205 .permissionFlag(permissionFlag) 206 .cooperateType(CooperateType.TRANSFER.getKey()) 207 .message(message) 208 .curUser(curUser) 209 .ignore(false); 210 return updateHandler(modifyHandler); 211 } 212 @Override 213 public boolean depute(Long taskId, FlowParams flowParams) { 214 List<User> users = FlowFactory.userService().getByProcessedBys(taskId, flowParams.getAddHandlers(), UserType.DEPUTE.getKey()); 215 AssertUtil.isNotEmpty(users, ExceptionCons.IS_ALREADY_DEPUTE); 216 flowParams.cooperateType(CooperateType.DEPUTE.getKey()) 217 .reductionHandlers(Collections.singletonList(flowParams.getHandler())); 218 219 return updateHandler(taskId, flowParams); 220 } 221 222 @Override 223 public boolean depute(Long taskId, String curUser, List<String> permissionFlag, List<String> addHandlers, String message) { 224 List<User> users = FlowFactory.userService().getByProcessedBys(taskId, addHandlers, UserType.DEPUTE.getKey()); 225 AssertUtil.isNotEmpty(users, ExceptionCons.IS_ALREADY_DEPUTE); 226 227 ModifyHandler modifyHandler = ModifyHandler.build() 228 .taskId(taskId) 229 .addHandlers(addHandlers) 230 .reductionHandlers(Collections.singletonList(curUser)) 231 .permissionFlag(permissionFlag) 232 .cooperateType(CooperateType.DEPUTE.getKey()) 233 .message(message) 234 .curUser(curUser) 235 .ignore(false); 236 return updateHandler(modifyHandler); 237 } 238 239 @Override 240 public boolean addSignature(Long taskId, FlowParams flowParams) { 241 List<User> users = FlowFactory.userService().getByProcessedBys(taskId, flowParams.getAddHandlers(), UserType.APPROVAL.getKey()); 242 AssertUtil.isNotEmpty(users, ExceptionCons.IS_ALREADY_SIGN); 243 flowParams.cooperateType(CooperateType.ADD_SIGNATURE.getKey()); 244 245 return updateHandler(taskId, flowParams); 246 } 247 248 @Override 249 public boolean addSignature(Long taskId, String curUser, List<String> permissionFlag, List<String> addHandlers, String message) { 250 List<User> users = FlowFactory.userService().getByProcessedBys(taskId, addHandlers, UserType.APPROVAL.getKey()); 251 AssertUtil.isNotEmpty(users, ExceptionCons.IS_ALREADY_SIGN); 252 253 ModifyHandler modifyHandler = ModifyHandler.build() 254 .taskId(taskId) 255 .addHandlers(addHandlers) 256 .permissionFlag(permissionFlag) 257 .cooperateType(CooperateType.ADD_SIGNATURE.getKey()) 258 .message(message) 259 .curUser(curUser) 260 .ignore(false); 261 return updateHandler(modifyHandler); 262 } 263 264 @Override 265 public boolean reductionSignature(Long taskId, FlowParams flowParams) { 266 List<User> users = FlowFactory.userService().list(FlowFactory.newUser().setAssociated(taskId) 267 .setType(UserType.APPROVAL.getKey())); 268 AssertUtil.isTrue(CollUtil.isEmpty(users) || users.size() == 1, ExceptionCons.REDUCTION_SIGN_ONE_ERROR); 269 flowParams.cooperateType(CooperateType.REDUCTION_SIGNATURE.getKey()); 270 271 return updateHandler(taskId, flowParams); 272 } 273 274 @Override 275 public boolean reductionSignature(Long taskId, String curUser, List<String> permissionFlag, List<String> reductionHandlers, String message) { 276 List<User> users = FlowFactory.userService().list(FlowFactory.newUser().setAssociated(taskId) 277 .setType(UserType.APPROVAL.getKey())); 278 279 AssertUtil.isTrue(CollUtil.isEmpty(users) || users.size() == 1, ExceptionCons.REDUCTION_SIGN_ONE_ERROR); 280 ModifyHandler modifyHandler = ModifyHandler.build() 281 .taskId(taskId) 282 .reductionHandlers(reductionHandlers) 283 .permissionFlag(permissionFlag) 284 .cooperateType(CooperateType.REDUCTION_SIGNATURE.getKey()) 285 .message(message) 286 .curUser(curUser) 287 .ignore(false); 288 return updateHandler(modifyHandler); 289 } 290 291 @Override 292 public boolean updateHandler(Long taskId, FlowParams flowParams) { 293 // 获取待办任务 294 R r = getAndCheck(taskId); 295 // 执行开始监听器 296 ListenerUtil.executeListener(new ListenerVariable(r.definition, r.instance, r.nowNode, null, r.task) 297 , Listener.LISTENER_START); 298 299 // 获取给谁的权限 300 if (!flowParams.isIgnore()) { 301 // 判断当前处理人是否有权限,获取当前办理人的权限 302 List<String> permissions = flowParams.getPermissionFlag(); 303 // 获取任务权限人 304 List<String> taskPermissions = FlowFactory.userService().getPermission(taskId 305 , UserType.APPROVAL.getKey(), UserType.TRANSFER.getKey(), UserType.DEPUTE.getKey()); 306 AssertUtil.isTrue(CollUtil.isNotEmpty(taskPermissions) && (CollUtil.isEmpty(permissions) 307 || CollUtil.notContainsAny(permissions, taskPermissions)), ExceptionCons.NOT_AUTHORITY); 308 } 309 // 留存历史记录 310 flowParams.skipType(SkipType.NONE.getKey()); 311 List<HisTask> hisTasks = null; 312 // 删除对应的操作人 313 if (CollUtil.isNotEmpty(flowParams.getReductionHandlers())) { 314 for (String reductionHandler : flowParams.getReductionHandlers()) { 315 FlowFactory.userService().remove(FlowFactory.newUser().setAssociated(taskId) 316 .setProcessedBy(reductionHandler)); 317 } 318 hisTasks = FlowFactory.hisTaskService().setCooperateHis(r.task, r.nowNode 319 , flowParams, flowParams.getReductionHandlers()); 320 } 321 322 // 新增权限人 323 if (CollUtil.isNotEmpty(flowParams.getAddHandlers())) { 324 String type; 325 if (CooperateType.TRANSFER.getKey().equals(flowParams.getCooperateType())) { 326 type = UserType.TRANSFER.getKey(); 327 } else if (CooperateType.DEPUTE.getKey().equals(flowParams.getCooperateType())) { 328 type = UserType.DEPUTE.getKey(); 329 } else { 330 type = UserType.APPROVAL.getKey(); 331 } 332 FlowFactory.userService().saveBatch(StreamUtils.toList(flowParams.getAddHandlers(), permission -> 333 FlowFactory.userService().structureUser(taskId, permission 334 , type, flowParams.getHandler()))); 335 hisTasks = FlowFactory.hisTaskService().setCooperateHis(r.task, r.nowNode 336 , flowParams, flowParams.getAddHandlers()); 337 } 338 if (CollUtil.isNotEmpty(hisTasks)) { 339 FlowFactory.hisTaskService().saveBatch(hisTasks); 340 } 341 // 最后判断是否存在节点监听器,存在执行节点监听器 342 ListenerUtil.executeListener(new ListenerVariable(r.definition, r.instance, r.nowNode, flowParams.getVariable() 343 , r.task), Listener.LISTENER_END); 344 return true; 345 } 346 @Override 347 public boolean updateHandler(ModifyHandler modifyHandler) { 348 return updateHandler(modifyHandler.getTaskId(), new FlowParams() 349 .handler(modifyHandler.getCurUser()) 350 .permissionFlag(modifyHandler.getPermissionFlag()) 351 .addHandlers(modifyHandler.getAddHandlers()) 352 .reductionHandlers(modifyHandler.getReductionHandlers()) 353 .cooperateType(modifyHandler.getCooperateType()) 354 .message(modifyHandler.getMessage()) 355 .ignore(modifyHandler.isIgnore())); 356 } 357 358 @Override 359 public Instance retrieve(Long instanceId, FlowParams flowParams) { 360 Instance instance = FlowFactory.insService().getById(instanceId); 361 AssertUtil.isNull(instance, ExceptionCons.NOT_FOUNT_INSTANCE); 362 // 验证权限是不是当前任务的发起人 363 AssertUtil.isFalse(instance.getCreateBy().equals(flowParams.getHandler()) 364 , ExceptionCons.NOT_DEF_PROMOTER_NOT_RETRIEVE); 365 // 如果没传nodeCode,则默认跳转开始节点 366 if (StringUtils.isEmpty(flowParams.getNodeCode())) { 367 flowParams.nodeCode(FlowFactory.nodeService().getOne(FlowFactory.newNode() 368 .setDefinitionId(instance.getDefinitionId()) 369 .setNodeType(NodeType.START.getKey())).getNodeCode()); 370 } 371 // TODO warm 监听器 372 Definition definition = FlowFactory.defService().getById(instance.getDefinitionId()); 373 AssertUtil.isFalse(judgeActivityStatus(definition, instance), ExceptionCons.NOT_ACTIVITY); 374 AssertUtil.isTrue(NodeType.isEnd(instance.getNodeType()), ExceptionCons.FLOW_FINISH); 375 376 AssertUtil.isTrue(StringUtils.isNotEmpty(flowParams.getMessage()) 377 && flowParams.getMessage().length() > 500, ExceptionCons.MSG_OVER_LENGTH); 378 // 查询目标节点信息 379 Node nextNode = FlowFactory.nodeService().getOne(FlowFactory.newNode() 380 .setNodeCode(flowParams.getNodeCode()).setDefinitionId(instance.getDefinitionId())); 381 AssertUtil.isNull(nextNode, ExceptionCons.LOST_DEST_NODE); 382 // 回退到的节点是否为结束节点,结束节点是不能回退 383 AssertUtil.isTrue(NodeType.isEnd(nextNode.getNodeType()), ExceptionCons.NODE_IS_END); 384 385 // 查询任务,如果前一个节点是并行网关,可能任务表有多个任务,增加查询和判断 386 List<Task> curTaskList = list(FlowFactory.newTask().setInstanceId(instance.getId())); 387 AssertUtil.isEmpty(curTaskList, ExceptionCons.NOT_FOUND_FLOW_TASK); 388 389 // 给回退到的那个节点赋权限-给当前处理人权限 390 Task nextTask = addTask(nextNode, instance, definition, flowParams); 391 // 流程参数 392 flowParams.setSkipType(SkipType.REJECT.getKey()); 393 // 删除待办任务,保存历史,删除所有代办任务的权限人 394 if (StringUtils.isNotEmpty(flowParams.getFlowStatus())) { 395 flowParams.flowStatus(FlowStatus.RETRIEVE.getKey()); 396 } 397 removeByIds(StreamUtils.toList(curTaskList, Task::getId)); 398 // 删除所有待办任务的权限人,处理人保存 399 FlowFactory.userService().deleteByTaskIds(StreamUtils.toList(curTaskList, Task::getId)); 400 FlowFactory.hisTaskService().saveBatch(StreamUtils.toList(curTaskList, 401 task -> FlowFactory.hisTaskService().setSkipHisTask(task, nextNode, flowParams))); 402 403 // 设置任务完成后的实例相关信息 404 setInsFinishInfo(instance, CollUtil.toList(nextTask), flowParams); 405 FlowFactory.insService().updateById(instance); 406 // 保存待办任务 407 List<User> users = FlowFactory.userService().taskAddUsers(CollUtil.toList(nextTask)); 408 FlowFactory.userService().saveBatch(users); 409 save(nextTask); 410 return instance; 411 } 412 413 @Override 414 public Task addTask(Node node, Instance instance, Definition definition, FlowParams flowParams) { 415 Task addTask = FlowFactory.newTask(); 416 FlowFactory.dataFillHandler().idFill(addTask); 417 addTask.setDefinitionId(instance.getDefinitionId()) 418 .setInstanceId(instance.getId()) 419 .setNodeCode(node.getNodeCode()) 420 .setNodeName(node.getNodeName()) 421 .setNodeType(node.getNodeType()) 422 .setCreateTime(new Date()) 423 .setPermissionList(CollUtil.isNotEmpty(node.getDynamicPermissionFlagList()) 424 ? node.getDynamicPermissionFlagList(): StringUtils.str2List(node.getPermissionFlag(), ",")); 425 426 if (StringUtils.isNotEmpty(node.getFormCustom()) && StringUtils.isNotEmpty(node.getFormPath())) { 427 // 节点有自定义表单则使用 428 addTask.setFormCustom(node.getFormCustom()).setFormPath(node.getFormPath()); 429 } else { 430 addTask.setFormCustom(definition.getFormCustom()).setFormPath(definition.getFormPath()); 431 } 432 433 return addTask; 434 } 435 436 @Override 437 public String setFlowStatus(Integer nodeType, String skipType) { 438 // 根据审批动作确定流程状态 439 if (NodeType.isStart(nodeType)) { 440 return FlowStatus.TOBESUBMIT.getKey(); 441 } else if (NodeType.isEnd(nodeType)) { 442 return FlowStatus.FINISHED.getKey(); 443 } else if (SkipType.isReject(skipType)) { 444 return FlowStatus.REJECT.getKey(); 445 } else { 446 return FlowStatus.APPROVAL.getKey(); 447 } 448 } 449 450 @Override 451 public Task getNextTask(List<Task> tasks) { 452 if (tasks.size() == 1) { 453 return tasks.get(0); 454 } 455 for (Task task : tasks) { 456 if (NodeType.isEnd(task.getNodeType())) { 457 return task; 458 } 459 } 460 return tasks.stream().max(Comparator.comparingLong(Task::getId)).orElse(null); 461 } 462 463 private R getAndCheck(Long taskId) { 464 return getAndCheck(getById(taskId)); 465 } 466 467 private R getAndCheck(Task task) { 468 AssertUtil.isNull(task, ExceptionCons.NOT_FOUNT_TASK); 469 Instance instance = FlowFactory.insService().getById(task.getInstanceId()); 470 AssertUtil.isNull(instance, ExceptionCons.NOT_FOUNT_INSTANCE); 471 Definition definition = FlowFactory.defService().getById(instance.getDefinitionId()); 472 AssertUtil.isFalse(judgeActivityStatus(definition, instance), ExceptionCons.NOT_ACTIVITY); 473 AssertUtil.isTrue(NodeType.isEnd(instance.getNodeType()), ExceptionCons.FLOW_FINISH); 474 Node nowNode = FlowFactory.nodeService().getOne(FlowFactory.newNode().setNodeCode(task.getNodeCode()) 475 .setDefinitionId(task.getDefinitionId())); 476 AssertUtil.isNull(nowNode, ExceptionCons.LOST_CUR_NODE); 477 return new R(instance, definition, nowNode, task); 478 } 479 480 private static class R { 481 public final Instance instance; 482 public final Definition definition; 483 public final Node nowNode; 484 public final Task task; 485 486 public R(Instance instance, Definition definition, Node nowNode, Task task) { 487 this.instance = instance; 488 this.definition = definition; 489 this.nowNode = nowNode; 490 this.task = task; 491 } 492 } 493 494 private boolean handleDepute(Task task, FlowParams flowParams) { 495 // 获取受托人 496 User entrustedUser = FlowFactory.userService().getOne(FlowFactory.newUser().setAssociated(task.getId()) 497 .setProcessedBy(flowParams.getHandler()).setType(UserType.DEPUTE.getKey())); 498 if (ObjectUtil.isNull(entrustedUser)) { 499 return false; 500 } 501 502 // 记录受托人处理任务记录 503 HisTask hisTask = FlowFactory.hisTaskService().setDeputeHisTask(task, flowParams, entrustedUser); 504 FlowFactory.hisTaskService().save(hisTask); 505 FlowFactory.userService().removeById(entrustedUser.getId()); 506 507 // 查询委托人,如果在flow_user不存在,则给委托人新增待办记录 508 User deputeUser = FlowFactory.userService().getOne(FlowFactory.newUser().setAssociated(task.getId()) 509 .setProcessedBy(entrustedUser.getCreateBy()).setType(UserType.APPROVAL.getKey())); 510 if (ObjectUtil.isNull(deputeUser)) { 511 User newUser = FlowFactory.userService().structureUser(entrustedUser.getAssociated() 512 , entrustedUser.getCreateBy() 513 , UserType.APPROVAL.getKey(), entrustedUser.getProcessedBy()); 514 FlowFactory.userService().save(newUser); 515 } 516 517 return true; 518 } 519 520 /** 521 * 会签,票签,协作处理,返回true;或签或者会签、票签结束返回false 522 * 523 * @param nowNode 当前节点 524 * @param task 任务 525 * @param flowParams 流程参数 526 * @return boolean 527 */ 528 private boolean cooperate(Node nowNode, Task task, FlowParams flowParams) { 529 BigDecimal nodeRatio = nowNode.getNodeRatio(); 530 // 或签,直接返回 531 if (CooperateType.isOrSign(nodeRatio)) { 532 return false; 533 } 534 535 // 办理人和转办人列表 536 List<User> todoList = FlowFactory.userService().listByAssociatedAndTypes(task.getId() 537 , UserType.APPROVAL.getKey(), UserType.TRANSFER.getKey(), UserType.DEPUTE.getKey()); 538 539 // 判断办理人是否有办理权限 540 AssertUtil.isEmpty(flowParams.getHandler(), ExceptionCons.SIGN_NULL_HANDLER); 541 User todoUser = CollUtil.getOne(StreamUtils.filter(todoList, u -> Objects.equals(u.getProcessedBy(), flowParams.getHandler()))); 542 AssertUtil.isNull(todoUser, ExceptionCons.NOT_AUTHORITY); 543 544 // 当只剩一位待办用户时,由当前用户决定走向 545 if (todoList.size() == 1) { 546 return false; 547 } 548 549 // 除当前办理人外剩余办理人列表 550 List<User> restList = StreamUtils.filter(todoList, u -> !Objects.equals(u.getProcessedBy(), flowParams.getHandler())); 551 552 // 会签并且当前人驳回直接返回 553 if (CooperateType.isCountersign(nodeRatio) && SkipType.isReject(flowParams.getSkipType())) { 554 FlowFactory.userService().removeByIds(StreamUtils.toList(restList, User::getId)); 555 return false; 556 } 557 558 // 查询会签票签已办列表 559 560 List<HisTask> doneList = FlowFactory.hisTaskService().listByTaskIdAndCooperateTypes(task.getId() 561 , CooperateType.isCountersign(nodeRatio) ? CooperateType.COUNTERSIGN.getKey() : CooperateType.VOTE.getKey()); 562 doneList = CollUtil.emptyDefault(doneList, Collections.emptyList()); 563 564 // TODO 这里处理 cooperation handler 获取下面的 passRatio rejectRatio all 值,能获取使用 handler的值,不能获取使用以下全自动计算代码 565 566 // 所有人 567 BigDecimal all = BigDecimal.ZERO.add(BigDecimal.valueOf(todoList.size())).add(BigDecimal.valueOf(doneList.size())); 568 569 List<HisTask> donePassList = StreamUtils.filter(doneList 570 , hisTask -> Objects.equals(hisTask.getSkipType(), SkipType.PASS.getKey())); 571 572 List<HisTask> doneRejectList = StreamUtils.filter(doneList 573 , hisTask -> Objects.equals(hisTask.getSkipType(), SkipType.REJECT.getKey())); 574 575 boolean isPass = SkipType.isPass(flowParams.getSkipType()); 576 577 // 计算通过率 578 BigDecimal passRatio = (isPass ? BigDecimal.ONE : BigDecimal.ZERO) 579 .add(BigDecimal.valueOf(donePassList.size())) 580 .divide(all, 4, RoundingMode.HALF_UP).multiply(CooperateType.ONE_HUNDRED); 581 582 // 计算驳回率 583 BigDecimal rejectRatio = (isPass ? BigDecimal.ZERO : BigDecimal.ONE) 584 .add(BigDecimal.valueOf(doneRejectList.size())) 585 .divide(all, 4, RoundingMode.HALF_UP).multiply(CooperateType.ONE_HUNDRED); 586 587 if (!isPass && rejectRatio.compareTo(CooperateType.ONE_HUNDRED.subtract(nodeRatio)) > 0) { 588 // 驳回,并且当前是驳回 589 FlowFactory.userService().removeByIds(StreamUtils.toList(restList, User::getId)); 590 return false; 591 } 592 593 if (passRatio.compareTo(nodeRatio) >= 0) { 594 // 大于等于 nodeRatio 设置值结束任务 595 FlowFactory.userService().removeByIds(StreamUtils.toList(restList, User::getId)); 596 return false; 597 } 598 599 // 添加历史任务 600 HisTask hisTask = FlowFactory.hisTaskService().setSignHisTask(task, flowParams, nodeRatio, isPass); 601 FlowFactory.hisTaskService().save(hisTask); 602 603 // 删掉待办用户 604 FlowFactory.userService().removeById(todoUser.getId()); 605 return true; 606 } 607 608 /** 609 * 构建增待办任务 610 * 611 * @param flowParams 流程参数 612 * @param task 待办任务 613 * @param instance 实例 614 * @param nextNode 下个节点 615 * @return List<Task> 616 */ 617 private List<Task> buildAddTasks(FlowParams flowParams, Task task, Instance instance 618 , List<Node> nextNodes, Node nextNode, Definition definition) { 619 boolean buildFlag = false; 620 // 下个节点非并行网关节点,可以直接生成下一个待办任务 621 if (!NodeType.isGateWayParallel(nextNode.getNodeType())) { 622 buildFlag = true; 623 } else { 624 // 下个节点是并行网关节点,判断前置节点是否都完成 625 if (gateWayParallelIsFinish(task, instance, nextNode.getNodeCode())) { 626 buildFlag = true; 627 } 628 } 629 630 if (buildFlag) { 631 List<Task> addTasks = new ArrayList<>(); 632 for (Node node : nextNodes) { 633 addTasks.add(addTask(node, instance, definition, flowParams)); 634 } 635 return addTasks; 636 } 637 return null; 638 } 639 640 /** 641 * 判断并行网关节点前置任务是否都完成 642 * 多条线路汇聚到并行网关,必须所有任务都完成,才能继续。 根据并行网关节点,查询前面的节点是否都完成, 643 * 判断规则,获取网关所有前置节点,并且查询是否有历史任务记录,前前置节点完成时间是否早于前置节点 644 * 645 * @param task 待办任务 646 * @param instance 实例 647 * @param nextNodeCode 下个节点编码 648 * @return boolean 649 */ 650 private boolean gateWayParallelIsFinish(Task task, Instance instance, String nextNodeCode) { 651 List<Skip> allSkips = FlowFactory.skipService().list(FlowFactory.newSkip() 652 .setDefinitionId(instance.getDefinitionId())); 653 Map<String, List<Skip>> skipNextMap = StreamUtils.groupByKeyFilter(skip -> !task.getNodeCode() 654 .equals(skip.getNowNodeCode()) || !nextNodeCode.equals(skip.getNextNodeCode()) 655 , allSkips, Skip::getNextNodeCode); 656 List<Skip> oneLastSkips = skipNextMap.get(nextNodeCode); 657 // 说明没有其他前置节点,那可以完成往下执行 658 if (CollUtil.isEmpty(oneLastSkips)) { 659 return true; 660 } 661 List<HisTask> hisTaskList = FlowFactory.hisTaskService().getNoReject(instance.getId()); 662 int wayParallelIsFinish = 0; 663 if (CollUtil.isNotEmpty(oneLastSkips)) { 664 for (Skip oneLastSkip : oneLastSkips) { 665 HisTask oneLastHisTask = FlowFactory.hisTaskService() 666 .getNoReject(oneLastSkip.getNowNodeCode(), null, hisTaskList); 667 // 查询前置节点是否有完成记录 668 if (ObjectUtil.isNull(oneLastHisTask)) { 669 return false; 670 } 671 List<Skip> twoLastSkips = skipNextMap.get(oneLastSkip.getNowNodeCode()); 672 for (Skip twoLastSkip : twoLastSkips) { 673 if (NodeType.isStart(twoLastSkip.getNowNodeType())) { 674 wayParallelIsFinish++; 675 } else if (NodeType.isGateWay(twoLastSkip.getNowNodeType())) { 676 // 如果前前置节点是网关,那网关前任意一个任务完成就算完成 677 List<Skip> threeLastSkips = skipNextMap.get(twoLastSkip.getNowNodeCode()); 678 for (Skip threeLastSkip : threeLastSkips) { 679 HisTask threeLastHisTask = FlowFactory.hisTaskService() 680 .getNoReject(threeLastSkip.getNowNodeCode(), null, hisTaskList); 681 if (ObjectUtil.isNotNull(threeLastHisTask) && (threeLastHisTask.getUpdateTime() 682 .before(oneLastHisTask.getUpdateTime()) || threeLastHisTask.getUpdateTime() 683 .equals(oneLastHisTask.getUpdateTime()))) { 684 wayParallelIsFinish++; 685 } 686 } 687 } else { 688 HisTask twoLastHisTask = FlowFactory.hisTaskService() 689 .getNoReject(twoLastSkip.getNowNodeCode(), null, hisTaskList); 690 // 前前置节点完成时间是否早于前置节点,如果是串行网关,那前前置节点必须只有一个完成,如果是并行网关都要完成 691 if (ObjectUtil.isNotNull(twoLastHisTask) && (twoLastHisTask.getUpdateTime() 692 .before(oneLastHisTask.getUpdateTime()) || twoLastHisTask.getUpdateTime() 693 .equals(oneLastHisTask.getUpdateTime()))) { 694 wayParallelIsFinish++; 695 } 696 } 697 } 698 } 699 } 700 return wayParallelIsFinish == oneLastSkips.size(); 701 } 702 703 /** 704 * 判断当前处理人是否有权限处理 705 * 706 * @param NowNode 当前节点权限(动态权限) 707 * @param task 当前任务(任务id) 708 * @param flowParams:包含流程相关参数的对象 709 */ 710 private void checkAuth(Node NowNode, Task task, FlowParams flowParams) { 711 if (flowParams.isIgnore()) { 712 return; 713 } 714 // 如果有动态权限标识,则优先使用动态权限标识 715 List<String> permissions; 716 if (CollUtil.isNotEmpty(NowNode.getDynamicPermissionFlagList())) { 717 permissions = NowNode.getDynamicPermissionFlagList(); 718 } else { 719 // 查询审批人和转办人 720 permissions = StreamUtils.toList(task.getUserList(), User::getProcessedBy); 721 } 722 // 当前节点 723 AssertUtil.isTrue(CollUtil.isNotEmpty(permissions) && (CollUtil.isEmpty(flowParams.getPermissionFlag()) 724 || CollUtil.notContainsAny(flowParams.getPermissionFlag(), permissions)), ExceptionCons.NULL_ROLE_NODE); 725 } 726 727 // 设置任务完成后的实例相关信息 728 private void setInsFinishInfo(Instance instance, List<Task> addTasks, FlowParams flowParams) { 729 instance.setUpdateTime(new Date()); 730 Map<String, Object> variable = flowParams.getVariable(); 731 if (MapUtil.isNotEmpty(variable)) { 732 String variableStr = instance.getVariable(); 733 Map<String, Object> deserialize = FlowFactory.jsonConvert.strToMap(variableStr); 734 deserialize.putAll(variable); 735 instance.setVariable(FlowFactory.jsonConvert.mapToStr(deserialize)); 736 } 737 if (CollUtil.isNotEmpty(addTasks)) { 738 addTasks.removeIf(addTask -> { 739 if (NodeType.isEnd(addTask.getNodeType())) { 740 instance.setNodeType(addTask.getNodeType()) 741 .setNodeCode(addTask.getNodeCode()) 742 .setNodeName(addTask.getNodeName()) 743 .setFlowStatus(ObjectUtil.isNotNull(flowParams.getFlowStatus()) 744 ? flowParams.getFlowStatus() : FlowStatus.FINISHED.getKey()); 745 return true; 746 } 747 return false; 748 }); 749 } 750 if (CollUtil.isNotEmpty(addTasks) && !NodeType.isEnd(instance.getNodeType())) { 751 Task nextTask = getNextTask(addTasks); 752 instance.setNodeType(nextTask.getNodeType()) 753 .setNodeCode(nextTask.getNodeCode()) 754 .setNodeName(nextTask.getNodeName()) 755 .setFlowStatus(ObjectUtil.isNotNull(flowParams.getFlowStatus()) ? flowParams.getFlowStatus() 756 : setFlowStatus(nextTask.getNodeType(), flowParams.getSkipType())); 757 } 758 } 759 760 /** 761 * 一票否决(谨慎使用),如果退回,退回指向节点后还存在其他正在执行的待办任务,转历史任务,状态都为退回,重走流程。 762 * 763 * @param task 当前任务 764 * @param flowParams 包含流程相关参数的对象 765 * @param nextNodeCode 下一个节点编码 766 */ 767 private void oneVoteVeto(Task task, FlowParams flowParams, String nextNodeCode) { 768 // 一票否决(谨慎使用),如果退回,退回指向节点后还存在其他正在执行的待办任务,转历史任务,状态失效,重走流程。 769 if (SkipType.isReject(flowParams.getSkipType())) { 770 List<Task> tasks = list(FlowFactory.newTask().setInstanceId(task.getInstanceId())); 771 List<Skip> allSkips = FlowFactory.skipService().list(FlowFactory.newSkip() 772 .setDefinitionId(task.getDefinitionId())); 773 // 排除执行当前节点的流程跳转 774 Map<String, List<Skip>> skipMap = StreamUtils.groupByKeyFilter(skip -> 775 !task.getNodeCode().equals(skip.getNextNodeCode()), allSkips, Skip::getNextNodeCode); 776 // 属于退回指向节点的后置未完成的任务 777 List<Task> noDoneTasks = new ArrayList<>(); 778 for (Task flowTask : tasks) { 779 if (!task.getNodeCode().equals(flowTask.getNodeCode())) { 780 List<Skip> lastSkips = skipMap.get(flowTask.getNodeCode()); 781 if (judgeReject(nextNodeCode, lastSkips, skipMap)) { 782 noDoneTasks.add(flowTask); 783 } 784 } 785 } 786 if (CollUtil.isNotEmpty(noDoneTasks)) { 787 convertHisTask(noDoneTasks, flowParams, FlowStatus.INVALID.getKey()); 788 } 789 } 790 } 791 792 793 /** 794 * 判断是否属于退回指向节点的后置未完成的任务 795 * 796 * @param nextNodeCode 下一个节点编码 797 * @param lastSkips 上一个跳转集合 798 * @param skipMap 跳转map 799 * @return boolean 800 */ 801 private boolean judgeReject(String nextNodeCode, List<Skip> lastSkips 802 , Map<String, List<Skip>> skipMap) { 803 if (CollUtil.isNotEmpty(lastSkips)) { 804 for (Skip lastSkip : lastSkips) { 805 if (nextNodeCode.equals(lastSkip.getNowNodeCode())) { 806 return true; 807 } 808 List<Skip> lastLastSkips = skipMap.get(lastSkip.getNowNodeCode()); 809 return judgeReject(nextNodeCode, lastLastSkips, skipMap); 810 } 811 } 812 return false; 813 } 814 815 /** 816 * 处理未完成的任务,当流程完成,还存在待办任务未完成,转历史任务,状态完成。 817 * 818 * @param instance 流程实例 819 */ 820 private void handUndoneTask(Instance instance, FlowParams flowParams) { 821 if (NodeType.isEnd(instance.getNodeType())) { 822 List<Task> taskList = list(FlowFactory.newTask().setInstanceId(instance.getId())); 823 if (CollUtil.isNotEmpty(taskList)) { 824 convertHisTask(taskList, flowParams, FlowStatus.AUTO_PASS.getKey()); 825 } 826 } 827 } 828 829 /** 830 * 待办任务转历史任务。 831 */ 832 private void convertHisTask(List<Task> taskList, FlowParams flowParams, String flowStatus) { 833 List<HisTask> insHisList = new ArrayList<>(); 834 for (Task task : taskList) { 835 List<User> userList = FlowFactory.userService().listByAssociatedAndTypes(task.getId()); 836 List<HisTask> hisTasks = FlowFactory.hisTaskService().autoHisTask(flowParams, flowStatus, task, userList, CooperateType.APPROVAL.getKey()); 837 // 设置每个HisTask的ext字段 838 hisTasks.forEach(hisTask -> hisTask.setExt(flowParams.getHisTaskExt())); 839 insHisList.addAll(hisTasks); 840 } 841 removeByIds(StreamUtils.toList(taskList, Task::getId)); 842 FlowFactory.hisTaskService().saveBatch(insHisList); 843 // 删除所有待办任务的权限人 844 FlowFactory.userService().deleteByTaskIds(StreamUtils.toList(taskList, Task::getId)); 845 } 846 847 /** 848 * 更新流程信息 849 * 850 * @param task 当前任务 851 * @param instance 流程实例 852 * @param addTasks 新增待办任务 853 * @param flowParams 包含流程相关参数的对象 854 * @param nextNodes 下一个节点集合 855 */ 856 private void updateFlowInfo(Task task, Instance instance, List<Task> addTasks, FlowParams flowParams 857 , List<Node> nextNodes) { 858 // 设置流程历史任务信息 859 List<HisTask> insHisList = FlowFactory.hisTaskService().setSkipInsHis(task, nextNodes, flowParams); 860 FlowFactory.hisTaskService().saveBatch(insHisList); 861 // 待办任务设置处理人 862 List<User> users = FlowFactory.userService().setSkipUser(addTasks, task.getId()); 863 removeById(task.getId()); 864 865 // 设置任务完成后的实例相关信息 866 setInsFinishInfo(instance, addTasks, flowParams); 867 if (CollUtil.isNotEmpty(addTasks)) { 868 saveBatch(addTasks); 869 } 870 FlowFactory.insService().updateById(instance); 871 // 保存下一个待办任务的权限人和历史任务的处理人 872 FlowFactory.userService().saveBatch(users); 873 } 874 875 private boolean judgeActivityStatus(Definition definition, Instance instance) { 876 return Objects.equals(definition.getActivityStatus(), ActivityStatus.ACTIVITY.getKey()) 877 && Objects.equals(instance.getActivityStatus(), ActivityStatus.ACTIVITY.getKey()); 878 } 879}