mirror of
http://git.pig4cloud.com/pig/pigx.git
synced 2026-11-14 06:09:03 +08:00
feat(flow): 新增驳回到发起人功能
- 在ModelUtil重构开始节点结构,添加root UserTask节点 - 新增RootTaskCreateListener处理驳回到发起人场景 - 新增RootTaskHandler解析发起人执行人 - 在ApproveServiceTask添加TO_START驳回处理逻辑 - 新增ProcessInstanceRecordVo包含驳回状态信息 - 在TaskService添加resubmitTask接口处理重新提交 - 在ProcessTaskController添加resubmitTask接口
This commit is contained in:
1 parent
0ad5864476
commit
16a7f9309f
10 files changed
+377
-8
No files matched your search
+10
@@ -50,6 +50,16 @@ public class ProcessInstanceConstant {
|
||||
*/
|
||||
public static final String USER_TASK_REFUSE_TYPE_TO_NODE = "TO_NODE";
|
||||
|
||||
/**
|
||||
* 拒绝处理策略:驳回到发起人 审批人拒绝后,流程跳转回发起人节点,发起人可重新编辑提交
|
||||
*/
|
||||
public static final String USER_TASK_REFUSE_TYPE_TO_START = "TO_START";
|
||||
|
||||
/**
|
||||
* 流程变量:驳回到发起人标识 用于标记流程实例是否处于驳回待重新提交状态
|
||||
*/
|
||||
public static final String REJECT_TO_STARTER_VAR = "rejectToStarter";
|
||||
|
||||
/**
|
||||
* 多人审批模式:会签 所有审批人都必须同意才能通过,任何一人拒绝则不通过
|
||||
*/
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package com.pig4cloud.pigx.flow.vo;
|
||||
|
||||
import com.pig4cloud.pigx.flow.entity.ProcessInstanceRecord;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 流程实例记录视图对象
|
||||
* <p>
|
||||
* 继承自ProcessInstanceRecord实体类,用于扩展查询返回的额外信息。
|
||||
* 包含流程实例的驳回状态等运行时信息。
|
||||
* </p>
|
||||
*
|
||||
* @author pigx
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class ProcessInstanceRecordVo extends ProcessInstanceRecord {
|
||||
|
||||
/**
|
||||
* 是否驳回到发起人状态
|
||||
* <p>
|
||||
* true表示流程已被驳回到发起人,等待发起人重新编辑提交;
|
||||
* false或null表示流程正常运行中
|
||||
* </p>
|
||||
*/
|
||||
private Boolean rejectToStarter;
|
||||
|
||||
/**
|
||||
* 重新提交的任务ID
|
||||
* <p>
|
||||
* 当rejectToStarter为true时,此字段保存发起人节点(root)的任务ID,
|
||||
* 用于前端调用重新提交接口
|
||||
* </p>
|
||||
*/
|
||||
private String resubmitTaskId;
|
||||
|
||||
}
|
||||
+19
@@ -159,4 +159,23 @@ public class ProcessTaskController {
|
||||
return taskService.back(taskParamDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新提交任务(驳回到发起人后)
|
||||
* <p>
|
||||
* 当流程被驳回到发起人后,发起人可使用此接口重新编辑表单并提交。
|
||||
* 与completeTask不同:
|
||||
* 1. 不需要填写审批意见
|
||||
* 2. 会自动清理驳回标识
|
||||
* 3. 提交后流程继续到下一个审批节点
|
||||
* </p>
|
||||
* @param taskParamDto 重新提交参数,包含:
|
||||
* - taskId: 发起人节点的任务ID
|
||||
* - formData: 更新后的表单数据
|
||||
* @return R 统一响应对象,操作成功返回提交结果
|
||||
*/
|
||||
@PostMapping("resubmitTask")
|
||||
public R resubmitTask(@RequestBody TaskParamDto taskParamDto) {
|
||||
return taskService.resubmitTask(taskParamDto);
|
||||
}
|
||||
|
||||
}
|
||||
+14
@@ -106,4 +106,18 @@ public interface ITaskService {
|
||||
*/
|
||||
R queryTaskData();
|
||||
|
||||
/**
|
||||
* 重新提交任务(驳回到发起人后)
|
||||
* <p>
|
||||
* 当流程被驳回到发起人时,发起人使用此方法重新编辑表单并提交。
|
||||
* 与普通completeTask不同:
|
||||
* 1. 不需要填写审批意见
|
||||
* 2. 会清理 rejectToStarter 流程变量
|
||||
* 3. 完成后流程继续到下一个审批节点
|
||||
* </p>
|
||||
* @param taskParamDto 任务参数,包含taskId和更新后的formData
|
||||
* @return 操作结果
|
||||
*/
|
||||
R resubmitTask(TaskParamDto taskParamDto);
|
||||
|
||||
}
|
||||
+34
-1
@@ -29,6 +29,7 @@ import com.pig4cloud.pigx.flow.support.utils.NodeUtil;
|
||||
import com.pig4cloud.pigx.flow.vo.NodeFormatParamVo;
|
||||
import com.pig4cloud.pigx.flow.vo.NodeVo;
|
||||
import com.pig4cloud.pigx.flow.vo.ProcessCopyVo;
|
||||
import com.pig4cloud.pigx.flow.vo.ProcessInstanceRecordVo;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -364,7 +365,39 @@ public class ProcessInstanceServiceImpl implements IProcessInstanceService {
|
||||
|
||||
Page<ProcessInstanceRecord> instanceRecordPage = processInstanceRecordService.lambdaQuery().eq(ProcessInstanceRecord::getUserId, userId).eq(ProcessInstanceRecord::getStatus, taskQueryParamDto.getStatus()).between(ArrayUtil.isNotEmpty(taskQueryParamDto.getTaskTime()), ProcessInstanceRecord::getCreateTime, ArrayUtil.isNotEmpty(taskQueryParamDto.getTaskTime()) ? taskQueryParamDto.getTaskTime()[0] : null, ArrayUtil.isNotEmpty(taskQueryParamDto.getTaskTime()) ? taskQueryParamDto.getTaskTime()[1] : null).orderByDesc(ProcessInstanceRecord::getCreateTime).page(new Page<>(taskQueryParamDto.getCurrent(), taskQueryParamDto.getSize()));
|
||||
|
||||
return R.ok(instanceRecordPage);
|
||||
// 转换为 VO 并添加驳回状态信息
|
||||
List<ProcessInstanceRecordVo> voList = BeanUtil.copyToList(instanceRecordPage.getRecords(), ProcessInstanceRecordVo.class);
|
||||
|
||||
for (ProcessInstanceRecordVo vo : voList) {
|
||||
try {
|
||||
// 从 Flowable 变量中获取 rejectToStarter 状态
|
||||
Object rejectVar = runtimeService.getVariable(
|
||||
vo.getProcessInstanceId(),
|
||||
"rejectToStarter"
|
||||
);
|
||||
vo.setRejectToStarter(Boolean.TRUE.equals(rejectVar));
|
||||
|
||||
// 如果是驳回状态,获取 root 任务 ID 用于重新提交
|
||||
if (Boolean.TRUE.equals(vo.getRejectToStarter())) {
|
||||
Task task = taskService.createTaskQuery()
|
||||
.processInstanceId(vo.getProcessInstanceId())
|
||||
.taskDefinitionKey("root")
|
||||
.singleResult();
|
||||
if (task != null) {
|
||||
vo.setResubmitTaskId(task.getId());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 流程可能已结束,设置为 false
|
||||
vo.setRejectToStarter(false);
|
||||
}
|
||||
}
|
||||
|
||||
// 构建返回的分页对象
|
||||
Page<ProcessInstanceRecordVo> resultPage = new Page<>(instanceRecordPage.getCurrent(), instanceRecordPage.getSize(), instanceRecordPage.getTotal());
|
||||
resultPage.setRecords(voList);
|
||||
|
||||
return R.ok(resultPage);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+74
@@ -10,6 +10,7 @@ import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder;
|
||||
import com.pig4cloud.pigx.common.security.util.SecurityUtils;
|
||||
import com.pig4cloud.pigx.flow.constant.NodeStatusEnum;
|
||||
import com.pig4cloud.pigx.flow.constant.ProcessInstanceConstant;
|
||||
import com.pig4cloud.pigx.flow.dto.IndexPageStatistics;
|
||||
import com.pig4cloud.pigx.flow.dto.Node;
|
||||
import com.pig4cloud.pigx.flow.dto.TaskParamDto;
|
||||
@@ -483,6 +484,79 @@ public class TaskServiceImpl implements ITaskService {
|
||||
return flowableEngineService.back(taskParamDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新提交任务(驳回到发起人后)
|
||||
* <p>
|
||||
* 当流程被驳回到发起人时,发起人使用此方法重新编辑表单并提交。
|
||||
* 该方法会:
|
||||
* 1. 验证任务存在且属于当前用户
|
||||
* 2. 验证任务是 root 节点任务
|
||||
* 3. 更新表单数据
|
||||
* 4. 清理 rejectToStarter 流程变量
|
||||
* 5. 完成任务,流程继续到下一个审批节点
|
||||
* </p>
|
||||
*
|
||||
* @param taskParamDto 任务参数,包含taskId和更新后的formData
|
||||
* @return R 操作结果
|
||||
*/
|
||||
@Override
|
||||
@SneakyThrows
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R resubmitTask(TaskParamDto taskParamDto) {
|
||||
long userId = SecurityUtils.getUser().getId();
|
||||
|
||||
// 1. 获取任务并验证
|
||||
Task task = taskService.createTaskQuery()
|
||||
.taskId(taskParamDto.getTaskId())
|
||||
.taskTenantId(TenantContextHolder.getTenantId().toString())
|
||||
.taskAssignee(String.valueOf(userId))
|
||||
.singleResult();
|
||||
|
||||
if (task == null) {
|
||||
return R.failed("任务不存在或无权限操作");
|
||||
}
|
||||
|
||||
// 2. 验证是 root 任务(发起人节点)
|
||||
if (!StrUtil.equals(task.getTaskDefinitionKey(), "root")) {
|
||||
return R.failed("非重新提交任务,无法操作");
|
||||
}
|
||||
|
||||
String processInstanceId = task.getProcessInstanceId();
|
||||
|
||||
// 3. 更新表单数据
|
||||
if (CollUtil.isNotEmpty(taskParamDto.getFormData())) {
|
||||
runtimeService.setVariables(task.getExecutionId(), taskParamDto.getFormData());
|
||||
|
||||
// 同步更新到 ProcessInstanceRecord
|
||||
ProcessInstanceRecord processInstanceRecord = processInstanceRecordService.lambdaQuery()
|
||||
.eq(ProcessInstanceRecord::getProcessInstanceId, processInstanceId)
|
||||
.one();
|
||||
|
||||
if (processInstanceRecord != null) {
|
||||
Map<String, Object> existingFormData = new HashMap<>();
|
||||
if (StrUtil.isNotBlank(processInstanceRecord.getFormData())) {
|
||||
existingFormData = objectMapper.readValue(processInstanceRecord.getFormData(),
|
||||
new TypeReference<Map<String, Object>>() {});
|
||||
}
|
||||
existingFormData.putAll(taskParamDto.getFormData());
|
||||
String updatedFormData = objectMapper.writeValueAsString(existingFormData);
|
||||
|
||||
processInstanceRecordService.lambdaUpdate()
|
||||
.set(ProcessInstanceRecord::getFormData, updatedFormData)
|
||||
.eq(ProcessInstanceRecord::getProcessInstanceId, processInstanceId)
|
||||
.update();
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 清理 rejectToStarter 变量
|
||||
runtimeService.removeVariable(processInstanceId, "rejectToStarter");
|
||||
|
||||
// 5. 完成任务,流程继续
|
||||
taskService.complete(taskParamDto.getTaskId());
|
||||
|
||||
return R.ok("重新提交成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归获取所有需要停止的子流程实例ID列表
|
||||
* <p>
|
||||
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
package com.pig4cloud.pigx.flow.support.listeners;
|
||||
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.engine.RuntimeService;
|
||||
import org.flowable.engine.TaskService;
|
||||
import org.flowable.task.service.delegate.DelegateTask;
|
||||
import org.flowable.task.service.delegate.TaskListener;
|
||||
|
||||
/**
|
||||
* 发起人任务创建监听器
|
||||
* <p>
|
||||
* 用于处理发起人节点(root节点)的任务创建事件。
|
||||
* 该监听器的核心职责是区分"正常发起流程"和"驳回到发起人"两种场景:
|
||||
* <ul>
|
||||
* <li>正常发起流程:自动完成root任务,让流程继续到第一个审批节点</li>
|
||||
* <li>驳回到发起人:保留任务,让发起人可以在待办任务中看到并处理</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
* <p>
|
||||
* 判断逻辑:
|
||||
* 通过检查流程变量 rejectToStarter 是否为 true 来判断是否是驳回场景。
|
||||
* 该变量在 ApproveServiceTask 处理驳回到发起人时设置。
|
||||
* </p>
|
||||
*
|
||||
* @author pigx
|
||||
* @see com.pig4cloud.pigx.flow.support.tasks.ApproveServiceTask
|
||||
*/
|
||||
@Slf4j
|
||||
public class RootTaskCreateListener implements TaskListener {
|
||||
|
||||
/**
|
||||
* 任务创建事件处理方法
|
||||
* <p>
|
||||
* 当root任务被创建时触发。根据是否是驳回场景决定是否自动完成任务。
|
||||
* </p>
|
||||
*
|
||||
* @param delegateTask 委派的任务对象
|
||||
*/
|
||||
@Override
|
||||
public void notify(DelegateTask delegateTask) {
|
||||
RuntimeService runtimeService = SpringUtil.getBean(RuntimeService.class);
|
||||
TaskService taskService = SpringUtil.getBean(TaskService.class);
|
||||
|
||||
String processInstanceId = delegateTask.getProcessInstanceId();
|
||||
String taskId = delegateTask.getId();
|
||||
String assignee = delegateTask.getAssignee();
|
||||
|
||||
log.debug("发起人任务创建 - 任务ID: {}, 执行人: {}, 流程实例ID: {}", taskId, assignee, processInstanceId);
|
||||
|
||||
// 检查是否是驳回场景
|
||||
Object rejectToStarter = runtimeService.getVariable(processInstanceId, "rejectToStarter");
|
||||
|
||||
if (!Boolean.TRUE.equals(rejectToStarter)) {
|
||||
// 非驳回场景:自动完成 root 任务,让流程继续到下一个节点
|
||||
log.debug("非驳回场景,自动完成发起人任务 - 任务ID: {}", taskId);
|
||||
taskService.complete(taskId);
|
||||
}
|
||||
else {
|
||||
// 驳回场景:保留任务给发起人处理
|
||||
// 发起人可以在待办任务列表中看到这个任务,并进行编辑重新提交
|
||||
log.info("驳回场景,保留任务给发起人 - 任务ID: {}, 执行人: {}", taskId, assignee);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
package com.pig4cloud.pigx.flow.support.node;
|
||||
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.pig4cloud.pigx.flow.constant.ProcessInstanceConstant;
|
||||
import com.pig4cloud.pigx.flow.dto.NodeUser;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 发起人任务处理器
|
||||
* <p>
|
||||
* 用于处理驳回到发起人场景下,发起人任务的执行人解析。
|
||||
* 该处理器作为Spring Bean注入,在BPMN模型中通过EL表达式调用。
|
||||
* </p>
|
||||
* <p>
|
||||
* 使用方式:
|
||||
* 在UserTask的assignee属性中配置:${rootTaskHandler.resolveAssignee(execution)}
|
||||
* </p>
|
||||
*
|
||||
* @author pigx
|
||||
*/
|
||||
@Component("rootTaskHandler")
|
||||
@Slf4j
|
||||
public class RootTaskHandler {
|
||||
|
||||
/**
|
||||
* 解析发起人作为任务执行人
|
||||
* <p>
|
||||
* 从流程变量中获取发起人信息(root变量),返回发起人的用户ID作为任务执行人。
|
||||
* 该方法在任务创建时由Flowable引擎通过EL表达式调用。
|
||||
* </p>
|
||||
*
|
||||
* @param execution 流程执行上下文,包含流程变量等信息
|
||||
* @return 发起人用户ID字符串,如果未找到则返回默认空执行人标识
|
||||
*/
|
||||
public String resolveAssignee(DelegateExecution execution) {
|
||||
// 从流程变量中获取发起人信息
|
||||
Object rootUserObj = execution.getVariable("root");
|
||||
if (rootUserObj == null) {
|
||||
log.warn("未找到发起人信息,流程实例ID: {}", execution.getProcessInstanceId());
|
||||
return ProcessInstanceConstant.DEFAULT_EMPTY_ASSIGN.toString();
|
||||
}
|
||||
|
||||
ObjectMapper objectMapper = SpringUtil.getBean(ObjectMapper.class);
|
||||
try {
|
||||
// 发起人信息存储为List<NodeUser>格式
|
||||
List<NodeUser> nodeUsers = objectMapper.readValue(objectMapper.writeValueAsString(rootUserObj),
|
||||
new TypeReference<List<NodeUser>>() {
|
||||
});
|
||||
if (!nodeUsers.isEmpty()) {
|
||||
Long userId = nodeUsers.get(0).getId();
|
||||
log.debug("解析发起人成功,用户ID: {}", userId);
|
||||
return userId.toString();
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("解析发起人信息失败,流程实例ID: {}", execution.getProcessInstanceId(), e);
|
||||
}
|
||||
return ProcessInstanceConstant.DEFAULT_EMPTY_ASSIGN.toString();
|
||||
}
|
||||
|
||||
}
|
||||
+5
@@ -105,6 +105,11 @@ public class ApproveServiceTask implements JavaDelegate {
|
||||
// 根据拒绝设置重定向到特定节点
|
||||
stateChangeBuilder.moveActivityIdTo(currentActivityId, refuseConfig.getNodeId()).changeState();
|
||||
}
|
||||
else if (StrUtil.equals(rejectionHandler, "TO_START")) {
|
||||
// 驳回到发起人:设置驳回标识变量,跳转到 root 节点
|
||||
runtimeService.setVariable(processInstanceId, "rejectToStarter", true);
|
||||
stateChangeBuilder.moveActivityIdTo(currentActivityId, "root").changeState();
|
||||
}
|
||||
else {
|
||||
// 默认行为:重定向到结束节点
|
||||
stateChangeBuilder.moveActivityIdTo(currentActivityId, "end").changeState();
|
||||
|
||||
+50
-7
@@ -13,6 +13,7 @@ import com.pig4cloud.pigx.flow.service.IProcessNodeDataService;
|
||||
import com.pig4cloud.pigx.flow.support.expression.condition.NodeExpressionStrategyFactory;
|
||||
import com.pig4cloud.pigx.flow.support.listeners.ApprovalCreateListener;
|
||||
import com.pig4cloud.pigx.flow.support.listeners.FlowProcessEventListener;
|
||||
import com.pig4cloud.pigx.flow.support.listeners.RootTaskCreateListener;
|
||||
import com.pig4cloud.pigx.flow.support.tasks.ApproveServiceTask;
|
||||
import com.pig4cloud.pigx.flow.support.tasks.CopyServiceTask;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -352,22 +353,53 @@ public class ModelUtil {
|
||||
/**
|
||||
* 构建开始节点
|
||||
* <p>
|
||||
* 创建BPMN流程的开始事件节点。
|
||||
* 每个流程必须有且只有一个开始节点。
|
||||
* 创建BPMN流程的开始事件节点和发起人任务节点。
|
||||
* 流程结构:StartEvent(start) → UserTask(root) → 第一个审批节点
|
||||
* </p>
|
||||
* <p>
|
||||
* 发起人任务节点的作用:
|
||||
* <ul>
|
||||
* <li>正常发起流程时,通过RootTaskCreateListener自动完成,流程继续到下一个节点</li>
|
||||
* <li>驳回到发起人时,任务保留给发起人,发起人可以在待办任务中编辑并重新提交</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*
|
||||
* @param node 前端传输的开始节点数据
|
||||
* @return 包含开始事件的流程元素列表
|
||||
* @return 包含开始事件和发起人任务的流程元素列表
|
||||
*/
|
||||
private static List<FlowElement> buildStartNode(Node node) {
|
||||
|
||||
List<FlowElement> flowElementList = new ArrayList<>();
|
||||
|
||||
// 1. 创建真正的开始事件(ID 为 start)
|
||||
StartEvent startEvent = new StartEvent();
|
||||
startEvent.setId(node.getId());
|
||||
startEvent.setName(node.getName());
|
||||
|
||||
startEvent.setId("start");
|
||||
startEvent.setName("开始");
|
||||
flowElementList.add(startEvent);
|
||||
|
||||
// 2. 创建发起人任务节点(ID 保持为 root)
|
||||
// 配置任务监听器,用于处理驳回场景
|
||||
FlowableListener createListener = new FlowableListener();
|
||||
createListener.setImplementation(RootTaskCreateListener.class.getCanonicalName());
|
||||
createListener.setImplementationType("class");
|
||||
createListener.setEvent("create");
|
||||
|
||||
UserTask rootTask = new UserTask();
|
||||
rootTask.setId(node.getId()); // 保持 "root" 作为 ID
|
||||
rootTask.setName(node.getName());
|
||||
// 动态获取发起人作为执行人
|
||||
rootTask.setAssignee("${rootTaskHandler.resolveAssignee(execution)}");
|
||||
|
||||
List<FlowableListener> taskListeners = new ArrayList<>();
|
||||
taskListeners.add(createListener);
|
||||
rootTask.setTaskListeners(taskListeners);
|
||||
|
||||
flowElementList.add(rootTask);
|
||||
|
||||
// 3. 更新节点的 head/tail 信息
|
||||
node.setHeadId("start"); // 头部是 StartEvent
|
||||
node.setTailId(node.getId()); // 尾部是 root UserTask
|
||||
|
||||
return flowElementList;
|
||||
}
|
||||
|
||||
@@ -655,7 +687,11 @@ public class ModelUtil {
|
||||
/**
|
||||
* 创建节点内部连接线
|
||||
* <p>
|
||||
* 创建节点内部的连接线,例如审批节点与其后续服务任务之间的连接。
|
||||
* 创建节点内部的连接线,例如:
|
||||
* <ul>
|
||||
* <li>开始节点:start → root(StartEvent到发起人UserTask)</li>
|
||||
* <li>审批节点:审批任务 → 服务任务</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param node 节点数据
|
||||
* @param flowId 流程定义ID
|
||||
@@ -673,6 +709,13 @@ public class ModelUtil {
|
||||
return sequenceFlowList;
|
||||
}
|
||||
|
||||
// 开始节点:创建 start → root 的连线
|
||||
if (node.getType() == NodeTypeEnum.ROOT.getValue().intValue()) {
|
||||
SequenceFlow sequenceFlow = buildSingleSequenceFlow("start", nodeId, null, "start->root");
|
||||
sequenceFlowList.add(sequenceFlow);
|
||||
}
|
||||
|
||||
// 审批节点:创建审批任务到服务任务的连线
|
||||
if (node.getType() == NodeTypeEnum.APPROVAL.getValue().intValue()) {
|
||||
|
||||
String gatewayId = StrUtil.format("approve_service_task_{}", nodeId);
|
||||
|
||||
Reference in new issue
Block a user