Merge branch 'feature/countersign_ext' into dev
This commit is contained in:
commit
770b5bc9d3
@ -21,6 +21,8 @@ public enum ConvertorRespCode implements IModuleRespCode {
|
|||||||
CONVERTOR_OPERATION_NUMBER_TYPE_ERROR("006", "条件节点(数字)运算符【{}】暂不支持"),
|
CONVERTOR_OPERATION_NUMBER_TYPE_ERROR("006", "条件节点(数字)运算符【{}】暂不支持"),
|
||||||
CONVERTOR_OPERATION_RADIO_TYPE_ERROR("007", "条件节点(单选)运算符【{}】暂不支持"),
|
CONVERTOR_OPERATION_RADIO_TYPE_ERROR("007", "条件节点(单选)运算符【{}】暂不支持"),
|
||||||
CONVERTOR_OPERATION_CHECKBOX_TYPE_ERROR("008", "条件节点(复选)运算符【{}】暂不支持"),
|
CONVERTOR_OPERATION_CHECKBOX_TYPE_ERROR("008", "条件节点(复选)运算符【{}】暂不支持"),
|
||||||
|
CREATE_BPMN_USER_TASK_ERROR("009", "创建 UserTask 失败, 不支持的节点模式【{}】"),
|
||||||
|
CREATE_BPMN_PRE_SIGN_ERROR("010", "创建前加签节点失败,原因:【{}】"),
|
||||||
;
|
;
|
||||||
|
|
||||||
private final String code;
|
private final String code;
|
||||||
|
|||||||
@ -47,6 +47,7 @@ public interface BpmnConstants {
|
|||||||
String BIZ_NODE_ALTER = "[_BIZ_NODE_ALTER_]";
|
String BIZ_NODE_ALTER = "[_BIZ_NODE_ALTER_]";
|
||||||
String INITIATOR_SPECIFY = "[_INITIATOR_SPECIFY_]";
|
String INITIATOR_SPECIFY = "[_INITIATOR_SPECIFY_]";
|
||||||
String SIGNATURE_COLLECTION = "[_SIGNATURE_COLLECTION_]";
|
String SIGNATURE_COLLECTION = "[_SIGNATURE_COLLECTION_]";
|
||||||
|
String FORWARD_COUNTERSIGN_COUNT = "[_FORWARD_COUNTERSIGN_COUNT_]";
|
||||||
String PROCESS_PREFIX = "Flowable";
|
String PROCESS_PREFIX = "Flowable";
|
||||||
@Deprecated
|
@Deprecated
|
||||||
String OLD_TASK_ASSIGNEE_SKIP_FLAT = "taskSkip";
|
String OLD_TASK_ASSIGNEE_SKIP_FLAT = "taskSkip";
|
||||||
@ -264,4 +265,8 @@ public interface BpmnConstants {
|
|||||||
* 提级审批变量标识
|
* 提级审批变量标识
|
||||||
*/
|
*/
|
||||||
String SUPPORT_UPGRADE_VARIABLE = "[_SUPPORT_UPGRADE_]";
|
String SUPPORT_UPGRADE_VARIABLE = "[_SUPPORT_UPGRADE_]";
|
||||||
|
/**
|
||||||
|
* 前加签节点 ID 片段
|
||||||
|
*/
|
||||||
|
String FORWARD_ACTIVITY_FRAGMENT = "[forward_sign]";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,6 +12,7 @@ public enum BpmnFlowNodeMode {
|
|||||||
GENERAL("GENERAL", "普通节点"),
|
GENERAL("GENERAL", "普通节点"),
|
||||||
OR("OR", "或签节点"),
|
OR("OR", "或签节点"),
|
||||||
AND("AND", "会签节点"),
|
AND("AND", "会签节点"),
|
||||||
|
SEQUENCE("SEQUENCE", "顺序节点"),
|
||||||
EXCEPTIONAL("EXCEPTIONAL", "异常"),
|
EXCEPTIONAL("EXCEPTIONAL", "异常"),
|
||||||
@JsonEnumDefaultValue
|
@JsonEnumDefaultValue
|
||||||
UNKNOWN("UNKNOWN", "未知"),
|
UNKNOWN("UNKNOWN", "未知"),
|
||||||
|
|||||||
@ -686,7 +686,7 @@ public class UserTaskJsonConverter extends AbstractBpmnJsonConverter<UserTask> {
|
|||||||
* @param node
|
* @param node
|
||||||
* @param userTask
|
* @param userTask
|
||||||
*/
|
*/
|
||||||
private static void setExecutionListeners(BpmnJsonNode node, UserTask userTask) {
|
public static void setExecutionListeners(BpmnJsonNode node, UserTask userTask) {
|
||||||
|
|
||||||
List<FlowableListener> executionListeners = new ArrayList<>();
|
List<FlowableListener> executionListeners = new ArrayList<>();
|
||||||
// 设置执行监听
|
// 设置执行监听
|
||||||
@ -725,7 +725,7 @@ public class UserTaskJsonConverter extends AbstractBpmnJsonConverter<UserTask> {
|
|||||||
*
|
*
|
||||||
* @param userTask
|
* @param userTask
|
||||||
*/
|
*/
|
||||||
private static void setTaskListeners(UserTask userTask) {
|
public static void setTaskListeners(UserTask userTask) {
|
||||||
List<FlowableListener> taskListeners = new ArrayList<>();
|
List<FlowableListener> taskListeners = new ArrayList<>();
|
||||||
// 设置任务监听
|
// 设置任务监听
|
||||||
FlowableListener taskListener = new FlowableListener();
|
FlowableListener taskListener = new FlowableListener();
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import cn.axzo.workflow.common.enums.BpmnFlowNodeMode;
|
|||||||
import cn.axzo.workflow.common.exception.WorkflowEngineException;
|
import cn.axzo.workflow.common.exception.WorkflowEngineException;
|
||||||
import cn.axzo.workflow.common.model.request.bpmn.task.AttachmentDTO;
|
import cn.axzo.workflow.common.model.request.bpmn.task.AttachmentDTO;
|
||||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
|
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
|
||||||
|
import cn.axzo.workflow.core.engine.cmd.helper.CustomBpmnModelHelper;
|
||||||
import cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper;
|
import cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper;
|
||||||
import cn.axzo.workflow.core.engine.model.AddComment;
|
import cn.axzo.workflow.core.engine.model.AddComment;
|
||||||
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
|
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
|
||||||
@ -13,25 +14,24 @@ import com.alibaba.fastjson.JSON;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.flowable.bpmn.model.BpmnModel;
|
import org.flowable.bpmn.model.BpmnModel;
|
||||||
import org.flowable.bpmn.model.FlowElement;
|
import org.flowable.bpmn.model.FlowElement;
|
||||||
|
import org.flowable.bpmn.model.Process;
|
||||||
import org.flowable.bpmn.model.UserTask;
|
import org.flowable.bpmn.model.UserTask;
|
||||||
import org.flowable.common.engine.impl.cfg.IdGenerator;
|
|
||||||
import org.flowable.common.engine.impl.interceptor.CommandContext;
|
import org.flowable.common.engine.impl.interceptor.CommandContext;
|
||||||
import org.flowable.engine.RuntimeService;
|
import org.flowable.engine.RuntimeService;
|
||||||
import org.flowable.engine.TaskService;
|
import org.flowable.engine.TaskService;
|
||||||
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
|
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
|
||||||
import org.flowable.engine.impl.util.CommandContextUtil;
|
import org.flowable.engine.impl.util.CommandContextUtil;
|
||||||
import org.flowable.engine.impl.util.ProcessDefinitionUtil;
|
import org.flowable.engine.impl.util.ProcessDefinitionUtil;
|
||||||
|
import org.flowable.engine.runtime.ProcessInstance;
|
||||||
import org.flowable.task.api.Task;
|
import org.flowable.task.api.Task;
|
||||||
import org.flowable.task.api.TaskInfo;
|
import org.flowable.task.api.TaskInfo;
|
||||||
import org.flowable.task.api.history.HistoricTaskInstance;
|
import org.flowable.task.api.history.HistoricTaskInstance;
|
||||||
import org.flowable.task.api.history.HistoricTaskInstanceQuery;
|
import org.flowable.task.api.history.HistoricTaskInstanceQuery;
|
||||||
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
|
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
|
||||||
import org.flowable.task.service.impl.persistence.entity.TaskEntityImpl;
|
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -42,10 +42,9 @@ import java.util.stream.Collectors;
|
|||||||
import static cn.axzo.workflow.common.code.OtherRespCode.ASSIGNEE_NODE_ID_NOT_EXISTS;
|
import static cn.axzo.workflow.common.code.OtherRespCode.ASSIGNEE_NODE_ID_NOT_EXISTS;
|
||||||
import static cn.axzo.workflow.common.constant.BpmnConstants.AND_SIGN_EXPRESSION;
|
import static cn.axzo.workflow.common.constant.BpmnConstants.AND_SIGN_EXPRESSION;
|
||||||
import static cn.axzo.workflow.common.constant.BpmnConstants.COUNTERSIGN_ASSIGNER_SHOW_NUMBER;
|
import static cn.axzo.workflow.common.constant.BpmnConstants.COUNTERSIGN_ASSIGNER_SHOW_NUMBER;
|
||||||
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_FORWARD_COUNTERSIGN;
|
import static cn.axzo.workflow.common.constant.BpmnConstants.FORWARD_ACTIVITY_FRAGMENT;
|
||||||
|
import static cn.axzo.workflow.common.constant.BpmnConstants.FORWARD_COUNTERSIGN_COUNT;
|
||||||
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT;
|
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT;
|
||||||
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_INFO;
|
|
||||||
import static cn.axzo.workflow.common.enums.BpmnCountersignTypeEnum.FORWARD_COUNTERSIGN;
|
|
||||||
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.COUNTERSIGN;
|
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.COUNTERSIGN;
|
||||||
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getCategoryVersion;
|
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getCategoryVersion;
|
||||||
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.addMultiTask;
|
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.addMultiTask;
|
||||||
@ -169,39 +168,34 @@ public class CustomCountersignUserTaskCmd extends AbstractCommand<Void> implemen
|
|||||||
private void forwardCountSign(CommandContext commandContext, TaskEntity task, List<BpmnTaskDelegateAssigner> valuTargetAssigneeList) {
|
private void forwardCountSign(CommandContext commandContext, TaskEntity task, List<BpmnTaskDelegateAssigner> valuTargetAssigneeList) {
|
||||||
ProcessEngineConfigurationImpl processEngineConfiguration =
|
ProcessEngineConfigurationImpl processEngineConfiguration =
|
||||||
CommandContextUtil.getProcessEngineConfiguration(commandContext);
|
CommandContextUtil.getProcessEngineConfiguration(commandContext);
|
||||||
IdGenerator idGenerator = processEngineConfiguration.getIdGenerator();
|
|
||||||
TaskService taskService = processEngineConfiguration.getTaskService();
|
|
||||||
RuntimeService runtimeService = processEngineConfiguration.getRuntimeService();
|
|
||||||
// 记录前加签的审批人快照
|
|
||||||
runtimeService.setVariable(task.getProcessInstanceId(), INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + INTERNAL_ACTIVITY_FORWARD_COUNTERSIGN + task.getId(), valuTargetAssigneeList);
|
|
||||||
if (task instanceof TaskEntityImpl) {
|
|
||||||
TaskEntityImpl taskEntity = (TaskEntityImpl) task;
|
|
||||||
taskEntity.setCountEnabled(true);
|
|
||||||
taskEntity.setOwner(task.getAssignee());
|
|
||||||
taskEntity.setAssignee(null);
|
|
||||||
taskEntity.setScopeType(FORWARD_COUNTERSIGN.getType());
|
|
||||||
taskService.saveTask(taskEntity);
|
|
||||||
|
|
||||||
valuTargetAssigneeList.forEach(e -> {
|
RuntimeService runtimeService = processEngineConfiguration.getRuntimeService();
|
||||||
TaskEntityImpl subTask = (TaskEntityImpl) taskService.newTask(idGenerator.getNextId());
|
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult();
|
||||||
subTask.setName(task.getName());
|
Process process = ProcessDefinitionUtil.getProcess(processInstance.getProcessDefinitionId());
|
||||||
subTask.setDescription(task.getDescription());
|
UserTask originalUserTask = (UserTask) process.getFlowElement(task.getTaskDefinitionKey());
|
||||||
subTask.setCategory(task.getCategory());
|
|
||||||
subTask.setParentTaskId(task.getId());
|
// 获取当前实例前加签次数
|
||||||
subTask.setProcessDefinitionId(task.getProcessDefinitionId());
|
Long forwardCounterSignCount = runtimeService.getVariable(processInstance.getId(), FORWARD_COUNTERSIGN_COUNT, Long.class);
|
||||||
subTask.setProcessInstanceId(task.getProcessInstanceId());
|
if (Objects.isNull(forwardCounterSignCount)) {
|
||||||
subTask.setTaskDefinitionKey(task.getTaskDefinitionKey());
|
forwardCounterSignCount = 0L;
|
||||||
subTask.setTaskDefinitionId(task.getTaskDefinitionId());
|
} else {
|
||||||
subTask.setPriority(task.getPriority());
|
forwardCounterSignCount = forwardCounterSignCount + 1;
|
||||||
subTask.setCreateTime(new Date());
|
|
||||||
subTask.setTenantId(task.getTenantId());
|
|
||||||
// subTask.setAssignee(e.buildAssigneeId());
|
|
||||||
taskService.saveTask(subTask);
|
|
||||||
// 设置快照信息
|
|
||||||
subTask.setVariable(INTERNAL_TASK_RELATION_ASSIGNEE_INFO + subTask.getId(), e.toJson());
|
|
||||||
taskService.setAssignee(subTask.getId(), e.buildAssigneeId());
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BpmnFlowNodeMode nodeMode = Objects.equals(originalUserTask.getLoopCharacteristics().getCompletionCondition(), AND_SIGN_EXPRESSION) ? BpmnFlowNodeMode.AND : BpmnFlowNodeMode.OR;
|
||||||
|
// 创建前加签节点
|
||||||
|
UserTask newUserTask = CustomBpmnModelHelper.createUserTask(processEngineConfiguration, originalUserTask, originalUserTask.getId() + FORWARD_ACTIVITY_FRAGMENT + forwardCounterSignCount, nodeMode, valuTargetAssigneeList);
|
||||||
|
// 加入模型
|
||||||
|
process.addFlowElement(newUserTask);
|
||||||
|
|
||||||
|
// 重新连接顺序流 (Sequence Flow)
|
||||||
|
CustomBpmnModelHelper.rewireSequenceFlows(process, originalUserTask, newUserTask);
|
||||||
|
|
||||||
|
runtimeService.createChangeActivityStateBuilder()
|
||||||
|
.processInstanceId(task.getProcessInstanceId())
|
||||||
|
// .moveExecutionsToSingleActivityId(Collections.singletonList(task.getExecutionId()), newUserTask.getId())
|
||||||
|
.moveActivityIdTo(task.getTaskDefinitionKey(), newUserTask.getId())
|
||||||
|
.changeState();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -0,0 +1,178 @@
|
|||||||
|
package cn.axzo.workflow.core.engine.cmd.helper;
|
||||||
|
|
||||||
|
import cn.axzo.workflow.common.enums.ApprovalMethodEnum;
|
||||||
|
import cn.axzo.workflow.common.enums.ApproverEmptyHandleTypeEnum;
|
||||||
|
import cn.axzo.workflow.common.enums.ApproverSpecifyEnum;
|
||||||
|
import cn.axzo.workflow.common.enums.BpmnFlowNodeMode;
|
||||||
|
import cn.axzo.workflow.common.enums.BpmnFlowNodeType;
|
||||||
|
import cn.axzo.workflow.common.exception.WorkflowEngineException;
|
||||||
|
import cn.axzo.workflow.common.model.request.bpmn.BpmnJsonNode;
|
||||||
|
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
|
||||||
|
import cn.hutool.core.lang.UUID;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.flowable.bpmn.model.ExtensionAttribute;
|
||||||
|
import org.flowable.bpmn.model.ExtensionElement;
|
||||||
|
import org.flowable.bpmn.model.MultiInstanceLoopCharacteristics;
|
||||||
|
import org.flowable.bpmn.model.Process;
|
||||||
|
import org.flowable.bpmn.model.SequenceFlow;
|
||||||
|
import org.flowable.bpmn.model.UserTask;
|
||||||
|
import org.flowable.engine.impl.bpmn.behavior.ParallelMultiInstanceBehavior;
|
||||||
|
import org.flowable.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
|
||||||
|
import org.flowable.engine.impl.bpmn.parser.factory.ActivityBehaviorFactory;
|
||||||
|
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static cn.axzo.workflow.common.code.ConvertorRespCode.CREATE_BPMN_PRE_SIGN_ERROR;
|
||||||
|
import static cn.axzo.workflow.common.code.ConvertorRespCode.CREATE_BPMN_USER_TASK_ERROR;
|
||||||
|
import static cn.axzo.workflow.common.constant.BpmnConstants.AND_SIGN_EXPRESSION;
|
||||||
|
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_APPROVAL_METHOD;
|
||||||
|
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_APPROVER_EMPTY_HANDLE_TYPE;
|
||||||
|
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_APPROVER_SPECIFY;
|
||||||
|
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_NODE_TYPE;
|
||||||
|
import static cn.axzo.workflow.common.constant.BpmnConstants.ELEMENT_ATTRIBUTE_DESC;
|
||||||
|
import static cn.axzo.workflow.common.constant.BpmnConstants.ELEMENT_ATTRIBUTE_VALUE;
|
||||||
|
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO;
|
||||||
|
import static cn.axzo.workflow.common.constant.BpmnConstants.OR_SIGN_EXPRESSION_ONLY_ONE;
|
||||||
|
import static cn.axzo.workflow.core.converter.json.UserTaskJsonConverter.setExecutionListeners;
|
||||||
|
import static cn.axzo.workflow.core.converter.json.UserTaskJsonConverter.setTaskListeners;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 动态操作 BPMN 定义内容的帮助类
|
||||||
|
*
|
||||||
|
* @author wangli
|
||||||
|
* @since 2025-10-15 17:05
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class CustomBpmnModelHelper {
|
||||||
|
|
||||||
|
private CustomBpmnModelHelper() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建 BPMN 中的 UserTask
|
||||||
|
*
|
||||||
|
* @param processEngineConfiguration
|
||||||
|
* @param originalUserTask
|
||||||
|
* @param nodeMode
|
||||||
|
*/
|
||||||
|
public static UserTask createUserTask(ProcessEngineConfigurationImpl processEngineConfiguration, UserTask originalUserTask, String customActivityId, BpmnFlowNodeMode nodeMode, List<BpmnTaskDelegateAssigner> assigners) {
|
||||||
|
UserTask newUserTask = new UserTask();
|
||||||
|
if (StringUtils.hasText(customActivityId)) {
|
||||||
|
newUserTask.setId(customActivityId);
|
||||||
|
} else {
|
||||||
|
newUserTask.setId(originalUserTask.getId());
|
||||||
|
}
|
||||||
|
newUserTask.setName(originalUserTask.getName());
|
||||||
|
newUserTask.setDocumentation("由" + originalUserTask.getId() + "节点前加签生成");
|
||||||
|
|
||||||
|
MultiInstanceLoopCharacteristics loopCharacteristics = new MultiInstanceLoopCharacteristics();
|
||||||
|
loopCharacteristics.setInputDataItem(INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO + newUserTask.getId());
|
||||||
|
loopCharacteristics.setElementVariable("assigneeName");
|
||||||
|
newUserTask.setLoopCharacteristics(loopCharacteristics);
|
||||||
|
newUserTask.setAssignee("${assigneeName}");
|
||||||
|
|
||||||
|
switch (nodeMode) {
|
||||||
|
case AND:
|
||||||
|
loopCharacteristics.setSequential(false);
|
||||||
|
loopCharacteristics.setCompletionCondition(AND_SIGN_EXPRESSION);
|
||||||
|
break;
|
||||||
|
case OR:
|
||||||
|
loopCharacteristics.setSequential(false);
|
||||||
|
loopCharacteristics.setCompletionCondition(OR_SIGN_EXPRESSION_ONLY_ONE);
|
||||||
|
break;
|
||||||
|
case SEQUENCE:
|
||||||
|
loopCharacteristics.setSequential(true);
|
||||||
|
loopCharacteristics.setCompletionCondition(AND_SIGN_EXPRESSION);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new WorkflowEngineException(CREATE_BPMN_USER_TASK_ERROR, nodeMode.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
setTaskListeners(newUserTask);
|
||||||
|
setExecutionListeners(new BpmnJsonNode(), newUserTask);
|
||||||
|
|
||||||
|
ExtensionElement approvalMethodElement = new ExtensionElement();
|
||||||
|
approvalMethodElement.setName(CONFIG_APPROVAL_METHOD);
|
||||||
|
|
||||||
|
ExtensionAttribute approvalMethodValueAttribute = new ExtensionAttribute();
|
||||||
|
approvalMethodValueAttribute.setName(ELEMENT_ATTRIBUTE_VALUE);
|
||||||
|
approvalMethodValueAttribute.setValue(ApprovalMethodEnum.human.getType());
|
||||||
|
approvalMethodElement.addAttribute(approvalMethodValueAttribute);
|
||||||
|
|
||||||
|
ExtensionAttribute approvalMethodDescAttribute = new ExtensionAttribute();
|
||||||
|
approvalMethodDescAttribute.setName(ELEMENT_ATTRIBUTE_DESC);
|
||||||
|
approvalMethodDescAttribute.setValue("审批方式");
|
||||||
|
approvalMethodElement.addAttribute(approvalMethodDescAttribute);
|
||||||
|
newUserTask.addExtensionElement(approvalMethodElement);
|
||||||
|
|
||||||
|
ExtensionElement approverSpecifyElement = new ExtensionElement();
|
||||||
|
approverSpecifyElement.setName(CONFIG_APPROVER_SPECIFY);
|
||||||
|
ExtensionAttribute approverSpecifyValueAttribute = new ExtensionAttribute();
|
||||||
|
approverSpecifyValueAttribute.setName(ELEMENT_ATTRIBUTE_VALUE);
|
||||||
|
approverSpecifyValueAttribute.setValue(ApproverSpecifyEnum.fixedPerson.getType());
|
||||||
|
approverSpecifyElement.addAttribute(approverSpecifyValueAttribute);
|
||||||
|
ExtensionAttribute approverSpecifyDescAttribute = new ExtensionAttribute();
|
||||||
|
approverSpecifyDescAttribute.setName(ELEMENT_ATTRIBUTE_DESC);
|
||||||
|
approverSpecifyDescAttribute.setValue("审批人指定");
|
||||||
|
approverSpecifyElement.addAttribute(approverSpecifyDescAttribute);
|
||||||
|
approverSpecifyElement.setElementText(JSON.toJSONString(assigners));
|
||||||
|
newUserTask.addExtensionElement(approverSpecifyElement);
|
||||||
|
|
||||||
|
ExtensionElement nodeTypeElement = new ExtensionElement();
|
||||||
|
nodeTypeElement.setName(CONFIG_NODE_TYPE);
|
||||||
|
nodeTypeElement.setElementText(BpmnFlowNodeType.NODE_TASK.getType());
|
||||||
|
newUserTask.addExtensionElement(nodeTypeElement);
|
||||||
|
|
||||||
|
// TODO 追加设置审批人为空的配置,因为查找审批人模式是固定人员,会执行退场、离职校验,导致最终审批人可能为空
|
||||||
|
// 审批人为空时
|
||||||
|
ExtensionElement approverEmptyHandleTypeElement = new ExtensionElement();
|
||||||
|
approverEmptyHandleTypeElement.setName(CONFIG_APPROVER_EMPTY_HANDLE_TYPE);
|
||||||
|
ExtensionAttribute approverEmptyHandleTypeValueAttribute = new ExtensionAttribute();
|
||||||
|
approverEmptyHandleTypeValueAttribute.setName(ELEMENT_ATTRIBUTE_VALUE);
|
||||||
|
approverEmptyHandleTypeValueAttribute.setValue(ApproverEmptyHandleTypeEnum.autoPassed.getType());
|
||||||
|
approverEmptyHandleTypeElement.setElementText("[]");
|
||||||
|
approverEmptyHandleTypeElement.addAttribute(approverEmptyHandleTypeValueAttribute);
|
||||||
|
|
||||||
|
ExtensionAttribute approverEmptyHandleTypeDescAttribute = new ExtensionAttribute();
|
||||||
|
approverEmptyHandleTypeDescAttribute.setName(ELEMENT_ATTRIBUTE_DESC);
|
||||||
|
approverEmptyHandleTypeDescAttribute.setValue("审批人为空时");
|
||||||
|
approverEmptyHandleTypeElement.addAttribute(approverEmptyHandleTypeDescAttribute);
|
||||||
|
newUserTask.addExtensionElement(approverEmptyHandleTypeElement);
|
||||||
|
|
||||||
|
ActivityBehaviorFactory activityBehaviorFactory = processEngineConfiguration.getActivityBehaviorFactory();
|
||||||
|
UserTaskActivityBehavior userTaskActivityBehavior = activityBehaviorFactory.createUserTaskActivityBehavior(newUserTask);
|
||||||
|
// TODO 这里设置的 userTaskActivityBehavior 似乎是不对的。需要
|
||||||
|
ParallelMultiInstanceBehavior behavior = activityBehaviorFactory.createParallelMultiInstanceBehavior(newUserTask, userTaskActivityBehavior);
|
||||||
|
|
||||||
|
behavior.setCollectionVariable(INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO + newUserTask.getId());
|
||||||
|
behavior.setCollectionElementVariable("assigneeName");
|
||||||
|
behavior.setCompletionCondition(loopCharacteristics.getCompletionCondition());
|
||||||
|
newUserTask.setBehavior(behavior);
|
||||||
|
return newUserTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void rewireSequenceFlows(Process process, UserTask originalUserTask, UserTask newUserTask) {
|
||||||
|
// 1. 找到所有指向原始节点的输入流
|
||||||
|
List<SequenceFlow> incomingFlows = originalUserTask.getIncomingFlows();
|
||||||
|
if (incomingFlows.isEmpty()) {
|
||||||
|
throw new WorkflowEngineException(CREATE_BPMN_PRE_SIGN_ERROR, "节点 " + originalUserTask.getId() + " 没有输入流,无法进行前加签");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 将这些输入流的目标从 originalUserTask 修改为 newUserTask
|
||||||
|
for (SequenceFlow incomingFlow : incomingFlows) {
|
||||||
|
incomingFlow.setTargetRef(newUserTask.getId());
|
||||||
|
// 如果需要,也可以更新FlowElement中的引用,但通常改TargetRef即可
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 创建一个新的顺序流,从 newUserTask 指向 originalUserTask
|
||||||
|
SequenceFlow newSequenceFlow = new SequenceFlow();
|
||||||
|
newSequenceFlow.setId("pre_sign_dynamic" + UUID.fastUUID());
|
||||||
|
newSequenceFlow.setSourceRef(newUserTask.getId());
|
||||||
|
newSequenceFlow.setTargetRef(originalUserTask.getId());
|
||||||
|
process.addFlowElement(newSequenceFlow);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -78,6 +78,10 @@ import static org.flowable.task.api.Task.DEFAULT_PRIORITY;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class CustomTaskHelper {
|
public class CustomTaskHelper {
|
||||||
|
|
||||||
|
private CustomTaskHelper() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public static void addMultiTask(CommandContext commandContext, TaskEntity originTask,
|
public static void addMultiTask(CommandContext commandContext, TaskEntity originTask,
|
||||||
BpmnTaskDelegateAssigner newTaskAssignee) {
|
BpmnTaskDelegateAssigner newTaskAssignee) {
|
||||||
if (Objects.isNull(originTask)) {
|
if (Objects.isNull(originTask)) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user