Commit 90ced26b017efe16bca90cc1ac5f5a8b38639daa

Authored by YunaiV
1 parent 9334edc9

【功能优化】工作流:流程模型的定义,增加谁可以发起、谁可以管理的字段 CRUD

yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/base/package-info.java 0 → 100644
  1 +/**
  2 + * 基础包,放一些通用的 VO 类
  3 + */
  4 +package cn.iocoder.yudao.module.bpm.controller.admin.base;
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/base/user/UserSimpleBaseVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.controller.admin.base.user;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +@Schema(description = "用户精简信息 VO")
  7 +@Data
  8 +public class UserSimpleBaseVO {
  9 +
  10 + @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  11 + private Long id;
  12 +
  13 + @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
  14 + private String nickname;
  15 +
  16 + @Schema(description = "用户头像", example = "https://www.iocoder.cn/1.png")
  17 + private String avatar;
  18 +
  19 +}
0 \ No newline at end of file 20 \ No newline at end of file
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java
@@ -15,6 +15,8 @@ import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryService; @@ -15,6 +15,8 @@ import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryService;
15 import cn.iocoder.yudao.module.bpm.service.definition.BpmFormService; 15 import cn.iocoder.yudao.module.bpm.service.definition.BpmFormService;
16 import cn.iocoder.yudao.module.bpm.service.definition.BpmModelService; 16 import cn.iocoder.yudao.module.bpm.service.definition.BpmModelService;
17 import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; 17 import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
  18 +import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  19 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
18 import io.swagger.v3.oas.annotations.Operation; 20 import io.swagger.v3.oas.annotations.Operation;
19 import io.swagger.v3.oas.annotations.Parameter; 21 import io.swagger.v3.oas.annotations.Parameter;
20 import io.swagger.v3.oas.annotations.tags.Tag; 22 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -31,6 +33,7 @@ import java.util.HashSet; @@ -31,6 +33,7 @@ import java.util.HashSet;
31 import java.util.List; 33 import java.util.List;
32 import java.util.Map; 34 import java.util.Map;
33 import java.util.Set; 35 import java.util.Set;
  36 +import java.util.stream.Stream;
