【同步】BOOT 和 CLOUD 的功能

pull/150/MERGE
YunaiV 2025-07-30 19:06:21 +08:00
parent 3c5c3ddc87
commit 7d9de01556
9 changed files with 141 additions and 37 deletions

View File

@ -17,6 +17,7 @@ uv run --with simple-ddl-parser convertor.py dm8 > ../dm/ruoyi-vue-pro-dm8.sql
import argparse import argparse
import pathlib import pathlib
import re import re
import sys
import time import time
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from typing import Dict, Generator, Optional, Tuple, Union from typing import Dict, Generator, Optional, Tuple, Union
@ -293,8 +294,10 @@ class Convertor(ABC):
# 将parse失败的脚本打印出来 # 将parse失败的脚本打印出来
if error_scripts: if error_scripts:
print("!!! 以下内容无法正常解析", file=sys.stderr)
for script in error_scripts: for script in error_scripts:
print(script) # print to stderr
print(script, file=sys.stderr)
class PostgreSQLConvertor(Convertor): class PostgreSQLConvertor(Convertor):

View File

@ -29,6 +29,7 @@ import org.springframework.util.Assert;
import org.springframework.validation.BindException; import org.springframework.validation.BindException;
import org.springframework.validation.FieldError; import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError; import org.springframework.validation.ObjectError;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException; import org.springframework.web.bind.MissingServletRequestParameterException;
@ -101,6 +102,9 @@ public class GlobalExceptionHandler {
if (ex instanceof HttpRequestMethodNotSupportedException) { if (ex instanceof HttpRequestMethodNotSupportedException) {
return httpRequestMethodNotSupportedExceptionHandler((HttpRequestMethodNotSupportedException) ex); return httpRequestMethodNotSupportedExceptionHandler((HttpRequestMethodNotSupportedException) ex);
} }
if (ex instanceof HttpMediaTypeNotSupportedException) {
return httpMediaTypeNotSupportedExceptionHandler((HttpMediaTypeNotSupportedException) ex);
}
if (ex instanceof ServiceException) { if (ex instanceof ServiceException) {
return serviceExceptionHandler((ServiceException) ex); return serviceExceptionHandler((ServiceException) ex);
} }
@ -179,9 +183,11 @@ public class GlobalExceptionHandler {
if (ex.getCause() instanceof InvalidFormatException) { if (ex.getCause() instanceof InvalidFormatException) {
InvalidFormatException invalidFormatException = (InvalidFormatException) ex.getCause(); InvalidFormatException invalidFormatException = (InvalidFormatException) ex.getCause();
return CommonResult.error(BAD_REQUEST.getCode(), String.format("请求参数类型错误:%s", invalidFormatException.getValue())); return CommonResult.error(BAD_REQUEST.getCode(), String.format("请求参数类型错误:%s", invalidFormatException.getValue()));
}else {
return defaultExceptionHandler(ServletUtils.getRequest(), ex);
} }
if (StrUtil.startWith(ex.getMessage(), "Required request body is missing")) {
return CommonResult.error(BAD_REQUEST.getCode(), "请求参数类型错误: request body 缺失");
}
return defaultExceptionHandler(ServletUtils.getRequest(), ex);
} }
/** /**
@ -237,6 +243,17 @@ public class GlobalExceptionHandler {
return CommonResult.error(METHOD_NOT_ALLOWED.getCode(), String.format("请求方法不正确:%s", ex.getMessage())); return CommonResult.error(METHOD_NOT_ALLOWED.getCode(), String.format("请求方法不正确:%s", ex.getMessage()));
} }
/**
* SpringMVC Content-Type
*
* A Content-Type application/json Content-Type application/octet-stream
*/
@ExceptionHandler(HttpMediaTypeNotSupportedException.class)
public CommonResult<?> httpMediaTypeNotSupportedExceptionHandler(HttpMediaTypeNotSupportedException ex) {
log.warn("[httpMediaTypeNotSupportedExceptionHandler]", ex);
return CommonResult.error(BAD_REQUEST.getCode(), String.format("请求类型不正确:%s", ex.getMessage()));
}
/** /**
* Spring Security * Spring Security
* *
@ -395,7 +412,7 @@ public class GlobalExceptionHandler {
return CommonResult.error(NOT_IMPLEMENTED.getCode(), return CommonResult.error(NOT_IMPLEMENTED.getCode(),
"[AI 大模型 yudao-module-ai - 表结构未导入][参考 https://cloud.iocoder.cn/ai/build/ 开启]"); "[AI 大模型 yudao-module-ai - 表结构未导入][参考 https://cloud.iocoder.cn/ai/build/ 开启]");
} }
// 9. IOT 物联网 // 9. IoT 物联网
if (message.contains("iot_")) { if (message.contains("iot_")) {
log.error("[IoT 物联网 yudao-module-iot - 表结构未导入][参考 https://doc.iocoder.cn/iot/build/ 开启]"); log.error("[IoT 物联网 yudao-module-iot - 表结构未导入][参考 https://doc.iocoder.cn/iot/build/ 开启]");
return CommonResult.error(NOT_IMPLEMENTED.getCode(), return CommonResult.error(NOT_IMPLEMENTED.getCode(),

View File

@ -58,7 +58,6 @@ public interface ErrorCodeConstants {
ErrorCode TASK_SIGN_DELETE_NO_PARENT = new ErrorCode(1_009_005_012, "任务减签失败,被减签的任务必须是通过加签生成的任务"); ErrorCode TASK_SIGN_DELETE_NO_PARENT = new ErrorCode(1_009_005_012, "任务减签失败,被减签的任务必须是通过加签生成的任务");
ErrorCode TASK_TRANSFER_FAIL_USER_REPEAT = new ErrorCode(1_009_005_013, "任务转办失败,转办人和当前审批人为同一人"); ErrorCode TASK_TRANSFER_FAIL_USER_REPEAT = new ErrorCode(1_009_005_013, "任务转办失败,转办人和当前审批人为同一人");
ErrorCode TASK_TRANSFER_FAIL_USER_NOT_EXISTS = new ErrorCode(1_009_005_014, "任务转办失败,转办人不存在"); ErrorCode TASK_TRANSFER_FAIL_USER_NOT_EXISTS = new ErrorCode(1_009_005_014, "任务转办失败,转办人不存在");
ErrorCode TASK_CREATE_FAIL_NO_CANDIDATE_USER = new ErrorCode(1_009_006_003, "操作失败,原因:找不到任务的审批人!");
ErrorCode TASK_SIGNATURE_NOT_EXISTS = new ErrorCode(1_009_005_015, "签名不能为空!"); ErrorCode TASK_SIGNATURE_NOT_EXISTS = new ErrorCode(1_009_005_015, "签名不能为空!");
ErrorCode TASK_REASON_REQUIRE = new ErrorCode(1_009_005_016, "审批意见不能为空!"); ErrorCode TASK_REASON_REQUIRE = new ErrorCode(1_009_005_016, "审批意见不能为空!");

View File

@ -14,6 +14,7 @@ import lombok.Getter;
@AllArgsConstructor @AllArgsConstructor
public enum BpmTaskStatusEnum { public enum BpmTaskStatusEnum {
SKIP(-2, "跳过"),
NOT_START(-1, "未开始"), NOT_START(-1, "未开始"),
RUNNING(1, "审批中"), RUNNING(1, "审批中"),
APPROVE(2, "审批通过"), APPROVE(2, "审批通过"),

View File

@ -71,6 +71,9 @@ public class BpmSimpleModelNodeVO {
@Schema(description = "是否填写审批意见", example = "false") @Schema(description = "是否填写审批意见", example = "false")
private Boolean reasonRequire; private Boolean reasonRequire;
@Schema(description = "跳过表达式", example = "{true}")
private String skipExpression; // 用于审批节点
/** /**
* *
*/ */

