Commit 73b68a10db8226a753aa472158a0ce26736179e4

Authored by YunaiV
1 parent ff23f866

【功能新增】工作流:流程模型增加批量修改 sort 接口

yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java
@@ -23,7 +23,7 @@ public interface ErrorCodeConstants { @@ -23,7 +23,7 @@ public interface ErrorCodeConstants {
23 "原因:用户任务({})未配置审批人,请点击【流程设计】按钮,选择该它的【任务(审批人)】进行配置"); 23 "原因:用户任务({})未配置审批人,请点击【流程设计】按钮,选择该它的【任务(审批人)】进行配置");
24 ErrorCode MODEL_DEPLOY_FAIL_BPMN_START_EVENT_NOT_EXISTS = new ErrorCode(1_009_002_005, "部署流程失败,原因:BPMN 流程图中,没有开始事件"); 24 ErrorCode MODEL_DEPLOY_FAIL_BPMN_START_EVENT_NOT_EXISTS = new ErrorCode(1_009_002_005, "部署流程失败,原因:BPMN 流程图中,没有开始事件");
25 ErrorCode MODEL_DEPLOY_FAIL_BPMN_USER_TASK_NAME_NOT_EXISTS = new ErrorCode(1_009_002_006, "部署流程失败,原因:BPMN 流程图中,用户任务({})的名字不存在"); 25 ErrorCode MODEL_DEPLOY_FAIL_BPMN_USER_TASK_NAME_NOT_EXISTS = new ErrorCode(1_009_002_006, "部署流程失败,原因:BPMN 流程图中,用户任务({})的名字不存在");
26 - ErrorCode MODEL_UPDATE_FAIL_NOT_MANAGER = new ErrorCode(1_009_002_007, "操作流程失败,原因:你不是该流程的管理员"); 26 + ErrorCode MODEL_UPDATE_FAIL_NOT_MANAGER = new ErrorCode(1_009_002_007, "操作流程失败,原因:你不是该流程({})的管理员");
27 27
28 // ========== 流程定义 1-009-003-000 ========== 28 // ========== 流程定义 1-009-003-000 ==========
29 ErrorCode PROCESS_DEFINITION_KEY_NOT_MATCH = new ErrorCode(1_009_003_000, "流程定义的标识期望是({}),当前是({}),请修改 BPMN 流程图"); 29 ErrorCode PROCESS_DEFINITION_KEY_NOT_MATCH = new ErrorCode(1_009_003_000, "流程定义的标识期望是({}),当前是({}),请修改 BPMN 流程图");
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java
@@ -26,7 +26,10 @@ import org.springframework.security.access.prepost.PreAuthorize; @@ -26,7 +26,10 @@ import org.springframework.security.access.prepost.PreAuthorize;
26 import org.springframework.validation.annotation.Validated; 26 import org.springframework.validation.annotation.Validated;
27 import org.springframework.web.bind.annotation.*; 27 import org.springframework.web.bind.annotation.*;
28 28
29 -import java.util.*; 29 +import java.util.Collections;
  30 +import java.util.List;
  31 +import java.util.Map;
  32 +import java.util.Set;
30 import java.util.stream.Stream; 33 import java.util.stream.Stream;
31 34
32 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 35 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -106,6 +109,7 @@ public class BpmModelController { @@ -106,6 +109,7 @@ public class BpmModelController {
106 return success(modelService.createModel(createRetVO)); 109 return success(modelService.createModel(createRetVO));
107 } 110 }
108 111
  112 +
109 @PutMapping("/update") 113 @PutMapping("/update")
110 @Operation(summary = "修改模型") 114 @Operation(summary = "修改模型")
111 @PreAuthorize("@ss.hasPermission('bpm:model:update')") 115 @PreAuthorize("@ss.hasPermission('bpm:model:update')")
@@ -114,6 +118,14 @@ public class BpmModelController { @@ -114,6 +118,14 @@ public class BpmModelController {
114 return success(true); 118 return success(true);
115 } 119 }
116 120
  121 + @PutMapping("/update-sort-batch")
  122 + @Operation(summary = "批量修改模型排序")
  123 + @Parameter(name = "ids", description = "编号数组", required = true, example = "1,2,3")
  124 + public CommonResult<Boolean> updateModelSortBatch(@RequestParam("ids") List<String> ids) {
  125 + modelService.updateModelSortBatch(getLoginUserId(), ids);
  126 + return success(true);
  127 + }
  128 +
