Преглед изворни кода

优化新增排序和发起人自己自动跳转

hubin пре 1 година
родитељ
комит
c67aa24140

+ 1 - 1
build.gradle

@@ -99,7 +99,7 @@ dependencies {
     implementation("com.aizuda:aizuda-monitor")
 
     // 工作流引擎
-    implementation("com.aizuda:flowlong-spring-boot-starter:0.0.6")
+    implementation("com.aizuda:flowlong-spring-boot-starter:0.0.7")
 
     // SpringBootAdmin 监控管理客户端,未使用可以删除
     // implementation("de.codecentric:spring-boot-admin-starter-client:3.0.2")

+ 1 - 1
pom.xml

@@ -98,7 +98,7 @@
 		<dependency>
 			<groupId>com.aizuda</groupId>
 			<artifactId>flowlong-spring-boot-starter</artifactId>
-			<version>0.0.6</version>
+			<version>0.0.7</version>
 		</dependency>
 
 		<!-- 服务监听 -->

+ 2 - 1
src/main/java/com/aizuda/boot/config/BlockHandlerInterceptor.java

@@ -16,7 +16,8 @@ public class BlockHandlerInterceptor implements HandlerInterceptor {
     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
         String uri = request.getRequestURI();
         if (uri.contains("/create") || uri.contains("/update")
-                || uri.contains("/delete") || uri.contains("/v1/process/delete")) {
+                || uri.contains("/delete") || uri.contains("/reset-password")
+                || uri.contains("/v1/process/delete")) {
             response.setStatus(HttpServletResponse.SC_FORBIDDEN);
             response.getWriter().write("{\"code\": -1,\"message\": \"Access forbidden in demo environment\"}");
             return false;

+ 0 - 8
src/main/java/com/aizuda/boot/modules/flw/controller/ProcessCategoryController.java

@@ -1,7 +1,6 @@
 package com.aizuda.boot.modules.flw.controller;
 
 import com.aizuda.boot.modules.flw.entity.FlwProcessCategory;
-import com.aizuda.boot.modules.flw.entity.dto.FlwCategorySortDTO;
 import com.aizuda.boot.modules.flw.service.IFlwProcessCategoryService;
 import com.aizuda.core.api.ApiController;
 import com.aizuda.core.validation.Create;
@@ -46,13 +45,6 @@ public class ProcessCategoryController extends ApiController {
         return flwProcessCategoryService.listAll();
     }
 
-    @Operation(summary = "排序")
-    @Permission("flw:processCategory")
-    @PostMapping("/sort")
-    public boolean sort(@Validated(Create.class) @RequestBody List<FlwCategorySortDTO> dtoList) {
-        return flwProcessCategoryService.sort(dtoList);
-    }
-
     @Operation(summary = "创建添加")
     @Permission("flw:processCategory:create")
     @PostMapping("/create")

+ 8 - 9
src/main/java/com/aizuda/boot/modules/flw/controller/ProcessController.java

@@ -1,5 +1,6 @@
 package com.aizuda.boot.modules.flw.controller;
 
+import com.aizuda.boot.modules.flw.entity.dto.FlwCategorySortDTO;
 import com.aizuda.boot.modules.flw.entity.dto.FlwProcessDTO;
 import com.aizuda.boot.modules.flw.entity.dto.ProcessStartDTO;
 import com.aizuda.boot.modules.flw.entity.vo.FlwProcessCategoryVO;
@@ -7,12 +8,14 @@ import com.aizuda.boot.modules.flw.flow.FlowHelper;
 import com.aizuda.boot.modules.flw.service.IFlwProcessService;
 import com.aizuda.bpm.engine.entity.FlwProcess;
 import com.aizuda.core.api.ApiController;
+import com.aizuda.core.validation.Create;
 import com.baomidou.kisso.annotation.Permission;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.Parameters;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.AllArgsConstructor;
+import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
@@ -124,15 +127,11 @@ public class ProcessController extends ApiController {
         return flwProcessService.removeProcessInfo(id);
     }
 
-    @Operation(summary = "根据流程定义ID更新排序")
-    @Permission("flw:process:updateSort")
-    @Parameters({
-            @Parameter(name = "id", description = "主键ID"),
-            @Parameter(name = "sort", description = "排序号")
-    })
-    @PostMapping("/update-sort-{id}")
-    public boolean updateSort(@PathVariable("id") Long id, @RequestParam Integer sort) {
-        return flwProcessService.updateSortById(id, sort);
+    @Operation(summary = "流程排序")
+    @Permission("flw:process")
+    @PostMapping("/sort")
+    public boolean sort(@Validated(Create.class) @RequestBody List<FlwCategorySortDTO> dtoList) {
+        return flwProcessService.sort(dtoList);
     }
 
     @Operation(summary = "根据流程定义ID更新流程状态")

+ 1 - 1
src/main/java/com/aizuda/boot/modules/flw/entity/FlwProcessApproval.java

@@ -56,7 +56,7 @@ public class FlwProcessApproval extends SuperEntity {
     @Schema(description = "任务 key 唯一标识")
     private String taskKey;
 
-    @Schema(description = "审批类型 0,评论 1,发起 2,抄送 3,办理 4,驳回 5,认领 6,转办 7,委派 8,跳转 9,拿回 10,唤醒 11,前加签 12,并加签 13,后加签 14,减签 15,撤销 16,终止 17,超时 18,委派归还任务")
+    @Schema(description = "审批类型 -1,待审 0,评论 1,发起 2,抄送 3,办理 4,驳回 5,认领 6,转办 7,委派 8,跳转 9,拿回 10,唤醒 11,前加签 12,并加签 13,后加签 14,减签 15,撤销 16,终止 17,超时 18,委派归还任务 19,自动跳转 20,自动完成 21,自动拒绝")
     @NotNull(groups = Create.class)
     @PositiveOrZero
     private Integer type;

+ 13 - 4
src/main/java/com/aizuda/boot/modules/flw/entity/dto/FlwCategorySortDTO.java

@@ -1,17 +1,26 @@
 package com.aizuda.boot.modules.flw.entity.dto;
 
+import com.aizuda.boot.modules.flw.entity.FlwProcessCategory;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Getter;
 import lombok.Setter;
 
+import java.util.List;
+
 @Getter
 @Setter
 public class FlwCategorySortDTO {
 
-    @Schema(description = "主键ID")
-    private Long id;
+    @Schema(description = "流程分类ID")
+    private Long categoryId;
 
-    @Schema(description = "排序")
-    private Integer sort;
+    @Schema(description = "流程ID列表")
+    private List<Long> processIds;
 
+    public FlwProcessCategory toFlwProcessCategory(Integer sort) {
+        FlwProcessCategory fpc = new FlwProcessCategory();
+        fpc.setId(categoryId);
+        fpc.setSort(sort);
+        return fpc;
+    }
 }

+ 62 - 24
src/main/java/com/aizuda/boot/modules/flw/flow/FlowTaskListener.java

@@ -6,15 +6,13 @@ import com.aizuda.boot.modules.flw.service.IFlwProcessApprovalService;
 import com.aizuda.bpm.engine.FlowDataTransfer;
 import com.aizuda.bpm.engine.FlowLongEngine;
 import com.aizuda.bpm.engine.core.FlowCreator;
-import com.aizuda.bpm.engine.core.enums.EventType;
-import com.aizuda.bpm.engine.core.enums.NodeSetType;
-import com.aizuda.bpm.engine.core.enums.PerformType;
-import com.aizuda.bpm.engine.core.enums.TaskType;
+import com.aizuda.bpm.engine.core.enums.*;
 import com.aizuda.bpm.engine.entity.FlwTask;
 import com.aizuda.bpm.engine.listener.TaskListener;
 import com.aizuda.bpm.engine.model.NodeModel;
 import com.aizuda.bpm.engine.model.ProcessModel;
 import com.aizuda.common.toolkit.StringUtils;
+import com.aizuda.core.api.ApiAssert;
 import jakarta.annotation.Resource;
 import org.springframework.stereotype.Component;
 
@@ -28,8 +26,20 @@ public class FlowTaskListener implements TaskListener {
     private FlowLongEngine flowLongEngine;
 
     @Override
-    public boolean notify(EventType eventType, Supplier<FlwTask> supplier, FlowCreator flowCreator) {
-        if (eventType == EventType.create || eventType == EventType.recreate) {
+    public boolean notify(EventType eventType, Supplier<FlwTask> supplier, NodeModel nodeModel, FlowCreator flowCreator) {
+        FlwTask flwTask = supplier.get();
+        if (EventType.create.eq(eventType) || EventType.recreate.eq(eventType)) {
+            // 获取当前节点信息
+            NodeModel currentNodeModel = this.getNodeModel(flwTask, nodeModel);
+            if (null != flwTask) {
+                if (NodeSetType.initiatorThemselves.eq(currentNodeModel.getSetType())) {
+                    // 发起人自己,自动跳过
+                    if (NodeApproveSelf.AutoSkip.eq(currentNodeModel.getApproveSelf())) {
+                        // 执行自动跳转逻辑
+                        flowLongEngine.autoJumpTask(flwTask.getId(), flowCreator);
+                    }
+                }
+            }
             // 创建任务直接跳过
             return true;
         }
@@ -37,9 +47,7 @@ public class FlowTaskListener implements TaskListener {
         // 监听处理其它任务事件
         FlwProcessApproval fpa = new FlwProcessApproval();
         fpa.setType(this.getType(eventType));
-        FlwTask flwTask = supplier.get();
         if (null != flwTask) {
-            ApprovalContent content = new ApprovalContent();
             fpa.setInstanceId(flwTask.getInstanceId());
             fpa.setTaskId(flwTask.getId());
             fpa.setTaskName(flwTask.getTaskName());
@@ -61,26 +69,34 @@ public class FlowTaskListener implements TaskListener {
                         fpa.setType(18);
                     }
                 }
-                ProcessModel processModel = flowLongEngine.runtimeService().getProcessModelByInstanceId(flwTask.getInstanceId());
-                NodeModel nodeModel = processModel.getNode(flwTask.getTaskKey());
-                if (null != nodeModel) {
-                    if (eventType != EventType.cc) {
-                        String opinion = FlowDataTransfer.get("processApprovalOpinion");
-                        if (StringUtils.hasLength(opinion)) {
-                            content.setOpinion(opinion);
-                        }
-                    }
 
-                    if (NodeSetType.specifyMembers.eq(nodeModel.getSetType())) {
-                        // 指定成员类型
-                        content.setNodeUserList(nodeModel.getNodeAssigneeList());
-                    } else if (NodeSetType.role.eq(nodeModel.getSetType())) {
-                        // 角色类型
-                        content.setNodeRoleList(nodeModel.getNodeAssigneeList());
+                // 获取当前节点信息
+                NodeModel currentNodeModel = this.getNodeModel(flwTask, nodeModel);
+                boolean saveContent = false;
+                ApprovalContent content = new ApprovalContent();
+                if (EventType.cc.ne(eventType)) {
+                    String opinion = FlowDataTransfer.get("processApprovalOpinion");
+                    if (StringUtils.hasLength(opinion)) {
+                        content.setOpinion(opinion);
+                        saveContent = true;
                     }
                 }
+
+                if (NodeSetType.specifyMembers.eq(currentNodeModel.getSetType())) {
+                    // 指定成员类型
+                    content.setNodeUserList(currentNodeModel.getNodeAssigneeList());
+                    saveContent = true;
+                } else if (NodeSetType.role.eq(currentNodeModel.getSetType())) {
+                    // 角色类型
+                    content.setNodeRoleList(currentNodeModel.getNodeAssigneeList());
+                    saveContent = true;
+                }
+
+                // 记录审批内容
+                if (saveContent) {
+                    fpa.setContent(content);
+                }
             }
-            fpa.setContent(content);
 
             //用于流程图颜色标记
             fpa.setTaskKey(flwTask.getTaskKey());
@@ -94,12 +110,25 @@ public class FlowTaskListener implements TaskListener {
         return flwProcessApprovalService.save(fpa);
     }
 
+    private NodeModel getNodeModel(FlwTask flwTask, NodeModel nodeModel) {
+        if (null == nodeModel) {
+            // 不存在情况从数据库中获取
+            ProcessModel processModel = flowLongEngine.runtimeService().getProcessModelByInstanceId(flwTask.getInstanceId());
+            ApiAssert.isEmpty(processModel, "流程模型节点查询异常");
+            return processModel.getNode(flwTask.getTaskKey());
+        }
+        return nodeModel;
+    }
+
     private int getType(EventType eventType) {
         // 办理
         int type = 3;
         if (eventType == EventType.start) {
             // 发起
             type = 1;
+        } else if (eventType == EventType.cc) {
+            // 抄送
+            type = 2;
         } else if (eventType == EventType.reject) {
             // 驳回
             type = 4;
@@ -124,6 +153,15 @@ public class FlowTaskListener implements TaskListener {
         } else if (eventType == EventType.timeout) {
             // 超时
             type = 17;
+        } else if (eventType == EventType.autoJump) {
+            // 自动跳转
+            type = 19;
+        } else if (eventType == EventType.autoComplete) {
+            // 自动完成
+            type = 20;
+        } else if (eventType == EventType.autoReject) {
+            // 自动拒绝
+            type = 21;
         }
         return type;
     }

+ 1 - 2
src/main/java/com/aizuda/boot/modules/flw/service/IFlwProcessCategoryService.java

@@ -1,7 +1,6 @@
 package com.aizuda.boot.modules.flw.service;
 
 import com.aizuda.boot.modules.flw.entity.FlwProcessCategory;
-import com.aizuda.boot.modules.flw.entity.dto.FlwCategorySortDTO;
 import com.aizuda.service.service.IBaseService;
 
 import java.util.List;
@@ -18,6 +17,6 @@ public interface IFlwProcessCategoryService extends IBaseService<FlwProcessCateg
 
     boolean removeCategoryByIds(List<Long> ids);
 
-    boolean sort(List<FlwCategorySortDTO> dtoList);
+    boolean sort(List<FlwProcessCategory> processCategorieList);
 
 }

+ 8 - 0
src/main/java/com/aizuda/boot/modules/flw/service/IFlwProcessConfigureService.java

@@ -1,6 +1,7 @@
 package com.aizuda.boot.modules.flw.service;
 
 import com.aizuda.boot.modules.flw.entity.FlwProcessConfigure;
+import com.aizuda.boot.modules.flw.entity.dto.FlwCategorySortDTO;
 import com.aizuda.boot.modules.flw.entity.dto.FlwProcessDTO;
 import com.aizuda.service.service.IBaseService;
 
@@ -42,4 +43,11 @@ public interface IFlwProcessConfigureService extends IBaseService<FlwProcessConf
      * @param processId 流程定义ID
      */
     FlwProcessConfigure getByProcessId(Long processId);
+
+    /**
+     * 根据流程ID更新流程分类关联关系
+     *
+     * @param dtoList 流程分类排序DTO列表
+     */
+    void updateRelation(List<FlwCategorySortDTO> dtoList);
 }

+ 3 - 3
src/main/java/com/aizuda/boot/modules/flw/service/IFlwProcessService.java

@@ -1,5 +1,6 @@
 package com.aizuda.boot.modules.flw.service;
 
+import com.aizuda.boot.modules.flw.entity.dto.FlwCategorySortDTO;
 import com.aizuda.boot.modules.flw.entity.dto.FlwProcessDTO;
 import com.aizuda.boot.modules.flw.entity.dto.ProcessStartDTO;
 import com.aizuda.boot.modules.flw.entity.vo.FlwProcessCategoryVO;
@@ -78,10 +79,9 @@ public interface IFlwProcessService extends IBaseService<FlwProcess> {
     /**
      * 根据ID更新流程定义排序
      *
-     * @param id   流程定义ID
-     * @param sort 流程定义排序
+     * @param dtoList 流程分类排序DTO列表
      */
-    boolean updateSortById(Long id, Integer sort);
+    boolean sort(List<FlwCategorySortDTO> dtoList);
 
     /**
      * 根据ID更新流程定义流程状态

+ 2 - 3
src/main/java/com/aizuda/boot/modules/flw/service/impl/FlwProcessCategoryServiceImpl.java

@@ -1,7 +1,6 @@
 package com.aizuda.boot.modules.flw.service.impl;
 
 import com.aizuda.boot.modules.flw.entity.FlwProcessCategory;
-import com.aizuda.boot.modules.flw.entity.dto.FlwCategorySortDTO;
 import com.aizuda.boot.modules.flw.mapper.FlwProcessCategoryMapper;
 import com.aizuda.boot.modules.flw.service.IFlwProcessCategoryService;
 import com.aizuda.boot.modules.flw.service.IFlwProcessConfigureService;
@@ -48,8 +47,8 @@ public class FlwProcessCategoryServiceImpl extends BaseServiceImpl<FlwProcessCat
     }
 
     @Override
-    public boolean sort(List<FlwCategorySortDTO> dtoList) {
-        return super.updateBatchById(dtoList.stream().map(t -> {
+    public boolean sort(List<FlwProcessCategory> processCategorieList) {
+        return super.updateBatchById(processCategorieList.stream().map(t -> {
             FlwProcessCategory fpc = new FlwProcessCategory();
             fpc.setId(t.getId());
             fpc.setSort(t.getSort());

+ 7 - 0
src/main/java/com/aizuda/boot/modules/flw/service/impl/FlwProcessConfigureServiceImpl.java

@@ -1,6 +1,7 @@
 package com.aizuda.boot.modules.flw.service.impl;
 
 import com.aizuda.boot.modules.flw.entity.FlwProcessConfigure;
+import com.aizuda.boot.modules.flw.entity.dto.FlwCategorySortDTO;
 import com.aizuda.boot.modules.flw.entity.dto.FlwProcessDTO;
 import com.aizuda.boot.modules.flw.mapper.FlwProcessConfigureMapper;
 import com.aizuda.boot.modules.flw.service.IFlwProcessConfigureService;
@@ -53,4 +54,10 @@ public class FlwProcessConfigureServiceImpl extends BaseServiceImpl<FlwProcessCo
         return super.count(Wrappers.<FlwProcessConfigure>lambdaQuery()
                 .in(FlwProcessConfigure::getCategoryId, categoryIdList)) > 0;
     }
+
+    @Override
+    public void updateRelation(List<FlwCategorySortDTO> dtoList) {
+        dtoList.forEach(t -> lambdaUpdate().set(FlwProcessConfigure::getCategoryId, t.getCategoryId())
+                .in(FlwProcessConfigure::getProcessId, t.getProcessIds()).update());
+    }
 }

+ 33 - 10
src/main/java/com/aizuda/boot/modules/flw/service/impl/FlwProcessServiceImpl.java

@@ -4,6 +4,7 @@ import com.aizuda.boot.modules.flw.entity.FlwProcessActor;
 import com.aizuda.boot.modules.flw.entity.FlwProcessCategory;
 import com.aizuda.boot.modules.flw.entity.FlwProcessConfigure;
 import com.aizuda.boot.modules.flw.entity.FlwProcessPermission;
+import com.aizuda.boot.modules.flw.entity.dto.FlwCategorySortDTO;
 import com.aizuda.boot.modules.flw.entity.dto.FlwProcessDTO;
 import com.aizuda.boot.modules.flw.entity.dto.FlwProcessPermissionDTO;
 import com.aizuda.boot.modules.flw.entity.dto.ProcessStartDTO;
@@ -147,8 +148,11 @@ public class FlwProcessServiceImpl extends ServiceImpl<FlwProcessMapper, FlwProc
         if (CollectionUtils.isNotEmpty(unsetAssigneeNodes)) {
             Map<String, DynamicAssignee> assigneeMap = dto.getAssigneeMap();
             ApiAssert.fail(MapUtils.isEmpty(assigneeMap), "发起人自选节点未设置处理人员");
-            unsetAssigneeNodes.forEach(t -> ApiAssert.fail(null == assigneeMap.get(t.getNodeKey()),
-                    "节点【 " + t.getNodeName() + " 】未设置处理人员"));
+            unsetAssigneeNodes.forEach(t -> {
+                DynamicAssignee dynamicAssignee = assigneeMap.get(t.getNodeKey());
+                ApiAssert.fail(null == dynamicAssignee || CollectionUtils.isEmpty(dynamicAssignee.getAssigneeList()),
+                        "节点【 " + t.getNodeName() + " 】未设置处理人员");
+            });
             // 传递动态分配处理人员
             FlowDataTransfer.dynamicAssignee(Collections.unmodifiableMap(assigneeMap));
         }
@@ -207,6 +211,7 @@ public class FlwProcessServiceImpl extends ServiceImpl<FlwProcessMapper, FlwProc
         flwProcess.setUseScope(dto.getUseScope());
         flwProcess.setModelContent(dto.getModelContent());
         flwProcess.setProcessState(0); // 创建 0 不可用状态,需要发布后才可以使用
+        flwProcess.setSort(1);
         flwProcess.setRemark(dto.getRemark());
         if (null == processId) {
             // 设置创建者信息
@@ -261,15 +266,33 @@ public class FlwProcessServiceImpl extends ServiceImpl<FlwProcessMapper, FlwProc
         return flwProcessPermissionService.getByUserIdAndProcessId(userSession.getId(), processId);
     }
 
+    @Transactional(rollbackFor = Exception.class)
     @Override
-    public boolean updateSortById(Long id, Integer sort) {
-        // 检查流程定义操作权限
-        this.checkOperateApproval(id);
-        // 更新流程定义排序
-        FlwProcess flwProcess = new FlwProcess();
-        flwProcess.setId(id);
-        flwProcess.setSort(sort);
-        return super.updateById(flwProcess);
+    public boolean sort(List<FlwCategorySortDTO> dtoList) {
+        if (CollectionUtils.isNotEmpty(dtoList)) {
+            int i = 0;
+            List<FlwProcessCategory> fpcList = new ArrayList<>();
+            List<FlwProcess> fpList = new ArrayList<>();
+            for (FlwCategorySortDTO dto : dtoList) {
+                List<Long> processIds = dto.getProcessIds();
+                if (CollectionUtils.isNotEmpty(processIds)) {
+                    int j = 0;
+                    fpcList.add(dto.toFlwProcessCategory(++i));
+                    for(Long processId : processIds) {
+                        FlwProcess fp = new FlwProcess();
+                        fp.setId(processId);
+                        fp.setSort(++j);
+                        fpList.add(fp);
+                    }
+                }
+            }
+            if (CollectionUtils.isNotEmpty(fpList)) {
+                flwProcessConfigureService.updateRelation(dtoList);
+                ApiAssert.fail(!super.updateBatchById(fpList), "流程顺序保存失败");
+                ApiAssert.fail(!flwProcessCategoryService.sort(fpcList), "流程分类顺序保存失败");
+            }
+        }
+        return true;
     }
 
     @Override

+ 1 - 1
src/main/java/com/aizuda/boot/modules/flw/service/impl/ProcessTaskServiceImpl.java

@@ -155,7 +155,7 @@ public class ProcessTaskServiceImpl implements IProcessTaskService {
                 fpa.setInstanceId(instanceId);
                 fpa.setTaskId(flwTask.getId());
                 fpa.setTaskName(flwTask.getTaskName());
-                fpa.setType(2);
+                fpa.setType(-1);
                 Integer performType = flwTask.getPerformType();
                 if (!(PerformType.timer.eq(performType) && PerformType.trigger.eq(performType))) {
                     // 排除 定时器 & 触发器