ソースを参照

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

YunaiV 8 ヶ月 前
コミット
90ced26b01

+ 4 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/base/package-info.java

@@ -0,0 +1,4 @@
+/**
+ * 基础包,放一些通用的 VO 类
+ */
+package cn.iocoder.yudao.module.bpm.controller.admin.base;

+ 19 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/base/user/UserSimpleBaseVO.java

@@ -0,0 +1,19 @@
+package cn.iocoder.yudao.module.bpm.controller.admin.base.user;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Schema(description = "用户精简信息 VO")
+@Data
+public class UserSimpleBaseVO {
+
+    @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    private Long id;
+
+    @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
+    private String nickname;
+
+    @Schema(description = "用户头像", example = "https://www.iocoder.cn/1.png")
+    private String avatar;
+
+}

+ 14 - 1
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;
 import cn.iocoder.yudao.module.bpm.service.definition.BpmFormService;
 import cn.iocoder.yudao.module.bpm.service.definition.BpmModelService;
 import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
+import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
+import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -31,6 +33,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Stream;
 
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
@@ -51,6 +54,9 @@ public class BpmModelController {
     @Resource
     private BpmProcessDefinitionService processDefinitionService;
 
+    @Resource
+    private AdminUserApi adminUserApi;
+
     @GetMapping("/page")
     @Operation(summary = "获得模型分页")
     public CommonResult<PageResult<BpmModelRespVO>> getModelPage(BpmModelPageReqVO pageVO) {
@@ -76,7 +82,14 @@ public class BpmModelController {
         // 获得 ProcessDefinition Map
         List<ProcessDefinition> processDefinitions = processDefinitionService.getProcessDefinitionListByDeploymentIds(deploymentIds);
         Map<String, ProcessDefinition> processDefinitionMap = convertMap(processDefinitions, ProcessDefinition::getDeploymentId);
-        return success(BpmModelConvert.INSTANCE.buildModelPage(pageResult, formMap, categoryMap, deploymentMap, processDefinitionMap));
+        // 获得 User Map
+        Set<Long> userIds = CollectionUtils.convertSetByFlatMap(pageResult.getList(), model -> {
+            BpmModelMetaInfoVO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoVO.class);
+            return metaInfo != null ? metaInfo.getStartUserIds().stream() : Stream.empty();
+        });
+        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);
+        return success(BpmModelConvert.INSTANCE.buildModelPage(pageResult,
+                formMap, categoryMap, deploymentMap, processDefinitionMap, userMap));
     }
 
     @GetMapping("/get")

+ 9 - 0
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;
 import lombok.Data;
 import org.hibernate.validator.constraints.URL;
 
+import java.util.List;
+
 /**
  * BPM 流程 MetaInfo Response DTO
  * 主要用于 { Model#setMetaInfo(String)} 的存储
@@ -50,4 +52,11 @@ public class BpmModelMetaInfoVO {
     @NotNull(message = "是否可见不能为空")
     private Boolean visible;
 
+    @Schema(description = "可发起用户编号数组", example = "[1,2,3]")
+    private List<Long> startUserIds;
+
+    @Schema(description = "可管理用户编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "[2,4,6]")
+    @NotEmpty(message = "可管理用户编号数组不能为空")
+    private List<Long> managerUserIds;
+
 }

+ 5 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelRespVO.java

@@ -1,10 +1,12 @@
 package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model;
 
+import cn.iocoder.yudao.module.bpm.controller.admin.base.user.UserSimpleBaseVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
 import java.time.LocalDateTime;
+import java.util.List;
 
 @Schema(description = "管理后台 - 流程模型 Response VO")
 @Data
@@ -36,6 +38,9 @@ public class BpmModelRespVO extends BpmModelMetaInfoVO {
     @Schema(description = "BPMN XML", requiredMode = Schema.RequiredMode.REQUIRED)
     private String bpmnXml;
 
+    @Schema(description = "可发起的用户数组")
+    private List<UserSimpleBaseVO> startUsers;
+
     /**
      * 最新部署的流程定义
      */

+ 1 - 0
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;
 import jakarta.validation.constraints.AssertTrue;
 import lombok.Data;
 
