Commit cdbcd4d673d491ad5203b8cdb05b00919deda6c9

Authored by YunaiV
1 parent dda09098

BPM:重构审批人的分配规则实现,移除 bpm_task_assign_rule 表,存储在 bpmn 的 userTask 中

Showing 19 changed files with 110 additions and 624 deletions
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/number/NumberUtils.java
... ... @@ -16,6 +16,10 @@ public class NumberUtils {
16 16 return StrUtil.isNotEmpty(str) ? Long.valueOf(str) : null;
17 17 }
18 18  
  19 + public static Integer parseInt(String str) {
  20 + return StrUtil.isNotEmpty(str) ? Integer.valueOf(str) : null;
  21 + }
  22 +
19 23 /**
20 24 * 通过经纬度获取地球上两点之间的距离
21 25 *
... ...
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/string/StrUtils.java
... ... @@ -6,6 +6,7 @@ import cn.hutool.core.util.StrUtil;
6 6 import java.util.Arrays;
7 7 import java.util.Collection;
8 8 import java.util.List;
  9 +import java.util.Set;
9 10 import java.util.stream.Collectors;
10 11  
11 12 /**
... ... @@ -45,6 +46,11 @@ public class StrUtils {
45 46 return Arrays.stream(longs).boxed().collect(Collectors.toList());
46 47 }
47 48  
  49 + public static Set<Long> splitToLongSet(String value, CharSequence separator) {
  50 + long[] longs = StrUtil.splitToLong(value, separator);
  51 + return Arrays.stream(longs).boxed().collect(Collectors.toSet());
  52 + }
  53 +
48 54 public static List<Integer> splitToInteger(String value, CharSequence separator) {
49 55 int[] integers = StrUtil.splitToInt(value, separator);
50 56 return Arrays.stream(integers).boxed().collect(Collectors.toList());
... ...
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java
... ... @@ -27,7 +27,7 @@ public interface ErrorCodeConstants {
27 27 ErrorCode MODEL_KEY_VALID = new ErrorCode(1_009_002_002, "流程标识格式不正确,需要以字母或下划线开头,后接任意字母、数字、中划线、下划线、句点!");
28 28 ErrorCode MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG = new ErrorCode(1_009_002_003, "部署流程失败,原因:流程表单未配置,请点击【修改流程】按钮进行配置");
29 29 ErrorCode MODEL_DEPLOY_FAIL_TASK_ASSIGN_RULE_NOT_CONFIG = new ErrorCode(1_009_002_004, "部署流程失败," +
30   - "原因:用户任务({})未配置分配规则,请点击【修改流程】按钮进行配置");
  30 + "原因:用户任务({})未配置审批人,请点击【流程设计】按钮,选择该它的【任务(审批人)】进行配置");
31 31 ErrorCode MODEL_DEPLOY_FAIL_TASK_INFO_EQUALS = new ErrorCode(1_009_003_005, "流程定义部署失败,原因:信息未发生变化");
32 32  
33 33 // ========== 流程定义 1-009-003-000 ==========
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/candidate/vo/BpmTaskCandidateRuleVO.java
1 1 package cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo;
2 2  
3   -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleBaseVO;
4 3 import io.swagger.v3.oas.annotations.media.Schema;
5 4 import jakarta.validation.constraints.NotNull;
6 5 import lombok.Data;
... ... @@ -10,8 +9,6 @@ import java.util.Set;
10 9 /**
11 10 * 流程任务分配规则 Base VO,提供给添加、修改、详细的子 VO 使用
12 11 * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
13   - *
14   - * @see BpmTaskAssignRuleBaseVO
15 12 */
16 13 @Data
17 14 public class BpmTaskCandidateRuleVO {
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java deleted
1   -package cn.iocoder.yudao.module.bpm.controller.admin.definition;
2   -
3   -import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4   -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO;
5   -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO;
6   -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;
7   -import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService;
8   -import io.swagger.v3.oas.annotations.tags.Tag;
9   -import io.swagger.v3.oas.annotations.Parameter;
10   -import io.swagger.v3.oas.annotations.Parameters;
11   -import io.swagger.v3.oas.annotations.Operation;
12   -import org.springframework.security.access.prepost.PreAuthorize;
13   -import org.springframework.validation.annotation.Validated;
14   -import org.springframework.web.bind.annotation.*;
15   -
16   -import jakarta.annotation.Resource;
17   -import jakarta.validation.Valid;
18   -import java.util.List;
19   -
20   -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
21   -
22   -@Tag(name = "管理后台 - 任务分配规则")
23   -@RestController
24   -@RequestMapping("/bpm/task-assign-rule")
25   -@Validated
26   -public class BpmTaskAssignRuleController {
27   -
28   - @Resource
29   - private BpmTaskAssignRuleService taskAssignRuleService;
30   -
31   - @GetMapping("/list")
32   - @Operation(summary = "获得任务分配规则列表")
33   - @Parameters({
34   - @Parameter(name = "modelId", description = "模型编号", example = "1024"),
35   - @Parameter(name = "processDefinitionId", description = "流程定义的编号", example = "2048")
36   - })
37   - @PreAuthorize("@ss.hasPermission('bpm:task-assign-rule:query')")
38   - public CommonResult<List<BpmTaskAssignRuleRespVO>> getTaskAssignRuleList(
39   - @RequestParam(value = "modelId", required = false) String modelId,
40   - @RequestParam(value = "processDefinitionId", required = false) String processDefinitionId) {
41   - return success(taskAssignRuleService.getTaskAssignRuleList(modelId, processDefinitionId));
42   - }
43   -
44   - @PostMapping("/create")
45   - @Operation(summary = "创建任务分配规则")
46   - @PreAuthorize("@ss.hasPermission('bpm:task-assign-rule:create')")
47   - public CommonResult<Long> createTaskAssignRule(@Valid @RequestBody BpmTaskAssignRuleCreateReqVO reqVO) {
48   - return success(taskAssignRuleService.createTaskAssignRule(reqVO));
49   - }
50   -
51   - @PutMapping("/update")
52   - @Operation(summary = "更新任务分配规则")
53   - @PreAuthorize("@ss.hasPermission('bpm:task-assign-rule:update')")
54   - public CommonResult<Boolean> updateTaskAssignRule(@Valid @RequestBody BpmTaskAssignRuleUpdateReqVO reqVO) {
55   - taskAssignRuleService.updateTaskAssignRule(reqVO);
56   - return success(true);
57   - }
58   -}
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleBaseVO.java deleted
1   -package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule;
2   -
3   -import io.swagger.v3.oas.annotations.media.Schema;
4   -import lombok.Data;
5   -
6   -import jakarta.validation.constraints.NotNull;
7   -import java.util.Set;
8   -
9   -/**
10   - * 流程任务分配规则 Base VO,提供给添加、修改、详细的子 VO 使用
11   - * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
12   - */
13   -@Data
14   -public class BpmTaskAssignRuleBaseVO {
15   -
16   - @Schema(description = "规则类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "bpm_task_assign_rule_type")
17   - @NotNull(message = "规则类型不能为空")
18   - private Integer type;
19   -
20   - @Schema(description = "规则值数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "1,2,3")
21   - @NotNull(message = "规则值数组不能为空")
22   - private Set<Long> options;
23   -
24   -}
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleCreateReqVO.java deleted
1   -package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule;
2   -
3   -import io.swagger.v3.oas.annotations.media.Schema;
4   -import lombok.Data;
5   -import lombok.EqualsAndHashCode;
6   -import lombok.ToString;
7   -
8   -import jakarta.validation.constraints.NotEmpty;
9   -
10   -@Schema(description = "管理后台 - 流程任务分配规则的创建 Request VO")
11   -@Data
12   -@EqualsAndHashCode(callSuper = true)
13   -@ToString(callSuper = true)
14   -public class BpmTaskAssignRuleCreateReqVO extends BpmTaskAssignRuleBaseVO {
15   -
16   - @Schema(description = "流程模型的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
17   - @NotEmpty(message = "流程模型的编号不能为空")
18   - private String modelId;
19   -
20   - @Schema(description = "流程任务定义的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048")
21   - @NotEmpty(message = "流程任务定义的编号不能为空")
22   - private String taskDefinitionKey;
23   -
24   -}
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleRespVO.java deleted
1   -package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule;
2   -
3   -import io.swagger.v3.oas.annotations.media.Schema;
4   -import lombok.Data;
5   -import lombok.EqualsAndHashCode;
6   -import lombok.ToString;
7   -
8   -@Schema(description = "管理后台 - 流程任务分配规则的 Response VO")
9   -@Data
10   -@EqualsAndHashCode(callSuper = true)
11   -@ToString(callSuper = true)
12   -public class BpmTaskAssignRuleRespVO extends BpmTaskAssignRuleBaseVO {
13   -
14   - @Schema(description = "任务分配规则的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
15   - private Long id;
16   -
17   - @Schema(description = "流程模型的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048")
18   - private String modelId;
19   -
20   - @Schema(description = "流程定义的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "4096")
21   - private String processDefinitionId;
22   -
23   - @Schema(description = "流程任务定义的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048")
24   - private String taskDefinitionKey;
25   - @Schema(description = "流程任务定义的名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "关注芋道")
26   - private String taskDefinitionName;
27   -
28   -}
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleUpdateReqVO.java deleted
1   -package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule;
2   -
3   -import io.swagger.v3.oas.annotations.media.Schema;
4   -import lombok.Data;
5   -import lombok.EqualsAndHashCode;
6   -import lombok.ToString;
7   -
8   -import jakarta.validation.constraints.NotNull;
9   -
10   -@Schema(description = "管理后台 - 流程任务分配规则的更新 Request VO")
11   -@Data
12   -@EqualsAndHashCode(callSuper = true)
13   -@ToString(callSuper = true)
14   -public class BpmTaskAssignRuleUpdateReqVO extends BpmTaskAssignRuleBaseVO {
15   -
16   - @Schema(description = "任务分配规则的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
17   - @NotNull(message = "任务分配规则的编号不能为空")
18   - private Long id;
19   -
20   -}
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmTaskAssignRuleConvert.java deleted
1   -package cn.iocoder.yudao.module.bpm.convert.definition;
2   -
3   -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
4   -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO;
5   -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO;
6   -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;
7   -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
8   -import org.flowable.bpmn.model.UserTask;
9   -import org.mapstruct.Mapper;
10   -import org.mapstruct.factory.Mappers;
11   -
12   -import java.util.List;
13   -import java.util.Map;
14   -
15   -@Mapper
16   -public interface BpmTaskAssignRuleConvert {
17   - BpmTaskAssignRuleConvert INSTANCE = Mappers.getMapper(BpmTaskAssignRuleConvert.class);
18   -
19   - default List<BpmTaskAssignRuleRespVO> convertList(List<UserTask> tasks, List<BpmTaskAssignRuleDO> rules) {
20   - Map<String, BpmTaskAssignRuleDO> ruleMap = CollectionUtils.convertMap(rules, BpmTaskAssignRuleDO::getTaskDefinitionKey);
21   - // 以 UserTask 为主维度,原因是:流程图编辑后,一些规则实际就没用了。
22   - return CollectionUtils.convertList(tasks, task -> {
23   - BpmTaskAssignRuleRespVO respVO = convert(ruleMap.get(task.getId()));
24   - if (respVO == null) {
25   - respVO = new BpmTaskAssignRuleRespVO();
26   - respVO.setTaskDefinitionKey(task.getId());
27   - }
28   - respVO.setTaskDefinitionName(task.getName());
29   - return respVO;
30   - });
31   - }
32   -
33   - BpmTaskAssignRuleRespVO convert(BpmTaskAssignRuleDO bean);
34   -
35   - BpmTaskAssignRuleDO convert(BpmTaskAssignRuleCreateReqVO bean);
36   -
37   - BpmTaskAssignRuleDO convert(BpmTaskAssignRuleUpdateReqVO bean);
38   -
39   - List<BpmTaskAssignRuleDO> convertList2(List<BpmTaskAssignRuleRespVO> list);
40   -}
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmTaskAssignRuleDO.java deleted
1   -package cn.iocoder.yudao.module.bpm.dal.dataobject.definition;
2   -
3   -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4   -import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler;
5   -import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum;
6   -import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;
7   -import com.baomidou.mybatisplus.annotation.TableField;
8   -import com.baomidou.mybatisplus.annotation.TableId;
9   -import com.baomidou.mybatisplus.annotation.TableName;
10   -import lombok.*;
11   -
12   -import java.util.Set;
13   -
14   -/**
15   - * Bpm 任务分配的规则表,用于自定义配置每个任务的负责人、候选人的分配规则。
16   - * 也就是说,废弃 BPMN 原本的 UserTask 设置的 assignee、candidateUsers 等配置,而是通过使用该规则进行计算对应的负责人。
17   - *
18   - * 1. 默认情况下,{@link #processDefinitionId} 为 {@link #PROCESS_DEFINITION_ID_NULL} 值,表示贵改则与流程模型关联
19   - * 2. 在流程模型部署后,会将他的所有规则记录,复制出一份新部署出来的流程定义,通过设置 {@link #processDefinitionId} 为新的流程定义的编号进行关联
20   - *
21   - * @author 芋道源码
22   - */
23   -@TableName(value = "bpm_task_assign_rule", autoResultMap = true)
24   -@Data
25   -@EqualsAndHashCode(callSuper = true)
26   -@ToString(callSuper = true)
27   -@Builder
28   -@NoArgsConstructor
29   -@AllArgsConstructor
30   -public class BpmTaskAssignRuleDO extends BaseDO {
31   -
32   - /**
33   - * {@link #processDefinitionId} 空串,用于标识属于流程模型,而不属于流程定义
34   - */
35   - public static final String PROCESS_DEFINITION_ID_NULL = "";
36   -
37   - /**
38   - * 编号
39   - */
40   - @TableId
41   - private Long id;
42   -
43   - /**
44   - * 流程模型编号
45   - *
46   - * 关联 Model 的 id 属性
47   - */
48   - private String modelId;
49   - /**
50   - * 流程定义编号
51   - *
52   - * 关联 ProcessDefinition 的 id 属性
53   - */
54   - private String processDefinitionId;
55   - /**
56   - * 流程任务的定义 Key
57   - *
58   - * 关联 Task 的 taskDefinitionKey 属性
59   - */
60   - private String taskDefinitionKey;
61   -
62   - /**
63   - * 规则类型
64   - *
65   - * 枚举 {@link BpmTaskAssignRuleTypeEnum}
66   - */
67   - @TableField("`type`")
68   - private Integer type;
69   - /**
70   - * 规则值数组,一般关联指定表的编号
71   - * 根据 type 不同,对应的值是不同的:
72   - *
73   - * 1. {@link BpmTaskAssignRuleTypeEnum#ROLE} 时:角色编号
74   - * 2. {@link BpmTaskAssignRuleTypeEnum#DEPT_MEMBER} 时:部门编号
75   - * 3. {@link BpmTaskAssignRuleTypeEnum#DEPT_LEADER} 时:部门编号
76   - * 4. {@link BpmTaskAssignRuleTypeEnum#USER} 时:用户编号
77   - * 5. {@link BpmTaskAssignRuleTypeEnum#USER_GROUP} 时:用户组编号
78   - * 6. {@link BpmTaskAssignRuleTypeEnum#SCRIPT} 时:脚本编号,目前通过 {@link BpmTaskRuleScriptEnum#getId()} 标识
79   - */
80   - @TableField(typeHandler = JsonLongSetTypeHandler.class)
81   - private Set<Long> options;
82   -
83   -}
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmTaskAssignRuleMapper.java deleted
1   -package cn.iocoder.yudao.module.bpm.dal.mysql.definition;
2   -
3   -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
4   -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5   -import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
6   -import org.apache.ibatis.annotations.Mapper;
7   -import org.springframework.lang.Nullable;
8   -
9   -import java.util.List;
10   -
11   -@Mapper
12   -public interface BpmTaskAssignRuleMapper extends BaseMapperX<BpmTaskAssignRuleDO> {
13   -
14   - default List<BpmTaskAssignRuleDO> selectListByProcessDefinitionId(String processDefinitionId,
15   - @Nullable String taskDefinitionKey) {
16   - return selectList(new QueryWrapperX<BpmTaskAssignRuleDO>()
17   - .eq("process_definition_id", processDefinitionId)
18   - .eqIfPresent("task_definition_key", taskDefinitionKey));
19   - }
20   -
21   - default List<BpmTaskAssignRuleDO> selectListByModelId(String modelId) {
22   - return selectList(new QueryWrapperX<BpmTaskAssignRuleDO>()
23   - .eq("model_id", modelId)
24   - .eq("process_definition_id", BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL));
25   - }
26   -
27   - default BpmTaskAssignRuleDO selectListByModelIdAndTaskDefinitionKey(String modelId,
28   - String taskDefinitionKey) {
29   - return selectOne(new QueryWrapperX<BpmTaskAssignRuleDO>()
30   - .eq("model_id", modelId)
31   - .eq("process_definition_id", BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL)
32   - .eq("task_definition_key", taskDefinitionKey));
33   - }
34   -
35   -
36   -
37   -}
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java
1 1 package cn.iocoder.yudao.module.bpm.service.definition;
2 2  
3   -import cn.hutool.core.util.ArrayUtil;
4 3 import cn.hutool.core.util.StrUtil;
5 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 5 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
7 6 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
8 7 import cn.iocoder.yudao.framework.common.util.object.PageUtils;
9 8 import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
  9 +import cn.iocoder.yudao.framework.flowable.core.util.BpmnModelUtils;
10 10 import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
11 11 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*;
12 12 import cn.iocoder.yudao.module.bpm.convert.definition.BpmModelConvert;
... ... @@ -17,10 +17,8 @@ import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCr
17 17 import jakarta.annotation.Resource;
18 18 import jakarta.validation.Valid;
19 19 import lombok.extern.slf4j.Slf4j;
20   -import org.flowable.bpmn.converter.BpmnXMLConverter;
21 20 import org.flowable.bpmn.model.BpmnModel;
22 21 import org.flowable.common.engine.impl.db.SuspensionState;
23   -import org.flowable.common.engine.impl.util.io.BytesStreamSource;
24 22 import org.flowable.engine.RepositoryService;
25 23 import org.flowable.engine.repository.Deployment;
26 24 import org.flowable.engine.repository.Model;
... ... @@ -168,15 +166,13 @@ public class BpmModelServiceImpl implements BpmModelService {
168 166 // 1.3 校验表单已配
169 167 BpmFormDO form = checkFormConfig(model.getMetaInfo());
170 168 // 1.4 校验任务分配规则已配置
171   - taskAssignRuleService.checkTaskAssignRuleAllConfig(id);
  169 + taskAssignRuleService.checkTaskAssignRuleAllConfig(bpmnBytes);
172 170  
173 171 // 1.5 校验模型是否发生修改。如果未修改,则不允许创建
174   - BpmProcessDefinitionCreateReqDTO definitionCreateReqDTO = BpmModelConvert.INSTANCE.convert2(model, form).setBpmnBytes(bpmnBytes);
  172 + BpmProcessDefinitionCreateReqDTO definitionCreateReqDTO = BpmModelConvert.INSTANCE.convert2(model, form)
  173 + .setBpmnBytes(bpmnBytes);
175 174 if (processDefinitionService.isProcessDefinitionEquals(definitionCreateReqDTO)) { // 流程定义的信息相等
176   - ProcessDefinition oldProcessDefinition = processDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId());
177   - if (oldProcessDefinition != null && taskAssignRuleService.isTaskAssignRulesEquals(model.getId(), oldProcessDefinition.getId())) {
178   - throw exception(MODEL_DEPLOY_FAIL_TASK_INFO_EQUALS);
179   - }
  175 + throw exception(MODEL_DEPLOY_FAIL_TASK_INFO_EQUALS);
180 176 }
181 177  
182 178 // 2.1 创建流程定义
... ... @@ -189,12 +185,8 @@ public class BpmModelServiceImpl implements BpmModelService {
189 185 ProcessDefinition definition = processDefinitionService.getProcessDefinition(definitionId);
190 186 model.setDeploymentId(definition.getDeploymentId());
191 187 repositoryService.saveModel(model);
192   -
193   - // 2.4 复制任务分配规则
194   - taskAssignRuleService.copyTaskAssignRules(id, definition.getId());
195 188 }
196 189  
197   -
198 190 @Override
199 191 @Transactional(rollbackFor = Exception.class)
200 192 public void deleteModel(String id) {
... ... @@ -229,11 +221,7 @@ public class BpmModelServiceImpl implements BpmModelService {
229 221 @Override
230 222 public BpmnModel getBpmnModel(String id) {
231 223 byte[] bpmnBytes = repositoryService.getModelEditorSource(id);
232   - if (ArrayUtil.isEmpty(bpmnBytes)) {
233   - return null;
234   - }
235   - BpmnXMLConverter converter = new BpmnXMLConverter();
236   - return converter.convertToBpmnModel(new BytesStreamSource(bpmnBytes), true, true);
  224 + return BpmnModelUtils.getBpmnModel(bpmnBytes);
237 225 }
238 226  
239 227 @Override
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java
... ... @@ -23,7 +23,6 @@ import lombok.extern.slf4j.Slf4j;
23 23 import org.flowable.bpmn.converter.BpmnXMLConverter;
24 24 import org.flowable.bpmn.model.BpmnModel;
25 25 import org.flowable.common.engine.impl.db.SuspensionState;
26   -import org.flowable.common.engine.impl.util.io.BytesStreamSource;
27 26 import org.flowable.engine.RepositoryService;
28 27 import org.flowable.engine.repository.Deployment;
29 28 import org.flowable.engine.repository.ProcessDefinition;
... ... @@ -124,6 +123,7 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
124 123 .key(createReqDTO.getKey()).name(createReqDTO.getName()).category(createReqDTO.getCategory())
125 124 .addBytes(createReqDTO.getKey() + BpmnModelConstants.BPMN_FILE_SUFFIX, createReqDTO.getBpmnBytes())
126 125 .tenantId(TenantContextHolder.getTenantIdStr())
  126 + .disableSchemaValidation() // 禁用 XML Schema 验证,因为有自定义的属性
127 127 .deploy();
128 128  
129 129 // 设置 ProcessDefinition 的 category 分类
... ... @@ -197,7 +197,7 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
197 197 return false;
198 198 }
199 199 // 校验 BPMN XML 信息
200   - BpmnModel newModel = buildBpmnModel(createReqDTO.getBpmnBytes());
  200 + BpmnModel newModel = BpmnModelUtils.getBpmnModel(createReqDTO.getBpmnBytes());
201 201 BpmnModel oldModel = getBpmnModel(oldProcessDefinition.getId());
202 202 // 对比字节变化
203 203 if (!BpmnModelUtils.equals(oldModel, newModel)) {
... ... @@ -207,18 +207,6 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
207 207 return true;
208 208 }
209 209  
210   - /**
211   - * 构建对应的 BPMN Model
212   - *
213   - * @param bpmnBytes 原始的 BPMN XML 字节数组
214   - * @return BPMN Model
215   - */
216   - private BpmnModel buildBpmnModel(byte[] bpmnBytes) {
217   - // 转换成 BpmnModel 对象
218   - BpmnXMLConverter converter = new BpmnXMLConverter();
219   - return converter.convertToBpmnModel(new BytesStreamSource(bpmnBytes), true, true);
220   - }
221   -
222 210 @Override
223 211 public BpmProcessDefinitionExtDO getProcessDefinitionExt(String id) {
224 212 return processDefinitionMapper.selectByProcessDefinitionId(id);
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java
1 1 package cn.iocoder.yudao.module.bpm.service.definition;
2 2  
3   -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO;
4   -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO;
5   -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;
6   -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
7 3 import org.flowable.engine.delegate.DelegateExecution;
8   -import org.springframework.lang.Nullable;
9 4  
10   -import jakarta.validation.Valid;
11   -import java.util.List;
12 5 import java.util.Set;
13 6  
14 7 /**
... ... @@ -19,72 +12,12 @@ import java.util.Set;
19 12 public interface BpmTaskAssignRuleService {
20 13  
21 14 /**
22   - * 获得流程定义的任务分配规则数组
23   - *
24   - * @param processDefinitionId 流程定义的编号
25   - * @param taskDefinitionKey 流程任务定义的 Key。允许空
26   - * @return 任务规则数组
27   - */
28   - List<BpmTaskAssignRuleDO> getTaskAssignRuleListByProcessDefinitionId(String processDefinitionId,
29   - @Nullable String taskDefinitionKey);
30   -
31   - /**
32   - * 获得流程模型的任务规则数组
33   - *
34   - * @param modelId 流程模型的编号
35   - * @return 任务规则数组
36   - */
37   - List<BpmTaskAssignRuleDO> getTaskAssignRuleListByModelId(String modelId);
38   -
39   - /**
40   - * 获得流程定义的任务分配规则数组
41   - *
42   - * @param modelId 流程模型的编号
43   - * @param processDefinitionId 流程定义的编号
44   - * @return 任务规则数组
45   - */
46   - List<BpmTaskAssignRuleRespVO> getTaskAssignRuleList(String modelId, String processDefinitionId);
47   -
48   - /**
49   - * 创建任务分配规则
50   - *
51   - * @param reqVO 创建信息
52   - * @return 规则编号
53   - */
54   - Long createTaskAssignRule(@Valid BpmTaskAssignRuleCreateReqVO reqVO);
55   -
56   - /**
57   - * 更新任务分配规则
58   - *
59   - * @param reqVO 创建信息
60   - */
61   - void updateTaskAssignRule(@Valid BpmTaskAssignRuleUpdateReqVO reqVO);
62   -
63   - /**
64   - * 判断指定流程模型和流程定义的分配规则是否相等
65   - *
66   - * @param modelId 流程模型编号
67   - * @param processDefinitionId 流程定义编号
68   - * @return 是否相等
69   - */
70   - boolean isTaskAssignRulesEquals(String modelId, String processDefinitionId);
71   -
72   - /**
73   - * 将流程流程模型的任务分配规则,复制一份给流程定义
74   - * 目的:每次流程模型部署时,都会生成一个新的流程定义,此时考虑到每次部署的流程不可变性,所以需要复制一份给该流程定义
75   - *
76   - * @param fromModelId 流程模型编号
77   - * @param toProcessDefinitionId 流程定义编号
78   - */
79   - void copyTaskAssignRules(String fromModelId, String toProcessDefinitionId);
80   -
81   - /**
82 15 * 校验流程模型的任务分配规则全部都配置了
83 16 * 目的:如果有规则未配置,会导致流程任务找不到负责人,进而流程无法进行下去!
84 17 *
85   - * @param id 流程模型编号
  18 + * @param bpmnBytes BPMN XML
86 19 */
87   - void checkTaskAssignRuleAllConfig(String id);
  20 + void checkTaskAssignRuleAllConfig(byte[] bpmnBytes);
88 21  
89 22 /**
90 23 * 计算当前执行任务的处理人
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java
1 1 package cn.iocoder.yudao.module.bpm.service.definition;
2 2  
3 3 import cn.hutool.core.collection.CollUtil;
4   -import cn.hutool.core.util.ObjectUtil;
5 4 import cn.hutool.core.util.StrUtil;
6 5 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
7 6 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  7 +import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
8 8 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
  9 +import cn.iocoder.yudao.framework.common.util.string.StrUtils;
9 10 import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
  11 +import cn.iocoder.yudao.framework.flowable.core.enums.BpmnModelConstants;
10 12 import cn.iocoder.yudao.framework.flowable.core.util.BpmnModelUtils;
11   -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO;
12   -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO;
13   -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;
14   -import cn.iocoder.yudao.module.bpm.convert.definition.BpmTaskAssignRuleConvert;
15   -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
16 13 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO;
17   -import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmTaskAssignRuleMapper;
18 14 import cn.iocoder.yudao.module.bpm.enums.DictTypeConstants;
19 15 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum;
20 16 import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript;
... ... @@ -28,17 +24,16 @@ import cn.iocoder.yudao.module.system.api.permission.RoleApi;
28 24 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
29 25 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
30 26 import com.google.common.annotations.VisibleForTesting;
  27 +import jakarta.annotation.Resource;
31 28 import lombok.extern.slf4j.Slf4j;
32 29 import org.flowable.bpmn.model.BpmnModel;
  30 +import org.flowable.bpmn.model.FlowElement;
33 31 import org.flowable.bpmn.model.UserTask;
34   -import org.flowable.common.engine.api.FlowableException;
35 32 import org.flowable.engine.delegate.DelegateExecution;
36 33 import org.springframework.context.annotation.Lazy;
37 34 import org.springframework.stereotype.Service;
38 35 import org.springframework.validation.annotation.Validated;
39 36  
40   -import jakarta.annotation.Resource;
41   -import jakarta.validation.Valid;
42 37 import java.util.*;
43 38 import java.util.function.Function;
44 39  
... ... @@ -46,7 +41,6 @@ import static cn.hutool.core.text.CharSequenceUtil.format;
46 41 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
47 42 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
48 43 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
49   -import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
50 44 import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
51 45  
52 46 /**
... ... @@ -58,15 +52,11 @@ import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
58 52 public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService {
59 53  
60 54 @Resource
61   - private BpmTaskAssignRuleMapper taskRuleMapper;
62   - @Resource
63   - @Lazy // 解决循环依赖
64   - private BpmModelService modelService;
  55 + private BpmUserGroupService userGroupService;
65 56 @Resource
66 57 @Lazy // 解决循环依赖
67   - private BpmProcessDefinitionService processDefinitionService;
68   - @Resource
69   - private BpmUserGroupService userGroupService;
  58 + private BpmProcessInstanceService processInstanceService;
  59 +
70 60 @Resource
71 61 private RoleApi roleApi;
72 62 @Resource
... ... @@ -79,9 +69,7 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService {
79 69 private DictDataApi dictDataApi;
80 70 @Resource
81 71 private PermissionApi permissionApi;
82   - @Resource
83   - @Lazy // 解决循环依赖
84   - private BpmProcessInstanceService processInstanceService;
  72 +
85 73 /**
86 74 * 任务分配脚本
87 75 */
... ... @@ -93,130 +81,23 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService {
93 81 }
94 82  
95 83 @Override
96   - public List<BpmTaskAssignRuleDO> getTaskAssignRuleListByProcessDefinitionId(String processDefinitionId,
97   - String taskDefinitionKey) {
98   - return taskRuleMapper.selectListByProcessDefinitionId(processDefinitionId, taskDefinitionKey);
99   - }
100   -
101   - @Override
102   - public List<BpmTaskAssignRuleDO> getTaskAssignRuleListByModelId(String modelId) {
103   - return taskRuleMapper.selectListByModelId(modelId);
104   - }
105   -
106   - @Override
107   - public List<BpmTaskAssignRuleRespVO> getTaskAssignRuleList(String modelId, String processDefinitionId) {
108   - // 获得规则
109   - List<BpmTaskAssignRuleDO> rules = Collections.emptyList();
110   - BpmnModel model = null;
111   - if (StrUtil.isNotEmpty(modelId)) {
112   - rules = getTaskAssignRuleListByModelId(modelId);
113   - model = modelService.getBpmnModel(modelId);
114   - } else if (StrUtil.isNotEmpty(processDefinitionId)) {
115   - rules = getTaskAssignRuleListByProcessDefinitionId(processDefinitionId, null);
116   - model = processDefinitionService.getBpmnModel(processDefinitionId);
117   - }
118   - if (model == null) {
119   - return Collections.emptyList();
120   - }
121   - // 获得用户任务,只有用户任务才可以设置分配规则
122   - List<UserTask> userTasks = BpmnModelUtils.getBpmnModelElements(model, UserTask.class);
123   - if (CollUtil.isEmpty(userTasks)) {
124   - return Collections.emptyList();
125   - }
126   - // 转换数据
127   - return BpmTaskAssignRuleConvert.INSTANCE.convertList(userTasks, rules);
128   - }
129   -
130   - @Override
131   - public Long createTaskAssignRule(@Valid BpmTaskAssignRuleCreateReqVO reqVO) {
132   - // 校验参数
133   - validTaskAssignRuleOptions(reqVO.getType(), reqVO.getOptions());
134   - // 校验是否已经配置
135   - BpmTaskAssignRuleDO existRule =
136   - taskRuleMapper.selectListByModelIdAndTaskDefinitionKey(reqVO.getModelId(), reqVO.getTaskDefinitionKey());
137   - if (existRule != null) {
138   - throw exception(TASK_ASSIGN_RULE_EXISTS, reqVO.getModelId(), reqVO.getTaskDefinitionKey());
139   - }
140   -
141   - // 存储
142   - BpmTaskAssignRuleDO rule = BpmTaskAssignRuleConvert.INSTANCE.convert(reqVO)
143   - .setProcessDefinitionId(BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL); // 只有流程模型,才允许新建
144   - taskRuleMapper.insert(rule);
145   - return rule.getId();
146   - }
147   -
148   - @Override
149   - public void updateTaskAssignRule(@Valid BpmTaskAssignRuleUpdateReqVO reqVO) {
150   - // 校验参数
151   - validTaskAssignRuleOptions(reqVO.getType(), reqVO.getOptions());
152   - // 校验是否存在
153   - BpmTaskAssignRuleDO existRule = taskRuleMapper.selectById(reqVO.getId());
154   - if (existRule == null) {
155   - throw exception(TASK_ASSIGN_RULE_NOT_EXISTS);
156   - }
157   - // 只允许修改流程模型的规则
158   - if (!Objects.equals(BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL, existRule.getProcessDefinitionId())) {
159   - throw exception(TASK_UPDATE_FAIL_NOT_MODEL);
160   - }
161   -
162   - // 执行更新
163   - taskRuleMapper.updateById(BpmTaskAssignRuleConvert.INSTANCE.convert(reqVO));
164   - }
165   -
166   - @Override
167   - public boolean isTaskAssignRulesEquals(String modelId, String processDefinitionId) {
168   - // 调用 VO 接口的原因是,过滤掉流程模型不需要的规则,保持和 copyTaskAssignRules 方法的一致性
169   - List<BpmTaskAssignRuleRespVO> modelRules = getTaskAssignRuleList(modelId, null);
170   - List<BpmTaskAssignRuleRespVO> processInstanceRules = getTaskAssignRuleList(null, processDefinitionId);
171   - if (modelRules.size() != processInstanceRules.size()) {
172   - return false;
173   - }
174   -
175   - // 遍历,匹配对应的规则
176   - Map<String, BpmTaskAssignRuleRespVO> processInstanceRuleMap =
177   - CollectionUtils.convertMap(processInstanceRules, BpmTaskAssignRuleRespVO::getTaskDefinitionKey);
178   - for (BpmTaskAssignRuleRespVO modelRule : modelRules) {
179   - BpmTaskAssignRuleRespVO processInstanceRule = processInstanceRuleMap.get(modelRule.getTaskDefinitionKey());
180   - if (processInstanceRule == null) {
181   - return false;
182   - }
183   - if (!ObjectUtil.equals(modelRule.getType(), processInstanceRule.getType()) || !ObjectUtil.equal(
184   - modelRule.getOptions(), processInstanceRule.getOptions())) {
185   - return false;
186   - }
187   - }
188   - return true;
189   - }
190   -
191   - @Override
192   - public void copyTaskAssignRules(String fromModelId, String toProcessDefinitionId) {
193   - List<BpmTaskAssignRuleRespVO> rules = getTaskAssignRuleList(fromModelId, null);
194   - if (CollUtil.isEmpty(rules)) {
195   - return;
196   - }
197   - // 开始复制
198   - List<BpmTaskAssignRuleDO> newRules = BpmTaskAssignRuleConvert.INSTANCE.convertList2(rules);
199   - newRules.forEach(rule -> rule.setProcessDefinitionId(toProcessDefinitionId).setId(null).setCreateTime(null)
200   - .setUpdateTime(null));
201   - taskRuleMapper.insertBatch(newRules);
202   - }
203   -
204   - @Override
205   - public void checkTaskAssignRuleAllConfig(String id) {
206   - // 一个用户任务都没配置,所以无需配置规则
207   - List<BpmTaskAssignRuleRespVO> taskAssignRules = getTaskAssignRuleList(id, null);
208   - if (CollUtil.isEmpty(taskAssignRules)) {
209   - return;
210   - }
211   - // 校验未配置规则的任务
212   - taskAssignRules.forEach(rule -> {
213   - if (CollUtil.isEmpty(rule.getOptions())) {
214   - throw exception(MODEL_DEPLOY_FAIL_TASK_ASSIGN_RULE_NOT_CONFIG, rule.getTaskDefinitionName());
  84 + public void checkTaskAssignRuleAllConfig(byte[] bpmnBytes) {
  85 + BpmnModel bpmnModel = BpmnModelUtils.getBpmnModel(bpmnBytes);
  86 + assert bpmnModel != null;
  87 + List<UserTask> userTaskList = BpmnModelUtils.getBpmnModelElements(bpmnModel, UserTask.class);
  88 + // 遍历所有的 UserTask,校验审批人配置
  89 + userTaskList.forEach(userTask -> {
  90 + // TODO 芋艿:assignType/assignOptions/, 枚举
  91 + Integer type = NumberUtils.parseInt(userTask.getAttributeValue(BpmnModelConstants.NAMESPACE, "assignType"));
  92 + String options = userTask.getAttributeValue(BpmnModelConstants.NAMESPACE, "assignOptions");
  93 + if (type == null || StrUtil.isBlank(options)) {
  94 + throw exception(MODEL_DEPLOY_FAIL_TASK_ASSIGN_RULE_NOT_CONFIG, userTask.getName());
215 95 }
  96 + validTaskAssignRuleOptions(type, StrUtils.splitToLong(options, ","));
216 97 });
217 98 }
218 99  
219   - private void validTaskAssignRuleOptions(Integer type, Set<Long> options) {
  100 + private void validTaskAssignRuleOptions(Integer type, Collection<Long> options) {
220 101 if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.ROLE.getType())) {
221 102 roleApi.validRoleList(options);
222 103 } else if (ObjectUtils.equalsAny(type, BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(),
... ... @@ -247,92 +128,83 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService {
247 128 return convertSet(assignee, Function.identity());
248 129 }
249 130 // 2. 通过分配规则,计算审批人
250   - BpmTaskAssignRuleDO rule = getTaskRule(execution);
251   - return calculateTaskCandidateUsers(execution, rule);
  131 + return calculateTaskCandidateUsers0(execution);
252 132 }
253 133  
254 134 @VisibleForTesting
255   - BpmTaskAssignRuleDO getTaskRule(DelegateExecution execution) {
256   - List<BpmTaskAssignRuleDO> taskRules = getTaskAssignRuleListByProcessDefinitionId(
257   - execution.getProcessDefinitionId(), execution.getCurrentActivityId());
258   - if (CollUtil.isEmpty(taskRules)) {
259   - throw new FlowableException(format("流程任务({}/{}/{}) 找不到符合的任务规则",
260   - execution.getId(), execution.getProcessDefinitionId(), execution.getCurrentActivityId()));
261   - }
262   - if (taskRules.size() > 1) {
263   - throw new FlowableException(format("流程任务({}/{}/{}) 找到过多任务规则({})",
264   - execution.getId(), execution.getProcessDefinitionId(), execution.getCurrentActivityId()));
265   - }
266   - return taskRules.get(0);
267   - }
268   -
269   - @VisibleForTesting
270   - Set<Long> calculateTaskCandidateUsers(DelegateExecution execution, BpmTaskAssignRuleDO rule) {
  135 + Set<Long> calculateTaskCandidateUsers0(DelegateExecution execution) {
  136 + // 获得审批人配置
  137 + // TODO 芋艿:assignType/assignOptions/, 枚举
  138 + FlowElement flowElement = execution.getCurrentFlowElement();
  139 + Integer type = NumberUtils.parseInt(flowElement.getAttributeValue(BpmnModelConstants.NAMESPACE, "assignType"));
  140 + Set<Long> options = StrUtils.splitToLongSet(flowElement.getAttributeValue(BpmnModelConstants.NAMESPACE, "assignOptions"), ",");
  141 +
  142 + // 计算审批人
271 143 Set<Long> assigneeUserIds = null;
272   - if (Objects.equals(BpmTaskAssignRuleTypeEnum.ROLE.getType(), rule.getType())) {
273   - assigneeUserIds = calculateTaskCandidateUsersByRole(rule);
274   - } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(), rule.getType())) {
275   - assigneeUserIds = calculateTaskCandidateUsersByDeptMember(rule);
276   - } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType(), rule.getType())) {
277   - assigneeUserIds = calculateTaskCandidateUsersByDeptLeader(rule);
278   - } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.POST.getType(), rule.getType())) {
279   - assigneeUserIds = calculateTaskCandidateUsersByPost(rule);
280   - } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER.getType(), rule.getType())) {
281   - assigneeUserIds = calculateTaskCandidateUsersByUser(rule);
282   - } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER_GROUP.getType(), rule.getType())) {
283   - assigneeUserIds = calculateTaskCandidateUsersByUserGroup(rule);
284   - } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.SCRIPT.getType(), rule.getType())) {
285   - assigneeUserIds = calculateTaskCandidateUsersByScript(execution, rule);
  144 + if (Objects.equals(BpmTaskAssignRuleTypeEnum.ROLE.getType(), type)) {
  145 + assigneeUserIds = calculateTaskCandidateUsersByRole(options);
  146 + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(), type)) {
  147 + assigneeUserIds = calculateTaskCandidateUsersByDeptMember(options);
  148 + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType(), type)) {
  149 + assigneeUserIds = calculateTaskCandidateUsersByDeptLeader(options);
  150 + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.POST.getType(), type)) {
  151 + assigneeUserIds = calculateTaskCandidateUsersByPost(options);
  152 + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER.getType(), type)) {
  153 + assigneeUserIds = calculateTaskCandidateUsersByUser(options);
  154 + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER_GROUP.getType(), type)) {
  155 + assigneeUserIds = calculateTaskCandidateUsersByUserGroup(options);
  156 + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.SCRIPT.getType(), type)) {
  157 + assigneeUserIds = calculateTaskCandidateUsersByScript(execution, options);
286 158 }
287 159  
288 160 // 移除被禁用的用户
289 161 removeDisableUsers(assigneeUserIds);
290 162 // 如果候选人为空,抛出异常
291 163 if (CollUtil.isEmpty(assigneeUserIds)) {
292   - log.error("[calculateTaskCandidateUsers][流程任务({}/{}/{}) 任务规则({}) 找不到候选人]", execution.getId(),
293   - execution.getProcessDefinitionId(), execution.getCurrentActivityId(), toJsonString(rule));
  164 + log.error("[calculateTaskCandidateUsers][流程任务({}/{}/{}) 任务规则({}/{}) 找不到候选人]", execution.getId(),
  165 + execution.getProcessDefinitionId(), execution.getCurrentActivityId(), type, options);
294 166 throw exception(TASK_CREATE_FAIL_NO_CANDIDATE_USER);
295 167 }
296 168 return assigneeUserIds;
297 169 }
298 170  
299   - private Set<Long> calculateTaskCandidateUsersByRole(BpmTaskAssignRuleDO rule) {
300   - return permissionApi.getUserRoleIdListByRoleIds(rule.getOptions());
  171 + private Set<Long> calculateTaskCandidateUsersByRole(Set<Long> roleIds) {
  172 + return permissionApi.getUserRoleIdListByRoleIds(roleIds);
301 173 }
302 174  
303   - private Set<Long> calculateTaskCandidateUsersByDeptMember(BpmTaskAssignRuleDO rule) {
304   - List<AdminUserRespDTO> users = adminUserApi.getUserListByDeptIds(rule.getOptions());
  175 + private Set<Long> calculateTaskCandidateUsersByDeptMember(Set<Long> deptIds) {
  176 + List<AdminUserRespDTO> users = adminUserApi.getUserListByDeptIds(deptIds);
305 177 return convertSet(users, AdminUserRespDTO::getId);
306 178 }
307 179  
308   - private Set<Long> calculateTaskCandidateUsersByDeptLeader(BpmTaskAssignRuleDO rule) {
309   - List<DeptRespDTO> depts = deptApi.getDeptList(rule.getOptions());
  180 + private Set<Long> calculateTaskCandidateUsersByDeptLeader(Set<Long> deptIds) {
  181 + List<DeptRespDTO> depts = deptApi.getDeptList(deptIds);
310 182 return convertSet(depts, DeptRespDTO::getLeaderUserId);
311 183 }
312 184  
313   - private Set<Long> calculateTaskCandidateUsersByPost(BpmTaskAssignRuleDO rule) {
314   - List<AdminUserRespDTO> users = adminUserApi.getUserListByPostIds(rule.getOptions());
  185 + private Set<Long> calculateTaskCandidateUsersByPost(Set<Long> postIds) {
  186 + List<AdminUserRespDTO> users = adminUserApi.getUserListByPostIds(postIds);
315 187 return convertSet(users, AdminUserRespDTO::getId);
316 188 }
317 189  
318   - private Set<Long> calculateTaskCandidateUsersByUser(BpmTaskAssignRuleDO rule) {
319   - return rule.getOptions();
  190 + private Set<Long> calculateTaskCandidateUsersByUser(Set<Long> userIds) {
  191 + return userIds;
320 192 }
321 193  
322   - private Set<Long> calculateTaskCandidateUsersByUserGroup(BpmTaskAssignRuleDO rule) {
323   - List<BpmUserGroupDO> userGroups = userGroupService.getUserGroupList(rule.getOptions());
  194 + private Set<Long> calculateTaskCandidateUsersByUserGroup(Set<Long> groupIds) {
  195 + List<BpmUserGroupDO> userGroups = userGroupService.getUserGroupList(groupIds);
324 196 Set<Long> userIds = new HashSet<>();
325 197 userGroups.forEach(group -> userIds.addAll(group.getMemberUserIds()));
326 198 return userIds;
327 199 }
328 200  
329   - private Set<Long> calculateTaskCandidateUsersByScript(DelegateExecution execution, BpmTaskAssignRuleDO rule) {
  201 + private Set<Long> calculateTaskCandidateUsersByScript(DelegateExecution execution, Set<Long> scriptIds) {
330 202 // 获得对应的脚本
331   - List<BpmTaskAssignScript> scripts = new ArrayList<>(rule.getOptions().size());
332   - rule.getOptions().forEach(id -> {
333   - BpmTaskAssignScript script = scriptMap.get(id);
  203 + List<BpmTaskAssignScript> scripts = new ArrayList<>(scriptIds.size());
  204 + scriptIds.forEach(scriptId -> {
  205 + BpmTaskAssignScript script = scriptMap.get(scriptId);
334 206 if (script == null) {
335   - throw exception(TASK_ASSIGN_SCRIPT_NOT_EXISTS, id);
  207 + throw exception(TASK_ASSIGN_SCRIPT_NOT_EXISTS, scriptId);
336 208 }
337 209 scripts.add(script);
338 210 });
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmUserGroupService.java
1 1 package cn.iocoder.yudao.module.bpm.service.definition;
2 2  
3   -import java.util.*;
4   -import jakarta.validation.*;
5   -
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 4 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupCreateReqVO;
7 5 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupPageReqVO;
8 6 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupUpdateReqVO;
9 7 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO;
10   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
  8 +import jakarta.validation.Valid;
  9 +
  10 +import java.util.Collection;
  11 +import java.util.List;
11 12  
12 13 /**
13 14 * 用户组 Service 接口
... ... @@ -77,6 +78,6 @@ public interface BpmUserGroupService {
77 78 *
78 79 * @param ids 用户组编号数组
79 80 */
80   - void validUserGroups(Set<Long> ids);
  81 + void validUserGroups(Collection<Long> ids);
81 82  
82 83 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmUserGroupServiceImpl.java
1 1 package cn.iocoder.yudao.module.bpm.service.definition;
2 2  
3 3 import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  5 +import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
4 8 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupCreateReqVO;
5 9 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupPageReqVO;
6 10 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupUpdateReqVO;
7 11 import cn.iocoder.yudao.module.bpm.convert.definition.BpmUserGroupConvert;
8 12 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO;
9 13 import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmUserGroupMapper;
10   -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
11   -import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
12   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
13   -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  14 +import jakarta.annotation.Resource;
14 15 import org.springframework.stereotype.Service;
15 16 import org.springframework.validation.annotation.Validated;
16 17  
17   -import jakarta.annotation.Resource;
18 18 import java.util.Collection;
19 19 import java.util.List;
20 20 import java.util.Map;
21   -import java.util.Set;
22 21  
23 22 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
24   -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
  23 +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.USER_GROUP_IS_DISABLE;
  24 +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.USER_GROUP_NOT_EXISTS;
25 25  
26 26 /**
27 27 * 用户组 Service 实现类
... ... @@ -89,7 +89,7 @@ public class BpmUserGroupServiceImpl implements BpmUserGroupService {
89 89 }
90 90  
91 91 @Override
92   - public void validUserGroups(Set<Long> ids) {
  92 + public void validUserGroups(Collection<Long> ids) {
93 93 if (CollUtil.isEmpty(ids)) {
94 94 return;
95 95 }
... ...
yudao-module-bpm/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/util/BpmnModelUtils.java
1 1 package cn.iocoder.yudao.framework.flowable.core.util;
2 2  
3 3 import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.util.ArrayUtil;
4 5 import org.flowable.bpmn.converter.BpmnXMLConverter;
5 6 import org.flowable.bpmn.model.Process;
6 7 import org.flowable.bpmn.model.*;
  8 +import org.flowable.common.engine.impl.util.io.BytesStreamSource;
7 9  
8 10 import java.util.*;
9 11  
... ... @@ -91,6 +93,15 @@ public class BpmnModelUtils {
91 93 return converter.convertToXML(model);
92 94 }
93 95  
  96 + public static BpmnModel getBpmnModel(byte[] bpmnBytes) {
  97 + if (ArrayUtil.isEmpty(bpmnBytes)) {
  98 + return null;
  99 + }
  100 + BpmnXMLConverter converter = new BpmnXMLConverter();
  101 + // 补充说明:由于在 Flowable 中自定义了属性,所以 validateSchema 传递 false
  102 + return converter.convertToBpmnModel(new BytesStreamSource(bpmnBytes), false, false);
  103 + }
  104 +
94 105 // ========== 遍历相关的方法 ==========
95 106  
96 107 /**
... ...