34 37
35 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 38 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
36 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; 39 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
@@ -51,6 +54,9 @@ public class BpmModelController { @@ -51,6 +54,9 @@ public class BpmModelController {
51 @Resource 54 @Resource
52 private BpmProcessDefinitionService processDefinitionService; 55 private BpmProcessDefinitionService processDefinitionService;
53 56
  57 + @Resource
  58 + private AdminUserApi adminUserApi;
  59 +
54 @GetMapping("/page") 60 @GetMapping("/page")
55 @Operation(summary = "获得模型分页") 61 @Operation(summary = "获得模型分页")
56 public CommonResult<PageResult<BpmModelRespVO>> getModelPage(BpmModelPageReqVO pageVO) { 62 public CommonResult<PageResult<BpmModelRespVO>> getModelPage(BpmModelPageReqVO pageVO) {
@@ -76,7 +82,14 @@ public class BpmModelController { @@ -76,7 +82,14 @@ public class BpmModelController {
76 // 获得 ProcessDefinition Map 82 // 获得 ProcessDefinition Map
77 List<ProcessDefinition> processDefinitions = processDefinitionService.getProcessDefinitionListByDeploymentIds(deploymentIds); 83 List<ProcessDefinition> processDefinitions = processDefinitionService.getProcessDefinitionListByDeploymentIds(deploymentIds);
78 Map<String, ProcessDefinition> processDefinitionMap = convertMap(processDefinitions, ProcessDefinition::getDeploymentId); 84 Map<String, ProcessDefinition> processDefinitionMap = convertMap(processDefinitions, ProcessDefinition::getDeploymentId);
79 - return success(BpmModelConvert.INSTANCE.buildModelPage(pageResult, formMap, categoryMap, deploymentMap, processDefinitionMap)); 85 + // 获得 User Map
  86 + Set<Long> userIds = CollectionUtils.convertSetByFlatMap(pageResult.getList(), model -> {
  87 + BpmModelMetaInfoVO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoVO.class);
  88 + return metaInfo != null ? metaInfo.getStartUserIds().stream() : Stream.empty();
  89 + });
  90 + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);
  91 + return success(BpmModelConvert.INSTANCE.buildModelPage(pageResult,
  92 + formMap, categoryMap, deploymentMap, processDefinitionMap, userMap));
80 } 93 }
81 94
82 @GetMapping("/get") 95 @GetMapping("/get")
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelMetaInfoVO.java
@@ -9,6 +9,8 @@ import jakarta.validation.constraints.NotNull; @@ -9,6 +9,8 @@ import jakarta.validation.constraints.NotNull;
9 import lombok.Data; 9 import lombok.Data;
10 import org.hibernate.validator.constraints.URL; 10 import org.hibernate.validator.constraints.URL;
11 11
  12 +import java.util.List;
  13 +
12 /** 14 /**
13 * BPM 流程 MetaInfo Response DTO 15 * BPM 流程 MetaInfo Response DTO
14 * 主要用于 { Model#setMetaInfo(String)} 的存储 16 * 主要用于 { Model#setMetaInfo(String)} 的存储
@@ -50,4 +52,11 @@ public class BpmModelMetaInfoVO { @@ -50,4 +52,11 @@ public class BpmModelMetaInfoVO {
50 @NotNull(message = "是否可见不能为空") 52 @NotNull(message = "是否可见不能为空")
51 private Boolean visible; 53 private Boolean visible;
52 54
  55 + @Schema(description = "可发起用户编号数组", example = "[1,2,3]")
  56 + private List<Long> startUserIds;
  57 +
  58 + @Schema(description = "可管理用户编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "[2,4,6]")
  59 + @NotEmpty(message = "可管理用户编号数组不能为空")
  60 + private List<Long> managerUserIds;
  61 +
53 } 62 }
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelRespVO.java
1 package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model; 1 package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model;
2 2
  3 +import cn.iocoder.yudao.module.bpm.controller.admin.base.user.UserSimpleBaseVO;
3 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO; 4 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
4 import io.swagger.v3.oas.annotations.media.Schema; 5 import io.swagger.v3.oas.annotations.media.Schema;
5 import lombok.Data; 6 import lombok.Data;
6 7
7 import java.time.LocalDateTime; 8 import java.time.LocalDateTime;
  9 +import java.util.List;
8 10
9 @Schema(description = "管理后台 - 流程模型 Response VO") 11 @Schema(description = "管理后台 - 流程模型 Response VO")
10 @Data 12 @Data
@@ -36,6 +38,9 @@ public class BpmModelRespVO extends BpmModelMetaInfoVO { @@ -36,6 +38,9 @@ public class BpmModelRespVO extends BpmModelMetaInfoVO {
36 @Schema(description = "BPMN XML", requiredMode = Schema.RequiredMode.REQUIRED) 38 @Schema(description = "BPMN XML", requiredMode = Schema.RequiredMode.REQUIRED)
37 private String bpmnXml; 39 private String bpmnXml;
38 40
  41 + @Schema(description = "可发起的用户数组")
  42 + private List<UserSimpleBaseVO> startUsers;
  43 +
39 /** 44 /**
40 * 最新部署的流程定义 45 * 最新部署的流程定义
41 */ 46 */
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmApprovalDetailReqVO.java
@@ -6,6 +6,7 @@ import io.swagger.v3.oas.annotations.media.Schema; @@ -6,6 +6,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
6 import jakarta.validation.constraints.AssertTrue; 6 import jakarta.validation.constraints.AssertTrue;
7 import lombok.Data; 7 import lombok.Data;
8 8
  9 +// TODO @jason:这个可以简化下,使用 @RequestParam。嘿嘿,主要 VO 项不要太多
9 @Schema(description = "管理后台 - 审批详情 Request VO") 10 @Schema(description = "管理后台 - 审批详情 Request VO")
10 @Data 11 @Data
11 public class BpmApprovalDetailReqVO { 12 public class BpmApprovalDetailReqVO {
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmApprovalDetailRespVO.java
@@ -47,6 +47,7 @@ public class BpmApprovalDetailRespVO { @@ -47,6 +47,7 @@ public class BpmApprovalDetailRespVO {
47 47
48 } 48 }
49 49
  50 + // TODO @jason:可以替换成 UserSimpleBaseVO。简化下
50 @Schema(description = "用户信息") 51 @Schema(description = "用户信息")
51 @Data 52 @Data
52 public static class User { 53 public static class User {
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmModelConvert.java
@@ -2,17 +2,18 @@ package cn.iocoder.yudao.module.bpm.convert.definition; @@ -2,17 +2,18 @@ package cn.iocoder.yudao.module.bpm.convert.definition;
2 2
3 import cn.hutool.core.util.ArrayUtil; 3 import cn.hutool.core.util.ArrayUtil;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;  
6 import cn.iocoder.yudao.framework.common.util.date.DateUtils; 5 import cn.iocoder.yudao.framework.common.util.date.DateUtils;
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.BeanUtils; 7 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  8 +import cn.iocoder.yudao.module.bpm.controller.admin.base.user.UserSimpleBaseVO;
  9 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelMetaInfoVO;
9 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelRespVO; 10 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelRespVO;
10 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelSaveReqVO; 11 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelSaveReqVO;
11 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO; 12 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
12 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO; 13 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
13 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; 14 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
14 import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils; 15 import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
15 -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelMetaInfoVO; 16 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
16 import org.flowable.common.engine.impl.db.SuspensionState; 17 import org.flowable.common.engine.impl.db.SuspensionState;
17 import org.flowable.engine.repository.Deployment; 18 import org.flowable.engine.repository.Deployment;
18 import org.flowable.engine.repository.Model; 19 import org.flowable.engine.repository.Model;
@@ -23,6 +24,8 @@ import org.mapstruct.factory.Mappers; @@ -23,6 +24,8 @@ import org.mapstruct.factory.Mappers;
23 import java.util.List; 24 import java.util.List;
24 import java.util.Map; 25 import java.util.Map;
25 26
  27 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  28 +
26 /** 29 /**
27 * 流程模型 Convert 30 * 流程模型 Convert
28 * 31 *
@@ -36,14 +39,16 @@ public interface BpmModelConvert { @@ -36,14 +39,16 @@ public interface BpmModelConvert {
36 default PageResult<BpmModelRespVO> buildModelPage(PageResult<Model> pageResult, 39 default PageResult<BpmModelRespVO> buildModelPage(PageResult<Model> pageResult,
37 Map<Long, BpmFormDO> formMap, 40 Map<Long, BpmFormDO> formMap,
38 Map<String, BpmCategoryDO> categoryMap, Map<String, Deployment> deploymentMap, 41 Map<String, BpmCategoryDO> categoryMap, Map<String, Deployment> deploymentMap,
39 - Map<String, ProcessDefinition> processDefinitionMap) {  
40 - List<BpmModelRespVO> list = CollectionUtils.convertList(pageResult.getList(), model -> { 42 + Map<String, ProcessDefinition> processDefinitionMap,
  43 + Map<Long, AdminUserRespDTO> userMap) {
  44 + List<BpmModelRespVO> list = convertList(pageResult.getList(), model -> {
41 BpmModelMetaInfoVO metaInfo = buildMetaInfo(model); 45 BpmModelMetaInfoVO metaInfo = buildMetaInfo(model);
42 BpmFormDO form = metaInfo != null ? formMap.get(metaInfo.getFormId()) : null; 46 BpmFormDO form = metaInfo != null ? formMap.get(metaInfo.getFormId()) : null;
43 BpmCategoryDO category = categoryMap.get(model.getCategory()); 47 BpmCategoryDO category = categoryMap.get(model.getCategory());
44 Deployment deployment = model.getDeploymentId() != null ? deploymentMap.get(model.getDeploymentId()) : null; 48 Deployment deployment = model.getDeploymentId() != null ? deploymentMap.get(model.getDeploymentId()) : null;
45 ProcessDefinition processDefinition = model.getDeploymentId() != null ? processDefinitionMap.get(model.getDeploymentId()) : null; 49 ProcessDefinition processDefinition = model.getDeploymentId() != null ? processDefinitionMap.get(model.getDeploymentId()) : null;
46 - return buildModel0(model, metaInfo, form, category, deployment, processDefinition); 50 + List<AdminUserRespDTO> startUsers = metaInfo != null ? convertList(metaInfo.getStartUserIds(), userMap::get) : null;
  51 + return buildModel0(model, metaInfo, form, category, deployment, processDefinition, startUsers);
47 }); 52 });
48 return new PageResult<>(list, pageResult.getTotal()); 53 return new PageResult<>(list, pageResult.getTotal());
49 } 54 }
@@ -51,7 +56,7 @@ public interface BpmModelConvert { @@ -51,7 +56,7 @@ public interface BpmModelConvert {
51 default BpmModelRespVO buildModel(Model model, 56 default BpmModelRespVO buildModel(Model model,
52 byte[] bpmnBytes) { 57 byte[] bpmnBytes) {
53 BpmModelMetaInfoVO metaInfo = buildMetaInfo(model); 58 BpmModelMetaInfoVO metaInfo = buildMetaInfo(model);
54 - BpmModelRespVO modelVO = buildModel0(model, metaInfo, null, null, null, null); 59 + BpmModelRespVO modelVO = buildModel0(model, metaInfo, null, null, null, null, null);
55 if (ArrayUtil.isNotEmpty(bpmnBytes)) { 60 if (ArrayUtil.isNotEmpty(bpmnBytes)) {
56 modelVO.setBpmnXml(BpmnModelUtils.getBpmnXml(bpmnBytes)); 61 modelVO.setBpmnXml(BpmnModelUtils.getBpmnXml(bpmnBytes));
57 } 62 }
@@ -60,7 +65,8 @@ public interface BpmModelConvert { @@ -60,7 +65,8 @@ public interface BpmModelConvert {
60 65
61 default BpmModelRespVO buildModel0(Model model, 66 default BpmModelRespVO buildModel0(Model model,
62 BpmModelMetaInfoVO metaInfo, BpmFormDO form, BpmCategoryDO category, 67 BpmModelMetaInfoVO metaInfo, BpmFormDO form, BpmCategoryDO category,
63 - Deployment deployment, ProcessDefinition processDefinition) { 68 + Deployment deployment, ProcessDefinition processDefinition,
  69 + List<AdminUserRespDTO> startUsers) {
64 BpmModelRespVO modelRespVO = new BpmModelRespVO().setId(model.getId()).setName(model.getName()) 70 BpmModelRespVO modelRespVO = new BpmModelRespVO().setId(model.getId()).setName(model.getName())
65 .setKey(model.getKey()).setCategory(model.getCategory()) 71 .setKey(model.getKey()).setCategory(model.getCategory())
66 .setCreateTime(DateUtils.of(model.getCreateTime())); 72 .setCreateTime(DateUtils.of(model.getCreateTime()));
@@ -82,6 +88,8 @@ public interface BpmModelConvert { @@ -82,6 +88,8 @@ public interface BpmModelConvert {
82 modelRespVO.getProcessDefinition().setDeploymentTime(DateUtils.of(deployment.getDeploymentTime())); 88 modelRespVO.getProcessDefinition().setDeploymentTime(DateUtils.of(deployment.getDeploymentTime()));
83 } 89 }
84 } 90 }
  91 + // User
  92 + modelRespVO.setStartUsers(BeanUtils.toBean(startUsers, UserSimpleBaseVO.class));
85 return modelRespVO; 93 return modelRespVO;
86 } 94 }
87 95
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessDefinitionInfoDO.java
1 package cn.iocoder.yudao.module.bpm.dal.dataobject.definition; 1 package cn.iocoder.yudao.module.bpm.dal.dataobject.definition;
2 2
3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.framework.mybatis.core.type.StringListTypeHandler;
4 import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum; 5 import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum;
5 import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelTypeEnum; 6 import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelTypeEnum;
  7 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
6 import com.baomidou.mybatisplus.annotation.TableField; 8 import com.baomidou.mybatisplus.annotation.TableField;
7 import com.baomidou.mybatisplus.annotation.TableId; 9 import com.baomidou.mybatisplus.annotation.TableId;
8 import com.baomidou.mybatisplus.annotation.TableName; 10 import com.baomidou.mybatisplus.annotation.TableName;
@@ -119,4 +121,26 @@ public class BpmProcessDefinitionInfoDO extends BaseDO { @@ -119,4 +121,26 @@ public class BpmProcessDefinitionInfoDO extends BaseDO {
119 */ 121 */
120 private Boolean visible; 122 private Boolean visible;
121 123
  124 + /**
  125 + * 可发起用户编号数组
  126 + *
  127 + * 关联 {@link AdminUserRespDTO#getId()} 字段的数组
  128 + *
  129 + * 如果为空,则表示“全部可以发起”!
  130 + *
  131 + * 它和 {@link #visible} 的区别在于:
  132 + * 1. {@link #visible} 只是决定是否可见。即使不可见,还是可以发起
  133 + * 2. startUserIds 决定某个用户是否可以发起。如果该用户不可发起,则他也是不可见的
  134 + */
  135 + @TableField(typeHandler = StringListTypeHandler.class) // 为了可以使用 find_in_set 进行过滤
  136 + private List<Long> startUserIds;
  137 +
  138 + /**
  139 + * 可管理用户编号数组
  140 + *
  141 + * 关联 {@link AdminUserRespDTO#getId()} 字段的数组
  142 + */
  143 + @TableField(typeHandler = StringListTypeHandler.class) // 为了可以使用 find_in_set 进行过滤
  144 + private List<Long> managerUserIds;
  145 +
122 } 146 }