瀏覽代碼

Merge remote-tracking branch 'origin/feature/bpm' into feature/bpm

# Conflicts:
#	yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java
jason 7 月之前
父節點
當前提交
5d5f0257f9
共有 21 個文件被更改,包括 196 次插入121 次删除
  1. 1 1
      yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java
  2. 0 1
      yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmTaskStatusEnum.java
  3. 9 0
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmCategoryController.java
  4. 24 17
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java
  5. 11 8
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelMetaInfoVO.java
  6. 0 23
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelPageReqVO.java
  7. 3 0
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionRespVO.java
  8. 1 4
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java
  9. 27 16
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmModelConvert.java
  10. 5 1
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java
  11. 5 5
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java
  12. 4 0
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessDefinitionInfoDO.java
  13. 6 0
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmProcessDefinitionInfoMapper.java
  14. 7 0
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmCategoryService.java
  15. 26 9
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmCategoryServiceImpl.java
  16. 15 7
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java
  17. 37 25
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java
  18. 9 1
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java
  19. 5 0
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java
  20. 0 0
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java
  21. 1 3
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java

+ 1 - 1
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 {
             "原因:用户任务({})未配置审批人,请点击【流程设计】按钮,选择该它的【任务(审批人)】进行配置");
     ErrorCode MODEL_DEPLOY_FAIL_BPMN_START_EVENT_NOT_EXISTS = new ErrorCode(1_009_002_005, "部署流程失败,原因:BPMN 流程图中,没有开始事件");
     ErrorCode MODEL_DEPLOY_FAIL_BPMN_USER_TASK_NAME_NOT_EXISTS = new ErrorCode(1_009_002_006, "部署流程失败,原因:BPMN 流程图中,用户任务({})的名字不存在");
-    ErrorCode MODEL_UPDATE_FAIL_NOT_MANAGER = new ErrorCode(1_009_002_007, "操作流程失败,原因:你不是该流程的管理员");
+    ErrorCode MODEL_UPDATE_FAIL_NOT_MANAGER = new ErrorCode(1_009_002_007, "操作流程失败,原因:你不是该流程({})的管理员");
 
     // ========== 流程定义 1-009-003-000 ==========
     ErrorCode PROCESS_DEFINITION_KEY_NOT_MATCH = new ErrorCode(1_009_003_000, "流程定义的标识期望是({}),当前是({}),请修改 BPMN 流程图");

+ 0 - 1
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmTaskStatusEnum.java

