Commit cdbcd4d673d491ad5203b8cdb05b00919deda6c9
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,6 +16,10 @@ public class NumberUtils { | ||
| 16 | return StrUtil.isNotEmpty(str) ? Long.valueOf(str) : null; | 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 +6,7 @@ import cn.hutool.core.util.StrUtil; | ||
| 6 | import java.util.Arrays; | 6 | import java.util.Arrays; |
| 7 | import java.util.Collection; | 7 | import java.util.Collection; |
| 8 | import java.util.List; | 8 | import java.util.List; |
| 9 | +import java.util.Set; | ||
| 9 | import java.util.stream.Collectors; | 10 | import java.util.stream.Collectors; |
| 10 | 11 | ||
| 11 | /** | 12 | /** |
| @@ -45,6 +46,11 @@ public class StrUtils { | @@ -45,6 +46,11 @@ public class StrUtils { | ||
| 45 | return Arrays.stream(longs).boxed().collect(Collectors.toList()); | 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 | public static List<Integer> splitToInteger(String value, CharSequence separator) { | 54 | public static List<Integer> splitToInteger(String value, CharSequence separator) { |
| 49 | int[] integers = StrUtil.splitToInt(value, separator); | 55 | int[] integers = StrUtil.splitToInt(value, separator); |
| 50 | return Arrays.stream(integers).boxed().collect(Collectors.toList()); | 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,7 +27,7 @@ public interface ErrorCodeConstants { | ||
| 27 | ErrorCode MODEL_KEY_VALID = new ErrorCode(1_009_002_002, "流程标识格式不正确,需要以字母或下划线开头,后接任意字母、数字、中划线、下划线、句点!"); | 27 | ErrorCode MODEL_KEY_VALID = new ErrorCode(1_009_002_002, "流程标识格式不正确,需要以字母或下划线开头,后接任意字母、数字、中划线、下划线、句点!"); |
| 28 | ErrorCode MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG = new ErrorCode(1_009_002_003, "部署流程失败,原因:流程表单未配置,请点击【修改流程】按钮进行配置"); | 28 | ErrorCode MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG = new ErrorCode(1_009_002_003, "部署流程失败,原因:流程表单未配置,请点击【修改流程】按钮进行配置"); |
| 29 | ErrorCode MODEL_DEPLOY_FAIL_TASK_ASSIGN_RULE_NOT_CONFIG = new ErrorCode(1_009_002_004, "部署流程失败," + | 29 | ErrorCode MODEL_DEPLOY_FAIL_TASK_ASSIGN_RULE_NOT_CONFIG = new ErrorCode(1_009_002_004, "部署流程失败," + |
| 30 | - "原因:用户任务({})未配置分配规则,请点击【修改流程】按钮进行配置"); | 30 | + "原因:用户任务({})未配置审批人,请点击【流程设计】按钮,选择该它的【任务(审批人)】进行配置"); |
| 31 | ErrorCode MODEL_DEPLOY_FAIL_TASK_INFO_EQUALS = new ErrorCode(1_009_003_005, "流程定义部署失败,原因:信息未发生变化"); | 31 | ErrorCode MODEL_DEPLOY_FAIL_TASK_INFO_EQUALS = new ErrorCode(1_009_003_005, "流程定义部署失败,原因:信息未发生变化"); |
| 32 | 32 | ||
| 33 | // ========== 流程定义 1-009-003-000 ========== | 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 | package cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo; | 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 | import io.swagger.v3.oas.annotations.media.Schema; | 3 | import io.swagger.v3.oas.annotations.media.Schema; |
| 5 | import jakarta.validation.constraints.NotNull; | 4 | import jakarta.validation.constraints.NotNull; |
| 6 | import lombok.Data; | 5 | import lombok.Data; |
| @@ -10,8 +9,6 @@ import java.util.Set; | @@ -10,8 +9,6 @@ import java.util.Set; | ||
| 10 | /** | 9 | /** |
| 11 | * 流程任务分配规则 Base VO,提供给添加、修改、详细的子 VO 使用 | 10 | * 流程任务分配规则 Base VO,提供给添加、修改、详细的子 VO 使用 |
| 12 | * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 | 11 | * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 |
| 13 | - * | ||
| 14 | - * @see BpmTaskAssignRuleBaseVO | ||
| 15 | */ | 12 | */ |
| 16 | @Data | 13 | @Data |
| 17 | public class BpmTaskCandidateRuleVO { | 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 | package cn.iocoder.yudao.module.bpm.service.definition; | 1 | package cn.iocoder.yudao.module.bpm.service.definition; |
| 2 | 2 | ||
| 3 | -import cn.hutool.core.util.ArrayUtil; | ||
| 4 | import cn.hutool.core.util.StrUtil; | 3 | import cn.hutool.core.util.StrUtil; |
| 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | 5 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 7 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | 6 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; |
| 8 | import cn.iocoder.yudao.framework.common.util.object.PageUtils; | 7 | import cn.iocoder.yudao.framework.common.util.object.PageUtils; |
| 9 | import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; | 8 | import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; |
| 9 | +import cn.iocoder.yudao.framework.flowable.core.util.BpmnModelUtils; | ||
| 10 | import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; | 10 | import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; |
| 11 | import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*; | 11 | import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*; |
| 12 | import cn.iocoder.yudao.module.bpm.convert.definition.BpmModelConvert; | 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,10 +17,8 @@ import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCr | ||
| 17 | import jakarta.annotation.Resource; | 17 | import jakarta.annotation.Resource; |
| 18 | import jakarta.validation.Valid; | 18 | import jakarta.validation.Valid; |
| 19 | import lombok.extern.slf4j.Slf4j; | 19 | import lombok.extern.slf4j.Slf4j; |
| 20 | -import org.flowable.bpmn.converter.BpmnXMLConverter; | ||
| 21 | import org.flowable.bpmn.model.BpmnModel; | 20 | import org.flowable.bpmn.model.BpmnModel; |
| 22 | import org.flowable.common.engine.impl.db.SuspensionState; | 21 | import org.flowable.common.engine.impl.db.SuspensionState; |
| 23 | -import org.flowable.common.engine.impl.util.io.BytesStreamSource; | ||
| 24 | import org.flowable.engine.RepositoryService; | 22 | import org.flowable.engine.RepositoryService; |
| 25 | import org.flowable.engine.repository.Deployment; | 23 | import org.flowable.engine.repository.Deployment; |
| 26 | import org.flowable.engine.repository.Model; | 24 | import org.flowable.engine.repository.Model; |
| @@ -168,15 +166,13 @@ public class BpmModelServiceImpl implements BpmModelService { | @@ -168,15 +166,13 @@ public class BpmModelServiceImpl implements BpmModelService { | ||
| 168 | // 1.3 校验表单已配 | 166 | // 1.3 校验表单已配 |
| 169 | BpmFormDO form = checkFormConfig(model.getMetaInfo()); | 167 | BpmFormDO form = checkFormConfig(model.getMetaInfo()); |
| 170 | // 1.4 校验任务分配规则已配置 | 168 | // 1.4 校验任务分配规则已配置 |
| 171 | - taskAssignRuleService.checkTaskAssignRuleAllConfig(id); | 169 | + taskAssignRuleService.checkTaskAssignRuleAllConfig(bpmnBytes); |
| 172 | 170 | ||
| 173 | // 1.5 校验模型是否发生修改。如果未修改,则不允许创建 | 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 | if (processDefinitionService.isProcessDefinitionEquals(definitionCreateReqDTO)) { // 流程定义的信息相等 | 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 | // 2.1 创建流程定义 | 178 | // 2.1 创建流程定义 |
| @@ -189,12 +185,8 @@ public class BpmModelServiceImpl implements BpmModelService { | @@ -189,12 +185,8 @@ public class BpmModelServiceImpl implements BpmModelService { | ||
| 189 | ProcessDefinition definition = processDefinitionService.getProcessDefinition(definitionId); | 185 | ProcessDefinition definition = processDefinitionService.getProcessDefinition(definitionId); |
| 190 | model.setDeploymentId(definition.getDeploymentId()); | 186 | model.setDeploymentId(definition.getDeploymentId()); |
| 191 | repositoryService.saveModel(model); | 187 | repositoryService.saveModel(model); |
| 192 | - | ||
| 193 | - // 2.4 复制任务分配规则 | ||
| 194 | - taskAssignRuleService.copyTaskAssignRules(id, definition.getId()); | ||
| 195 | } | 188 | } |
| 196 | 189 | ||
| 197 | - | ||
| 198 | @Override | 190 | @Override |
| 199 | @Transactional(rollbackFor = Exception.class) | 191 | @Transactional(rollbackFor = Exception.class) |
| 200 | public void deleteModel(String id) { | 192 | public void deleteModel(String id) { |
| @@ -229,11 +221,7 @@ public class BpmModelServiceImpl implements BpmModelService { | @@ -229,11 +221,7 @@ public class BpmModelServiceImpl implements BpmModelService { | ||
| 229 | @Override | 221 | @Override |
| 230 | public BpmnModel getBpmnModel(String id) { | 222 | public BpmnModel getBpmnModel(String id) { |
| 231 | byte[] bpmnBytes = repositoryService.getModelEditorSource(id); | 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 | @Override | 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,7 +23,6 @@ import lombok.extern.slf4j.Slf4j; | ||
| 23 | import org.flowable.bpmn.converter.BpmnXMLConverter; | 23 | import org.flowable.bpmn.converter.BpmnXMLConverter; |
| 24 | import org.flowable.bpmn.model.BpmnModel; | 24 | import org.flowable.bpmn.model.BpmnModel; |
| 25 | import org.flowable.common.engine.impl.db.SuspensionState; | 25 | import org.flowable.common.engine.impl.db.SuspensionState; |
| 26 | -import org.flowable.common.engine.impl.util.io.BytesStreamSource; | ||
| 27 | import org.flowable.engine.RepositoryService; | 26 | import org.flowable.engine.RepositoryService; |
| 28 | import org.flowable.engine.repository.Deployment; | 27 | import org.flowable.engine.repository.Deployment; |
| 29 | import org.flowable.engine.repository.ProcessDefinition; | 28 | import org.flowable.engine.repository.ProcessDefinition; |
| @@ -124,6 +123,7 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ | @@ -124,6 +123,7 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ | ||
| 124 | .key(createReqDTO.getKey()).name(createReqDTO.getName()).category(createReqDTO.getCategory()) | 123 | .key(createReqDTO.getKey()).name(createReqDTO.getName()).category(createReqDTO.getCategory()) |
| 125 | .addBytes(createReqDTO.getKey() + BpmnModelConstants.BPMN_FILE_SUFFIX, createReqDTO.getBpmnBytes()) | 124 | .addBytes(createReqDTO.getKey() + BpmnModelConstants.BPMN_FILE_SUFFIX, createReqDTO.getBpmnBytes()) |
| 126 | .tenantId(TenantContextHolder.getTenantIdStr()) | 125 | .tenantId(TenantContextHolder.getTenantIdStr()) |
| 126 | + .disableSchemaValidation() // 禁用 XML Schema 验证,因为有自定义的属性 | ||
| 127 | .deploy(); | 127 | .deploy(); |
| 128 | 128 | ||
| 129 | // 设置 ProcessDefinition 的 category 分类 | 129 | // 设置 ProcessDefinition 的 category 分类 |
| @@ -197,7 +197,7 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ | @@ -197,7 +197,7 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ | ||
| 197 | return false; | 197 | return false; |
| 198 | } | 198 | } |
| 199 | // 校验 BPMN XML 信息 | 199 | // 校验 BPMN XML 信息 |
| 200 | - BpmnModel newModel = buildBpmnModel(createReqDTO.getBpmnBytes()); | 200 | + BpmnModel newModel = BpmnModelUtils.getBpmnModel(createReqDTO.getBpmnBytes()); |
| 201 | BpmnModel oldModel = getBpmnModel(oldProcessDefinition.getId()); | 201 | BpmnModel oldModel = getBpmnModel(oldProcessDefinition.getId()); |
| 202 | // 对比字节变化 | 202 | // 对比字节变化 |
| 203 | if (!BpmnModelUtils.equals(oldModel, newModel)) { | 203 | if (!BpmnModelUtils.equals(oldModel, newModel)) { |
| @@ -207,18 +207,6 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ | @@ -207,18 +207,6 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ | ||
| 207 | return true; | 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 | @Override | 210 | @Override |
| 223 | public BpmProcessDefinitionExtDO getProcessDefinitionExt(String id) { | 211 | public BpmProcessDefinitionExtDO getProcessDefinitionExt(String id) { |
| 224 | return processDefinitionMapper.selectByProcessDefinitionId(id); | 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 | package cn.iocoder.yudao.module.bpm.service.definition; | 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 | import org.flowable.engine.delegate.DelegateExecution; | 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 | import java.util.Set; | 5 | import java.util.Set; |
| 13 | 6 | ||
| 14 | /** | 7 | /** |
| @@ -19,72 +12,12 @@ import java.util.Set; | @@ -19,72 +12,12 @@ import java.util.Set; | ||
| 19 | public interface BpmTaskAssignRuleService { | 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 | package cn.iocoder.yudao.module.bpm.service.definition; | 1 | package cn.iocoder.yudao.module.bpm.service.definition; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.collection.CollUtil; | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | -import cn.hutool.core.util.ObjectUtil; | ||
| 5 | import cn.hutool.core.util.StrUtil; | 4 | import cn.hutool.core.util.StrUtil; |
| 6 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | 5 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| 7 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | 6 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 7 | +import cn.iocoder.yudao.framework.common.util.number.NumberUtils; | ||
| 8 | import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; | 8 | import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; |
| 9 | +import cn.iocoder.yudao.framework.common.util.string.StrUtils; | ||
| 9 | import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission; | 10 | import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission; |
| 11 | +import cn.iocoder.yudao.framework.flowable.core.enums.BpmnModelConstants; | ||
| 10 | import cn.iocoder.yudao.framework.flowable.core.util.BpmnModelUtils; | 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 | import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO; | 13 | import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO; |
| 17 | -import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmTaskAssignRuleMapper; | ||
| 18 | import cn.iocoder.yudao.module.bpm.enums.DictTypeConstants; | 14 | import cn.iocoder.yudao.module.bpm.enums.DictTypeConstants; |
| 19 | import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; | 15 | import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; |
| 20 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript; | 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,17 +24,16 @@ import cn.iocoder.yudao.module.system.api.permission.RoleApi; | ||
| 28 | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | 24 | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| 29 | import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; | 25 | import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; |
| 30 | import com.google.common.annotations.VisibleForTesting; | 26 | import com.google.common.annotations.VisibleForTesting; |
| 27 | +import jakarta.annotation.Resource; | ||
| 31 | import lombok.extern.slf4j.Slf4j; | 28 | import lombok.extern.slf4j.Slf4j; |
| 32 | import org.flowable.bpmn.model.BpmnModel; | 29 | import org.flowable.bpmn.model.BpmnModel; |
| 30 | +import org.flowable.bpmn.model.FlowElement; | ||
| 33 | import org.flowable.bpmn.model.UserTask; | 31 | import org.flowable.bpmn.model.UserTask; |
| 34 | -import org.flowable.common.engine.api.FlowableException; | ||
| 35 | import org.flowable.engine.delegate.DelegateExecution; | 32 | import org.flowable.engine.delegate.DelegateExecution; |
| 36 | import org.springframework.context.annotation.Lazy; | 33 | import org.springframework.context.annotation.Lazy; |
| 37 | import org.springframework.stereotype.Service; | 34 | import org.springframework.stereotype.Service; |
| 38 | import org.springframework.validation.annotation.Validated; | 35 | import org.springframework.validation.annotation.Validated; |
| 39 | 36 | ||
| 40 | -import jakarta.annotation.Resource; | ||
| 41 | -import jakarta.validation.Valid; | ||
| 42 | import java.util.*; | 37 | import java.util.*; |
| 43 | import java.util.function.Function; | 38 | import java.util.function.Function; |
| 44 | 39 | ||
| @@ -46,7 +41,6 @@ import static cn.hutool.core.text.CharSequenceUtil.format; | @@ -46,7 +41,6 @@ import static cn.hutool.core.text.CharSequenceUtil.format; | ||
| 46 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 41 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 47 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; | 42 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; |
| 48 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | 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 | import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; | 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,15 +52,11 @@ import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; | ||
| 58 | public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService { | 52 | public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService { |
| 59 | 53 | ||
| 60 | @Resource | 54 | @Resource |
| 61 | - private BpmTaskAssignRuleMapper taskRuleMapper; | ||
| 62 | - @Resource | ||
| 63 | - @Lazy // 解决循环依赖 | ||
| 64 | - private BpmModelService modelService; | 55 | + private BpmUserGroupService userGroupService; |
| 65 | @Resource | 56 | @Resource |
| 66 | @Lazy // 解决循环依赖 | 57 | @Lazy // 解决循环依赖 |
| 67 | - private BpmProcessDefinitionService processDefinitionService; | ||
| 68 | - @Resource | ||
| 69 | - private BpmUserGroupService userGroupService; | 58 | + private BpmProcessInstanceService processInstanceService; |
| 59 | + | ||
| 70 | @Resource | 60 | @Resource |
| 71 | private RoleApi roleApi; | 61 | private RoleApi roleApi; |
| 72 | @Resource | 62 | @Resource |
| @@ -79,9 +69,7 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService { | @@ -79,9 +69,7 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService { | ||
| 79 | private DictDataApi dictDataApi; | 69 | private DictDataApi dictDataApi; |
| 80 | @Resource | 70 | @Resource |
| 81 | private PermissionApi permissionApi; | 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,130 +81,23 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService { | ||
| 93 | } | 81 | } |
| 94 | 82 | ||
| 95 | @Override | 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 | if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.ROLE.getType())) { | 101 | if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.ROLE.getType())) { |
| 221 | roleApi.validRoleList(options); | 102 | roleApi.validRoleList(options); |
| 222 | } else if (ObjectUtils.equalsAny(type, BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(), | 103 | } else if (ObjectUtils.equalsAny(type, BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(), |
| @@ -247,92 +128,83 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService { | @@ -247,92 +128,83 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService { | ||
| 247 | return convertSet(assignee, Function.identity()); | 128 | return convertSet(assignee, Function.identity()); |
| 248 | } | 129 | } |
| 249 | // 2. 通过分配规则,计算审批人 | 130 | // 2. 通过分配规则,计算审批人 |
| 250 | - BpmTaskAssignRuleDO rule = getTaskRule(execution); | ||
| 251 | - return calculateTaskCandidateUsers(execution, rule); | 131 | + return calculateTaskCandidateUsers0(execution); |
| 252 | } | 132 | } |
| 253 | 133 | ||
| 254 | @VisibleForTesting | 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 | Set<Long> assigneeUserIds = null; | 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 | removeDisableUsers(assigneeUserIds); | 161 | removeDisableUsers(assigneeUserIds); |
| 290 | // 如果候选人为空,抛出异常 | 162 | // 如果候选人为空,抛出异常 |
| 291 | if (CollUtil.isEmpty(assigneeUserIds)) { | 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 | throw exception(TASK_CREATE_FAIL_NO_CANDIDATE_USER); | 166 | throw exception(TASK_CREATE_FAIL_NO_CANDIDATE_USER); |
| 295 | } | 167 | } |
| 296 | return assigneeUserIds; | 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 | return convertSet(users, AdminUserRespDTO::getId); | 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 | return convertSet(depts, DeptRespDTO::getLeaderUserId); | 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 | return convertSet(users, AdminUserRespDTO::getId); | 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 | Set<Long> userIds = new HashSet<>(); | 196 | Set<Long> userIds = new HashSet<>(); |
| 325 | userGroups.forEach(group -> userIds.addAll(group.getMemberUserIds())); | 197 | userGroups.forEach(group -> userIds.addAll(group.getMemberUserIds())); |
| 326 | return userIds; | 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 | if (script == null) { | 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 | scripts.add(script); | 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 | package cn.iocoder.yudao.module.bpm.service.definition; | 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 | import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupCreateReqVO; | 4 | import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupCreateReqVO; |
| 7 | import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupPageReqVO; | 5 | import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupPageReqVO; |
| 8 | import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupUpdateReqVO; | 6 | import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupUpdateReqVO; |
| 9 | import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO; | 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 | * 用户组 Service 接口 | 14 | * 用户组 Service 接口 |
| @@ -77,6 +78,6 @@ public interface BpmUserGroupService { | @@ -77,6 +78,6 @@ public interface BpmUserGroupService { | ||
| 77 | * | 78 | * |
| 78 | * @param ids 用户组编号数组 | 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 | package cn.iocoder.yudao.module.bpm.service.definition; | 1 | package cn.iocoder.yudao.module.bpm.service.definition; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.collection.CollUtil; | 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 | import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupCreateReqVO; | 8 | import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupCreateReqVO; |
| 5 | import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupPageReqVO; | 9 | import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupPageReqVO; |
| 6 | import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupUpdateReqVO; | 10 | import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupUpdateReqVO; |
| 7 | import cn.iocoder.yudao.module.bpm.convert.definition.BpmUserGroupConvert; | 11 | import cn.iocoder.yudao.module.bpm.convert.definition.BpmUserGroupConvert; |
| 8 | import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO; | 12 | import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO; |
| 9 | import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmUserGroupMapper; | 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 | import org.springframework.stereotype.Service; | 15 | import org.springframework.stereotype.Service; |
| 15 | import org.springframework.validation.annotation.Validated; | 16 | import org.springframework.validation.annotation.Validated; |
| 16 | 17 | ||
| 17 | -import jakarta.annotation.Resource; | ||
| 18 | import java.util.Collection; | 18 | import java.util.Collection; |
| 19 | import java.util.List; | 19 | import java.util.List; |
| 20 | import java.util.Map; | 20 | import java.util.Map; |
| 21 | -import java.util.Set; | ||
| 22 | 21 | ||
| 23 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 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 | * 用户组 Service 实现类 | 27 | * 用户组 Service 实现类 |
| @@ -89,7 +89,7 @@ public class BpmUserGroupServiceImpl implements BpmUserGroupService { | @@ -89,7 +89,7 @@ public class BpmUserGroupServiceImpl implements BpmUserGroupService { | ||
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | @Override | 91 | @Override |
| 92 | - public void validUserGroups(Set<Long> ids) { | 92 | + public void validUserGroups(Collection<Long> ids) { |
| 93 | if (CollUtil.isEmpty(ids)) { | 93 | if (CollUtil.isEmpty(ids)) { |
| 94 | return; | 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 | package cn.iocoder.yudao.framework.flowable.core.util; | 1 | package cn.iocoder.yudao.framework.flowable.core.util; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.collection.CollUtil; | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | +import cn.hutool.core.util.ArrayUtil; | ||
| 4 | import org.flowable.bpmn.converter.BpmnXMLConverter; | 5 | import org.flowable.bpmn.converter.BpmnXMLConverter; |
| 5 | import org.flowable.bpmn.model.Process; | 6 | import org.flowable.bpmn.model.Process; |
| 6 | import org.flowable.bpmn.model.*; | 7 | import org.flowable.bpmn.model.*; |
| 8 | +import org.flowable.common.engine.impl.util.io.BytesStreamSource; | ||
| 7 | 9 | ||
| 8 | import java.util.*; | 10 | import java.util.*; |
| 9 | 11 | ||
| @@ -91,6 +93,15 @@ public class BpmnModelUtils { | @@ -91,6 +93,15 @@ public class BpmnModelUtils { | ||
| 91 | return converter.convertToXML(model); | 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 | /** |