Ver Fonte

BPM:新增【流程实例】菜单,用于全部流程实例的查询

YunaiV há 11 meses atrás
pai
commit
ba4b3701bf
13 ficheiros alterados com 96 adições e 37 exclusões
  1. 3 2
      yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmDeleteReasonEnum.java
  2. 3 3
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionRespVO.java
  3. 51 10
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java
  4. 5 6
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstancePageReqVO.java
  5. 4 1
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceRespVO.java
  6. 1 1
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRespVO.java
  7. 10 4
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java
  8. 1 0
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java
  9. 3 3
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java
  10. 1 1
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/event/BpmProcessInstanceEventPublisher.java
  11. 13 5
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java
  12. 0 0
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java
  13. 1 1
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java

+ 3 - 2
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmDeleteReasonEnum.java

@@ -16,11 +16,12 @@ public enum BpmDeleteReasonEnum {
     // ========== 流程实例的独有原因 ==========
 
     REJECT_TASK("审批不通过任务,原因:{}"), // 场景:用户审批不通过任务。修改文案时,需要注意 isRejectReason 方法
-    CANCEL_PROCESS_INSTANCE("用户主动取消流程,原因:{}"), // 场景:用户主动取消流程
+    CANCEL_PROCESS_INSTANCE_BY_START_USER("用户主动取消流程,原因:{}"), // 场景:用户主动取消流程
+    CANCEL_PROCESS_INSTANCE_BY_ADMIN("管理员【{}】取消流程,原因:{}"), // 场景:管理员取消流程
 
     // ========== 流程任务的独有原因 ==========
 
-    CANCEL_SYSTEM("系统自动取消"), // 场景:非常多,比如说:1)多任务审批已经满足条件,无需审批该任务;2)流程实例被取消,无需审批该任务;等等
+    CANCEL_BY_SYSTEM("系统自动取消"), // 场景:非常多,比如说:1)多任务审批已经满足条件,无需审批该任务;2)流程实例被取消,无需审批该任务;等等
     ;
 
     private final String reason;

+ 3 - 3
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionRespVO.java

@@ -3,8 +3,6 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
-import jakarta.validation.constraints.NotEmpty;
-
 import java.time.LocalDateTime;
 import java.util.List;
 
@@ -19,9 +17,11 @@ public class BpmProcessDefinitionRespVO {
     private Integer version;
 
     @Schema(description = "流程名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
-    @NotEmpty(message = "流程名称不能为空")
     private String name;
 
+    @Schema(description = "流程标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "yudao")
+    private String key;
+
     @Schema(description = "流程描述", example = "我是描述")
     private String description;
 

+ 51 - 10
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java

@@ -4,7 +4,10 @@ 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.number.NumberUtils;
-import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*;
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCancelReqVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCreateReqVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstancePageReqVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
 import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
@@ -59,9 +62,10 @@ public class BpmProcessInstanceController {
     @GetMapping("/my-page")
     @Operation(summary = "获得我的实例分页列表", description = "在【我的流程】菜单中,进行调用")
     @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
-    public CommonResult<PageResult<BpmProcessInstanceRespVO>> getMyProcessInstancePage(
-            @Valid BpmProcessInstanceMyPageReqVO pageReqVO) {
-        PageResult<HistoricProcessInstance> pageResult = processInstanceService.getMyProcessInstancePage(getLoginUserId(), pageReqVO);
+    public CommonResult<PageResult<BpmProcessInstanceRespVO>> getProcessInstanceMyPage(
+            @Valid BpmProcessInstancePageReqVO pageReqVO) {
+        PageResult<HistoricProcessInstance> pageResult = processInstanceService.getProcessInstancePage(
+                getLoginUserId(), pageReqVO);
         if (CollUtil.isEmpty(pageResult.getList())) {
             return success(PageResult.empty(pageResult.getTotal()));
         }
@@ -73,8 +77,35 @@ public class BpmProcessInstanceController {
                 convertSet(pageResult.getList(), HistoricProcessInstance::getProcessDefinitionId));
         Map<String, BpmCategoryDO> categoryMap = categoryService.getCategoryMap(
                 convertSet(processDefinitionMap.values(), ProcessDefinition::getCategory));
-        return success(BpmProcessInstanceConvert.INSTANCE.buildMyProcessInstancePage(pageResult,
-                processDefinitionMap, categoryMap, taskMap));
+        return success(BpmProcessInstanceConvert.INSTANCE.buildProcessInstancePage(pageResult,
+                processDefinitionMap, categoryMap, taskMap, null, null));
+    }
+
+    @GetMapping("/manager-page")
+    @Operation(summary = "获得管理流程实例的分页列表", description = "在【流程实例】菜单中,进行调用")
+    @PreAuthorize("@ss.hasPermission('bpm:process-instance:manager-query')")
+    public CommonResult<PageResult<BpmProcessInstanceRespVO>> getProcessInstanceManagerPage(
+            @Valid BpmProcessInstancePageReqVO pageReqVO) {
+        PageResult<HistoricProcessInstance> pageResult = processInstanceService.getProcessInstancePage(
+                null, pageReqVO);
+        if (CollUtil.isEmpty(pageResult.getList())) {
+            return success(PageResult.empty(pageResult.getTotal()));
+        }
+
+        // 拼接返回
+        Map<String, List<Task>> taskMap = taskService.getTaskMapByProcessInstanceIds(
+                convertList(pageResult.getList(), HistoricProcessInstance::getId));
+        Map<String, ProcessDefinition> processDefinitionMap = processDefinitionService.getProcessDefinitionMap(
+                convertSet(pageResult.getList(), HistoricProcessInstance::getProcessDefinitionId));
+        Map<String, BpmCategoryDO> categoryMap = categoryService.getCategoryMap(
+                convertSet(processDefinitionMap.values(), ProcessDefinition::getCategory));
+        // 发起人信息
+        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
+                convertSet(pageResult.getList(), processInstance -> NumberUtils.parseLong(processInstance.getStartUserId())));
+        Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(
+                convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
+        return success(BpmProcessInstanceConvert.INSTANCE.buildProcessInstancePage(pageResult,
+                processDefinitionMap, categoryMap, taskMap, userMap, deptMap));
     }
 
     @PostMapping("/create")
@@ -109,11 +140,21 @@ public class BpmProcessInstanceController {
                 processDefinition, processDefinitionInfo, bpmnXml, startUser, dept));
     }
 
-    @DeleteMapping("/cancel")
-    @Operation(summary = "取消流程实例", description = "撤回发起的流程")
+    @DeleteMapping("/cancel-by-start-user")
+    @Operation(summary = "用户取消流程实例", description = "取消发起的流程")
     @PreAuthorize("@ss.hasPermission('bpm:process-instance:cancel')")
-    public CommonResult<Boolean> cancelProcessInstance(@Valid @RequestBody BpmProcessInstanceCancelReqVO cancelReqVO) {
-        processInstanceService.cancelProcessInstance(getLoginUserId(), cancelReqVO);
+    public CommonResult<Boolean> cancelProcessInstanceByStartUser(
+            @Valid @RequestBody BpmProcessInstanceCancelReqVO cancelReqVO) {
+        processInstanceService.cancelProcessInstanceByStartUser(getLoginUserId(), cancelReqVO);
+        return success(true);
+    }
+
+    @DeleteMapping("/cancel-by-admin")
+    @Operation(summary = "管理员取消流程实例", description = "管理员撤回流程")
+    @PreAuthorize("@ss.hasPermission('bpm:process-instance:cancel-by-admin')")
+    public CommonResult<Boolean> cancelProcessInstanceByManager(
+            @Valid @RequestBody BpmProcessInstanceCancelReqVO cancelReqVO) {
+        processInstanceService.cancelProcessInstanceByAdmin(getLoginUserId(), cancelReqVO);
         return success(true);
     }
 

+ 5 - 6
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceMyPageReqVO.java → yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstancePageReqVO.java

@@ -5,19 +5,15 @@ import cn.iocoder.yudao.framework.common.validation.InEnum;
 import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
 import org.springframework.format.annotation.DateTimeFormat;
 
 import java.time.LocalDateTime;
 
 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
 
-@Schema(description = "管理后台 - 流程实例的分页 Item Response VO")
+@Schema(description = "管理后台 - 流程实例分页 Request VO")
 @Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class BpmProcessInstanceMyPageReqVO extends PageParam {
+public class BpmProcessInstancePageReqVO extends PageParam {
 
     @Schema(description = "流程名称", example = "芋道")
     private String name;
@@ -36,4 +32,7 @@ public class BpmProcessInstanceMyPageReqVO extends PageParam {
     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
     private LocalDateTime[] createTime;
 
+    @Schema(description = "发起用户编号", example = "1024")
+    private Long startUserId; // 注意,只有在【流程实例】菜单,才使用该参数
+
 }

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

@@ -26,12 +26,15 @@ public class BpmProcessInstanceRespVO {
     @Schema(description = "流程实例的状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
     private Integer status; // 参见 BpmProcessInstanceStatusEnum 枚举
 
-    @Schema(description = "提交时间", requiredMode = Schema.RequiredMode.REQUIRED)
+    @Schema(description = "发起时间", requiredMode = Schema.RequiredMode.REQUIRED)
     private LocalDateTime startTime;
 
     @Schema(description = "结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
     private LocalDateTime endTime;
 
+    @Schema(description = "持续时间", example = "1000")
+    private Long durationInMillis;
+
     @Schema(description = "提交的表单值", requiredMode = Schema.RequiredMode.REQUIRED)
     private Map<String, Object> formVariables;
 

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

@@ -24,7 +24,7 @@ public class BpmTaskRespVO {
     @Schema(description = "结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
     private LocalDateTime endTime;
 
-    @Schema(description = "持续时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000")
+    @Schema(description = "持续时间", example = "1000")
     private Long durationInMillis;
 
     @Schema(description = "任务状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")

+ 10 - 4
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java

@@ -36,10 +36,12 @@ public interface BpmProcessInstanceConvert {
 
     BpmProcessInstanceConvert INSTANCE = Mappers.getMapper(BpmProcessInstanceConvert.class);
 
-    default PageResult<BpmProcessInstanceRespVO> buildMyProcessInstancePage(PageResult<HistoricProcessInstance> pageResult,
-                                                                            Map<String, ProcessDefinition> processDefinitionMap,
-                                                                            Map<String, BpmCategoryDO> categoryMap,
-                                                                            Map<String, List<Task>> taskMap) {
+    default PageResult<BpmProcessInstanceRespVO> buildProcessInstancePage(PageResult<HistoricProcessInstance> pageResult,
+                                                                          Map<String, ProcessDefinition> processDefinitionMap,
+                                                                          Map<String, BpmCategoryDO> categoryMap,
+                                                                          Map<String, List<Task>> taskMap,
+                                                                          Map<Long, AdminUserRespDTO> userMap,
+                                                                          Map<Long, DeptRespDTO> deptMap) {
         PageResult<BpmProcessInstanceRespVO> vpPageResult = BeanUtils.toBean(pageResult, BpmProcessInstanceRespVO.class);
         for (int i = 0; i < pageResult.getList().size(); i++) {
             BpmProcessInstanceRespVO respVO = vpPageResult.getList().get(i);
@@ -48,6 +50,10 @@ public interface BpmProcessInstanceConvert {
                     processDefinition -> respVO.setCategory(processDefinition.getCategory()));
             MapUtils.findAndThen(categoryMap, respVO.getCategory(), category -> respVO.setCategoryName(category.getName()));
             respVO.setTasks(BeanUtils.toBean(taskMap.get(respVO.getId()), BpmProcessInstanceRespVO.Task.class));
+            // user
+            AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(pageResult.getList().get(i).getStartUserId()));
+            respVO.setStartUser(BeanUtils.toBean(startUser, BpmProcessInstanceRespVO.User.class));
+            MapUtils.findAndThen(deptMap, startUser.getDeptId(), dept -> respVO.getStartUser().setDeptName(dept.getName()));
         }
         return vpPageResult;
     }

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

@@ -46,6 +46,7 @@ public interface BpmTaskConvert {
             if (processInstance == null) {
                 return;
             }
+            taskVO.setProcessInstance(BeanUtils.toBean(processInstance, BpmTaskRespVO.ProcessInstance.class));
             AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));
             taskVO.getProcessInstance().setStartUser(BeanUtils.toBean(startUser, BpmProcessInstanceRespVO.User.class));
         });

+ 3 - 3
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java

@@ -4,7 +4,7 @@ import cn.hutool.core.collection.ListUtil;
 import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.BpmActivityBehaviorFactory;
 import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateInvoker;
 import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
-import cn.iocoder.yudao.module.bpm.framework.flowable.core.event.BpmProcessInstanceResultEventPublisher;
+import cn.iocoder.yudao.module.bpm.framework.flowable.core.event.BpmProcessInstanceEventPublisher;
 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
 import org.flowable.common.engine.api.delegate.event.FlowableEventListener;
 import org.flowable.spring.SpringProcessEngineConfiguration;
@@ -84,8 +84,8 @@ public class BpmFlowableConfiguration {
     // =========== 自己拓展的 Bean ==========
 
     @Bean
-    public BpmProcessInstanceResultEventPublisher processInstanceResultEventPublisher(ApplicationEventPublisher publisher) {
-        return new BpmProcessInstanceResultEventPublisher(publisher);
+    public BpmProcessInstanceEventPublisher processInstanceEventPublisher(ApplicationEventPublisher publisher) {
+        return new BpmProcessInstanceEventPublisher(publisher);
     }
 
 }

+ 1 - 1
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/event/BpmProcessInstanceResultEventPublisher.java → yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/event/BpmProcessInstanceEventPublisher.java

@@ -14,7 +14,7 @@ import jakarta.validation.Valid;
  */
 @AllArgsConstructor
 @Validated
-public class BpmProcessInstanceResultEventPublisher {
+public class BpmProcessInstanceEventPublisher {
 
     private final ApplicationEventPublisher publisher;
 

+ 13 - 5
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java

@@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCancelReqVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCreateReqVO;
-import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceMyPageReqVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstancePageReqVO;
 import jakarta.validation.Valid;
 import org.flowable.engine.delegate.event.FlowableCancelledEvent;
 import org.flowable.engine.history.HistoricProcessInstance;
@@ -93,8 +93,8 @@ public interface BpmProcessInstanceService {
      * @param pageReqVO 分页请求
      * @return 流程实例的分页
      */
-    PageResult<HistoricProcessInstance> getMyProcessInstancePage(Long userId,
-                                                                 @Valid BpmProcessInstanceMyPageReqVO pageReqVO);
+    PageResult<HistoricProcessInstance> getProcessInstancePage(Long userId,
+                                                               @Valid BpmProcessInstancePageReqVO pageReqVO);
 
     /**
      * 创建流程实例(提供给前端)
@@ -115,12 +115,20 @@ public interface BpmProcessInstanceService {
     String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO createReqDTO);
 
     /**
-     * 取消流程实例
+     * 发起人取消流程实例
      *
      * @param userId      用户编号
      * @param cancelReqVO 取消信息
      */
-    void cancelProcessInstance(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO);
+    void cancelProcessInstanceByStartUser(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO);
+
+    /**
+     * 管理员取消流程实例
+     *
+     * @param userId           用户编号
+     * @param cancelReqVO 取消信息
+     */
+    void cancelProcessInstanceByAdmin(Long userId, BpmProcessInstanceCancelReqVO cancelReqVO);
 
     /**
      * 更新 ProcessInstance 拓展记录为取消

Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java


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

@@ -375,7 +375,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
             log.error("[updateTaskStatusWhenCanceled][taskId({}) 处于结果({}),无需进行更新]", taskId, status);
             return;
         }
-        updateTaskStatusAndReason(taskId, BpmTaskStatustEnum.CANCEL.getStatus(), BpmDeleteReasonEnum.CANCEL_SYSTEM.getReason());
+        updateTaskStatusAndReason(taskId, BpmTaskStatustEnum.CANCEL.getStatus(), BpmDeleteReasonEnum.CANCEL_BY_SYSTEM.getReason());
         // 补充说明:由于 Task 被删除成 HistoricTask 后,无法通过 taskService.addComment 添加理由,所以无法存储具体的取消理由
     }
 

Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff