Commit d9758636b191a4b7d0201b8d3943c15c5b7b220a
1 parent
d8871807
仿钉钉流程设计-抄送节点实现
Showing
6 changed files
with
90 additions
and
33 deletions
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmSimpleModelNodeType.java
| @@ -20,8 +20,10 @@ public enum BpmSimpleModelNodeType implements IntArrayValuable { | @@ -20,8 +20,10 @@ public enum BpmSimpleModelNodeType implements IntArrayValuable { | ||
| 20 | // TODO @jaosn:-1、0、1、4、-2 是前端已经定义好的么?感觉未来可以考虑搞成和 BPMN 尽量一致的单词哈;类似 usertask 用户审批; | 20 | // TODO @jaosn:-1、0、1、4、-2 是前端已经定义好的么?感觉未来可以考虑搞成和 BPMN 尽量一致的单词哈;类似 usertask 用户审批; |
| 21 | START_EVENT_NODE(0, "开始节点"), | 21 | START_EVENT_NODE(0, "开始节点"), |
| 22 | APPROVE_USER_NODE (1, "审批人节点"), | 22 | APPROVE_USER_NODE (1, "审批人节点"), |
| 23 | + // 抄送人节点、对应 BPMN 的 ScriptTask. 使用ScriptTask 原因。好像 ServiceTask 自定义属性不能写入 XML | ||
| 24 | + SCRIPT_TASK_NODE(2, "抄送人节点"), | ||
| 23 | EXCLUSIVE_GATEWAY_NODE(4, "排他网关"), | 25 | EXCLUSIVE_GATEWAY_NODE(4, "排他网关"), |
| 24 | - END_NODE(-2, "结束节点"); | 26 | + END_EVENT_NODE(-2, "结束节点"); |
| 25 | 27 | ||
| 26 | public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BpmSimpleModelNodeType::getType).toArray(); | 28 | public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BpmSimpleModelNodeType::getType).toArray(); |
| 27 | 29 |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java
| @@ -13,6 +13,7 @@ import org.flowable.bpmn.BpmnAutoLayout; | @@ -13,6 +13,7 @@ import org.flowable.bpmn.BpmnAutoLayout; | ||
| 13 | import org.flowable.bpmn.converter.BpmnXMLConverter; | 13 | import org.flowable.bpmn.converter.BpmnXMLConverter; |
| 14 | import org.flowable.bpmn.model.Process; | 14 | import org.flowable.bpmn.model.Process; |
| 15 | import org.flowable.bpmn.model.*; | 15 | import org.flowable.bpmn.model.*; |
| 16 | +import org.flowable.common.engine.impl.scripting.ScriptingEngines; | ||
| 16 | import org.flowable.common.engine.impl.util.io.BytesStreamSource; | 17 | import org.flowable.common.engine.impl.util.io.BytesStreamSource; |
| 17 | 18 | ||
| 18 | import java.util.ArrayList; | 19 | import java.util.ArrayList; |
| @@ -20,11 +21,15 @@ import java.util.HashSet; | @@ -20,11 +21,15 @@ import java.util.HashSet; | ||
| 20 | import java.util.List; | 21 | import java.util.List; |
| 21 | import java.util.Set; | 22 | import java.util.Set; |
| 22 | 23 | ||
| 24 | +import static org.flowable.bpmn.constants.BpmnXMLConstants.*; | ||
| 25 | + | ||
| 23 | /** | 26 | /** |
| 24 | * 流程模型转操作工具类 | 27 | * 流程模型转操作工具类 |
| 25 | */ | 28 | */ |
| 26 | public class BpmnModelUtils { | 29 | public class BpmnModelUtils { |
| 27 | 30 | ||
| 31 | + public static final String BPMN_SIMPLE_COPY_EXECUTION_SCRIPT = "#{bpmSimpleNodeService.copy(execution)}"; | ||
| 32 | + | ||
| 28 | public static Integer parseCandidateStrategy(FlowElement userTask) { | 33 | public static Integer parseCandidateStrategy(FlowElement userTask) { |
| 29 | return NumberUtils.parseInt(userTask.getAttributeValue( | 34 | return NumberUtils.parseInt(userTask.getAttributeValue( |
| 30 | BpmnModelConstants.NAMESPACE, BpmnModelConstants.USER_TASK_CANDIDATE_STRATEGY)); | 35 | BpmnModelConstants.NAMESPACE, BpmnModelConstants.USER_TASK_CANDIDATE_STRATEGY)); |
| @@ -379,26 +384,27 @@ public class BpmnModelUtils { | @@ -379,26 +384,27 @@ public class BpmnModelUtils { | ||
| 379 | Assert.notNull(nodeType, "模型节点类型不支持"); | 384 | Assert.notNull(nodeType, "模型节点类型不支持"); |
| 380 | switch (nodeType) { | 385 | switch (nodeType) { |
| 381 | case START_EVENT_NODE: | 386 | case START_EVENT_NODE: |
| 382 | - case APPROVE_USER_NODE: { | 387 | + case APPROVE_USER_NODE: |
| 388 | + case SCRIPT_TASK_NODE: { | ||
| 383 | addBpmnSequenceFlowElement(mainProcess, node.getId(), childNode.getId(), null, null); | 389 | addBpmnSequenceFlowElement(mainProcess, node.getId(), childNode.getId(), null, null); |
| 384 | // 递归调用后续节点 | 390 | // 递归调用后续节点 |
| 385 | - addBpmnSequenceFlow(mainProcess, childNode,endId); | 391 | + addBpmnSequenceFlow(mainProcess, childNode, endId); |
| 386 | break; | 392 | break; |
| 387 | } | 393 | } |
| 388 | case EXCLUSIVE_GATEWAY_NODE: { | 394 | case EXCLUSIVE_GATEWAY_NODE: { |
| 389 | - String gateWayEndId = ( childNode == null || childNode.getId() == null ) ? BpmnModelConstants.END_EVENT_ID : childNode.getId(); | 395 | + String gateWayEndId = (childNode == null || childNode.getId() == null) ? BpmnModelConstants.END_EVENT_ID : childNode.getId(); |
| 390 | List<BpmSimpleModelNodeVO> conditionNodes = node.getConditionNodes(); | 396 | List<BpmSimpleModelNodeVO> conditionNodes = node.getConditionNodes(); |
| 391 | Assert.notEmpty(conditionNodes, "网关节点的条件节点不能为空"); | 397 | Assert.notEmpty(conditionNodes, "网关节点的条件节点不能为空"); |
| 392 | for (int i = 0; i < conditionNodes.size(); i++) { | 398 | for (int i = 0; i < conditionNodes.size(); i++) { |
| 393 | BpmSimpleModelNodeVO item = conditionNodes.get(i); | 399 | BpmSimpleModelNodeVO item = conditionNodes.get(i); |
| 394 | - BpmSimpleModelNodeVO nextNodeOnCondition = getNextNodeOnCondition(item); | 400 | + BpmSimpleModelNodeVO nextNodeOnCondition = item.getChildNode(); |
| 395 | if (nextNodeOnCondition != null && nextNodeOnCondition.getId() != null) { | 401 | if (nextNodeOnCondition != null && nextNodeOnCondition.getId() != null) { |
| 396 | addBpmnSequenceFlowElement(mainProcess, node.getId(), nextNodeOnCondition.getId(), | 402 | addBpmnSequenceFlowElement(mainProcess, node.getId(), nextNodeOnCondition.getId(), |
| 397 | - String.format("%s_SequenceFlow_%d", node.getId(), i+1), null); | 403 | + String.format("%s_SequenceFlow_%d", node.getId(), i + 1), null); |
| 398 | addBpmnSequenceFlow(mainProcess, nextNodeOnCondition, gateWayEndId); | 404 | addBpmnSequenceFlow(mainProcess, nextNodeOnCondition, gateWayEndId); |
| 399 | } else { | 405 | } else { |
| 400 | addBpmnSequenceFlowElement(mainProcess, node.getId(), gateWayEndId, | 406 | addBpmnSequenceFlowElement(mainProcess, node.getId(), gateWayEndId, |
| 401 | - String.format("%s_SequenceFlow_%d", node.getId(), i+1), null); | 407 | + String.format("%s_SequenceFlow_%d", node.getId(), i + 1), null); |
| 402 | } | 408 | } |
| 403 | } | 409 | } |
| 404 | // 递归调用后续节点 | 410 | // 递归调用后续节点 |
| @@ -412,10 +418,6 @@ public class BpmnModelUtils { | @@ -412,10 +418,6 @@ public class BpmnModelUtils { | ||
| 412 | 418 | ||
| 413 | } | 419 | } |
| 414 | 420 | ||
| 415 | - private static BpmSimpleModelNodeVO getNextNodeOnCondition(BpmSimpleModelNodeVO conditionNode) { | ||
| 416 | - return conditionNode.getChildNode(); | ||
| 417 | - } | ||
| 418 | - | ||
| 419 | private static void addBpmnSequenceFlowElement(Process mainProcess, String sourceId, String targetId, String seqFlowId, String conditionExpression) { | 421 | private static void addBpmnSequenceFlowElement(Process mainProcess, String sourceId, String targetId, String seqFlowId, String conditionExpression) { |
| 420 | SequenceFlow sequenceFlow = new SequenceFlow(sourceId, targetId); | 422 | SequenceFlow sequenceFlow = new SequenceFlow(sourceId, targetId); |
| 421 | if (StrUtil.isNotEmpty(conditionExpression)) { | 423 | if (StrUtil.isNotEmpty(conditionExpression)) { |
| @@ -439,7 +441,10 @@ public class BpmnModelUtils { | @@ -439,7 +441,10 @@ public class BpmnModelUtils { | ||
| 439 | addBpmnStartEventNode(mainProcess, simpleModelNode); | 441 | addBpmnStartEventNode(mainProcess, simpleModelNode); |
| 440 | break; | 442 | break; |
| 441 | case APPROVE_USER_NODE: | 443 | case APPROVE_USER_NODE: |
| 442 | - addBpmnUserTaskEventNode(mainProcess, simpleModelNode); | 444 | + addBpmnUserTaskNode(mainProcess, simpleModelNode); |
| 445 | + break; | ||
| 446 | + case SCRIPT_TASK_NODE: | ||
| 447 | + addBpmnScriptTaSskNode(mainProcess, simpleModelNode); | ||
| 443 | break; | 448 | break; |
| 444 | case EXCLUSIVE_GATEWAY_NODE: | 449 | case EXCLUSIVE_GATEWAY_NODE: |
| 445 | addBpmnExclusiveGatewayNode(mainProcess, simpleModelNode); | 450 | addBpmnExclusiveGatewayNode(mainProcess, simpleModelNode); |
| @@ -467,6 +472,25 @@ public class BpmnModelUtils { | @@ -467,6 +472,25 @@ public class BpmnModelUtils { | ||
| 467 | } | 472 | } |
| 468 | } | 473 | } |
| 469 | 474 | ||
| 475 | + private static void addBpmnScriptTaSskNode(Process mainProcess, BpmSimpleModelNodeVO node) { | ||
| 476 | + ScriptTask scriptTask = new ScriptTask(); | ||
| 477 | + scriptTask.setId(node.getId()); | ||
| 478 | + scriptTask.setName(node.getName()); | ||
| 479 | + scriptTask.setScriptFormat(ScriptingEngines.DEFAULT_SCRIPTING_LANGUAGE); | ||
| 480 | + scriptTask.setScript(BPMN_SIMPLE_COPY_EXECUTION_SCRIPT); | ||
| 481 | + // 添加自定义属性 | ||
| 482 | + addExtensionAttributes(node, scriptTask); | ||
| 483 | + mainProcess.addFlowElement(scriptTask); | ||
| 484 | + } | ||
| 485 | + | ||
| 486 | + private static void addExtensionAttributes(BpmSimpleModelNodeVO node, FlowElement flowElement) { | ||
| 487 | + Integer candidateStrategy = MapUtil.getInt(node.getAttributes(), BpmnModelConstants.USER_TASK_CANDIDATE_STRATEGY); | ||
| 488 | + addExtensionAttributes(flowElement, BpmnModelConstants.NAMESPACE, BpmnModelConstants.USER_TASK_CANDIDATE_STRATEGY, | ||
| 489 | + candidateStrategy == null ? null : String.valueOf(candidateStrategy)); | ||
| 490 | + addExtensionAttributes(flowElement, BpmnModelConstants.NAMESPACE, BpmnModelConstants.USER_TASK_CANDIDATE_PARAM, | ||
| 491 | + MapUtil.getStr(node.getAttributes(), BpmnModelConstants.USER_TASK_CANDIDATE_PARAM)); | ||
| 492 | + } | ||
| 493 | + | ||
| 470 | private static void addBpmnExclusiveGatewayNode(Process mainProcess, BpmSimpleModelNodeVO node) { | 494 | private static void addBpmnExclusiveGatewayNode(Process mainProcess, BpmSimpleModelNodeVO node) { |
| 471 | Assert.notEmpty(node.getConditionNodes(), "网关节点的条件节点不能为空"); | 495 | Assert.notEmpty(node.getConditionNodes(), "网关节点的条件节点不能为空"); |
| 472 | ExclusiveGateway exclusiveGateway = new ExclusiveGateway(); | 496 | ExclusiveGateway exclusiveGateway = new ExclusiveGateway(); |
| @@ -483,25 +507,21 @@ public class BpmnModelUtils { | @@ -483,25 +507,21 @@ public class BpmnModelUtils { | ||
| 483 | mainProcess.addFlowElement(endEvent); | 507 | mainProcess.addFlowElement(endEvent); |
| 484 | } | 508 | } |
| 485 | 509 | ||
| 486 | - private static void addBpmnUserTaskEventNode(Process mainProcess, BpmSimpleModelNodeVO node) { | 510 | + private static void addBpmnUserTaskNode(Process mainProcess, BpmSimpleModelNodeVO node) { |
| 487 | UserTask userTask = new UserTask(); | 511 | UserTask userTask = new UserTask(); |
| 488 | userTask.setId(node.getId()); | 512 | userTask.setId(node.getId()); |
| 489 | userTask.setName(node.getName()); | 513 | userTask.setName(node.getName()); |
| 490 | - Integer candidateStrategy = MapUtil.getInt(node.getAttributes(), BpmnModelConstants.USER_TASK_CANDIDATE_STRATEGY); | ||
| 491 | - // 添加自定义属性 | ||
| 492 | - addExtensionAttribute(userTask, BpmnModelConstants.NAMESPACE, BpmnModelConstants.USER_TASK_CANDIDATE_STRATEGY, | ||
| 493 | - candidateStrategy == null ? null : String.valueOf(candidateStrategy)); | ||
| 494 | - addExtensionAttribute(userTask, BpmnModelConstants.NAMESPACE, BpmnModelConstants.USER_TASK_CANDIDATE_PARAM, | ||
| 495 | - MapUtil.getStr(node.getAttributes(), BpmnModelConstants.USER_TASK_CANDIDATE_PARAM)); | 514 | + addExtensionAttributes(node, userTask); |
| 496 | mainProcess.addFlowElement(userTask); | 515 | mainProcess.addFlowElement(userTask); |
| 497 | } | 516 | } |
| 498 | 517 | ||
| 499 | - private static void addExtensionAttribute(FlowElement element, String namespace, String name, String value) { | 518 | + private static void addExtensionAttributes(FlowElement element, String namespace, String name, String value) { |
| 500 | if (value == null) { | 519 | if (value == null) { |
| 501 | return; | 520 | return; |
| 502 | } | 521 | } |
| 503 | ExtensionAttribute extensionAttribute = new ExtensionAttribute(name, value); | 522 | ExtensionAttribute extensionAttribute = new ExtensionAttribute(name, value); |
| 504 | extensionAttribute.setNamespace(namespace); | 523 | extensionAttribute.setNamespace(namespace); |
| 524 | + extensionAttribute.setNamespacePrefix(FLOWABLE_EXTENSIONS_PREFIX); | ||
| 505 | element.addAttribute(extensionAttribute); | 525 | element.addAttribute(extensionAttribute); |
| 506 | } | 526 | } |
| 507 | 527 |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceCopyService.java
| @@ -17,9 +17,11 @@ public interface BpmProcessInstanceCopyService { | @@ -17,9 +17,11 @@ public interface BpmProcessInstanceCopyService { | ||
| 17 | * 流程实例的抄送 | 17 | * 流程实例的抄送 |
| 18 | * | 18 | * |
| 19 | * @param userIds 抄送的用户编号 | 19 | * @param userIds 抄送的用户编号 |
| 20 | - * @param taskId 流程任务编号 | 20 | + * @param processInstanceId 流程编号 |
| 21 | + * @param taskId 任务编号 | ||
| 22 | + * @param taskName 任务名称 | ||
| 21 | */ | 23 | */ |
| 22 | - void createProcessInstanceCopy(Collection<Long> userIds, String taskId); | 24 | + void createProcessInstanceCopy(Collection<Long> userIds, String processInstanceId, String taskId, String taskName); |
| 23 | 25 | ||
| 24 | /** | 26 | /** |
| 25 | * 获得抄送的流程的分页 | 27 | * 获得抄送的流程的分页 |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceCopyServiceImpl.java
| 1 | package cn.iocoder.yudao.module.bpm.service.task; | 1 | package cn.iocoder.yudao.module.bpm.service.task; |
| 2 | 2 | ||
| 3 | -import cn.hutool.core.util.ObjectUtil; | ||
| 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCopyPageReqVO; | 4 | import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCopyPageReqVO; |
| 6 | import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceCopyDO; | 5 | import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceCopyDO; |
| @@ -11,7 +10,6 @@ import jakarta.annotation.Resource; | @@ -11,7 +10,6 @@ import jakarta.annotation.Resource; | ||
| 11 | import lombok.extern.slf4j.Slf4j; | 10 | import lombok.extern.slf4j.Slf4j; |
| 12 | import org.flowable.engine.repository.ProcessDefinition; | 11 | import org.flowable.engine.repository.ProcessDefinition; |
| 13 | import org.flowable.engine.runtime.ProcessInstance; | 12 | import org.flowable.engine.runtime.ProcessInstance; |
| 14 | -import org.flowable.task.api.Task; | ||
| 15 | import org.springframework.context.annotation.Lazy; | 13 | import org.springframework.context.annotation.Lazy; |
| 16 | import org.springframework.stereotype.Service; | 14 | import org.springframework.stereotype.Service; |
| 17 | import org.springframework.validation.annotation.Validated; | 15 | import org.springframework.validation.annotation.Validated; |
| @@ -47,14 +45,14 @@ public class BpmProcessInstanceCopyServiceImpl implements BpmProcessInstanceCopy | @@ -47,14 +45,14 @@ public class BpmProcessInstanceCopyServiceImpl implements BpmProcessInstanceCopy | ||
| 47 | private BpmProcessDefinitionService processDefinitionService; | 45 | private BpmProcessDefinitionService processDefinitionService; |
| 48 | 46 | ||
| 49 | @Override | 47 | @Override |
| 50 | - public void createProcessInstanceCopy(Collection<Long> userIds, String taskId) { | ||
| 51 | - // 1.1 校验任务存在 | ||
| 52 | - Task task = taskService.getTask(taskId); | ||
| 53 | - if (ObjectUtil.isNull(task)) { | ||
| 54 | - throw exception(ErrorCodeConstants.TASK_NOT_EXISTS); | ||
| 55 | - } | 48 | + public void createProcessInstanceCopy(Collection<Long> userIds, String processInstanceId, String taskId, String taskName) { |
| 49 | + // 1.1 校验任务存在 暂时去掉这个校验. 因为任务可能仿钉钉快搭的抄送节点(ScriptTask) | ||
| 50 | +// Task task = taskService.getTask(taskId); | ||
| 51 | +// if (ObjectUtil.isNull(task)) { | ||
| 52 | +// throw exception(ErrorCodeConstants.TASK_NOT_EXISTS); | ||
| 53 | +// } | ||
| 56 | // 1.2 校验流程实例存在 | 54 | // 1.2 校验流程实例存在 |
| 57 | - String processInstanceId = task.getProcessInstanceId(); | 55 | +// String processInstanceId = task.getProcessInstanceId(); |
| 58 | ProcessInstance processInstance = processInstanceService.getProcessInstance(processInstanceId); | 56 | ProcessInstance processInstance = processInstanceService.getProcessInstance(processInstanceId); |
| 59 | if (processInstance == null) { | 57 | if (processInstance == null) { |
| 60 | throw exception(ErrorCodeConstants.PROCESS_INSTANCE_NOT_EXISTS); | 58 | throw exception(ErrorCodeConstants.PROCESS_INSTANCE_NOT_EXISTS); |
| @@ -70,7 +68,7 @@ public class BpmProcessInstanceCopyServiceImpl implements BpmProcessInstanceCopy | @@ -70,7 +68,7 @@ public class BpmProcessInstanceCopyServiceImpl implements BpmProcessInstanceCopy | ||
| 70 | List<BpmProcessInstanceCopyDO> copyList = convertList(userIds, userId -> new BpmProcessInstanceCopyDO() | 68 | List<BpmProcessInstanceCopyDO> copyList = convertList(userIds, userId -> new BpmProcessInstanceCopyDO() |
| 71 | .setUserId(userId).setStartUserId(Long.valueOf(processInstance.getStartUserId())) | 69 | .setUserId(userId).setStartUserId(Long.valueOf(processInstance.getStartUserId())) |
| 72 | .setProcessInstanceId(processInstanceId).setProcessInstanceName(processInstance.getName()) | 70 | .setProcessInstanceId(processInstanceId).setProcessInstanceName(processInstance.getName()) |
| 73 | - .setCategory(processDefinition.getCategory()).setTaskId(taskId).setTaskName(task.getName())); | 71 | + .setCategory(processDefinition.getCategory()).setTaskId(taskId).setTaskName(taskName)); |
| 74 | processInstanceCopyMapper.insertBatch(copyList); | 72 | processInstanceCopyMapper.insertBatch(copyList); |
| 75 | } | 73 | } |
| 76 | 74 |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmSimpleNodeService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.task; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateInvoker; | ||
| 4 | +import jakarta.annotation.Resource; | ||
| 5 | +import org.flowable.bpmn.model.FlowElement; | ||
| 6 | +import org.flowable.engine.delegate.DelegateExecution; | ||
| 7 | +import org.springframework.stereotype.Service; | ||
| 8 | + | ||
| 9 | +import java.util.Set; | ||
| 10 | + | ||
| 11 | +/** | ||
| 12 | + * 仿钉钉快搭各个节点 Service | ||
| 13 | + * @author jason | ||
| 14 | + */ | ||
| 15 | +@Service | ||
| 16 | +public class BpmSimpleNodeService { | ||
| 17 | + | ||
| 18 | + @Resource | ||
| 19 | + private BpmTaskCandidateInvoker taskCandidateInvoker; | ||
| 20 | + @Resource | ||
| 21 | + private BpmProcessInstanceCopyService processInstanceCopyService; | ||
| 22 | + | ||
| 23 | + /** | ||
| 24 | + * 仿钉钉快搭抄送 | ||
| 25 | + * @param execution 执行的任务(ScriptTask) | ||
| 26 | + */ | ||
| 27 | + public Boolean copy(DelegateExecution execution) { | ||
| 28 | + Set<Long> userIds = taskCandidateInvoker.calculateUsers(execution); | ||
| 29 | + FlowElement currentFlowElement = execution.getCurrentFlowElement(); | ||
| 30 | + processInstanceCopyService.createProcessInstanceCopy(userIds, execution.getProcessInstanceId(), | ||
| 31 | + currentFlowElement.getId(), currentFlowElement.getName()); | ||
| 32 | + return Boolean.TRUE; | ||
| 33 | + } | ||
| 34 | +} |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java
| @@ -185,7 +185,8 @@ public class BpmTaskServiceImpl implements BpmTaskService { | @@ -185,7 +185,8 @@ public class BpmTaskServiceImpl implements BpmTaskService { | ||
| 185 | 185 | ||
| 186 | // 2. 抄送用户 | 186 | // 2. 抄送用户 |
| 187 | if (CollUtil.isNotEmpty(reqVO.getCopyUserIds())) { | 187 | if (CollUtil.isNotEmpty(reqVO.getCopyUserIds())) { |
| 188 | - processInstanceCopyService.createProcessInstanceCopy(reqVO.getCopyUserIds(), reqVO.getId()); | 188 | + processInstanceCopyService.createProcessInstanceCopy(reqVO.getCopyUserIds(), instance.getProcessInstanceId(), |
| 189 | + reqVO.getId(), task.getName()); | ||
| 189 | } | 190 | } |
| 190 | 191 | ||
| 191 | // 情况一:被委派的任务,不调用 complete 去完成任务 | 192 | // 情况一:被委派的任务,不调用 complete 去完成任务 |