View File

@ -800,9 +800,10 @@ public class BpmnModelUtils {
|| currentElement instanceof EndEvent || currentElement instanceof EndEvent
|| currentElement instanceof UserTask || currentElement instanceof UserTask
|| currentElement instanceof ServiceTask) { || currentElement instanceof ServiceTask) {
// 添加元素 // 添加节点
FlowNode flowNode = (FlowNode) currentElement; FlowNode flowNode = (FlowNode) currentElement;
resultElements.add(flowNode); resultElements.add(flowNode);
// 遍历子节点 // 遍历子节点
flowNode.getOutgoingFlows().forEach( flowNode.getOutgoingFlows().forEach(
nextElement -> simulateNextFlowElements(nextElement.getTargetFlowElement(), variables, resultElements, visitElements)); nextElement -> simulateNextFlowElements(nextElement.getTargetFlowElement(), variables, resultElements, visitElements));
@ -835,6 +836,31 @@ public class BpmnModelUtils {
} }
} }
/**
*
*
* @param flowNode
* @param variables
*/
public static boolean isSkipNode(FlowElement flowNode, Map<String, Object> variables) {
// 1. 检查节点是否有跳过表达式(支持多种任务节点类型)
String skipExpression = null;
if (flowNode instanceof UserTask) {
skipExpression = ((UserTask) flowNode).getSkipExpression();
} else if (flowNode instanceof ServiceTask) {
skipExpression = ((ServiceTask) flowNode).getSkipExpression();
} else if (flowNode instanceof ScriptTask) {
skipExpression = ((ScriptTask) flowNode).getSkipExpression();
}
if (StrUtil.isEmpty(skipExpression)) {
return false;
}
// 2. 计算跳过表达式的值
return evalConditionExpress(variables, skipExpression);
}
/** /**
* *
* *
@ -997,7 +1023,7 @@ public class BpmnModelUtils {
* @return * @return
*/ */
public static boolean evalConditionExpress(Map<String, Object> variables, String expression) { public static boolean evalConditionExpress(Map<String, Object> variables, String expression) {
if (expression == null) { if (StrUtil.isEmpty(expression)) {
return Boolean.FALSE; return Boolean.FALSE;
} }
// 如果 variables 为空,则创建一个的原因?可能 expression 的计算,不依赖于 variables // 如果 variables 为空,则创建一个的原因?可能 expression 的计算,不依赖于 variables

View File

@ -4,7 +4,6 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.*; import cn.hutool.core.util.*;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO.ConditionGroups; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO.ConditionGroups;
@ -17,13 +16,14 @@ import cn.iocoder.yudao.module.bpm.service.task.listener.BpmCallActivityListener
import cn.iocoder.yudao.module.bpm.service.task.listener.BpmUserTaskListener; import cn.iocoder.yudao.module.bpm.service.task.listener.BpmUserTaskListener;
import org.flowable.bpmn.BpmnAutoLayout; import org.flowable.bpmn.BpmnAutoLayout;
import org.flowable.bpmn.constants.BpmnXMLConstants; import org.flowable.bpmn.constants.BpmnXMLConstants;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.*; import org.flowable.bpmn.model.*;
import org.flowable.bpmn.model.Process;
import org.flowable.engine.delegate.ExecutionListener; import org.flowable.engine.delegate.ExecutionListener;
import org.flowable.engine.delegate.TaskListener; import org.flowable.engine.delegate.TaskListener;
import java.util.*; import java.util.*;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.*; import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.*;
import static cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils.*; import static cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils.*;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
@ -239,13 +239,13 @@ public class SimpleModelUtils {
// 3.1 分支有后续节点。即分支 1: A->B->C->D 的情况 // 3.1 分支有后续节点。即分支 1: A->B->C->D 的情况
if (isValidNode(conditionChildNode)) { if (isValidNode(conditionChildNode)) {
// 3.1.1 建立与后续的节点的连线。例如说,建立 A->B 的连线 // 3.1.1 建立与后续的节点的连线。例如说,建立 A->B 的连线
SequenceFlow sequenceFlow = ConditionNodeConvert.buildSequenceFlow(node.getId(), conditionChildNode.getId(), item); SequenceFlow sequenceFlow = ConditionNodeConvert.buildSequenceFlow(node.getId(), conditionChildNode.getId(), nodeType, item);
process.addFlowElement(sequenceFlow); process.addFlowElement(sequenceFlow);
// 3.1.2 递归调用后续节点连线。例如说,建立 B->C->D 的连线 // 3.1.2 递归调用后续节点连线。例如说,建立 B->C->D 的连线
traverseNodeToBuildSequenceFlow(process, conditionChildNode, branchEndNodeId); traverseNodeToBuildSequenceFlow(process, conditionChildNode, branchEndNodeId);
} else { } else {
// 3.2 分支没有后续节点。例如说,建立 A->D 的连线 // 3.2 分支没有后续节点。例如说,建立 A->D 的连线
SequenceFlow sequenceFlow = ConditionNodeConvert.buildSequenceFlow(node.getId(), branchEndNodeId, item); SequenceFlow sequenceFlow = ConditionNodeConvert.buildSequenceFlow(node.getId(), branchEndNodeId, nodeType, item);
process.addFlowElement(sequenceFlow); process.addFlowElement(sequenceFlow);
} }
} }
@ -464,6 +464,10 @@ public class SimpleModelUtils {
addReasonRequire(node.getReasonRequire(), userTask); addReasonRequire(node.getReasonRequire(), userTask);
// 节点类型 // 节点类型
addNodeType(node.getType(), userTask); addNodeType(node.getType(), userTask);
// 添加跳过表达式
if (StrUtil.isNotEmpty(node.getSkipExpression())) {
userTask.setSkipExpression(node.getSkipExpression());
}
return userTask; return userTask;
} }
@ -591,17 +595,23 @@ public class SimpleModelUtils {
private static class ParallelBranchNodeConvert implements NodeConvert { private static class ParallelBranchNodeConvert implements NodeConvert {
/**
* 使 true https://t.zsxq.com/m6GXh 反馈问题
*
* @see {@link ConditionNodeConvert#buildSequenceFlow}
*/
@Override @Override
public List<ParallelGateway> convertList(BpmSimpleModelNodeVO node) { public List<InclusiveGateway> convertList(BpmSimpleModelNodeVO node) {
ParallelGateway parallelGateway = new ParallelGateway();
parallelGateway.setId(node.getId()); InclusiveGateway inclusiveGateway = new InclusiveGateway();
inclusiveGateway.setId(node.getId());
// TODO @jasonsetName // TODO @jasonsetName
// 行聚合网关由程序创建,前端不需要传入 // 并网关 由程序创建,前端不需要传入
ParallelGateway joinParallelGateway = new ParallelGateway(); InclusiveGateway joinParallelGateway = new InclusiveGateway();
joinParallelGateway.setId(buildGatewayJoinId(node.getId())); joinParallelGateway.setId(buildGatewayJoinId(node.getId()));
// TODO @jasonsetName // TODO @jasonsetName
return CollUtil.newArrayList(parallelGateway, joinParallelGateway); return CollUtil.newArrayList(inclusiveGateway, joinParallelGateway);
} }
@Override @Override
@ -652,8 +662,14 @@ public class SimpleModelUtils {
} }
public static SequenceFlow buildSequenceFlow(String sourceId, String targetId, public static SequenceFlow buildSequenceFlow(String sourceId, String targetId,
BpmSimpleModelNodeVO node) { BpmSimpleModelNodeTypeEnum nodeType, BpmSimpleModelNodeVO node) {
String conditionExpression = buildConditionExpression(node.getConditionSetting()); String conditionExpression;
// 并行分支,使用包容网关实现,强制设置条件表达式为 true
if (BpmSimpleModelNodeTypeEnum.PARALLEL_BRANCH_NODE == nodeType) {
conditionExpression ="${true}";
} else {
conditionExpression = buildConditionExpression(node.getConditionSetting());
}
return buildBpmnSequenceFlow(sourceId, targetId, node.getId(), node.getName(), conditionExpression); return buildBpmnSequenceFlow(sourceId, targetId, node.getId(), node.getName(), conditionExpression);
} }
} }
@ -662,7 +678,6 @@ public class SimpleModelUtils {
* *
*/ */
public static String buildConditionExpression(BpmSimpleModelNodeVO.ConditionSetting conditionSetting) { public static String buildConditionExpression(BpmSimpleModelNodeVO.ConditionSetting conditionSetting) {
// 并行网关不需要设置条件
if (conditionSetting == null) { if (conditionSetting == null) {
return null; return null;
} }
@ -684,15 +699,18 @@ public class SimpleModelUtils {
if (conditionGroups == null || CollUtil.isEmpty(conditionGroups.getConditions())) { if (conditionGroups == null || CollUtil.isEmpty(conditionGroups.getConditions())) {
return null; return null;
} }
List<String> strConditionGroups = CollectionUtils.convertList(conditionGroups.getConditions(), item -> { List<String> strConditionGroups = convertList(conditionGroups.getConditions(), item -> {
if (CollUtil.isEmpty(item.getRules())) { if (CollUtil.isEmpty(item.getRules())) {
return ""; return "";
} }
// 构造规则表达式 // 构造规则表达式
List<String> list = CollectionUtils.convertList(item.getRules(), (rule) -> { List<String> list = convertList(item.getRules(), (rule) -> {
String rightSide = NumberUtil.isNumber(rule.getRightSide()) ? rule.getRightSide() String rightSide = NumberUtil.isNumber(rule.getRightSide()) ? rule.getRightSide()
: "\"" + rule.getRightSide() + "\""; // 如果非数值类型加引号 : "\"" + rule.getRightSide() + "\""; // 如果非数值类型加引号
return String.format(" %s %s var:convertByType(%s,%s)", rule.getLeftSide(), rule.getOpCode(), rule.getLeftSide(), rightSide); return String.format(" vars:getOrDefault(%s, null) %s var:convertByType(%s,%s) ",
rule.getLeftSide(), // 左侧:读取变量
rule.getOpCode(), // 中间:操作符,比较
rule.getLeftSide(), rightSide); // 右侧转换变量VariableConvertByTypeExpressionFunction
}); });
// 构造条件组的表达式 // 构造条件组的表达式
Boolean and = item.getAnd(); Boolean and = item.getAnd();
@ -954,7 +972,7 @@ public class SimpleModelUtils {
|| nodeType == BpmSimpleModelNodeTypeEnum.COPY_NODE || nodeType == BpmSimpleModelNodeTypeEnum.COPY_NODE
|| nodeType == BpmSimpleModelNodeTypeEnum.CHILD_PROCESS || nodeType == BpmSimpleModelNodeTypeEnum.CHILD_PROCESS
|| nodeType == BpmSimpleModelNodeTypeEnum.END_NODE) { || nodeType == BpmSimpleModelNodeTypeEnum.END_NODE) {
// 添加元素 // 添加此节点
resultNodes.add(currentNode); resultNodes.add(currentNode);
} }
@ -1000,6 +1018,16 @@ public class SimpleModelUtils {
simulateNextNode(currentNode.getChildNode(), variables, resultNodes); simulateNextNode(currentNode.getChildNode(), variables, resultNodes);
} }
/**
*
*/
public static boolean isSkipNode(BpmSimpleModelNodeVO currentNode, Map<String, Object> variables) {
if (StrUtil.isEmpty(currentNode.getSkipExpression())) {
return false;
}
return BpmnModelUtils.evalConditionExpress(variables, currentNode.getSkipExpression());
}
public static boolean evalConditionExpress(Map<String, Object> variables, BpmSimpleModelNodeVO.ConditionSetting conditionSetting) { public static boolean evalConditionExpress(Map<String, Object> variables, BpmSimpleModelNodeVO.ConditionSetting conditionSetting) {
return BpmnModelUtils.evalConditionExpress(variables, buildConditionExpression(conditionSetting)); return BpmnModelUtils.evalConditionExpress(variables, buildConditionExpression(conditionSetting));
} }

View File

@ -398,7 +398,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
? BpmSimpleModelNodeTypeEnum.START_USER_NODE.getType() ? BpmSimpleModelNodeTypeEnum.START_USER_NODE.getType()
: ObjUtil.defaultIfNull(parseNodeType(flowNode), // 目的:解决“办理节点”的识别 : ObjUtil.defaultIfNull(parseNodeType(flowNode), // 目的:解决“办理节点”的识别
BpmSimpleModelNodeTypeEnum.APPROVE_NODE.getType())) BpmSimpleModelNodeTypeEnum.APPROVE_NODE.getType()))
.setStatus(FlowableUtils.getTaskStatus(task)) .setStatus(getEndActivityNodeStatus(task))
.setCandidateStrategy(BpmnModelUtils.parseCandidateStrategy(flowNode)) .setCandidateStrategy(BpmnModelUtils.parseCandidateStrategy(flowNode))
.setStartTime(DateUtils.of(task.getCreateTime())).setEndTime(DateUtils.of(task.getEndTime())) .setStartTime(DateUtils.of(task.getCreateTime())).setEndTime(DateUtils.of(task.getEndTime()))
.setTasks(singletonList(BpmProcessInstanceConvert.INSTANCE.buildApprovalTaskInfo(task))); .setTasks(singletonList(BpmProcessInstanceConvert.INSTANCE.buildApprovalTaskInfo(task)));
@ -462,6 +462,18 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
return approvalNodes; return approvalNodes;
} }
/**
*
*/
private Integer getEndActivityNodeStatus(HistoricTaskInstance task) {
Integer status = FlowableUtils.getTaskStatus(task);
if (status != null) {
return status;
}
// 结束节点未获取到状态,为跳过状态。可见 bpmn 或者 simple 的 skipExpression
return BpmTaskStatusEnum.SKIP.getStatus();
}
/** /**
* *
*/ */
@ -565,10 +577,14 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
if (runActivityIds.contains(node.getId())) { if (runActivityIds.contains(node.getId())) {
return null; return null;
} }
Integer status = BpmTaskStatusEnum.NOT_START.getStatus();
// 如果节点被跳过。设置状态为跳过
if (SimpleModelUtils.isSkipNode(node, processVariables)) {
status = BpmTaskStatusEnum.SKIP.getStatus();
}
ActivityNode activityNode = new ActivityNode().setId(node.getId()).setName(node.getName()) ActivityNode activityNode = new ActivityNode().setId(node.getId()).setName(node.getName())
.setNodeType(node.getType()).setCandidateStrategy(node.getCandidateStrategy()) .setNodeType(node.getType()).setCandidateStrategy(node.getCandidateStrategy())
.setStatus(BpmTaskStatusEnum.NOT_START.getStatus()); .setStatus(status);
// 1. 开始节点/审批节点 // 1. 开始节点/审批节点
if (ObjectUtils.equalsAny(node.getType(), if (ObjectUtils.equalsAny(node.getType(),
@ -608,8 +624,13 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
if (runActivityIds.contains(node.getId())) { if (runActivityIds.contains(node.getId())) {
return null; return null;
} }
Integer status = BpmTaskStatusEnum.NOT_START.getStatus();
// 如果节点被跳过,状态设置为跳过
if(BpmnModelUtils.isSkipNode(node, processVariables)){
status = BpmTaskStatusEnum.SKIP.getStatus();
}
ActivityNode activityNode = new ActivityNode().setId(node.getId()) ActivityNode activityNode = new ActivityNode().setId(node.getId())
.setStatus(BpmTaskStatusEnum.NOT_START.getStatus()); .setStatus(status);
// 1. 开始节点 // 1. 开始节点
if (node instanceof StartEvent) { if (node instanceof StartEvent) {

View File

@ -947,7 +947,10 @@ public class BpmTaskServiceImpl implements BpmTaskService {
BpmCommentTypeEnum.DELEGATE_START.formatComment(currentUser.getNickname(), delegateUser.getNickname(), reqVO.getReason())); BpmCommentTypeEnum.DELEGATE_START.formatComment(currentUser.getNickname(), delegateUser.getNickname(), reqVO.getReason()));
// 3.1 设置任务所有人 (owner) 为原任务的处理人 (assignee) // 3.1 设置任务所有人 (owner) 为原任务的处理人 (assignee)
// 特殊如果已经被委派owner 非空),则不需要更新 ownerhttps://gitee.com/zhijiantianya/yudao-cloud/issues/ICJ153
if (StrUtil.isEmpty(task.getOwner())) {
taskService.setOwner(taskId, task.getAssignee()); taskService.setOwner(taskId, task.getAssignee());
}
// 3.2 执行委派,将任务委派给 delegateUser // 3.2 执行委派,将任务委派给 delegateUser
taskService.delegateTask(taskId, reqVO.getDelegateUserId().toString()); taskService.delegateTask(taskId, reqVO.getDelegateUserId().toString());
// 补充说明:委托不单独设置状态。如果需要,可通过 Task 的 DelegationState 字段,判断是否为 DelegationState.PENDING 委托中 // 补充说明:委托不单独设置状态。如果需要,可通过 Task 的 DelegationState 字段,判断是否为 DelegationState.PENDING 委托中
@ -973,7 +976,10 @@ public class BpmTaskServiceImpl implements BpmTaskService {
BpmCommentTypeEnum.TRANSFER.formatComment(currentUser.getNickname(), assigneeUser.getNickname(), reqVO.getReason())); BpmCommentTypeEnum.TRANSFER.formatComment(currentUser.getNickname(), assigneeUser.getNickname(), reqVO.getReason()));
// 3.1 设置任务所有人 (owner) 为原任务的处理人 (assignee) // 3.1 设置任务所有人 (owner) 为原任务的处理人 (assignee)
// 特殊如果已经被转派owner 非空),则不需要更新 ownerhttps://gitee.com/zhijiantianya/yudao-cloud/issues/ICJ153
if (StrUtil.isEmpty(task.getOwner())) {
taskService.setOwner(taskId, task.getAssignee()); taskService.setOwner(taskId, task.getAssignee());
}
// 3.2 执行转派(审批人),将任务转派给 assigneeUser // 3.2 执行转派(审批人),将任务转派给 assigneeUser
// 委托( delegate和转派transfer的差别就在这块的调用 // 委托( delegate和转派transfer的差别就在这块的调用
taskService.setAssignee(taskId, reqVO.getAssigneeUserId().toString()); taskService.setAssignee(taskId, reqVO.getAssigneeUserId().toString());