+// TODO @jason:这个可以简化下,使用 @RequestParam。嘿嘿,主要 VO 项不要太多
 @Schema(description = "管理后台 - 审批详情 Request VO")
 @Data
 public class BpmApprovalDetailReqVO {

+ 1 - 0
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 {
 
     }
 
+    // TODO @jason:可以替换成 UserSimpleBaseVO。简化下
     @Schema(description = "用户信息")
     @Data
     public static class User {

+ 15 - 7
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;
 
 import cn.hutool.core.util.ArrayUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.framework.common.util.date.DateUtils;
 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.bpm.controller.admin.base.user.UserSimpleBaseVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelMetaInfoVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelRespVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelSaveReqVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
 import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
-import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelMetaInfoVO;
+import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 import org.flowable.common.engine.impl.db.SuspensionState;
 import org.flowable.engine.repository.Deployment;
 import org.flowable.engine.repository.Model;
@@ -23,6 +24,8 @@ import org.mapstruct.factory.Mappers;
 import java.util.List;
 import java.util.Map;
 
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
+
 /**
  * 流程模型 Convert
  *
@@ -36,14 +39,16 @@ public interface BpmModelConvert {
     default PageResult<BpmModelRespVO> buildModelPage(PageResult<Model> pageResult,
                                                       Map<Long, BpmFormDO> formMap,
                                                       Map<String, BpmCategoryDO> categoryMap, Map<String, Deployment> deploymentMap,
-                                                      Map<String, ProcessDefinition> processDefinitionMap) {
-        List<BpmModelRespVO> list = CollectionUtils.convertList(pageResult.getList(), model -> {
+                                                      Map<String, ProcessDefinition> processDefinitionMap,
+                                                      Map<Long, AdminUserRespDTO> userMap) {
+        List<BpmModelRespVO> list = convertList(pageResult.getList(), model -> {
             BpmModelMetaInfoVO metaInfo = buildMetaInfo(model);
             BpmFormDO form = metaInfo != null ? formMap.get(metaInfo.getFormId()) : null;
             BpmCategoryDO category = categoryMap.get(model.getCategory());
             Deployment deployment = model.getDeploymentId() != null ? deploymentMap.get(model.getDeploymentId()) : null;
             ProcessDefinition processDefinition = model.getDeploymentId() != null ? processDefinitionMap.get(model.getDeploymentId()) : null;
-            return buildModel0(model, metaInfo, form, category, deployment, processDefinition);
+            List<AdminUserRespDTO> startUsers = metaInfo != null ? convertList(metaInfo.getStartUserIds(), userMap::get) : null;
+            return buildModel0(model, metaInfo, form, category, deployment, processDefinition, startUsers);
         });
         return new PageResult<>(list, pageResult.getTotal());
     }
@@ -51,7 +56,7 @@ public interface BpmModelConvert {
     default BpmModelRespVO buildModel(Model model,
                                      byte[] bpmnBytes) {
         BpmModelMetaInfoVO metaInfo = buildMetaInfo(model);
-        BpmModelRespVO modelVO = buildModel0(model, metaInfo, null, null, null, null);
+        BpmModelRespVO modelVO = buildModel0(model, metaInfo, null, null, null, null, null);
         if (ArrayUtil.isNotEmpty(bpmnBytes)) {
             modelVO.setBpmnXml(BpmnModelUtils.getBpmnXml(bpmnBytes));
         }
@@ -60,7 +65,8 @@ public interface BpmModelConvert {
 
     default BpmModelRespVO buildModel0(Model model,
                                        BpmModelMetaInfoVO metaInfo, BpmFormDO form, BpmCategoryDO category,
-                                       Deployment deployment, ProcessDefinition processDefinition) {
+                                       Deployment deployment, ProcessDefinition processDefinition,
+                                       List<AdminUserRespDTO> startUsers) {
         BpmModelRespVO modelRespVO = new BpmModelRespVO().setId(model.getId()).setName(model.getName())
                 .setKey(model.getKey()).setCategory(model.getCategory())
                 .setCreateTime(DateUtils.of(model.getCreateTime()));
@@ -82,6 +88,8 @@ public interface BpmModelConvert {
                 modelRespVO.getProcessDefinition().setDeploymentTime(DateUtils.of(deployment.getDeploymentTime()));
             }
         }
+        // User
+        modelRespVO.setStartUsers(BeanUtils.toBean(startUsers, UserSimpleBaseVO.class));
         return modelRespVO;
     }
 

+ 24 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessDefinitionInfoDO.java

@@ -1,8 +1,10 @@
 package cn.iocoder.yudao.module.bpm.dal.dataobject.definition;
 
 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.mybatis.core.type.StringListTypeHandler;
 import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum;
 import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelTypeEnum;
+import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
@@ -119,4 +121,26 @@ public class BpmProcessDefinitionInfoDO extends BaseDO {
      */
     private Boolean visible;
 
+    /**
+     * 可发起用户编号数组
+     *
+     * 关联 {@link AdminUserRespDTO#getId()} 字段的数组
+     *
+     * 如果为空,则表示“全部可以发起”!
+     *
+     * 它和 {@link #visible} 的区别在于:
+     * 1. {@link #visible} 只是决定是否可见。即使不可见,还是可以发起
+     * 2. startUserIds 决定某个用户是否可以发起。如果该用户不可发起,则他也是不可见的
+     */
+    @TableField(typeHandler = StringListTypeHandler.class) // 为了可以使用 find_in_set 进行过滤
+    private List<Long> startUserIds;
+
+    /**
+     * 可管理用户编号数组
+     *
+     * 关联 {@link AdminUserRespDTO#getId()} 字段的数组
+     */
+    @TableField(typeHandler = StringListTypeHandler.class) // 为了可以使用 find_in_set 进行过滤
+    private List<Long> managerUserIds;
+
 }