Browse Source

Merge remote-tracking branch 'origin/lc_saas' into master_20240722

dongpo 1 year ago
parent
commit
f30b09e565
22 changed files with 311 additions and 60 deletions
  1. 11 1
      yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/DictDataConstants.java
  2. 6 0
      yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/DictTypeConstants.java
  3. 24 14
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/universal/OaUniversalController.java
  4. 15 7
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java
  5. 32 8
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java
  6. 8 0
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceRespVO.java
  7. 3 0
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java
  8. 2 4
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskPageReqVO.java
  9. 6 0
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRespVO.java
  10. 3 0
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskReturnReqVO.java
  11. 27 3
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java
  12. 22 3
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java
  13. 5 1
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/FlowableUtils.java
  14. 11 11
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/web/config/BpmWebConfiguration.java
  15. 0 1
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java
  16. 9 0
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java
  17. 11 0
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java
  18. 2 0
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/universal/OaUniversalService.java
  19. 72 0
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/universal/OaUniversalServiceImpl.java
  20. 9 0
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java
  21. 32 7
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java
  22. 1 0
      yudao-server/src/main/resources/application-local.yaml

+ 11 - 1
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/DictDataConstants.java

@@ -35,5 +35,15 @@ public interface DictDataConstants {
      * 已撤回状态
      */
     String OA_AUDIT_STATUS_RECALLED = "6";
-    
+
+    /**
+     * bpm任务定义节点Key:申请节点
+     */
+    String OA_TASK_DEFINITION_KEY_MODIFY_APPLY = "modifyApply";
+
+    /**
+     * bpm任务定义节点Key:审核节点
+     */
+    String OA_TASK_DEFINITION_KEY_APPROVER = "approver";
+
 }

+ 6 - 0
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/DictTypeConstants.java

@@ -14,4 +14,10 @@ public interface DictTypeConstants {
      * bpm流程审核状态
      */
     String BPM_TASK_AUDIT_STATUS = "bpm_task_audit_status";
+
+    /**
+     * bpm任务定义节点Key
+     */
+    String BPM_TASK_DEFINITION_KEY = "bpm_task_definition_key";
+
 }

+ 24 - 14
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/universal/OaUniversalController.java