@@ -21,7 +21,6 @@ public enum BpmTaskStatusEnum {
     CANCEL(4, "已取消"),
 
     RETURN(5, "已退回"),
-    DELEGATE(6, "委派中"),
 
     /**
      * 使用场景:

+ 9 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmCategoryController.java

@@ -48,6 +48,15 @@ public class BpmCategoryController {
         return success(true);
     }
 
+    @PutMapping("/update-sort-batch")
+    @Operation(summary = "批量更新流程分类的排序")
+    @Parameter(name = "ids", description = "分类编号列表", required = true, example = "1,2,3")
+    @PreAuthorize("@ss.hasPermission('bpm:category:update')")
+    public CommonResult<Boolean> updateCategorySortBatch(@RequestParam("ids") List<Long> ids) {
+        categoryService.updateCategorySortBatch(ids);
+        return success(true);
+    }
+
     @DeleteMapping("/delete")
     @Operation(summary = "删除流程分类")
     @Parameter(name = "id", description = "编号", required = true)

+ 24 - 17
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java

@@ -2,8 +2,6 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition;
 
 import cn.hutool.core.collection.CollUtil;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelUpdateReqVO;
@@ -28,7 +26,7 @@ import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
-import java.util.HashSet;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -56,38 +54,38 @@ public class BpmModelController {
     @Resource
     private AdminUserApi adminUserApi;
 
-    @GetMapping("/page")
+    @GetMapping("/list")
     @Operation(summary = "获得模型分页")
-    public CommonResult<PageResult<BpmModelRespVO>> getModelPage(BpmModelPageReqVO pageVO) {
-        PageResult<Model> pageResult = modelService.getModelPage(pageVO);
-        if (CollUtil.isEmpty(pageResult.getList())) {
-            return success(PageResult.empty(pageResult.getTotal()));
+    @Parameter(name = "name", description = "模型名称", example = "芋艿")
+    public CommonResult<List<BpmModelRespVO>> getModelPage(@RequestParam(value = "name", required = false) String name) {
+        List<Model> list = modelService.getModelList(name);
+        if (CollUtil.isEmpty(list)) {
+            return success(Collections.emptyList());
         }
 
-        // 拼接数据
         // 获得 Form 表单
-        Set<Long> formIds = convertSet(pageResult.getList(), model -> {
+        Set<Long> formIds = convertSet(list, model -> {
             BpmModelMetaInfoVO metaInfo = BpmModelConvert.INSTANCE.parseMetaInfo(model);
             return metaInfo != null ? metaInfo.getFormId() : null;
         });
         Map<Long, BpmFormDO> formMap = formService.getFormMap(formIds);
         // 获得 Category Map
         Map<String, BpmCategoryDO> categoryMap = categoryService.getCategoryMap(
-                convertSet(pageResult.getList(), Model::getCategory));
+                convertSet(list, Model::getCategory));
         // 获得 Deployment Map
-        Set<String> deploymentIds = new HashSet<>();
-        pageResult.getList().forEach(model -> CollectionUtils.addIfNotNull(deploymentIds, model.getDeploymentId()));
-        Map<String, Deployment> deploymentMap = processDefinitionService.getDeploymentMap(deploymentIds);
+        Map<String, Deployment> deploymentMap = processDefinitionService.getDeploymentMap(
+                convertSet(list, Model::getDeploymentId));
         // 获得 ProcessDefinition Map
-        List<ProcessDefinition> processDefinitions = processDefinitionService.getProcessDefinitionListByDeploymentIds(deploymentIds);
+        List<ProcessDefinition> processDefinitions = processDefinitionService.getProcessDefinitionListByDeploymentIds(
+                deploymentMap.keySet());
         Map<String, ProcessDefinition> processDefinitionMap = convertMap(processDefinitions, ProcessDefinition::getDeploymentId);
         // 获得 User Map
-        Set<Long> userIds = convertSetByFlatMap(pageResult.getList(), model -> {
+        Set<Long> userIds = convertSetByFlatMap(list, model -> {
             BpmModelMetaInfoVO metaInfo = BpmModelConvert.INSTANCE.parseMetaInfo(model);
             return metaInfo != null ? metaInfo.getStartUserIds().stream() : Stream.empty();
         });
         Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);
-        return success(BpmModelConvert.INSTANCE.buildModelPage(pageResult,
+        return success(BpmModelConvert.INSTANCE.buildModelList(list,
                 formMap, categoryMap, deploymentMap, processDefinitionMap, userMap));
     }
 
@@ -111,6 +109,7 @@ public class BpmModelController {
         return success(modelService.createModel(createRetVO));
     }
 
+
     @PutMapping("/update")
     @Operation(summary = "修改模型")
     @PreAuthorize("@ss.hasPermission('bpm:model:update')")
@@ -119,6 +118,14 @@ public class BpmModelController {
         return success(true);
     }
 
+    @PutMapping("/update-sort-batch")
+    @Operation(summary = "批量修改模型排序")
+    @Parameter(name = "ids", description = "编号数组", required = true, example = "1,2,3")
+    public CommonResult<Boolean> updateModelSortBatch(@RequestParam("ids") List<String> ids) {
+        modelService.updateModelSortBatch(getLoginUserId(), ids);
+        return success(true);
+    }
+
     @PostMapping("/deploy")
     @Operation(summary = "部署模型")
     @Parameter(name = "id", description = "编号", required = true, example = "1024")

+ 11 - 8
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelMetaInfoVO.java

@@ -15,7 +15,9 @@ import java.util.List;
  * BPM 流程 MetaInfo Response DTO
  * 主要用于 { Model#setMetaInfo(String)} 的存储
  *
- * 最终,它的字段和 {@link cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO} 是一致的
+ * 最终,它的字段和
+ * {@link cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO}
+ * 是一致的
  *
  * @author 芋道源码
  */
@@ -40,13 +42,11 @@ public class BpmModelMetaInfoVO {
     @NotNull(message = "表单类型不能为空")
     private Integer formType;
     @Schema(description = "表单编号", example = "1024")
-    private Long formId;  // formType 为 NORMAL 使用,必须非空
-    @Schema(description = "自定义表单的提交路径,使用 Vue 的路由地址",
-            example = "/bpm/oa/leave/create")
-    private String formCustomCreatePath;  // 表单类型为 CUSTOM 时,必须非空
-    @Schema(description = "自定义表单的查看路径,使用 Vue 的路由地址",
-            example = "/bpm/oa/leave/view")
-    private String formCustomViewPath;  // 表单类型为 CUSTOM 时,必须非空
+    private Long formId; // formType 为 NORMAL 使用,必须非空
+    @Schema(description = "自定义表单的提交路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/create")
+    private String formCustomCreatePath; // 表单类型为 CUSTOM 时,必须非空
+    @Schema(description = "自定义表单的查看路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/view")
+    private String formCustomViewPath; // 表单类型为 CUSTOM 时,必须非空
 
     @Schema(description = "是否可见", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
     @NotNull(message = "是否可见不能为空")
@@ -59,4 +59,7 @@ public class BpmModelMetaInfoVO {
     @NotEmpty(message = "可管理用户编号数组不能为空")
     private List<Long> managerUserIds;
 
+    @Schema(description = "排序", example = "1")
+    private Long sort; // 创建时,后端自动生成
+
 }

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

@@ -1,23 +0,0 @@
-package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model;
-
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
-
-
-@Schema(description = "管理后台 - 流程模型分页 Request VO")
-@Data
-public class BpmModelPageReqVO extends PageParam {
-
-    @Schema(description = "标识,精准匹配", example = "process1641042089407")
-    private String key;
-
-    @Schema(description = "名字,模糊匹配", example = "芋道")
-    private String name;
-
-    @Schema(description = "流程分类", example = "1")
-    private String category;
-
-}

+ 3 - 0
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 {
     @Schema(description = "BPMN XML")
     private String bpmnXml; // 需要从对应的 BpmnModel 读取,非必须返回
 
+    @Schema(description = "流程定义排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    private Long sort;
+
     @Schema(description = "发起用户需要选择审批人的任务数组")
     private List<UserTask> startUserSelectTasks; // 需要从对应的 BpmnModel 读取,非必须返回
 

+ 1 - 4
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java

@@ -123,18 +123,15 @@ public class BpmTaskController {
         }
 
         // 拼接数据
-        HistoricProcessInstance processInstance = processInstanceService.getHistoricProcessInstance(processInstanceId);
-        // 获得 User 和 Dept Map
         Set<Long> userIds = convertSetByFlatMap(taskList, task ->
                 Stream.of(NumberUtils.parseLong(task.getAssignee()), NumberUtils.parseLong(task.getOwner())));
-        userIds.add(NumberUtils.parseLong(processInstance.getStartUserId()));
         Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);
         Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(
                 convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
         // 获得 Form Map
         Map<Long, BpmFormDO> formMap = formService.getFormMap(
                 convertSet(taskList, task -> NumberUtils.parseLong(task.getFormKey())));
-        return success(BpmTaskConvert.INSTANCE.buildTaskListByProcessInstanceId(taskList, processInstance,
+        return success(BpmTaskConvert.INSTANCE.buildTaskListByProcessInstanceId(taskList,
                 formMap, userMap, deptMap));
     }
 

+ 27 - 16
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmModelConvert.java

@@ -1,7 +1,6 @@
 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.date.DateUtils;
 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
@@ -22,6 +21,7 @@ import org.mapstruct.Mapper;
 import org.mapstruct.factory.Mappers;
 
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
 
@@ -37,25 +37,31 @@ public interface BpmModelConvert {
 
     BpmModelConvert INSTANCE = Mappers.getMapper(BpmModelConvert.class);
 
-    default PageResult<BpmModelRespVO> buildModelPage(PageResult<Model> pageResult,
-                                                      Map<Long, BpmFormDO> formMap,
-                                                      Map<String, BpmCategoryDO> categoryMap, Map<String, Deployment> deploymentMap,
-                                                      Map<String, ProcessDefinition> processDefinitionMap,
-                                                      Map<Long, AdminUserRespDTO> userMap) {
-        List<BpmModelRespVO> list = convertList(pageResult.getList(), model -> {
+    default List<BpmModelRespVO> buildModelList(List<Model> list,
+                                                Map<Long, BpmFormDO> formMap,
+                                                Map<String, BpmCategoryDO> categoryMap,
+                                                Map<String, Deployment> deploymentMap,
+                                                Map<String, ProcessDefinition> processDefinitionMap,
+                                                Map<Long, AdminUserRespDTO> userMap) {
+        List<BpmModelRespVO> result = convertList(list, model -> {
             BpmModelMetaInfoVO metaInfo = parseMetaInfo(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;
-            List<AdminUserRespDTO> startUsers = metaInfo != null ? convertList(metaInfo.getStartUserIds(), userMap::get) : null;
+            ProcessDefinition processDefinition = model.getDeploymentId() != null
+                    ? processDefinitionMap.get(model.getDeploymentId())
+                    : null;
+            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());
+        // 排序
+        result.sort(Comparator.comparing(BpmModelMetaInfoVO::getSort));
+        return result;
     }
 
     default BpmModelRespVO buildModel(Model model,
-                                     byte[] bpmnBytes) {
+            byte[] bpmnBytes) {
         BpmModelMetaInfoVO metaInfo = parseMetaInfo(model);
         BpmModelRespVO modelVO = buildModel0(model, metaInfo, null, null, null, null, null);
         if (ArrayUtil.isNotEmpty(bpmnBytes)) {
@@ -65,9 +71,9 @@ public interface BpmModelConvert {
     }
 
     default BpmModelRespVO buildModel0(Model model,
-                                       BpmModelMetaInfoVO metaInfo, BpmFormDO form, BpmCategoryDO category,
-                                       Deployment deployment, ProcessDefinition processDefinition,
-                                       List<AdminUserRespDTO> startUsers) {
+            BpmModelMetaInfoVO metaInfo, BpmFormDO form, BpmCategoryDO category,
+            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()));
@@ -83,8 +89,9 @@ public interface BpmModelConvert {
         // ProcessDefinition
         if (processDefinition != null) {
             modelRespVO.setProcessDefinition(BeanUtils.toBean(processDefinition, BpmProcessDefinitionRespVO.class));
-            modelRespVO.getProcessDefinition().setSuspensionState(processDefinition.isSuspended() ?
-                    SuspensionState.SUSPENDED.getStateCode() : SuspensionState.ACTIVE.getStateCode());
+            modelRespVO.getProcessDefinition()
+                    .setSuspensionState(processDefinition.isSuspended() ? SuspensionState.SUSPENDED.getStateCode()
+                            : SuspensionState.ACTIVE.getStateCode());
             if (deployment != null) {
                 modelRespVO.getProcessDefinition().setDeploymentTime(DateUtils.of(deployment.getDeploymentTime()));
             }
@@ -112,6 +119,10 @@ public interface BpmModelConvert {
         if (vo.getStartUserIds() == null) {
             vo.setStartUserIds(Collections.emptyList());
         }
+        // 如果为空,兜底处理,使用 createTime 创建时间
+        if (vo.getSort() == null) {
+            vo.setSort(model.getCreateTime().getTime());
+        }
         return vo;
     }
 

+ 5 - 1
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;
 import org.mapstruct.MappingTarget;
 import org.mapstruct.factory.Mappers;
 
+import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
 
@@ -47,7 +48,7 @@ public interface BpmProcessDefinitionConvert {
                                                                         Map<String, BpmProcessDefinitionInfoDO> processDefinitionInfoMap,
                                                                         Map<Long, BpmFormDO> formMap,
                                                                         Map<String, BpmCategoryDO> categoryMap) {
-        return CollectionUtils.convertList(list, definition -> {
+        List<BpmProcessDefinitionRespVO> result = CollectionUtils.convertList(list, definition -> {
             Deployment deployment = MapUtil.get(deploymentMap, definition.getDeploymentId(), Deployment.class);
             BpmProcessDefinitionInfoDO processDefinitionInfo = MapUtil.get(processDefinitionInfoMap, definition.getId(), BpmProcessDefinitionInfoDO.class);
             BpmFormDO form = null;
@@ -57,6 +58,9 @@ public interface BpmProcessDefinitionConvert {
             BpmCategoryDO category = MapUtil.get(categoryMap, definition.getCategory(), BpmCategoryDO.class);
             return buildProcessDefinition(definition, deployment, processDefinitionInfo, form, category, null, null);
         });
+        // 排序
+        result.sort(Comparator.comparing(BpmProcessDefinitionRespVO::getSort));
+        return result;
     }
 
     default BpmProcessDefinitionRespVO buildProcessDefinition(ProcessDefinition definition,

+ 5 - 5
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java

@@ -9,6 +9,7 @@ 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.task.vo.task.BpmTaskRespVO;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
+import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
 import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
 import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO;
 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
@@ -78,18 +79,17 @@ public interface BpmTaskConvert {
     }
 
     default List<BpmTaskRespVO> buildTaskListByProcessInstanceId(List<HistoricTaskInstance> taskList,
-                                                                 HistoricProcessInstance processInstance,
                                                                  Map<Long, BpmFormDO> formMap,
                                                                  Map<Long, AdminUserRespDTO> userMap,
                                                                  Map<Long, DeptRespDTO> deptMap) {
         return CollectionUtils.convertList(taskList, task -> {
+            // 特殊:已取消的任务,不返回
             BpmTaskRespVO taskVO = BeanUtils.toBean(task, BpmTaskRespVO.class);
             Integer taskStatus = FlowableUtils.getTaskStatus(task);
+            if (BpmTaskStatusEnum.isCancelStatus(taskStatus)) {
+                return null;
+            }
             taskVO.setStatus(taskStatus).setReason(FlowableUtils.getTaskReason(task));
-            // 流程实例
-            AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));
-            taskVO.setProcessInstance(BeanUtils.toBean(processInstance, BpmTaskRespVO.ProcessInstance.class));
-            taskVO.getProcessInstance().setStartUser(BeanUtils.toBean(startUser, UserSimpleBaseVO.class));
             // 表单信息
             BpmFormDO form = MapUtil.get(formMap, NumberUtils.parseLong(task.getFormKey()), BpmFormDO.class);
             if (form != null) {

+ 4 - 0
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 {
      * 目的:如果 false 不可见,则不展示在“发起流程”的列表里
      */
     private Boolean visible;
+    /**
+     * 排序值
+     */
+    private Long sort;
 
     /**
      * 可发起用户编号数组

+ 6 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmProcessDefinitionInfoMapper.java

@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.module.bpm.dal.mysql.definition;
 
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import org.apache.ibatis.annotations.Mapper;
@@ -18,4 +19,9 @@ public interface BpmProcessDefinitionInfoMapper extends BaseMapperX<BpmProcessDe
         return selectOne(BpmProcessDefinitionInfoDO::getProcessDefinitionId, processDefinitionId);
     }
 
+    default void updateByModelId(String modelId, BpmProcessDefinitionInfoDO updateObj) {
+        update(updateObj,
+                new LambdaQueryWrapperX<BpmProcessDefinitionInfoDO>().eq(BpmProcessDefinitionInfoDO::getModelId, modelId));
+    }
+
 }

+ 7 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmCategoryService.java

@@ -82,4 +82,11 @@ public interface BpmCategoryService {
      */
     List<BpmCategoryDO> getCategoryListByStatus(Integer status);
 
+    /**
+     * 批量更新流程分类的排序:每个分类的 sort 值,从 0 开始递增
+     *
+     * @param ids 分类编号列表
+     */
+    void updateCategorySortBatch(List<Long> ids);
+
 }

+ 26 - 9
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmCategoryServiceImpl.java

@@ -2,21 +2,22 @@ package cn.iocoder.yudao.module.bpm.service.definition;
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjUtil;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.category.BpmCategoryPageReqVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.category.BpmCategorySaveReqVO;
-import org.springframework.stereotype.Service;
-import jakarta.annotation.Resource;
-import org.springframework.validation.annotation.Validated;
-
 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-
 import cn.iocoder.yudao.module.bpm.dal.mysql.category.BpmCategoryMapper;
+import jakarta.annotation.Resource;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.validation.annotation.Validated;
 
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
@@ -58,7 +59,7 @@ public class BpmCategoryServiceImpl implements BpmCategoryService {
     private void validateCategoryNameUnique(BpmCategorySaveReqVO updateReqVO) {
         BpmCategoryDO category = bpmCategoryMapper.selectByName(updateReqVO.getName());
         if (category == null
-            || ObjUtil.equal(category.getId(), updateReqVO.getId())) {
+                || ObjUtil.equal(category.getId(), updateReqVO.getId())) {
             return;
         }
         throw exception(CATEGORY_NAME_DUPLICATE, updateReqVO.getName());
@@ -67,7 +68,7 @@ public class BpmCategoryServiceImpl implements BpmCategoryService {
     private void validateCategoryCodeUnique(BpmCategorySaveReqVO updateReqVO) {
         BpmCategoryDO category = bpmCategoryMapper.selectByCode(updateReqVO.getCode());
         if (category == null
-            || ObjUtil.equal(category.getId(), updateReqVO.getId())) {
+                || ObjUtil.equal(category.getId(), updateReqVO.getId())) {
             return;
         }
         throw exception(CATEGORY_CODE_DUPLICATE, updateReqVO.getCode());
@@ -110,4 +111,20 @@ public class BpmCategoryServiceImpl implements BpmCategoryService {
         return bpmCategoryMapper.selectListByStatus(status);
     }
 
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void updateCategorySortBatch(List<Long> ids) {
+        // 校验分类都存在
+        List<BpmCategoryDO> categories = bpmCategoryMapper.selectByIds(ids);
+        if (categories.size() != ids.size()) {
+            throw exception(CATEGORY_NOT_EXISTS);
+        }
+
+        // 批量更新排序
+        List<BpmCategoryDO> updateList = IntStream.range(0, ids.size())
+                .mapToObj(index -> new BpmCategoryDO().setId(ids.get(index)).setSort(index))
+                .collect(Collectors.toList());
+        bpmCategoryMapper.updateBatch(updateList);
+    }
+
 }

+ 15 - 7
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java

@@ -1,7 +1,5 @@
 package cn.iocoder.yudao.module.bpm.service.definition;
 
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelPageReqVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelSaveReqVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelUpdateReqVO;
@@ -9,20 +7,22 @@ import jakarta.validation.Valid;
 import org.flowable.bpmn.model.BpmnModel;
 import org.flowable.engine.repository.Model;
 
+import java.util.List;
+
 /**
- * Flowable流程模型接口
+ * 流程模型接口
  *
  * @author yunlongn
  */
 public interface BpmModelService {
 
     /**
-     * 获得流程模型分页
+     * 获得流程模型列表
      *
-     * @param pageVO 分页查询
-     * @return 流程模型分页
+     * @param name 模型名称
+     * @return 流程模型列表
      */
-    PageResult<Model> getModelPage(BpmModelPageReqVO pageVO);
+    List<Model> getModelList(String name);
 
     /**
      * 创建流程模型
@@ -64,6 +64,14 @@ public interface BpmModelService {
      */
     void updateModel(Long userId, @Valid BpmModelSaveReqVO updateReqVO);
 
+    /**
+     * 批量更新模型排序
+     *
+     * @param userId 用户编号
+     * @param ids 编号列表
+     */
+    void updateModelSortBatch(Long userId, List<String> ids);
+
     /**
      * 将流程模型,部署成一个流程定义
      *

+ 37 - 25
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java

@@ -3,12 +3,9 @@ package cn.iocoder.yudao.module.bpm.service.definition;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ArrayUtil;
 import cn.hutool.core.util.StrUtil;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
-import cn.iocoder.yudao.framework.common.util.object.PageUtils;
 import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelMetaInfoVO;
-import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelPageReqVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelSaveReqVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelUpdateReqVO;
@@ -35,14 +32,15 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
 import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
 
 /**
- * Flowable流程模型实现
- * 主要进行 Flowable {@link Model} 的维护
+ * 流程模型实现:主要进行 Flowable {@link Model} 的维护
  *
  * @author yunlongn
  * @author 芋道源码
@@ -64,27 +62,12 @@ public class BpmModelServiceImpl implements BpmModelService {
     private BpmTaskCandidateInvoker taskCandidateInvoker;
 
     @Override
-    public PageResult<Model> getModelPage(BpmModelPageReqVO pageVO) {
+    public List<Model> getModelList(String name) {
         ModelQuery modelQuery = repositoryService.createModelQuery();
-        modelQuery.modelTenantId(FlowableUtils.getTenantId());
-        if (StrUtil.isNotBlank(pageVO.getKey())) {
-            modelQuery.modelKey(pageVO.getKey());
+        if (StrUtil.isNotEmpty(name)) {
+            modelQuery.modelNameLike(name);
         }
-        if (StrUtil.isNotBlank(pageVO.getName())) {
-            modelQuery.modelNameLike("%" + pageVO.getName() + "%"); // 模糊匹配
-        }
-        if (StrUtil.isNotBlank(pageVO.getCategory())) {
-            modelQuery.modelCategory(pageVO.getCategory());
-        }
-        // 执行查询
-        long count = modelQuery.count();
-        if (count == 0) {
-            return PageResult.empty(count);
-        }
-        List<Model> models = modelQuery
-                .orderByCreateTime().desc()
-                .listPage(PageUtils.getStart(pageVO), pageVO.getPageSize());
-        return new PageResult<>(models, count);
+        return modelQuery.list();
     }
 
     @Override
@@ -100,6 +83,7 @@ public class BpmModelServiceImpl implements BpmModelService {
         }
 
         // 2.1 创建流程定义
+        createReqVO.setSort(System.currentTimeMillis()); // 使用当前时间,作为排序
         Model model = repositoryService.newModel();
         BpmModelConvert.INSTANCE.copyToModel(model, createReqVO);
         model.setTenantId(FlowableUtils.getTenantId());
@@ -120,6 +104,34 @@ public class BpmModelServiceImpl implements BpmModelService {
         repositoryService.saveModel(model);
     }
 
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void updateModelSortBatch(Long userId, List<String> ids) {
+        // 1.1 校验流程模型存在
+        List<Model> models = repositoryService.createModelQuery()
+                .modelTenantId(FlowableUtils.getTenantId()).list();
+        models.removeIf(model ->!ids.contains(model.getId()));
+        if (ids.size() != models.size()) {
+            throw exception(MODEL_NOT_EXISTS);
+        }
+        Map<String, Model> modelMap = convertMap(models, Model::getId);
+        // 1.2 校验是否为管理员
+        ids.forEach(id -> validateModelManager(id, userId));
+
+        // 保存排序
+        long sort = System.currentTimeMillis(); // 使用时间戳 - i 作为排序
+        for (int i = ids.size() - 1; i > 0; i--) {
+            Model model = modelMap.get(ids.get(i));
+            // 更新模型
+            BpmModelMetaInfoVO metaInfo = BpmModelConvert.INSTANCE.parseMetaInfo(model).setSort(sort);
+            model.setMetaInfo(JsonUtils.toJsonString(metaInfo));
+            repositoryService.saveModel(model);
+            // 更新排序
+            processDefinitionService.updateProcessDefinitionSortByModelId(model.getId(), sort);
+            sort--;
+        }
+    }
+
     private Model validateModelExists(String id) {
         Model model = repositoryService.getModel(id);
         if (model == null) {
@@ -139,7 +151,7 @@ public class BpmModelServiceImpl implements BpmModelService {
         Model model = validateModelExists(id);
         BpmModelMetaInfoVO metaInfo = BpmModelConvert.INSTANCE.parseMetaInfo(model);
         if (metaInfo == null || !CollUtil.contains(metaInfo.getManagerUserIds(), userId)) {
-            throw exception(MODEL_UPDATE_FAIL_NOT_MANAGER);
+            throw exception(MODEL_UPDATE_FAIL_NOT_MANAGER, model.getName());
         }
         return model;
     }

+ 9 - 1
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;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
 
 /**
- * Flowable流程定义接口
+ * 流程定义接口
  *
  * @author yunlong.li
  * @author ZJQ
@@ -63,6 +63,14 @@ public interface BpmProcessDefinitionService {
      */
     void updateProcessDefinitionState(String id, Integer state);
 
+    /**
+     * 更新模型编号
+     *
+     * @param modelId 流程定义编号
+     * @param sort 排序
+     */
+    void updateProcessDefinitionSortByModelId(String modelId, Long sort);
+
     /**
      * 获得流程定义对应的 BPMN
      *

+ 5 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java

@@ -172,6 +172,11 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
         log.error("[updateProcessDefinitionState][流程定义({}) 修改未知状态({})]", id, state);
     }
 
+    @Override
+    public void updateProcessDefinitionSortByModelId(String modelId, Long sort) {
+        processDefinitionMapper.updateByModelId(modelId, new BpmProcessDefinitionInfoDO().setSort(sort));
+    }
+
     @Override
     public BpmnModel getProcessDefinitionBpmnModel(String id) {
         return repositoryService.getBpmnModel(id);

File diff suppressed because it is too large
+ 0 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java


+ 1 - 3
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java

@@ -764,9 +764,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
         taskService.setOwner(taskId, task.getAssignee());
         // 3.2 执行委派,将任务委派给 delegateUser
         taskService.delegateTask(taskId, reqVO.getDelegateUserId().toString());
-        // 3.3 更新 task 状态。
-        // 为什么不更新原因?因为原因目前主要给审批通过、不通过时使用
-        updateTaskStatus(taskId, BpmTaskStatusEnum.DELEGATE.getStatus());
+        // 补充说明:委托不单独设置状态。如果需要,可通过 Task 的 DelegationState 字段,判断是否为 DelegationState.PENDING 委托中
     }
 
     @Override

Some files were not shown because too many files changed in this diff