117 @PostMapping("/deploy") 129 @PostMapping("/deploy")
118 @Operation(summary = "部署模型") 130 @Operation(summary = "部署模型")
119 @Parameter(name = "id", description = "编号", required = true, example = "1024") 131 @Parameter(name = "id", description = "编号", required = true, example = "1024")
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionRespVO.java
@@ -62,6 +62,9 @@ public class BpmProcessDefinitionRespVO { @@ -62,6 +62,9 @@ public class BpmProcessDefinitionRespVO {
62 @Schema(description = "BPMN XML") 62 @Schema(description = "BPMN XML")
63 private String bpmnXml; // 需要从对应的 BpmnModel 读取,非必须返回 63 private String bpmnXml; // 需要从对应的 BpmnModel 读取,非必须返回
64 64
  65 + @Schema(description = "流程定义排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  66 + private Long sort;
  67 +
65 @Schema(description = "发起用户需要选择审批人的任务数组") 68 @Schema(description = "发起用户需要选择审批人的任务数组")
66 private List<UserTask> startUserSelectTasks; // 需要从对应的 BpmnModel 读取,非必须返回 69 private List<UserTask> startUserSelectTasks; // 需要从对应的 BpmnModel 读取,非必须返回
67 70
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java
@@ -20,6 +20,7 @@ import org.mapstruct.Mapping; @@ -20,6 +20,7 @@ import org.mapstruct.Mapping;
20 import org.mapstruct.MappingTarget; 20 import org.mapstruct.MappingTarget;
21 import org.mapstruct.factory.Mappers; 21 import org.mapstruct.factory.Mappers;
22 22
  23 +import java.util.Comparator;
23 import java.util.List; 24 import java.util.List;
24 import java.util.Map; 25 import java.util.Map;
25 26
@@ -47,7 +48,7 @@ public interface BpmProcessDefinitionConvert { @@ -47,7 +48,7 @@ public interface BpmProcessDefinitionConvert {
47 Map<String, BpmProcessDefinitionInfoDO> processDefinitionInfoMap, 48 Map<String, BpmProcessDefinitionInfoDO> processDefinitionInfoMap,
48 Map<Long, BpmFormDO> formMap, 49 Map<Long, BpmFormDO> formMap,
49 Map<String, BpmCategoryDO> categoryMap) { 50 Map<String, BpmCategoryDO> categoryMap) {
50 - return CollectionUtils.convertList(list, definition -> { 51 + List<BpmProcessDefinitionRespVO> result = CollectionUtils.convertList(list, definition -> {
51 Deployment deployment = MapUtil.get(deploymentMap, definition.getDeploymentId(), Deployment.class); 52 Deployment deployment = MapUtil.get(deploymentMap, definition.getDeploymentId(), Deployment.class);
52 BpmProcessDefinitionInfoDO processDefinitionInfo = MapUtil.get(processDefinitionInfoMap, definition.getId(), BpmProcessDefinitionInfoDO.class); 53 BpmProcessDefinitionInfoDO processDefinitionInfo = MapUtil.get(processDefinitionInfoMap, definition.getId(), BpmProcessDefinitionInfoDO.class);
53 BpmFormDO form = null; 54 BpmFormDO form = null;
@@ -57,6 +58,9 @@ public interface BpmProcessDefinitionConvert { @@ -57,6 +58,9 @@ public interface BpmProcessDefinitionConvert {
57 BpmCategoryDO category = MapUtil.get(categoryMap, definition.getCategory(), BpmCategoryDO.class); 58 BpmCategoryDO category = MapUtil.get(categoryMap, definition.getCategory(), BpmCategoryDO.class);
58 return buildProcessDefinition(definition, deployment, processDefinitionInfo, form, category, null, null); 59 return buildProcessDefinition(definition, deployment, processDefinitionInfo, form, category, null, null);
59 }); 60 });
  61 + // 排序
  62 + result.sort(Comparator.comparing(BpmProcessDefinitionRespVO::getSort));
  63 + return result;
60 } 64 }
61 65
62 default BpmProcessDefinitionRespVO buildProcessDefinition(ProcessDefinition definition, 66 default BpmProcessDefinitionRespVO buildProcessDefinition(ProcessDefinition definition,
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessDefinitionInfoDO.java
@@ -121,6 +121,10 @@ public class BpmProcessDefinitionInfoDO extends BaseDO { @@ -121,6 +121,10 @@ public class BpmProcessDefinitionInfoDO extends BaseDO {
121 * 目的:如果 false 不可见,则不展示在“发起流程”的列表里 121 * 目的:如果 false 不可见,则不展示在“发起流程”的列表里
122 */ 122 */
123 private Boolean visible; 123 private Boolean visible;
  124 + /**
  125 + * 排序值
  126 + */
  127 + private Long sort;
124 128
125 /** 129 /**
126 * 可发起用户编号数组 130 * 可发起用户编号数组
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmProcessDefinitionInfoMapper.java
1 package cn.iocoder.yudao.module.bpm.dal.mysql.definition; 1 package cn.iocoder.yudao.module.bpm.dal.mysql.definition;
2 2
  3 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
3 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO; 4 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 5 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 import org.apache.ibatis.annotations.Mapper; 6 import org.apache.ibatis.annotations.Mapper;
@@ -18,4 +19,9 @@ public interface BpmProcessDefinitionInfoMapper extends BaseMapperX&lt;BpmProcessDe @@ -18,4 +19,9 @@ public interface BpmProcessDefinitionInfoMapper extends BaseMapperX&lt;BpmProcessDe
18 return selectOne(BpmProcessDefinitionInfoDO::getProcessDefinitionId, processDefinitionId); 19 return selectOne(BpmProcessDefinitionInfoDO::getProcessDefinitionId, processDefinitionId);
19 } 20 }
20 21
  22 + default void updateByModelId(String modelId, BpmProcessDefinitionInfoDO updateObj) {
  23 + update(updateObj,
  24 + new LambdaQueryWrapperX<BpmProcessDefinitionInfoDO>().eq(BpmProcessDefinitionInfoDO::getModelId, modelId));
  25 + }
  26 +
21 } 27 }
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmCategoryService.java
@@ -83,7 +83,7 @@ public interface BpmCategoryService { @@ -83,7 +83,7 @@ public interface BpmCategoryService {
83 List<BpmCategoryDO> getCategoryListByStatus(Integer status); 83 List<BpmCategoryDO> getCategoryListByStatus(Integer status);
84 84
85 /** 85 /**
86 - * 更新流程分类的排序:每个分类的 sort 值,从 0 开始递增 86 + * 批量更新流程分类的排序:每个分类的 sort 值,从 0 开始递增
87 * 87 *
88 * @param ids 分类编号列表 88 * @param ids 分类编号列表
89 */ 89 */
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java
@@ -65,6 +65,14 @@ public interface BpmModelService { @@ -65,6 +65,14 @@ public interface BpmModelService {
65 void updateModel(Long userId, @Valid BpmModelSaveReqVO updateReqVO); 65 void updateModel(Long userId, @Valid BpmModelSaveReqVO updateReqVO);
66 66
67 /** 67 /**
  68 + * 批量更新模型排序
  69 + *
  70 + * @param userId 用户编号
  71 + * @param ids 编号列表
  72 + */
  73 + void updateModelSortBatch(Long userId, List<String> ids);
  74 +
  75 + /**
68 * 将流程模型,部署成一个流程定义 76 * 将流程模型,部署成一个流程定义
69 * 77 *
70 * @param userId 用户编号 78 * @param userId 用户编号
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java
@@ -32,9 +32,11 @@ import org.springframework.transaction.annotation.Transactional; @@ -32,9 +32,11 @@ import org.springframework.transaction.annotation.Transactional;
32 import org.springframework.validation.annotation.Validated; 32 import org.springframework.validation.annotation.Validated;
33 33
34 import java.util.List; 34 import java.util.List;
  35 +import java.util.Map;
35 import java.util.Objects; 36 import java.util.Objects;
36 37
37 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 38 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  39 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
38 import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; 40 import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
39 41
40 /** 42 /**
@@ -102,6 +104,34 @@ public class BpmModelServiceImpl implements BpmModelService { @@ -102,6 +104,34 @@ public class BpmModelServiceImpl implements BpmModelService {
102 repositoryService.saveModel(model); 104 repositoryService.saveModel(model);
103 } 105 }
104 106
  107 + @Override
  108 + @Transactional(rollbackFor = Exception.class)
  109 + public void updateModelSortBatch(Long userId, List<String> ids) {
  110 + // 1.1 校验流程模型存在
  111 + List<Model> models = repositoryService.createModelQuery()
  112 + .modelTenantId(FlowableUtils.getTenantId()).list();
  113 + models.removeIf(model ->!ids.contains(model.getId()));
  114 + if (ids.size() != models.size()) {
  115 + throw exception(MODEL_NOT_EXISTS);
  116 + }
  117 + Map<String, Model> modelMap = convertMap(models, Model::getId);
  118 + // 1.2 校验是否为管理员
  119 + ids.forEach(id -> validateModelManager(id, userId));
  120 +
  121 + // 保存排序
  122 + long sort = System.currentTimeMillis(); // 使用时间戳 - i 作为排序
  123 + for (int i = ids.size() - 1; i > 0; i--) {
  124 + Model model = modelMap.get(ids.get(i));
  125 + // 更新模型
  126 + BpmModelMetaInfoVO metaInfo = BpmModelConvert.INSTANCE.parseMetaInfo(model).setSort(sort);
  127 + model.setMetaInfo(JsonUtils.toJsonString(metaInfo));
  128 + repositoryService.saveModel(model);
  129 + // 更新排序
  130 + processDefinitionService.updateProcessDefinitionSortByModelId(model.getId(), sort);
  131 + sort--;
  132 + }
  133 + }
  134 +
105 private Model validateModelExists(String id) { 135 private Model validateModelExists(String id) {
106 Model model = repositoryService.getModel(id); 136 Model model = repositoryService.getModel(id);
107 if (model == null) { 137 if (model == null) {
@@ -121,7 +151,7 @@ public class BpmModelServiceImpl implements BpmModelService { @@ -121,7 +151,7 @@ public class BpmModelServiceImpl implements BpmModelService {
121 Model model = validateModelExists(id); 151 Model model = validateModelExists(id);
122 BpmModelMetaInfoVO metaInfo = BpmModelConvert.INSTANCE.parseMetaInfo(model); 152 BpmModelMetaInfoVO metaInfo = BpmModelConvert.INSTANCE.parseMetaInfo(model);
123 if (metaInfo == null || !CollUtil.contains(metaInfo.getManagerUserIds(), userId)) { 153 if (metaInfo == null || !CollUtil.contains(metaInfo.getManagerUserIds(), userId)) {
124 - throw exception(MODEL_UPDATE_FAIL_NOT_MANAGER); 154 + throw exception(MODEL_UPDATE_FAIL_NOT_MANAGER, model.getName());
125 } 155 }
126 return model; 156 return model;
127 } 157 }
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java
@@ -18,7 +18,7 @@ import java.util.Set; @@ -18,7 +18,7 @@ import java.util.Set;
18 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; 18 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
19 19
20 /** 20 /**
21 - * Flowable流程定义接口 21 + * 流程定义接口
22 * 22 *
23 * @author yunlong.li 23 * @author yunlong.li
24 * @author ZJQ 24 * @author ZJQ
@@ -64,6 +64,14 @@ public interface BpmProcessDefinitionService { @@ -64,6 +64,14 @@ public interface BpmProcessDefinitionService {
64 void updateProcessDefinitionState(String id, Integer state); 64 void updateProcessDefinitionState(String id, Integer state);
65 65
66 /** 66 /**
  67 + * 更新模型编号
  68 + *
  69 + * @param modelId 流程定义编号
  70 + * @param sort 排序
  71 + */
  72 + void updateProcessDefinitionSortByModelId(String modelId, Long sort);
  73 +
  74 + /**
67 * 获得流程定义对应的 BPMN 75 * 获得流程定义对应的 BPMN
68 * 76 *
69 * @param id 流程定义编号 77 * @param id 流程定义编号
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java
@@ -173,6 +173,11 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ @@ -173,6 +173,11 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
173 } 173 }
174 174
175 @Override 175 @Override
  176 + public void updateProcessDefinitionSortByModelId(String modelId, Long sort) {
  177 + processDefinitionMapper.updateByModelId(modelId, new BpmProcessDefinitionInfoDO().setSort(sort));
  178 + }
  179 +
  180 + @Override
176 public BpmnModel getProcessDefinitionBpmnModel(String id) { 181 public BpmnModel getProcessDefinitionBpmnModel(String id) {
177 return repositoryService.getBpmnModel(id); 182 return repositoryService.getBpmnModel(id);
178 } 183 }