@@ -40,7 +40,7 @@ public class OaUniversalController {
     @PostMapping("/staging")
     @Operation(summary = "暂存通用事项审批流程信息")
     @ApiOperationSupport(order = 1)
-    @PreAuthorize("@ss.hasPermission('bpm:oa-universal:staging')")
+    // @PreAuthorize("@ss.hasPermission('bpm:oa-universal:staging')")
     public CommonResult<Long> startOaUniversal(@RequestBody OaUniversalSaveReqVO stagingReqVO) {
         Long oaUniversalId = oaUniversalService.stagingOaUniversal(stagingReqVO);
         return success(oaUniversalId, "暂存成功");
@@ -49,7 +49,7 @@ public class OaUniversalController {
     @PostMapping("/commit")
     @Operation(summary = "提交通用事项审批流程信息")
     @ApiOperationSupport(order = 2)
-    @PreAuthorize("@ss.hasPermission('bpm:oa-universal:commit')")
+    // @PreAuthorize("@ss.hasPermission('bpm:oa-universal:commit')")
     public CommonResult<Long> commitOaUniversal(@Valid @RequestBody OaUniversalSaveReqVO commitReqVO) {
         Long oaUniversalId = oaUniversalService.commitOaUniversal(commitReqVO);
         return success(oaUniversalId, "提交成功");
@@ -58,7 +58,7 @@ public class OaUniversalController {
     @PostMapping("/agree")
     @Operation(summary = "审批同意通用事项审批流程信息")
     @ApiOperationSupport(order = 3)
-    @PreAuthorize("@ss.hasPermission('bpm:oa-universal:agree')")
+    // @PreAuthorize("@ss.hasPermission('bpm:oa-universal:agree')")
     public CommonResult<Long> agreeOaUniversal(@Valid @RequestBody BpmTaskApproveReqVO agreeReqVO) {
         Long result = oaUniversalService.agreeOaUniversal(agreeReqVO);
         return success(result, "审批成功");
@@ -67,7 +67,7 @@ public class OaUniversalController {
     @PostMapping("/disagree")
     @Operation(summary = "驳回通用事项审批流程信息")
     @ApiOperationSupport(order = 4)
-    @PreAuthorize("@ss.hasPermission('bpm:oa-universal:disagree')")
+    // @PreAuthorize("@ss.hasPermission('bpm:oa-universal:disagree')")
     public CommonResult<Long> disagreeOaUniversal(@Valid @RequestBody BpmTaskReturnReqVO disagreeReqVO) {
         Long result = oaUniversalService.disagreeOaUniversal(disagreeReqVO);
         return success(result, "驳回成功");
@@ -76,7 +76,7 @@ public class OaUniversalController {
     @PostMapping("/revocation")
     @Operation(summary = "撤回通用事项审批流程信息")
     @ApiOperationSupport(order = 5)
-    @PreAuthorize("@ss.hasPermission('bpm:oa-universal:revocation')")
+    // @PreAuthorize("@ss.hasPermission('bpm:oa-universal:revocation')")
     public CommonResult<Long> revocationOaUniversal(@Valid @RequestBody BpmTaskApproveReqVO revocationReqVO) {
         Long result = oaUniversalService.revocationOaUniversal(revocationReqVO);
         return success(result, "撤回成功");
@@ -85,16 +85,16 @@ public class OaUniversalController {
     @PostMapping("/reCommit")
     @Operation(summary = "驳回或撤回后再次提交通用用事项审批流程信息")
     @ApiOperationSupport(order = 6)
-    @PreAuthorize("@ss.hasPermission('bpm:oa-universal:re-commit')")
+    // @PreAuthorize("@ss.hasPermission('bpm:oa-universal:re-commit')")
     public CommonResult<Long> reCommitOaUniversal(@Valid @RequestBody OaUniversalSaveReqVO reCommitReqVO) {
         Long result = oaUniversalService.reCommitOaUniversal(reCommitReqVO);
-        return success(result, "提交成功");
+        return success(result, "再次提交成功");
     }
 
     @PostMapping("/close")
     @Operation(summary = "驳回或撤回后关闭通用事项审批流程信息")
     @ApiOperationSupport(order = 7)
-    @PreAuthorize("@ss.hasPermission('bpm:oa-entry:close')")
+    // @PreAuthorize("@ss.hasPermission('bpm:oa-entry:close')")
     public CommonResult<Long> updateCompleteOaUniversal(@RequestBody OaUniversalSaveReqVO closeReqVO) {
         Long result = oaUniversalService.closeOaUniversal(closeReqVO);
 
@@ -105,7 +105,7 @@ public class OaUniversalController {
     @Operation(summary = "删除通用事项审批流程信息")
     @ApiOperationSupport(order = 8)
     @Parameter(name = "id", description = "编号", required = true)
-    @PreAuthorize("@ss.hasPermission('bpm:oa-universal:delete')")
+    // @PreAuthorize("@ss.hasPermission('bpm:oa-universal:delete')")
     public CommonResult<Boolean> deleteOaUniversal(@RequestParam("id") Long id) {
         oaUniversalService.deleteOaUniversal(id);
         return success(true, "删除成功");
@@ -115,24 +115,34 @@ public class OaUniversalController {
     @Operation(summary = "根据id获得通用事项审批流程信息")
     @Parameter(name = "id", description = "编号", required = true, example = "1")
     @ApiOperationSupport(order = 9)
-    @PreAuthorize("@ss.hasPermission('bpm:oa-universal:query-id')")
+    // @PreAuthorize("@ss.hasPermission('bpm:oa-universal:query-id')")
     public CommonResult<OaUniversalRespVO> getOaUniversal(@RequestParam("id") Long id) {
         OaUniversalRespVO respVO = oaUniversalService.getOaUniversal(id);
         return success(respVO, "查询对象成功");
     }
 
+    @GetMapping("/getByProcInstId")
+    @Operation(summary = "根据流程实例id获得通用事项审批流程信息")
+    @Parameter(name = "procInstId", description = "流程实例id", required = true, example = "9528a78d-457e-11ef-853c-4c034fce6445")
+    @ApiOperationSupport(order = 10)
+    // @PreAuthorize("@ss.hasPermission('bpm:oa-universal:query-proc-inst-id')")
+    public CommonResult<OaUniversalRespVO> getOaUniversalByProcInstId(@RequestParam("procInstId") String procInstId) {
+        OaUniversalRespVO respVO = oaUniversalService.getOaUniversalByProcInstId(procInstId);
+        return success(respVO, "查询对象成功");
+    }
+
     @GetMapping("/page")
     @Operation(summary = "获得通用事项审批流程信息分页")
-    @ApiOperationSupport(order = 10)
-    @PreAuthorize("@ss.hasPermission('bpm:oa-universal:query-page')")
+    @ApiOperationSupport(order = 11)
+    // @PreAuthorize("@ss.hasPermission('bpm:oa-universal:query-page')")
     public CommonResult<PageResult<OaUniversalRespVO>> getOaUniversalPage(@Valid OaUniversalPageReqVO pageReqVO) {
         return success(oaUniversalService.getOaUniversalPage(pageReqVO), "查询列表成功");
     }
 
     @GetMapping("/export-excel")
     @Operation(summary = "导出通用事项审批流程信息 Excel")
-    @ApiOperationSupport(order = 11)
-    @PreAuthorize("@ss.hasPermission('bpm:oa-universal:export')")
+    @ApiOperationSupport(order = 12)
+    // @PreAuthorize("@ss.hasPermission('bpm:oa-universal:export')")
     @ApiAccessLog(operateType = EXPORT)
     public void exportOaUniversalExcel(@Valid OaUniversalPageReqVO pageReqVO,
               HttpServletResponse response) throws IOException {

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

@@ -26,6 +26,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
 import org.flowable.engine.history.HistoricProcessInstance;
 import org.flowable.engine.repository.ProcessDefinition;
 import org.flowable.task.api.Task;
+import org.springdoc.api.annotations.ParameterObject;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
@@ -34,10 +35,10 @@ import javax.annotation.Resource;
 import javax.validation.Valid;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 
 @Tag(name = "管理后台 - 流程实例") // 流程实例,通过流程定义创建的一次“申请”
@@ -61,10 +62,10 @@ public class BpmProcessInstanceController {
     private DeptApi deptApi;
 
     @GetMapping("/my-page")
-    @Operation(summary = "获得我发起的流程实例分页列表", description = "在【我的流程】菜单中,进行调用")
-    @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
+    @Operation(summary = "获得我发起的流程实例分页列表", description = "在【我的流程】菜单中,进行调用")
+    // @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
     public CommonResult<PageResult<BpmProcessInstanceRespVO>> getProcessInstanceMyPage(
-            @Valid BpmProcessInstancePageReqVO pageReqVO) {
+            @Valid @ParameterObject BpmProcessInstancePageReqVO pageReqVO) {
         PageResult<HistoricProcessInstance> pageResult = processInstanceService.getProcessInstancePage(
                 getLoginUserId(), pageReqVO);
         if (CollUtil.isEmpty(pageResult.getList())) {
@@ -76,10 +77,17 @@ public class BpmProcessInstanceController {
                 convertList(pageResult.getList(), HistoricProcessInstance::getId));
         Map<String, ProcessDefinition> processDefinitionMap = processDefinitionService.getProcessDefinitionMap(
                 convertSet(pageResult.getList(), HistoricProcessInstance::getProcessDefinitionId));
+        List<Task> tasksByProcessInstanceIds = taskService.getTasksByProcessInstanceIds(pageResult.getList().stream().map(HistoricProcessInstance::getId).collect(Collectors.toList()));
+        List<Long> collect = tasksByProcessInstanceIds.stream().map(task -> Long.valueOf(task.getAssignee())).collect(Collectors.toList());
+        List<AdminUserRespDTO> userList = adminUserApi.getUserList(collect);
+        Map<Long, AdminUserRespDTO> userMap = convertMap(userList, AdminUserRespDTO::getId);
         Map<String, BpmCategoryDO> categoryMap = categoryService.getCategoryMap(
                 convertSet(processDefinitionMap.values(), ProcessDefinition::getCategory));
+        Map<String, BpmProcessDefinitionExtDO> bpmProcessDefinitionExtDOMap = processDefinitionService.getProcessDefinitionExtMap(
+                convertSet(pageResult.getList(), HistoricProcessInstance::getProcessDefinitionId)
+        );
         return success(BpmProcessInstanceConvert.INSTANCE.buildProcessInstancePage(pageResult,
-                processDefinitionMap, categoryMap, taskMap, null, null));
+                processDefinitionMap, categoryMap, taskMap, userMap, null, bpmProcessDefinitionExtDOMap));
     }
 
     @GetMapping("/manager-page")
@@ -106,7 +114,7 @@ public class BpmProcessInstanceController {
         Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(
                 convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
         return success(BpmProcessInstanceConvert.INSTANCE.buildProcessInstancePage(pageResult,
-                processDefinitionMap, categoryMap, taskMap, userMap, deptMap));
+                processDefinitionMap, categoryMap, taskMap, userMap, deptMap, null));
     }
 
     @PostMapping("/create")

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

@@ -7,13 +7,16 @@ import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
 import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
+import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
 import cn.iocoder.yudao.module.bpm.service.definition.BpmFormService;
+import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
 import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
 import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -22,6 +25,7 @@ import org.flowable.engine.history.HistoricProcessInstance;
 import org.flowable.engine.runtime.ProcessInstance;
 import org.flowable.task.api.Task;
 import org.flowable.task.api.history.HistoricTaskInstance;
+import org.springdoc.api.annotations.ParameterObject;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
@@ -49,6 +53,8 @@ public class BpmTaskController {
     @Resource
     private BpmProcessInstanceService processInstanceService;
     @Resource
+    private BpmProcessDefinitionService processDefinitionService;
+    @Resource
     private BpmFormService formService;
 
     @Resource
@@ -56,27 +62,42 @@ public class BpmTaskController {
     @Resource
     private DeptApi deptApi;
 
+    @GetMapping("todo-count")
+    @Operation(summary = "获取我的待办任务数量")
+    @ApiOperationSupport(order = 1)
+    // @PreAuthorize("@ss.hasPermission('bpm:task:count')")
+    public CommonResult<Long> getTaskTodoCount(@Valid @ParameterObject BpmTaskPageReqVO pageVO) {
+        Long todoCount = taskService.getTaskTodoCount(getLoginUserId(), pageVO);
+        return success(todoCount, "查询我的待办任务数量成功");
+    }
+
     @GetMapping("todo-page")
     @Operation(summary = "获取我的待办任务分页")
-    @PreAuthorize("@ss.hasPermission('bpm:task:query')")
-    public CommonResult<PageResult<BpmTaskRespVO>> getTaskTodoPage(@Valid BpmTaskPageReqVO pageVO) {
+    @ApiOperationSupport(order = 2)
+    // @PreAuthorize("@ss.hasPermission('bpm:task:query')")
+    public CommonResult<PageResult<BpmTaskRespVO>> getTaskTodoPage(@Valid @ParameterObject BpmTaskPageReqVO pageVO) {
         PageResult<Task> pageResult = taskService.getTaskTodoPage(getLoginUserId(), pageVO);
         if (CollUtil.isEmpty(pageResult.getList())) {
             return success(PageResult.empty());
         }
 
         // 拼接数据
+        Map<String, Task> taskMap = convertMap(pageResult.getList(), Task::getId);
         Map<String, ProcessInstance> processInstanceMap = processInstanceService.getProcessInstanceMap(
                 convertSet(pageResult.getList(), Task::getProcessInstanceId));
         Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
                 convertSet(processInstanceMap.values(), instance -> Long.valueOf(instance.getStartUserId())));
-        return success(BpmTaskConvert.INSTANCE.buildTodoTaskPage(pageResult, processInstanceMap, userMap));
+        Map<String, BpmProcessDefinitionExtDO> bpmProcessDefinitionExtDOMap = processDefinitionService.getProcessDefinitionExtMap(
+                convertSet(processInstanceMap.values(), ProcessInstance::getProcessDefinitionId)
+        );
+        PageResult<BpmTaskRespVO> taskRespVOPageResult = BpmTaskConvert.INSTANCE.buildTodoTaskPage(pageResult, processInstanceMap, userMap, bpmProcessDefinitionExtDOMap, taskMap);
+        return success(taskRespVOPageResult, "查询我的待办任务成功");
     }
 
     @GetMapping("done-page")
-    @Operation(summary = "获取我的已办任务分页")
-    @PreAuthorize("@ss.hasPermission('bpm:task:query')")
-    public CommonResult<PageResult<BpmTaskRespVO>> getTaskDonePage(@Valid BpmTaskPageReqVO pageVO) {
+    @Operation(summary = "获取我的已处理任务分页")
+    // @PreAuthorize("@ss.hasPermission('bpm:task:query')")
+    public CommonResult<PageResult<BpmTaskRespVO>> getTaskDonePage(@Valid @ParameterObject BpmTaskPageReqVO pageVO) {
         PageResult<HistoricTaskInstance> pageResult = taskService.getTaskDonePage(getLoginUserId(), pageVO);
         if (CollUtil.isEmpty(pageResult.getList())) {
             return success(PageResult.empty());
@@ -87,7 +108,10 @@ public class BpmTaskController {
                 convertSet(pageResult.getList(), HistoricTaskInstance::getProcessInstanceId));
         Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
                 convertSet(processInstanceMap.values(), instance -> Long.valueOf(instance.getStartUserId())));
-        return success(BpmTaskConvert.INSTANCE.buildTaskPage(pageResult, processInstanceMap, userMap, null));
+        Map<String, BpmProcessDefinitionExtDO> bpmProcessDefinitionExtDOMap = processDefinitionService.getProcessDefinitionExtMap(
+                convertSet(processInstanceMap.values(), HistoricProcessInstance::getProcessDefinitionId)
+        );
+        return success(BpmTaskConvert.INSTANCE.buildTaskPage(pageResult, processInstanceMap, userMap, null, bpmProcessDefinitionExtDOMap));
     }
 
     @GetMapping("manager-page")
@@ -108,7 +132,7 @@ public class BpmTaskController {
         Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);
         Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(
                 convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
-        return success(BpmTaskConvert.INSTANCE.buildTaskPage(pageResult, processInstanceMap, userMap, deptMap));
+        return success(BpmTaskConvert.INSTANCE.buildTaskPage(pageResult, processInstanceMap, userMap, deptMap, null));
     }
 
     @GetMapping("/list-by-process-instance-id")

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

@@ -46,6 +46,11 @@ public class BpmProcessInstanceRespVO {
      */
     private User startUser;
 
+    /**
+     * 当前处理人
+     */
+    private User currentAuditUser;
+
     @Schema(description = "流程定义的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048")
     private String processDefinitionId;
     /**
@@ -84,6 +89,9 @@ public class BpmProcessInstanceRespVO {
         @Schema(description = "任务名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
         private String name;
 
+        @Schema(description = "当前任务处理人")
+        private String assignee;
+
     }
 
 }

+ 3 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java

@@ -24,4 +24,7 @@ public class BpmTaskApproveReqVO {
     @Schema(description = "变量实例(动态表单)", requiredMode = Schema.RequiredMode.AUTO)
     private Map<String, Object> variables;
 
+    @Schema(description = "任务状态(冗余字段)")
+    private Integer taskStatus;
+
 }

+ 2 - 4
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskPageReqVO.java

@@ -4,8 +4,6 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam;
 import cn.iocoder.yudao.framework.common.util.date.DateUtils;
 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;
@@ -14,10 +12,10 @@ import java.time.LocalDateTime;
 @Data
 public class BpmTaskPageReqVO extends PageParam {
 
-    @Schema(description = "流程任务名", example = "芋道")
+    @Schema(description = "流程名", example = "通用")
     private String name;
 
-    @Schema(description = "创建时间")
+    @Schema(description = "创建时间,区间查询", example = "2024-07-20 00:00:00,2024-07-20 23:59:59")
     @DateTimeFormat(pattern = DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
     private LocalDateTime[] createTime;
 

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

@@ -1,6 +1,7 @@
 package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task;
 
 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
+import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
@@ -52,6 +53,11 @@ public class BpmTaskRespVO {
      */
     private ProcessInstance processInstance;
 
+    /**
+     * 流程定义扩展信息
+     */
+    private BpmProcessDefinitionExtDO processDefinition;
+
     @Schema(description = "父任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
     private String parentTaskId;
     @Schema(description = "子任务列表(由加签生成)", requiredMode = Schema.RequiredMode.REQUIRED, example = "childrenTask")

+ 3 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskReturnReqVO.java

@@ -22,4 +22,7 @@ public class BpmTaskReturnReqVO {
     @NotBlank(message = "回退意见不能为空")
     private String reason;
 
+    @Schema(description = "任务状态(冗余字段)")
+    private Integer taskStatus;
+
 }

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

@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.module.bpm.convert.task;
 
+import cn.hutool.core.collection.CollectionUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
@@ -8,12 +9,15 @@ import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmPro
 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
+import cn.iocoder.yudao.module.bpm.enums.DictDataConstants;
 import cn.iocoder.yudao.module.bpm.event.BpmProcessInstanceStatusEvent;
+import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmConstants;
 import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
 import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceApproveReqDTO;
 import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceRejectReqDTO;
 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
+import io.swagger.v3.oas.models.security.SecurityScheme;
 import org.flowable.engine.history.HistoricProcessInstance;
 import org.flowable.engine.repository.ProcessDefinition;
 import org.flowable.engine.runtime.ProcessInstance;
@@ -41,15 +45,31 @@ public interface BpmProcessInstanceConvert {
                                                                           Map<String, BpmCategoryDO> categoryMap,
                                                                           Map<String, List<Task>> taskMap,
                                                                           Map<Long, AdminUserRespDTO> userMap,
-                                                                          Map<Long, DeptRespDTO> deptMap) {
+                                                                          Map<Long, DeptRespDTO> deptMap,
+                                                                          Map<String, BpmProcessDefinitionExtDO> bpmProcessDefinitionExtDOMap) {
         PageResult<BpmProcessInstanceRespVO> vpPageResult = BeanUtils.toBean(pageResult, BpmProcessInstanceRespVO.class);
         for (int i = 0; i < pageResult.getList().size(); i++) {
             BpmProcessInstanceRespVO respVO = vpPageResult.getList().get(i);
-            respVO.setStatus(FlowableUtils.getProcessInstanceStatus(pageResult.getList().get(i)));
+            HistoricProcessInstance historicProcessInstance = pageResult.getList().get(i);
+            Integer processInstanceStatus = FlowableUtils.getProcessInstanceStatus(historicProcessInstance);
+            // 保底设置状态,暂时不用
+            if (historicProcessInstance.getEndTime() != null && processInstanceStatus != Integer.valueOf(DictDataConstants.OA_AUDIT_STATUS_CLOSED)) {
+                processInstanceStatus = Integer.valueOf(DictDataConstants.OA_AUDIT_STATUS_AUDITED);
+            }
+            respVO.setStatus(processInstanceStatus);
+
             MapUtils.findAndThen(processDefinitionMap, respVO.getProcessDefinitionId(),
                     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));
+            List<Task> tasks = taskMap.get(respVO.getId());
+            respVO.setTasks(BeanUtils.toBean(tasks, BpmProcessInstanceRespVO.Task.class));
+            if (CollectionUtil.isNotEmpty(tasks)) {
+                String assignee = tasks.get(0).getAssignee();
+                if (userMap != null){
+                    AdminUserRespDTO adminUserRespDTO = userMap.get(Long.valueOf(assignee));
+                    respVO.setCurrentAuditUser(BeanUtils.toBean(adminUserRespDTO, BpmProcessInstanceRespVO.User.class));
+                }
+            }
             // user
             if (userMap != null) {
                 AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(pageResult.getList().get(i).getStartUserId()));
@@ -58,6 +78,10 @@ public interface BpmProcessInstanceConvert {
                     MapUtils.findAndThen(deptMap, startUser.getDeptId(), dept -> respVO.getStartUser().setDeptName(dept.getName()));
                 }
             }
+            BpmProcessDefinitionExtDO bpmProcessDefinitionExtDO = bpmProcessDefinitionExtDOMap.get(respVO.getProcessDefinitionId());
+            BpmProcessDefinitionRespVO bpmProcessDefinitionRespVO = BeanUtils.toBean(bpmProcessDefinitionExtDO, BpmProcessDefinitionRespVO.class);
+            respVO.setProcessDefinition(bpmProcessDefinitionRespVO);
+
         }
         return vpPageResult;
     }

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

@@ -4,16 +4,20 @@ import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
+import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
 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.dal.dataobject.definition.BpmProcessDefinitionExtDO;
+import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmConstants;
 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;
 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 import org.flowable.engine.history.HistoricProcessInstance;
+import org.flowable.engine.repository.Model;
 import org.flowable.engine.runtime.ProcessInstance;
 import org.flowable.task.api.Task;
 import org.flowable.task.api.history.HistoricTaskInstance;
@@ -21,7 +25,9 @@ import org.flowable.task.service.impl.persistence.entity.TaskEntityImpl;
 import org.mapstruct.Mapper;
 import org.mapstruct.factory.Mappers;
 
+import java.lang.reflect.Type;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -40,14 +46,21 @@ public interface BpmTaskConvert {
 
     default PageResult<BpmTaskRespVO> buildTodoTaskPage(PageResult<Task> pageResult,
                                                         Map<String, ProcessInstance> processInstanceMap,
-                                                        Map<Long, AdminUserRespDTO> userMap) {
+                                                        Map<Long, AdminUserRespDTO> userMap,
+                                                        Map<String, BpmProcessDefinitionExtDO> bpmProcessDefinitionExtDOMap,
+                                                        Map<String, Task> taskMap) {
         return BeanUtils.toBean(pageResult, BpmTaskRespVO.class, taskVO -> {
+            Task task = taskMap.get(taskVO.getId());
+            Map<String, Object> processVariables = task.getProcessVariables();
+            taskVO.setStatus((Integer) processVariables.get(BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS));
             ProcessInstance processInstance = processInstanceMap.get(taskVO.getProcessInstanceId());
             if (processInstance == null) {
                 return;
             }
             taskVO.setProcessInstance(BeanUtils.toBean(processInstance, BpmTaskRespVO.ProcessInstance.class));
             AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));
+            BpmProcessDefinitionExtDO bpmProcessDefinitionExtDO = bpmProcessDefinitionExtDOMap.get(processInstance.getProcessDefinitionId());
+            taskVO.setProcessDefinition(BeanUtils.toBean(bpmProcessDefinitionExtDO, BpmProcessDefinitionExtDO.class));
             taskVO.getProcessInstance().setStartUser(BeanUtils.toBean(startUser, BpmProcessInstanceRespVO.User.class));
         });
     }
@@ -55,10 +68,13 @@ public interface BpmTaskConvert {
     default PageResult<BpmTaskRespVO> buildTaskPage(PageResult<HistoricTaskInstance> pageResult,
                                                     Map<String, HistoricProcessInstance> processInstanceMap,
                                                     Map<Long, AdminUserRespDTO> userMap,
-                                                    Map<Long, DeptRespDTO> deptMap) {
+                                                    Map<Long, DeptRespDTO> deptMap,
+                                                    Map<String, BpmProcessDefinitionExtDO> bpmProcessDefinitionExtDOMap) {
         List<BpmTaskRespVO> taskVOList = CollectionUtils.convertList(pageResult.getList(), task -> {
             BpmTaskRespVO taskVO = BeanUtils.toBean(task, BpmTaskRespVO.class);
-            taskVO.setStatus(FlowableUtils.getTaskStatus(task)).setReason(FlowableUtils.getTaskReason(task));
+            Integer taskStatus = FlowableUtils.getTaskStatus(task);
+            String taskReason = FlowableUtils.getTaskReason(task);
+            taskVO.setStatus(taskStatus).setReason(taskReason);
             // 用户信息
             AdminUserRespDTO assignUser = userMap.get(NumberUtils.parseLong(task.getAssignee()));
             if (assignUser != null) {
@@ -71,6 +87,9 @@ public interface BpmTaskConvert {
                 AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));
                 taskVO.setProcessInstance(BeanUtils.toBean(processInstance, BpmTaskRespVO.ProcessInstance.class));
                 taskVO.getProcessInstance().setStartUser(BeanUtils.toBean(startUser, BpmProcessInstanceRespVO.User.class));
+
+                BpmProcessDefinitionExtDO bpmProcessDefinitionExtDO = bpmProcessDefinitionExtDOMap.get(processInstance.getProcessDefinitionId());
+                taskVO.setProcessDefinition(BeanUtils.toBean(bpmProcessDefinitionExtDO, BpmProcessDefinitionExtDO.class));
             }
             return taskVO;
         });

+ 5 - 1
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/FlowableUtils.java

@@ -78,7 +78,11 @@ public class FlowableUtils {
      * @return 状态
      */
     private static Integer getProcessInstanceStatus(Map<String, Object> processVariables) {
-        return (Integer) processVariables.get(BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS);
+        Object status = processVariables.get(BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS);
+        if (status instanceof String) {
+            status = Integer.valueOf((String) status);
+        }
+        return (Integer) status;
     }
 
     /**

+ 11 - 11
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/web/config/BpmWebConfiguration.java

@@ -13,7 +13,7 @@ import org.springframework.context.annotation.Configuration;
  *
  * @author 芋道源码
  */
-//@Configuration(proxyBeanMethods = false)
+@Configuration(proxyBeanMethods = false)
 public class BpmWebConfiguration {
 
     /**
@@ -24,15 +24,15 @@ public class BpmWebConfiguration {
         return YudaoSwaggerAutoConfiguration.buildGroupedOpenApi("bpm");
     }
 
-    /**
-     * 配置 Flowable Web 过滤器
-     */
-    @Bean
-    public FilterRegistrationBean<FlowableWebFilter> flowableWebFilter() {
-        FilterRegistrationBean<FlowableWebFilter> registrationBean = new FilterRegistrationBean<>();
-        registrationBean.setFilter(new FlowableWebFilter());
-        registrationBean.setOrder(WebFilterOrderEnum.FLOWABLE_FILTER);
-        return registrationBean;
-    }
+    // /**
+    //  * 配置 Flowable Web 过滤器
+    //  */
+    // @Bean
+    // public FilterRegistrationBean<FlowableWebFilter> flowableWebFilter() {
+    //     FilterRegistrationBean<FlowableWebFilter> registrationBean = new FilterRegistrationBean<>();
+    //     registrationBean.setFilter(new FlowableWebFilter());
+    //     registrationBean.setOrder(WebFilterOrderEnum.FLOWABLE_FILTER);
+    //     return registrationBean;
+    // }
 
 }

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

@@ -41,7 +41,6 @@ import java.util.Objects;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
-import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.MODEL_DEPLOY_FAIL_TASK_INFO_EQUALS;
 
 /**
  * Flowable流程模型实现

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

@@ -193,4 +193,13 @@ public interface BpmProcessDefinitionService {
      * @return BPMN XML
      */
     String getProcessDefinitionBpmnXML(String id);
+
+    /**
+     * 根据流程定义id集合查询流程定义拓展信息集合
+     *
+     * @param processDefinitionIds 流程定义id集合
+     * @return 流程定义拓展信息集合,以流程定义id为key,以对应的流程定义拓展信息为value
+     */
+    Map<String, BpmProcessDefinitionExtDO> getProcessDefinitionExtMap(Collection<String> processDefinitionIds);
+
 }

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

@@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.common.util.object.PageUtils;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO;
@@ -14,6 +15,7 @@ import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConsta
 import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
 import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO;
 import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import lombok.extern.slf4j.Slf4j;
 import org.flowable.bpmn.converter.BpmnXMLConverter;
 import org.flowable.bpmn.model.BpmnModel;
@@ -270,4 +272,13 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
         return StrUtil.utf8Str(converter.convertToXML(bpmnModel));
     }
 
+    @Override
+    public Map<String, BpmProcessDefinitionExtDO> getProcessDefinitionExtMap(Collection<String> processDefinitionIds) {
+        LambdaQueryWrapper<BpmProcessDefinitionExtDO> wrapper = new LambdaQueryWrapper<BpmProcessDefinitionExtDO>();
+        if (CollUtil.isNotEmpty(processDefinitionIds)) {
+            wrapper.in(BpmProcessDefinitionExtDO::getProcessDefinitionId, processDefinitionIds);
+        }
+        return CollectionUtils.convertMap(processDefinitionMapper.selectList(wrapper), BpmProcessDefinitionExtDO::getProcessDefinitionId);
+    }
+
 }

+ 2 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/universal/OaUniversalService.java

@@ -32,6 +32,8 @@ public interface OaUniversalService {
 
     OaUniversalRespVO getOaUniversal(Long id);
 
+    OaUniversalRespVO getOaUniversalByProcInstId(String procInstId);
+
     PageResult<OaUniversalRespVO> getOaUniversalPage(OaUniversalPageReqVO pageReqVO);
 
     PageResult<OaUniversalRespVO> exportOaUniversalExcel(OaUniversalPageReqVO pageReqVO);

+ 72 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/universal/OaUniversalServiceImpl.java

@@ -171,6 +171,8 @@ public class OaUniversalServiceImpl implements OaUniversalService {
         BpmTaskApproveReqVO agreeReqVO = new BpmTaskApproveReqVO();
         agreeReqVO.setId(task.getId());
         agreeReqVO.setReason("[首次提交]");
+        agreeReqVO.setTaskStatus(Integer.valueOf(DictDataConstants.OA_AUDIT_STATUS_COMMITTED));
+        taskService.setVariable(task.getId(),BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, DictDataConstants.OA_AUDIT_STATUS_COMMITTED);
         taskService.setVariable(task.getId(), "auditPass", "true");
         bpmTaskService.approveTask(loginUserId, agreeReqVO);
 
@@ -204,21 +206,35 @@ public class OaUniversalServiceImpl implements OaUniversalService {
         if (currentTask == null) {
             throw exception(ErrorCodeConstants.TASK_NOT_EXISTS);
         }
+        // 先更新为审批中
+        taskService.setVariable(currentTask.getId(), BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, DictDataConstants.OA_AUDIT_STATUS_AUDITING);
         LambdaQueryWrapper<OaUniversalDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
         lambdaQueryWrapper.eq(OaUniversalDO::getProcInstId, currentTask.getProcessInstanceId());
         OaUniversalDO oaUniversal = oaUniversalMapper.selectOne(lambdaQueryWrapper);
+        // 如果是最后一个人审批同意,设置流程审批状态为已审核
+        String[] auditPersons = oaUniversal.getStartUserSelectAssignees().split(",");
+        String lastAuditPerson = Arrays.stream(auditPersons)
+                .reduce((first, second) -> second)
+                .orElse(null);
+        if (currentTask.getAssignee().equals(lastAuditPerson)) {
+            // 更新为已审核(暂时未生效,未找到原因,先不处理)
+            taskService.setVariable(agreeReqVO.getId(),BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, DictDataConstants.OA_AUDIT_STATUS_AUDITED);
+        }
         // 审批同意
         String reason = "[同意]";
         if (StrUtil.isNotBlank(agreeReqVO.getReason())) {
             reason = reason + agreeReqVO.getReason();
         }
         agreeReqVO.setReason(reason);
+        agreeReqVO.setTaskStatus(Integer.valueOf(DictDataConstants.OA_AUDIT_STATUS_AUDITING));
         taskService.setVariable(agreeReqVO.getId(), "auditPass", "true");
         bpmTaskService.approveTask(loginUserId, agreeReqVO);
 
         Task nextTask = taskService.createTaskQuery().processInstanceId(currentTask.getProcessInstanceId()).singleResult();
         OaUniversalDO oaUniversalDO = new OaUniversalDO();
         if (nextTask != null) {
+            // 如果审批人重复,实际未结束,再次更新为审核中
+            taskService.setVariable(nextTask.getId(), BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, DictDataConstants.OA_AUDIT_STATUS_AUDITING);
             oaUniversalDO.setAuditStatus(DictDataConstants.OA_AUDIT_STATUS_AUDITING)
                     .setCurrentAuditEmployeeId(Long.valueOf(nextTask.getAssignee()))
                     .setFinalAuditDate(LocalDateTime.now())
@@ -251,7 +267,9 @@ public class OaUniversalServiceImpl implements OaUniversalService {
 
         disagreeReqVO.setTargetTaskDefinitionKey("modifyApply");
         disagreeReqVO.setReason("[驳回]" + disagreeReqVO.getReason());
+        disagreeReqVO.setTaskStatus(Integer.valueOf(DictDataConstants.OA_AUDIT_STATUS_RETURNED));
         taskService.setVariable(disagreeReqVO.getId(), "auditPass", "false");
+        taskService.setVariable(disagreeReqVO.getId(),BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, DictDataConstants.OA_AUDIT_STATUS_RETURNED);
         bpmTaskService.returnTask(loginUserId, disagreeReqVO);
 
         Task nextTask = taskService.createTaskQuery().processInstanceId(currentTask.getProcessInstanceId()).singleResult();
@@ -295,6 +313,8 @@ public class OaUniversalServiceImpl implements OaUniversalService {
             reason = reason + returnReqVO.getReason();
         }
         returnReqVO.setReason(reason);
+        returnReqVO.setTaskStatus(Integer.valueOf(DictDataConstants.OA_AUDIT_STATUS_RECALLED));
+        taskService.setVariable(currentTask.getId(),BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, DictDataConstants.OA_AUDIT_STATUS_RECALLED);
         bpmTaskService.revocationTask(loginUserId, returnReqVO);
 
         Task nextTask = taskService.createTaskQuery().processInstanceId(currentTask.getProcessInstanceId()).singleResult();
@@ -331,6 +351,7 @@ public class OaUniversalServiceImpl implements OaUniversalService {
         BpmTaskApproveReqVO approveReqVO = new BpmTaskApproveReqVO();
         approveReqVO.setId(currentTask.getId())
                 .setReason("[再次提交]");
+        approveReqVO.setTaskStatus(Integer.valueOf(DictDataConstants.OA_AUDIT_STATUS_COMMITTED));
         if (CollectionUtil.isNotEmpty(reCommitReqVO.getStartUserSelectAssignees())) {
             // 添加审批人信息到流程参数中
             Map<String, List<Long>> startUserSelectAssignees = new HashMap<>();
@@ -341,6 +362,7 @@ public class OaUniversalServiceImpl implements OaUniversalService {
             oaUniversalNew.setStartUserSelectAssignees(selectAssignees.stream().map(String::valueOf).collect(Collectors.joining(",")));
         }
         taskService.setVariable(currentTask.getId(), "auditPass", "true");
+        taskService.setVariable(currentTask.getId(),BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, DictDataConstants.OA_AUDIT_STATUS_COMMITTED);
         // 再次提交,和审批通过逻辑相同
         bpmTaskService.approveTask(loginUserId, approveReqVO);
 
@@ -373,7 +395,9 @@ public class OaUniversalServiceImpl implements OaUniversalService {
         BpmTaskApproveReqVO approveReqVO = new BpmTaskApproveReqVO();
         approveReqVO.setId(currentTask.getId())
                 .setReason("[关闭]");
+        approveReqVO.setTaskStatus(Integer.valueOf(DictDataConstants.OA_AUDIT_STATUS_CLOSED));
         taskService.setVariable(currentTask.getId(), "auditPass", "false");
+        taskService.setVariable(currentTask.getId(),BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, DictDataConstants.OA_AUDIT_STATUS_CLOSED);
         // 关闭,使用审批通过的方法实现
         bpmTaskService.approveTask(loginUserId, approveReqVO);
 
@@ -397,6 +421,54 @@ public class OaUniversalServiceImpl implements OaUniversalService {
     public OaUniversalRespVO getOaUniversal(Long id) {
         OaUniversalDO oaUniversalDO = oaUniversalMapper.selectById(id);
         OaUniversalRespVO oaUniversalRespVO = BeanUtils.toBean(oaUniversalDO, OaUniversalRespVO.class);
+        if (oaUniversalDO.getDeptId() != null) {
+            DeptRespDTO dept = deptApi.getDept(oaUniversalDO.getDeptId());
+            if (dept != null) {
+                oaUniversalRespVO.setDeptName(dept.getName());
+            }
+        }
+
+        // 附件列表
+        List<FileDTO> fileList = fileApi.getFileDTOListByBiz(oaUniversalDO.getUniversalId());
+        oaUniversalRespVO.setFileList(fileList);
+
+        // 审批记录
+        if (StrUtil.isNotBlank(oaUniversalDO.getProcInstId())) {
+            List<BpmTaskRespVO> auditRecordList = bpmTaskService.getAuditRecordListByProcessInstanceId(oaUniversalDO.getProcInstId());
+            oaUniversalRespVO.setAuditRecordList(auditRecordList);
+        }
+
+        // 审批人
+        String startUserSelectAssignees = oaUniversalDO.getStartUserSelectAssignees();
+        if (StrUtil.isNotEmpty(startUserSelectAssignees)) {
+            List<Long> userIdList = Arrays.stream(startUserSelectAssignees.split(","))
+                    .map(Long::valueOf).collect(Collectors.toList());
+            List<AdminUserRespDTO> userList = adminUserApi.getUserList(userIdList);
+            List<AdminUserRespDTO> auditUserList = new ArrayList<>();
+            for (Long userId : userIdList) {
+                for (AdminUserRespDTO adminUserRespDTO : userList) {
+                    if (Objects.equals(userId, adminUserRespDTO.getId())) {
+                        auditUserList.add(adminUserRespDTO);
+                        break;
+                    }
+                }
+            }
+            oaUniversalRespVO.setAuditUserList(auditUserList);
+        }
+
+        return oaUniversalRespVO;
+    }
+
+    @Override
+    public OaUniversalRespVO getOaUniversalByProcInstId(String procInstId) {
+        OaUniversalDO oaUniversalDO = oaUniversalMapper.selectOne(OaUniversalDO::getProcInstId, procInstId);
+        OaUniversalRespVO oaUniversalRespVO = BeanUtils.toBean(oaUniversalDO, OaUniversalRespVO.class);
+        if (oaUniversalDO.getDeptId() != null) {
+            DeptRespDTO dept = deptApi.getDept(oaUniversalDO.getDeptId());
+            if (dept != null) {
+                oaUniversalRespVO.setDeptName(dept.getName());
+            }
+        }
 
         // 附件列表
         List<FileDTO> fileList = fileApi.getFileDTOListByBiz(oaUniversalDO.getUniversalId());

+ 9 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java

@@ -20,6 +20,15 @@ import java.util.Map;
  */
 public interface BpmTaskService {
 
+    /**
+     * 获得待办的流程任务数量
+     *
+     * @param userId    用户编号
+     * @param pageReqVO 请求参数
+     * @return 流程任务数量
+     */
+    Long getTaskTodoCount(Long userId, BpmTaskPageReqVO pageReqVO);
+
     /**
      * 获得待办的流程任务分页
      *

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

@@ -93,6 +93,23 @@ public class BpmTaskServiceImpl implements BpmTaskService {
     @Resource
     private DeptApi deptApi;
 
+    @Override
+    public Long getTaskTodoCount(Long userId, BpmTaskPageReqVO pageVO) {
+        TaskQuery taskQuery = taskService.createTaskQuery()
+                .taskAssignee(String.valueOf(userId)) // 分配给自己
+                .active()
+                .includeProcessVariables()
+                .orderByTaskCreateTime().desc(); // 创建时间倒序
+        if (StrUtil.isNotBlank(pageVO.getName())) {
+            taskQuery.processDefinitionNameLike("%" + pageVO.getName() + "%");
+        }
+        if (ArrayUtil.isNotEmpty(pageVO.getCreateTime())) {
+            taskQuery.taskCreatedAfter(DateUtils.of(pageVO.getCreateTime()[0]));
+            taskQuery.taskCreatedBefore(DateUtils.of(pageVO.getCreateTime()[1]));
+        }
+        return taskQuery.count();
+    }
+
     @Override
     public PageResult<Task> getTaskTodoPage(Long userId, BpmTaskPageReqVO pageVO) {
         TaskQuery taskQuery = taskService.createTaskQuery()
@@ -101,11 +118,11 @@ public class BpmTaskServiceImpl implements BpmTaskService {
                 .includeProcessVariables()
                 .orderByTaskCreateTime().desc(); // 创建时间倒序
         if (StrUtil.isNotBlank(pageVO.getName())) {
-            taskQuery.taskNameLike("%" + pageVO.getName() + "%");
+            taskQuery.processDefinitionNameLike("%" + pageVO.getName() + "%");
         }
         if (ArrayUtil.isNotEmpty(pageVO.getCreateTime())) {
             taskQuery.taskCreatedAfter(DateUtils.of(pageVO.getCreateTime()[0]));
-            taskQuery.taskCreatedAfter(DateUtils.of(pageVO.getCreateTime()[1]));
+            taskQuery.taskCreatedBefore(DateUtils.of(pageVO.getCreateTime()[1]));
         }
         long count = taskQuery.count();
         if (count == 0) {
@@ -123,11 +140,11 @@ public class BpmTaskServiceImpl implements BpmTaskService {
                 .includeTaskLocalVariables()
                 .orderByHistoricTaskInstanceEndTime().desc(); // 审批时间倒序
         if (StrUtil.isNotBlank(pageVO.getName())) {
-            taskQuery.taskNameLike("%" + pageVO.getName() + "%");
+            taskQuery.processDefinitionNameLike("%" + pageVO.getName() + "%");
         }
         if (ArrayUtil.isNotEmpty(pageVO.getCreateTime())) {
             taskQuery.taskCreatedAfter(DateUtils.of(pageVO.getCreateTime()[0]));
-            taskQuery.taskCreatedAfter(DateUtils.of(pageVO.getCreateTime()[1]));
+            taskQuery.taskCreatedBefore(DateUtils.of(pageVO.getCreateTime()[1]));
         }
         // 执行查询
         long count = taskQuery.count();
@@ -211,7 +228,11 @@ public class BpmTaskServiceImpl implements BpmTaskService {
 
         // 情况三:审批普通的任务。大多数情况下,都是这样
         // 3.1 更新 task 状态、原因
-        updateTaskStatusAndReason(task.getId(), BpmTaskStatusEnum.APPROVE.getStatus(), reqVO.getReason());
+        Integer status = BpmTaskStatusEnum.APPROVE.getStatus();
+        if (reqVO.getTaskStatus() != null) {
+            status = reqVO.getTaskStatus();
+        }
+        updateTaskStatusAndReason(task.getId(), status, reqVO.getReason());
         // 3.2 添加评论
         taskService.addComment(task.getId(), task.getProcessInstanceId(), BpmCommentTypeEnum.APPROVE.getType(),
                 BpmCommentTypeEnum.APPROVE.formatComment(reqVO.getReason()));
@@ -219,7 +240,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
         // 其中,variables 是存储动态表单到 local 任务级别。过滤一下,避免 ProcessInstance 系统级的变量被占用
         if (CollUtil.isNotEmpty(reqVO.getVariables())) {
             Map<String, Object> variables = FlowableUtils.filterTaskFormVariable(reqVO.getVariables());
-            taskService.complete(task.getId(), variables, true);
+            taskService.complete(task.getId(), variables, false);
         } else {
             taskService.complete(task.getId());
         }
@@ -555,7 +576,11 @@ public class BpmTaskServiceImpl implements BpmTaskService {
             taskService.addComment(task.getId(), currentTask.getProcessInstanceId(), BpmCommentTypeEnum.RETURN.getType(),
                     BpmCommentTypeEnum.RETURN.formatComment(reqVO.getReason()));
             // 2.2 更新 task 状态 + 原因
-            updateTaskStatusAndReason(task.getId(), BpmTaskStatusEnum.RETURN.getStatus(), reqVO.getReason());
+            Integer status = BpmTaskStatusEnum.RETURN.getStatus();
+            if (reqVO.getTaskStatus() != null) {
+                status = reqVO.getTaskStatus();
+            }
+            updateTaskStatusAndReason(task.getId(), status, reqVO.getReason());
         });
 
         // 3. 执行驳回

+ 1 - 0
yudao-server/src/main/resources/application-local.yaml

@@ -174,6 +174,7 @@ logging:
     cn.iocoder.yudao.module.erp.dal.mysql: debug
     cn.iocoder.yudao.module.personnel.dal.mysql: debug
     org.springframework.context.support.PostProcessorRegistrationDelegate: ERROR # TODO 芋艿:先禁用,Spring Boot 3.X 存在部分错误的 WARN 提示
+#    org.flowable: debug
 
 debug: false