Browse Source

Revert "工作流代码更新"

This reverts commit d9689dc4880fa816f6227e56dbedd60998f3e919.
还原变更
zjc 8 months ago
parent
commit
664841dc4e
100 changed files with 1270 additions and 2445 deletions
  1. 12 1
      yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/task/dto/BpmProcessInstanceCreateReqDTO.java
  2. 55 39
      yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java
  3. 13 2
      yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmModelFormTypeEnum.java
  4. 0 33
      yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmTaskAssignRuleTypeEnum.java
  5. 0 30
      yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmTaskRuleScriptEnum.java
  6. 0 58
      yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceDeleteReasonEnum.java
  7. 0 48
      yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceResultEnum.java
  8. 16 4
      yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceStatusEnum.java
  9. 17 13
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmFormController.java
  10. 59 8
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java
  11. 71 16
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessDefinitionController.java
  12. 0 58
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java
  13. 24 17
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmUserGroupController.java
  14. 0 24
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormBaseVO.java
  15. 0 22
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormCreateReqVO.java
  16. 0 2
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormPageReqVO.java
  17. 17 9
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormRespVO.java
  18. 0 16
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormSimpleRespVO.java
  19. 0 25
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormUpdateReqVO.java
  20. 0 30
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupBaseVO.java
  21. 0 11
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupCreateReqVO.java
  22. 3 2
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupPageReqVO.java
  23. 18 7
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupRespVO.java
  24. 0 20
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupSimpleRespVO.java
  25. 0 16
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupUpdateReqVO.java
  26. 1 3
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModeImportReqVO.java
  27. 0 40
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelBaseVO.java
  28. 2 2
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelCreateReqVO.java
  29. 0 48
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelPageItemRespVO.java
  30. 3 5
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelPageReqVO.java
  31. 42 10
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelRespVO.java
  32. 11 3
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelUpdateReqVO.java
  33. 3 3
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelUpdateStateReqVO.java
  34. 0 18
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionListReqVO.java
  35. 0 22
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageItemRespVO.java
  36. 0 2
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageReqVO.java
  37. 40 12
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionRespVO.java
  38. 0 24
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleBaseVO.java
  39. 0 24
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleCreateReqVO.java
  40. 0 28
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleRespVO.java
  41. 0 20
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleUpdateReqVO.java
  42. 7 7
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOALeaveController.java
  43. 0 32
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveBaseVO.java
  44. 28 5
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveCreateReqVO.java
  45. 11 9
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeavePageReqVO.java
  46. 20 15
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveRespVO.java
  47. 115 11
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java
  48. 159 13
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java
  49. 6 6
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/activity/BpmActivityRespVO.java
  50. 2 4
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCancelReqVO.java
  51. 6 2
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCreateReqVO.java
  52. 0 39
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceMyPageReqVO.java
  53. 0 54
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstancePageItemRespVO.java
  54. 32 37
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceRespVO.java
  55. 10 2
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java
  56. 0 26
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDonePageItemRespVO.java
  57. 0 31
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDonePageReqVO.java
  58. 2 2
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRejectReqVO.java
  59. 76 19
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRespVO.java
  60. 0 53
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskTodoPageItemRespVO.java
  61. 0 28
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskTodoPageReqVO.java
  62. 0 24
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskUpdateAssigneeReqVO.java
  63. 0 34
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmFormConvert.java
  64. 68 72
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmModelConvert.java
  65. 57 43
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java
  66. 0 40
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmTaskAssignRuleConvert.java
  67. 0 38
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmUserGroupConvert.java
  68. 0 30
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/oa/BpmOALeaveConvert.java
  69. 2 1
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmActivityConvert.java
  70. 52 50
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java
  71. 122 117
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java
  72. 0 1
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/package-info.java
  73. 1 3
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmFormDO.java
  74. 0 90
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessDefinitionExtDO.java
  75. 0 83
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmTaskAssignRuleDO.java
  76. 0 5
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmTaskMessageRuleDO.java
  77. 1 3
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmUserGroupDO.java
  78. 9 10
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOALeaveDO.java
  79. 0 105
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmActivityDO.java
  80. 0 90
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmProcessInstanceExtDO.java
  81. 0 85
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmTaskExtDO.java
  82. 0 22
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmProcessDefinitionExtMapper.java
  83. 0 37
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmTaskAssignRuleMapper.java
  84. 1 1
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOALeaveMapper.java
  85. 0 34
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmProcessInstanceExtMapper.java
  86. 0 26
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmTaskExtMapper.java
  87. 0 19
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/config/BpmCommonConfiguration.java
  88. 0 28
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/config/BpmSecurityConfiguration.java
  89. 0 44
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/event/BpmProcessInstanceResultEvent.java
  90. 0 34
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/event/BpmProcessInstanceResultEventListener.java
  91. 0 24
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/event/BpmProcessInstanceResultEventPublisher.java
  92. 0 6
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/event/package-info.java
  93. 0 4
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/package-info.java
  94. 0 6
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/package-info.java
  95. 49 4
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java
  96. 14 14
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmActivityBehaviorFactory.java
  97. 8 10
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmParallelMultiInstanceBehavior.java
  98. 5 4
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmUserTaskActivityBehavior.java
  99. 0 34
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/BpmTaskAssignScript.java
  100. 0 0
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderAbstractScript.java

+ 12 - 1
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/task/dto/BpmProcessInstanceCreateReqDTO.java

@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.bpm.api.task.dto;
 import lombok.Data;
 
 import javax.validation.constraints.NotEmpty;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -19,7 +20,7 @@ public class BpmProcessInstanceCreateReqDTO {
     @NotEmpty(message = "流程定义的标识不能为空")
     private String processDefinitionKey;
     /**
-     * 变量实例
+     * 变量实例(动态表单)
      */
     private Map<String, Object> variables;
 
@@ -30,4 +31,14 @@ public class BpmProcessInstanceCreateReqDTO {
      */
     @NotEmpty(message = "业务的唯一标识")
     private String businessKey;
+
+    /**
+     * 发起人自选审批人 Map
+     *
+     * key:taskKey 任务编码
+     * value:审批人的数组
+     * 例如:{ taskKey1 :[1, 2] },则表示 taskKey1 这个任务,提前设定了,由 userId 为 1,2 的用户进行审批
+     */
+    private Map<String, List<Long>> startUserSelectAssignees;
+
 }

+ 55 - 39
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java

@@ -3,62 +3,78 @@ package cn.iocoder.yudao.module.bpm.enums;
 import cn.iocoder.yudao.framework.common.exception.ErrorCode;
 
 /**
- * 工作流 错误码枚举类
- *
- * 工作流系统,使用 1-009-000-000 段
+ * Bpm 错误码枚举类
+ * <p>
+ * bpm 系统,使用 1-009-000-000 段
  */
 public interface ErrorCodeConstants {
 
     // ==========  通用流程处理 模块 1-009-000-000 ==========
-    ErrorCode HIGHLIGHT_IMG_ERROR = new ErrorCode(1009000002, "获取高亮流程图异常");
 
     // ========== OA 流程模块 1-009-001-000 ==========
-    ErrorCode OA_LEAVE_NOT_EXISTS = new ErrorCode(1009001001, "请假申请不存在");
-    ErrorCode OA_PM_POST_NOT_EXISTS = new ErrorCode(1009001002, "项目经理岗位未设置");
-    ErrorCode OA_DEPART_PM_POST_NOT_EXISTS = new ErrorCode(1009001009, "部门的项目经理不存在");
-    ErrorCode OA_BM_POST_NOT_EXISTS = new ErrorCode(1009001004, "部门经理岗位未设置");
-    ErrorCode OA_DEPART_BM_POST_NOT_EXISTS = new ErrorCode(1009001005, "部门的部门经理不存在");
-    ErrorCode OA_HR_POST_NOT_EXISTS = new ErrorCode(1009001006, "HR岗位未设置");
-    ErrorCode OA_DAY_LEAVE_ERROR = new ErrorCode(1009001007, "请假天数必须>=1");
+    ErrorCode OA_LEAVE_NOT_EXISTS = new ErrorCode(1_009_001_001, "请假申请不存在");
 
     // ========== 流程模型 1-009-002-000 ==========
-    ErrorCode MODEL_KEY_EXISTS = new ErrorCode(1009002000, "已经存在流程标识为【{}】的流程");
-    ErrorCode MODEL_NOT_EXISTS = new ErrorCode(1009002001, "流程模型不存在");
-    ErrorCode MODEL_KEY_VALID = new ErrorCode(1009002002, "流程标识格式不正确,需要以字母或下划线开头,后接任意字母、数字、中划线、下划线、句点!");
-    ErrorCode MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG = new ErrorCode(1009002003, "部署流程失败,原因:流程表单未配置,请点击【修改流程】按钮进行配置");
-    ErrorCode MODEL_DEPLOY_FAIL_TASK_ASSIGN_RULE_NOT_CONFIG = new ErrorCode(1009002004, "部署流程失败," +
-            "原因:用户任务({})未配置分配规则,请点击【修改流程】按钮进行配置");
-    ErrorCode MODEL_DEPLOY_FAIL_TASK_INFO_EQUALS = new ErrorCode(1009003005, "流程定义部署失败,原因:信息未发生变化");
+    ErrorCode MODEL_KEY_EXISTS = new ErrorCode(1_009_002_000, "已经存在流程标识为【{}】的流程");
+    ErrorCode MODEL_NOT_EXISTS = new ErrorCode(1_009_002_001, "流程模型不存在");
+    ErrorCode MODEL_KEY_VALID = new ErrorCode(1_009_002_002, "流程标识格式不正确,需要以字母或下划线开头,后接任意字母、数字、中划线、下划线、句点!");
+    ErrorCode MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG = new ErrorCode(1_009_002_003, "部署流程失败,原因:流程表单未配置,请点击【修改流程】按钮进行配置");
+    ErrorCode MODEL_DEPLOY_FAIL_TASK_CANDIDATE_NOT_CONFIG = new ErrorCode(1_009_002_004, "部署流程失败," +
+            "原因:用户任务({})未配置审批人,请点击【流程设计】按钮,选择该它的【任务(审批人)】进行配置");
+    ErrorCode MODEL_DEPLOY_FAIL_BPMN_START_EVENT_NOT_EXISTS = new ErrorCode(1_009_002_005, "部署流程失败,原因:BPMN 流程图中,没有开始事件");
+    ErrorCode MODEL_DEPLOY_FAIL_BPMN_USER_TASK_NAME_NOT_EXISTS = new ErrorCode(1_009_002_006, "部署流程失败,原因:BPMN 流程图中,用户任务({})的名字不存在");
 
     // ========== 流程定义 1-009-003-000 ==========
-    ErrorCode PROCESS_DEFINITION_KEY_NOT_MATCH = new ErrorCode(1009003000, "流程定义的标识期望是({}),当前是({}),请修改 BPMN 流程图");
-    ErrorCode PROCESS_DEFINITION_NAME_NOT_MATCH = new ErrorCode(1009003001, "流程定义的名字期望是({}),当前是({}),请修改 BPMN 流程图");
-    ErrorCode PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1009003002, "流程定义不存在");
-    ErrorCode PROCESS_DEFINITION_IS_SUSPENDED = new ErrorCode(1009003003, "流程定义处于挂起状态");
-    ErrorCode PROCESS_DEFINITION_BPMN_MODEL_NOT_EXISTS = new ErrorCode(1009003004, "流程定义的模型不存在");
+    ErrorCode PROCESS_DEFINITION_KEY_NOT_MATCH = new ErrorCode(1_009_003_000, "流程定义的标识期望是({}),当前是({}),请修改 BPMN 流程图");
+    ErrorCode PROCESS_DEFINITION_NAME_NOT_MATCH = new ErrorCode(1_009_003_001, "流程定义的名字期望是({}),当前是({}),请修改 BPMN 流程图");
+    ErrorCode PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1_009_003_002, "流程定义不存在");
+    ErrorCode PROCESS_DEFINITION_IS_SUSPENDED = new ErrorCode(1_009_003_003, "流程定义处于挂起状态");
 
     // ========== 流程实例 1-009-004-000 ==========
-    ErrorCode PROCESS_INSTANCE_NOT_EXISTS = new ErrorCode(1009004000, "流程实例不存在");
-    ErrorCode PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS = new ErrorCode(1009004001, "流程取消失败,流程不处于运行中");
-    ErrorCode PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF = new ErrorCode(1009004002, "流程取消失败,该流程不是你发起的");
+    ErrorCode PROCESS_INSTANCE_NOT_EXISTS = new ErrorCode(1_009_004_000, "流程实例不存在");
+    ErrorCode PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS = new ErrorCode(1_009_004_001, "流程取消失败,流程不处于运行中");
+    ErrorCode PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF = new ErrorCode(1_009_004_002, "流程取消失败,该流程不是你发起的");
+    ErrorCode PROCESS_INSTANCE_START_USER_SELECT_ASSIGNEES_NOT_CONFIG = new ErrorCode(1_009_004_003, "审批任务({})的审批人未配置");
+    ErrorCode PROCESS_INSTANCE_START_USER_SELECT_ASSIGNEES_NOT_EXISTS = new ErrorCode(1_009_004_004, "审批任务({})的审批人({})不存在");
 
     // ========== 流程任务 1-009-005-000 ==========
-    ErrorCode TASK_COMPLETE_FAIL_NOT_EXISTS = new ErrorCode(1009005000, "审批任务失败,原因:该任务不处于未审批");
-    ErrorCode TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF = new ErrorCode(1009005001, "审批任务失败,原因:该任务的审批人不是你");
-
-    // ========== 流程任务分配规则 1-009-006-000 ==========
-    ErrorCode TASK_ASSIGN_RULE_EXISTS = new ErrorCode(1009006000, "流程({}) 的任务({}) 已经存在分配规则");
-    ErrorCode TASK_ASSIGN_RULE_NOT_EXISTS = new ErrorCode(1009006001, "流程任务分配规则不存在");
-    ErrorCode TASK_UPDATE_FAIL_NOT_MODEL = new ErrorCode(1009006002, "只有流程模型的任务分配规则,才允许被修改");
-    ErrorCode TASK_CREATE_FAIL_NO_CANDIDATE_USER = new ErrorCode(1009006003, "操作失败,原因:找不到任务的审批人!");
-    ErrorCode TASK_ASSIGN_SCRIPT_NOT_EXISTS = new ErrorCode(1009006004, "操作失败,原因:任务分配脚本({}) 不存在");
+    ErrorCode TASK_OPERATE_FAIL_ASSIGN_NOT_SELF = new ErrorCode(1_009_005_001, "操作失败,原因:该任务的审批人不是你");
+    ErrorCode TASK_NOT_EXISTS = new ErrorCode(1_009_005_002, "流程任务不存在");
+    ErrorCode TASK_IS_PENDING = new ErrorCode(1_009_005_003, "当前任务处于挂起状态,不能操作");
+    ErrorCode TASK_TARGET_NODE_NOT_EXISTS = new ErrorCode(1_009_005_004, " 目标节点不存在");
+    ErrorCode TASK_RETURN_FAIL_SOURCE_TARGET_ERROR = new ErrorCode(1_009_005_006, "回退任务失败,目标节点是在并行网关上或非同一路线上,不可跳转");
+    ErrorCode TASK_DELEGATE_FAIL_USER_REPEAT = new ErrorCode(1_009_005_007, "任务委派失败,委派人和当前审批人为同一人");
+    ErrorCode TASK_DELEGATE_FAIL_USER_NOT_EXISTS = new ErrorCode(1_009_005_008, "任务委派失败,被委派人不存在");
+    ErrorCode TASK_SIGN_CREATE_USER_NOT_EXIST = new ErrorCode(1_009_005_009, "任务加签:选择的用户不存在");
+    ErrorCode TASK_SIGN_CREATE_TYPE_ERROR = new ErrorCode(1_009_005_010, "任务加签:当前任务已经{},不能{}");
+    ErrorCode TASK_SIGN_CREATE_USER_REPEAT = new ErrorCode(1_009_005_011, "任务加签失败,加签人与现有审批人[{}]重复");
+    ErrorCode TASK_SIGN_DELETE_NO_PARENT = new ErrorCode(1_009_005_012, "任务减签失败,被减签的任务必须是通过加签生成的任务");
+    ErrorCode TASK_TRANSFER_FAIL_USER_REPEAT = new ErrorCode(1_009_005_013, "任务转办失败,转办人和当前审批人为同一人");
+    ErrorCode TASK_TRANSFER_FAIL_USER_NOT_EXISTS = new ErrorCode(1_009_005_014, "任务转办失败,转办人不存在");
+    ErrorCode TASK_CREATE_FAIL_NO_CANDIDATE_USER = new ErrorCode(1_009_006_003, "操作失败,原因:找不到任务的审批人!");
 
     // ========== 动态表单模块 1-009-010-000 ==========
-    ErrorCode FORM_NOT_EXISTS = new ErrorCode(1009010000, "动态表单不存在");
-    ErrorCode FORM_FIELD_REPEAT = new ErrorCode(1009010001, "表单项({}) 和 ({}) 使用了相同的字段名({})");
+    ErrorCode FORM_NOT_EXISTS = new ErrorCode(1_009_010_000, "动态表单不存在");
+    ErrorCode FORM_FIELD_REPEAT = new ErrorCode(1_009_010_001, "表单项({}) 和 ({}) 使用了相同的字段名({})");
 
     // ========== 用户组模块 1-009-011-000 ==========
-    ErrorCode USER_GROUP_NOT_EXISTS = new ErrorCode(1009011000, "用户组不存在");
-    ErrorCode USER_GROUP_IS_DISABLE = new ErrorCode(1009011001, "名字为【{}】的用户组已被禁用");
+    ErrorCode USER_GROUP_NOT_EXISTS = new ErrorCode(1_009_011_000, "用户分组不存在");
+    ErrorCode USER_GROUP_IS_DISABLE = new ErrorCode(1_009_011_001, "名字为【{}】的用户分组已被禁用");
+
+    // ========== 用户组模块 1-009-012-000 ==========
+    ErrorCode CATEGORY_NOT_EXISTS = new ErrorCode(1_009_012_000, "流程分类不存在");
+    ErrorCode CATEGORY_NAME_DUPLICATE = new ErrorCode(1_009_012_001, "流程分类名字【{}】重复");
+    ErrorCode CATEGORY_CODE_DUPLICATE = new ErrorCode(1_009_012_002, "流程分类编码【{}】重复");
+
+    // ========== BPM 流程监听器 1-009-013-000 ==========
+    ErrorCode PROCESS_LISTENER_NOT_EXISTS = new ErrorCode(1_009_013_000, "流程监听器不存在");
+    ErrorCode PROCESS_LISTENER_CLASS_NOT_FOUND = new ErrorCode(1_009_013_001, "流程监听器类({})不存在");
+    ErrorCode PROCESS_LISTENER_CLASS_IMPLEMENTS_ERROR = new ErrorCode(1_009_013_002, "流程监听器类({})没有实现接口({})");
+    ErrorCode PROCESS_LISTENER_EXPRESSION_INVALID = new ErrorCode(1_009_013_003, "流程监听器表达式({})不合法");
+
+    // ========== BPM 流程表达式 1-009-014-000 ==========
+    ErrorCode PROCESS_EXPRESSION_NOT_EXISTS = new ErrorCode(1_009_014_000, "流程表达式不存在");
+    // ========== BPM 流程规则 1_009_015_000 ==========
+    ErrorCode TASK_ASSIGN_RULE_NOT_EXISTS = new ErrorCode(1_009_015_000, "Bpm 任务规则不存在");
 
 }

+ 13 - 2
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmModelFormTypeEnum.java

@@ -1,8 +1,11 @@
 package cn.iocoder.yudao.module.bpm.enums.definition;
 
+import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
 import lombok.AllArgsConstructor;
 import lombok.Getter;
 
+import java.util.Arrays;
+
 /**
  * BPM 模型的表单类型的枚举
  *
@@ -10,12 +13,20 @@ import lombok.Getter;
  */
 @Getter
 @AllArgsConstructor
-public enum BpmModelFormTypeEnum {
+public enum BpmModelFormTypeEnum implements IntArrayValuable {
 
     NORMAL(10, "流程表单"), // 对应 BpmFormDO
     CUSTOM(20, "业务表单") // 业务自己定义的表单,自己进行数据的存储
     ;
 
+    public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BpmModelFormTypeEnum::getType).toArray();
+
     private final Integer type;
-    private final String desc;
+    private final String name;
+
+    @Override
+    public int[] array() {
+        return ARRAYS;
+    }
+
 }

+ 0 - 33
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmTaskAssignRuleTypeEnum.java

@@ -1,33 +0,0 @@
-package cn.iocoder.yudao.module.bpm.enums.definition;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * BPM 任务分配规则的类型枚举
- *
- * @author 芋道源码
- */
-@Getter
-@AllArgsConstructor
-public enum BpmTaskAssignRuleTypeEnum {
-
-    ROLE(10, "角色"),
-    DEPT_MEMBER(20, "部门的成员"), // 包括负责人
-    DEPT_LEADER(21, "部门的负责人"),
-    POST(22, "岗位"),
-    USER(30, "用户"),
-    USER_GROUP(40, "用户组"),
-    SCRIPT(50, "自定义脚本"), // 例如说,发起人所在部门的领导、发起人所在部门的领导的领导
-    ;
-
-    /**
-     * 类型
-     */
-    private final Integer type;
-    /**
-     * 描述
-     */
-    private final String desc;
-
-}

+ 0 - 30
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmTaskRuleScriptEnum.java

@@ -1,30 +0,0 @@
-package cn.iocoder.yudao.module.bpm.enums.definition;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * BPM 任务规则的脚本枚举
- * 目前暂时通过 TODO 芋艿:硬编码,未来可以考虑 Groovy 动态脚本的方式
- *
- * @author 芋道源码
- */
-@Getter
-@AllArgsConstructor
-public enum BpmTaskRuleScriptEnum {
-
-    START_USER(10L, "流程发起人"),
-
-    LEADER_X1(20L, "流程发起人的一级领导"),
-    LEADER_X2(21L, "流程发起人的二级领导");
-
-    /**
-     * 脚本编号
-     */
-    private final Long id;
-    /**
-     * 脚本描述
-     */
-    private final String desc;
-
-}

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

@@ -1,58 +0,0 @@
-package cn.iocoder.yudao.module.bpm.enums.task;
-
-import cn.hutool.core.util.StrUtil;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * 流程实例的删除原因
- *
- * @author 芋道源码
- */
-@Getter
-@AllArgsConstructor
-public enum BpmProcessInstanceDeleteReasonEnum {
-
-    REJECT_TASK("不通过任务,原因:{}"), // 修改文案时,需要注意 isRejectReason 方法
-    CANCEL_TASK("主动取消任务,原因:{}"),
-
-    // ========== 流程任务的独有原因 ==========
-    MULTI_TASK_END("系统自动取消,原因:多任务审批已经满足条件,无需审批该任务"), // 多实例满足 condition 而结束时,其它任务实例任务会被取消,对应的删除原因是 MI_END
-
-    ;
-
-    private final String reason;
-
-    /**
-     * 格式化理由
-     *
-     * @param args 参数
-     * @return 理由
-     */
-    public String format(Object... args) {
-        return StrUtil.format(reason, args);
-    }
-
-    // ========== 逻辑 ==========
-
-    public static boolean isRejectReason(String reason) {
-        return StrUtil.startWith(reason, "不通过任务,原因:");
-    }
-
-    /**
-     * 将 Flowable 的删除原因,翻译成对应的中文原因
-     *
-     * @param reason 原始原因
-     * @return 原因
-     */
-    public static String translateReason(String reason) {
-        if (StrUtil.isEmpty(reason)) {
-            return reason;
-        }
-        switch (reason) {
-            case "MI_END": return MULTI_TASK_END.getReason();
-            default: return reason;
-        }
-    }
-
-}

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

@@ -1,48 +0,0 @@
-package cn.iocoder.yudao.module.bpm.enums.task;
-
-import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * 流程实例的结果
- *
- * @author jason
- */
-@Getter
-@AllArgsConstructor
-public enum BpmProcessInstanceResultEnum {
-
-    PROCESS(1, "处理中"),
-    APPROVE(2, "通过"),
-    REJECT(3, "不通过"),
-    CANCEL(4, "已取消"),
-
-    // ========== 流程任务独有的状态 ==========
-
-    BACK(5, "退回/驳回");
-
-    /**
-     * 结果
-     *
-     * 如果新增时,注意 {@link #isEndResult(Integer)} 是否需要变更
-     */
-    private final Integer result;
-    /**
-     * 描述
-     */
-    private final String desc;
-
-    /**
-     * 判断该结果是否已经处于 End 最终结果
-     *
-     * 主要用于一些结果更新的逻辑,如果已经是最终结果,就不再进行更新
-     *
-     * @param result 结果
-     * @return 是否
-     */
-    public static boolean isEndResult(Integer result) {
-        return ObjectUtils.equalsAny(result, APPROVE.getResult(), REJECT.getResult(), CANCEL.getResult(), BACK.getResult());
-    }
-
-}

+ 16 - 4
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceStatusEnum.java

@@ -1,19 +1,26 @@
 package cn.iocoder.yudao.module.bpm.enums.task;
 
+import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
 import lombok.AllArgsConstructor;
 import lombok.Getter;
 
+import java.util.Arrays;
+
 /**
- * 流程实例的状态
+ * 流程实例 ProcessInstance 的状态
  *
  * @author 芋道源码
  */
 @Getter
 @AllArgsConstructor
-public enum BpmProcessInstanceStatusEnum {
+public enum BpmProcessInstanceStatusEnum implements IntArrayValuable {
+
+    RUNNING(1, "审批中"),
+    APPROVE(2, "审批通过"),
+    REJECT(3, "审批不通过"),
+    CANCEL(4, "已取消");
 
-    RUNNING(1, "进行中"),
-    FINISH(2, "已完成");
+    public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BpmProcessInstanceStatusEnum::getStatus).toArray();
 
     /**
      * 状态
@@ -24,4 +31,9 @@ public enum BpmProcessInstanceStatusEnum {
      */
     private final String desc;
 
+    @Override
+    public int[] array() {
+        return new int[0];
+    }
+
 }

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

@@ -1,14 +1,16 @@
 package cn.iocoder.yudao.module.bpm.controller.admin.definition;
 
-import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.*;
-import cn.iocoder.yudao.module.bpm.convert.definition.BpmFormConvert;
-import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
-import cn.iocoder.yudao.module.bpm.service.definition.BpmFormService;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import io.swagger.v3.oas.annotations.Parameter;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormPageReqVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormRespVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormSaveReqVO;
+import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
+import cn.iocoder.yudao.module.bpm.service.definition.BpmFormService;
 import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
@@ -18,6 +20,7 @@ import javax.validation.Valid;
 import java.util.List;
 
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
 
 @Tag(name = "管理后台 - 动态表单")
 @RestController
@@ -31,14 +34,14 @@ public class BpmFormController {
     @PostMapping("/create")
     @Operation(summary = "创建动态表单")
     @PreAuthorize("@ss.hasPermission('bpm:form:create')")
-    public CommonResult<Long> createForm(@Valid @RequestBody BpmFormCreateReqVO createReqVO) {
+    public CommonResult<Long> createForm(@Valid @RequestBody BpmFormSaveReqVO createReqVO) {
         return success(formService.createForm(createReqVO));
     }
 
     @PutMapping("/update")
     @Operation(summary = "更新动态表单")
     @PreAuthorize("@ss.hasPermission('bpm:form:update')")
-    public CommonResult<Boolean> updateForm(@Valid @RequestBody BpmFormUpdateReqVO updateReqVO) {
+    public CommonResult<Boolean> updateForm(@Valid @RequestBody BpmFormSaveReqVO updateReqVO) {
         formService.updateForm(updateReqVO);
         return success(true);
     }
@@ -58,14 +61,15 @@ public class BpmFormController {
     @PreAuthorize("@ss.hasPermission('bpm:form:query')")
     public CommonResult<BpmFormRespVO> getForm(@RequestParam("id") Long id) {
         BpmFormDO form = formService.getForm(id);
-        return success(BpmFormConvert.INSTANCE.convert(form));
+        return success(BeanUtils.toBean(form, BpmFormRespVO.class));
     }
 
-    @GetMapping("/list-all-simple")
+    @GetMapping({"/list-all-simple", "/simple-list"})
     @Operation(summary = "获得动态表单的精简列表", description = "用于表单下拉框")
-    public CommonResult<List<BpmFormSimpleRespVO>> getSimpleForms() {
+    public CommonResult<List<BpmFormRespVO>> getFormSimpleList() {
         List<BpmFormDO> list = formService.getFormList();
-        return success(BpmFormConvert.INSTANCE.convertList2(list));
+        return success(convertList(list, formDO -> // 只返回 id、name 字段
+                new BpmFormRespVO().setId(formDO.getId()).setName(formDO.getName())));
     }
 
     @GetMapping("/page")
@@ -73,7 +77,7 @@ public class BpmFormController {
     @PreAuthorize("@ss.hasPermission('bpm:form:query')")
     public CommonResult<PageResult<BpmFormRespVO>> getFormPage(@Valid BpmFormPageReqVO pageVO) {
         PageResult<BpmFormDO> pageResult = formService.getFormPage(pageVO);
-        return success(BpmFormConvert.INSTANCE.convertPage(pageResult));
+        return success(BeanUtils.toBean(pageResult, BpmFormRespVO.class));
     }
 
 }

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

@@ -1,24 +1,42 @@
 package cn.iocoder.yudao.module.bpm.controller.admin.definition;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.framework.common.util.io.IoUtils;
+import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*;
 import cn.iocoder.yudao.module.bpm.convert.definition.BpmModelConvert;
+import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
+import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
+import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryService;
+import cn.iocoder.yudao.module.bpm.service.definition.BpmFormService;
 import cn.iocoder.yudao.module.bpm.service.definition.BpmModelService;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import io.swagger.v3.oas.annotations.Parameter;
+import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
+import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO;
 import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.flowable.engine.repository.Deployment;
+import org.flowable.engine.repository.Model;
+import org.flowable.engine.repository.ProcessDefinition;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
 import javax.validation.Valid;
-
 import java.io.IOException;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
 
 @Tag(name = "管理后台 - 流程模型")
 @RestController
@@ -28,11 +46,39 @@ public class BpmModelController {
 
     @Resource
     private BpmModelService modelService;
+    @Resource
+    private BpmFormService formService;
+    @Resource
+    private BpmCategoryService categoryService;
+    @Resource
+    private BpmProcessDefinitionService processDefinitionService;
 
     @GetMapping("/page")
     @Operation(summary = "获得模型分页")
-    public CommonResult<PageResult<BpmModelPageItemRespVO>> getModelPage(BpmModelPageReqVO pageVO) {
-        return success(modelService.getModelPage(pageVO));
+    public CommonResult<PageResult<BpmModelRespVO>> getModelPage(BpmModelPageReqVO pageVO) {
+        PageResult<Model> pageResult = modelService.getModelPage(pageVO);
+        if (CollUtil.isEmpty(pageResult.getList())) {
+            return success(PageResult.empty(pageResult.getTotal()));
+        }
+
+        // 拼接数据
+        // 获得 Form 表单
+        Set<Long> formIds = convertSet(pageResult.getList(), model -> {
+            BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
+            return metaInfo != null ? metaInfo.getFormId() : null;
+        });
+        Map<Long, BpmFormDO> formMap = formService.getFormMap(formIds);
+        // 获得 Category Map
+        Map<String, BpmCategoryDO> categoryMap = categoryService.getCategoryMap(
+                convertSet(pageResult.getList(), Model::getCategory));
+        // 获得 Deployment Map
+        Set<String> deploymentIds = new HashSet<>();
+        pageResult.getList().forEach(model -> CollectionUtils.addIfNotNull(deploymentIds, model.getDeploymentId()));
+        Map<String, Deployment> deploymentMap = processDefinitionService.getDeploymentMap(deploymentIds);
+        // 获得 ProcessDefinition Map
+        List<ProcessDefinition> processDefinitions = processDefinitionService.getProcessDefinitionListByDeploymentIds(deploymentIds);
+        Map<String, ProcessDefinition> processDefinitionMap = convertMap(processDefinitions, ProcessDefinition::getDeploymentId);
+        return success(BpmModelConvert.INSTANCE.buildModelPage(pageResult, formMap, categoryMap, deploymentMap, processDefinitionMap));
     }
 
     @GetMapping("/get")
@@ -40,8 +86,12 @@ public class BpmModelController {
     @Parameter(name = "id", description = "编号", required = true, example = "1024")
     @PreAuthorize("@ss.hasPermission('bpm:model:query')")
     public CommonResult<BpmModelRespVO> getModel(@RequestParam("id") String id) {
-        BpmModelRespVO model = modelService.getModel(id);
-        return success(model);
+        Model model = modelService.getModel(id);
+        if (model == null) {
+            return null;
+        }
+        byte[] bpmnBytes = modelService.getModelBpmnXML(id);
+        return success(BpmModelConvert.INSTANCE.buildModel(model, bpmnBytes));
     }
 
     @PostMapping("/create")
@@ -63,7 +113,7 @@ public class BpmModelController {
     @Operation(summary = "导入模型")
     @PreAuthorize("@ss.hasPermission('bpm:model:import')")
     public CommonResult<String> importModel(@Valid BpmModeImportReqVO importReqVO) throws IOException {
-        BpmModelCreateReqVO createReqVO = BpmModelConvert.INSTANCE.convert(importReqVO);
+        BpmModelCreateReqVO createReqVO = BeanUtils.toBean(importReqVO, BpmModelCreateReqVO.class);
         // 读取文件
         String bpmnXml = IoUtils.readUtf8(importReqVO.getBpmnFile().getInputStream(), false);
         return success(modelService.createModel(createReqVO, bpmnXml));
@@ -94,4 +144,5 @@ public class BpmModelController {
         modelService.deleteModel(id);
         return success(true);
     }
+
 }

+ 71 - 16
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessDefinitionController.java

@@ -1,15 +1,25 @@
 package cn.iocoder.yudao.module.bpm.controller.admin.definition;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionListReqVO;
-import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
+import cn.iocoder.yudao.module.bpm.convert.definition.BpmProcessDefinitionConvert;
+import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
+import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
+import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
+import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.BpmTaskCandidateStartUserSelectStrategy;
+import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryService;
+import cn.iocoder.yudao.module.bpm.service.definition.BpmFormService;
 import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.flowable.bpmn.model.BpmnModel;
+import org.flowable.bpmn.model.UserTask;
+import org.flowable.engine.repository.Deployment;
+import org.flowable.engine.repository.ProcessDefinition;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -18,10 +28,12 @@ import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
-
+import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
 
 @Tag(name = "管理后台 - 流程定义")
 @RestController
@@ -30,30 +42,73 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 public class BpmProcessDefinitionController {
 
     @Resource
-    private BpmProcessDefinitionService bpmDefinitionService;
+    private BpmProcessDefinitionService processDefinitionService;
+    @Resource
+    private BpmFormService formService;
+    @Resource
+    private BpmCategoryService categoryService;
 
     @GetMapping("/page")
     @Operation(summary = "获得流程定义分页")
     @PreAuthorize("@ss.hasPermission('bpm:process-definition:query')")
-    public CommonResult<PageResult<BpmProcessDefinitionPageItemRespVO>> getProcessDefinitionPage(
+    public CommonResult<PageResult<BpmProcessDefinitionRespVO>> getProcessDefinitionPage(
             BpmProcessDefinitionPageReqVO pageReqVO) {
-        return success(bpmDefinitionService.getProcessDefinitionPage(pageReqVO));
+        PageResult<ProcessDefinition> pageResult = processDefinitionService.getProcessDefinitionPage(pageReqVO);
+        if (CollUtil.isEmpty(pageResult.getList())) {
+            return success(PageResult.empty(pageResult.getTotal()));
+        }
+
+        // 获得 Category Map
+        Map<String, BpmCategoryDO> categoryMap = categoryService.getCategoryMap(
+                convertSet(pageResult.getList(), ProcessDefinition::getCategory));
+        // 获得 Deployment Map
+        Map<String, Deployment> deploymentMap = processDefinitionService.getDeploymentMap(
+                convertSet(pageResult.getList(), ProcessDefinition::getDeploymentId));
+        // 获得 BpmProcessDefinitionInfoDO Map
+        Map<String, BpmProcessDefinitionInfoDO> processDefinitionMap = processDefinitionService.getProcessDefinitionInfoMap(
+                convertSet(pageResult.getList(), ProcessDefinition::getId));
+        // 获得 Form Map
+        Map<Long, BpmFormDO> formMap = formService.getFormMap(
+               convertSet(processDefinitionMap.values(), BpmProcessDefinitionInfoDO::getFormId));
+        return success(BpmProcessDefinitionConvert.INSTANCE.buildProcessDefinitionPage(
+                pageResult, deploymentMap, processDefinitionMap, formMap, categoryMap));
     }
 
     @GetMapping ("/list")
     @Operation(summary = "获得流程定义列表")
+    @Parameter(name = "suspensionState", description = "挂起状态", required = true, example = "1") // 参见 Flowable SuspensionState 枚举
     @PreAuthorize("@ss.hasPermission('bpm:process-definition:query')")
     public CommonResult<List<BpmProcessDefinitionRespVO>> getProcessDefinitionList(
-            BpmProcessDefinitionListReqVO listReqVO) {
-        return success(bpmDefinitionService.getProcessDefinitionList(listReqVO));
+            @RequestParam("suspensionState") Integer suspensionState) {
+        List<ProcessDefinition> list = processDefinitionService.getProcessDefinitionListBySuspensionState(suspensionState);
+        if (CollUtil.isEmpty(list)) {
+            return success(Collections.emptyList());
+        }
+
+        // 获得 BpmProcessDefinitionInfoDO Map
+        Map<String, BpmProcessDefinitionInfoDO> processDefinitionMap = processDefinitionService.getProcessDefinitionInfoMap(
+                convertSet(list, ProcessDefinition::getId));
+        return success(BpmProcessDefinitionConvert.INSTANCE.buildProcessDefinitionList(
+                list, null, processDefinitionMap, null, null));
     }
 
-    @GetMapping ("/get-bpmn-xml")
-    @Operation(summary = "获得流程定义的 BPMN XML")
-    @Parameter(name = "id", description = "编号", required = true, example = "1024")
+    @GetMapping ("/get")
+    @Operation(summary = "获得流程定义")
+    @Parameter(name = "id", description = "流程编号", required = true, example = "1024")
+    @Parameter(name = "key", description = "流程定义标识", required = true, example = "1024")
     @PreAuthorize("@ss.hasPermission('bpm:process-definition:query')")
-    public CommonResult<String> getProcessDefinitionBpmnXML(@RequestParam("id") String id) {
-        String bpmnXML = bpmDefinitionService.getProcessDefinitionBpmnXML(id);
-        return success(bpmnXML);
+    public CommonResult<BpmProcessDefinitionRespVO> getProcessDefinition(
+            @RequestParam(value = "id", required = false) String id,
+            @RequestParam(value = "key", required = false) String key) {
+        ProcessDefinition processDefinition = id != null ? processDefinitionService.getProcessDefinition(id)
+                : processDefinitionService.getActiveProcessDefinition(key);
+        if (processDefinition == null) {
+            return success(null);
+        }
+        BpmnModel bpmnModel = processDefinitionService.getProcessDefinitionBpmnModel(processDefinition.getId());
+        List<UserTask> userTaskList = BpmTaskCandidateStartUserSelectStrategy.getStartUserSelectUserTaskList(bpmnModel);
+        return success(BpmProcessDefinitionConvert.INSTANCE.buildProcessDefinition(
+                processDefinition, null, null, null, null, bpmnModel, userTaskList));
     }
+
 }

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

@@ -1,58 +0,0 @@
-package cn.iocoder.yudao.module.bpm.controller.admin.definition;
-
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO;
-import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO;
-import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;
-import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import io.swagger.v3.oas.annotations.Parameter;
-import io.swagger.v3.oas.annotations.Parameters;
-import io.swagger.v3.oas.annotations.Operation;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import javax.annotation.Resource;
-import javax.validation.Valid;
-import java.util.List;
-
-import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-
-@Tag(name = "管理后台 - 任务分配规则")
-@RestController
-@RequestMapping("/bpm/task-assign-rule")
-@Validated
-public class BpmTaskAssignRuleController {
-
-    @Resource
-    private BpmTaskAssignRuleService taskAssignRuleService;
-
-    @GetMapping("/list")
-    @Operation(summary = "获得任务分配规则列表")
-    @Parameters({
-            @Parameter(name = "modelId", description = "模型编号", example = "1024"),
-            @Parameter(name = "processDefinitionId", description = "流程定义的编号", example = "2048")
-    })
-    @PreAuthorize("@ss.hasPermission('bpm:task-assign-rule:query')")
-    public CommonResult<List<BpmTaskAssignRuleRespVO>> getTaskAssignRuleList(
-            @RequestParam(value = "modelId", required = false) String modelId,
-            @RequestParam(value = "processDefinitionId", required = false) String processDefinitionId) {
-        return success(taskAssignRuleService.getTaskAssignRuleList(modelId, processDefinitionId));
-    }
-
-    @PostMapping("/create")
-    @Operation(summary = "创建任务分配规则")
-    @PreAuthorize("@ss.hasPermission('bpm:task-assign-rule:create')")
-    public CommonResult<Long> createTaskAssignRule(@Valid @RequestBody BpmTaskAssignRuleCreateReqVO reqVO) {
-        return success(taskAssignRuleService.createTaskAssignRule(reqVO));
-    }
-
-    @PutMapping("/update")
-    @Operation(summary = "更新任务分配规则")
-    @PreAuthorize("@ss.hasPermission('bpm:task-assign-rule:update')")
-    public CommonResult<Boolean> updateTaskAssignRule(@Valid @RequestBody BpmTaskAssignRuleUpdateReqVO reqVO) {
-        taskAssignRuleService.updateTaskAssignRule(reqVO);
-        return success(true);
-    }
-}

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

@@ -1,18 +1,19 @@
 package cn.iocoder.yudao.module.bpm.controller.admin.definition;
 
-import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupCreateReqVO;
+import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormRespVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupPageReqVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupRespVO;
-import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupUpdateReqVO;
-import cn.iocoder.yudao.module.bpm.convert.definition.BpmUserGroupConvert;
+import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupSaveReqVO;
+import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO;
 import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService;
-import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
@@ -22,6 +23,7 @@ import javax.validation.Valid;
 import java.util.List;
 
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
 
 @Tag(name = "管理后台 - 用户组")
 @RestController
@@ -35,14 +37,14 @@ public class BpmUserGroupController {
     @PostMapping("/create")
     @Operation(summary = "创建用户组")
     @PreAuthorize("@ss.hasPermission('bpm:user-group:create')")
-    public CommonResult<Long> createUserGroup(@Valid @RequestBody BpmUserGroupCreateReqVO createReqVO) {
+    public CommonResult<Long> createUserGroup(@Valid @RequestBody BpmUserGroupSaveReqVO createReqVO) {
         return success(userGroupService.createUserGroup(createReqVO));
     }
 
     @PutMapping("/update")
     @Operation(summary = "更新用户组")
     @PreAuthorize("@ss.hasPermission('bpm:user-group:update')")
-    public CommonResult<Boolean> updateUserGroup(@Valid @RequestBody BpmUserGroupUpdateReqVO updateReqVO) {
+    public CommonResult<Boolean> updateUserGroup(@Valid @RequestBody BpmUserGroupSaveReqVO updateReqVO) {
         userGroupService.updateUserGroup(updateReqVO);
         return success(true);
     }
@@ -62,7 +64,7 @@ public class BpmUserGroupController {
     @PreAuthorize("@ss.hasPermission('bpm:user-group:query')")
     public CommonResult<BpmUserGroupRespVO> getUserGroup(@RequestParam("id") Long id) {
         BpmUserGroupDO userGroup = userGroupService.getUserGroup(id);
-        return success(BpmUserGroupConvert.INSTANCE.convert(userGroup));
+        return success(BeanUtils.toBean(userGroup, BpmUserGroupRespVO.class));
     }
 
     @GetMapping("/page")
@@ -70,16 +72,21 @@ public class BpmUserGroupController {
     @PreAuthorize("@ss.hasPermission('bpm:user-group:query')")
     public CommonResult<PageResult<BpmUserGroupRespVO>> getUserGroupPage(@Valid BpmUserGroupPageReqVO pageVO) {
         PageResult<BpmUserGroupDO> pageResult = userGroupService.getUserGroupPage(pageVO);
-        return success(BpmUserGroupConvert.INSTANCE.convertPage(pageResult));
+        return success(BeanUtils.toBean(pageResult, BpmUserGroupRespVO.class));
     }
 
-    @GetMapping("/list-all-simple")
+    @GetMapping("/simple-list")
     @Operation(summary = "获取用户组精简信息列表", description = "只包含被开启的用户组,主要用于前端的下拉选项")
-    public CommonResult<List<BpmUserGroupRespVO>> getSimpleUserGroups() {
-        // 获用户门列表,只要开启状态的
+    public CommonResult<List<BpmUserGroupRespVO>> getUserGroupSimpleList() {
+        List<BpmUserGroupDO> list = userGroupService.getUserGroupListByStatus(CommonStatusEnum.ENABLE.getStatus());
+        return success(convertList(list, group -> new BpmUserGroupRespVO().setId(group.getId()).setName(group.getName())));
+    }
+
+    @GetMapping("/list-all-simple")
+    @Operation(summary = "获取用户组精简信息列表", description = "只包含被开启的用户组")
+    public CommonResult<List<BpmUserGroupRespVO>> getUserGroupSimpleListAll() {
         List<BpmUserGroupDO> list = userGroupService.getUserGroupListByStatus(CommonStatusEnum.ENABLE.getStatus());
-        // 排序后,返回给前端
-        return success(BpmUserGroupConvert.INSTANCE.convertList2(list));
+        return success(convertList(list, group -> new BpmUserGroupRespVO().setId(group.getId()).setName(group.getName())));
     }
 
 }

+ 0 - 24
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormBaseVO.java

@@ -1,24 +0,0 @@
-package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.*;
-import javax.validation.constraints.*;
-
-/**
-* 动态表单 Base VO,提供给添加、修改、详细的子 VO 使用
-* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
-*/
-@Data
-public class BpmFormBaseVO {
-
-    @Schema(description = "表单名称", required = true, example = "芋道")
-    @NotNull(message = "表单名称不能为空")
-    private String name;
-
-    @Schema(description = "表单状态-参见 CommonStatusEnum 枚举", required = true, example = "1")
-    @NotNull(message = "表单状态不能为空")
-    private Integer status;
-
-    @Schema(description = "备注", example = "我是备注")
-    private String remark;
-
-}

+ 0 - 22
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormCreateReqVO.java

@@ -1,22 +0,0 @@
-package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.*;
-
-import javax.validation.constraints.NotNull;
-import java.util.List;
-
-@Schema(description = "管理后台 - 动态表单创建 Request VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class BpmFormCreateReqVO extends BpmFormBaseVO {
-
-    @Schema(description = "表单的配置-JSON 字符串", required = true)
-    @NotNull(message = "表单的配置不能为空")
-    private String conf;
-
-    @Schema(description = "表单项的数组-JSON 字符串的数组", required = true)
-    @NotNull(message = "表单项的数组不能为空")
-    private List<String> fields;
-
-}

+ 0 - 2
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormPageReqVO.java

@@ -8,8 +8,6 @@ import lombok.ToString;
 
 @Schema(description = "管理后台 - 动态表单分页 Request VO")
 @Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
 public class BpmFormPageReqVO extends PageParam {
 
     @Schema(description = "表单名称", example = "芋道")

+ 17 - 9
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormRespVO.java

@@ -1,8 +1,7 @@
 package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form;
+
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
 
 import javax.validation.constraints.NotNull;
 import java.time.LocalDateTime;
@@ -10,22 +9,31 @@ import java.util.List;
 
 @Schema(description = "管理后台 - 动态表单 Response VO")
 @Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class BpmFormRespVO extends BpmFormBaseVO {
+public class BpmFormRespVO {
 
-    @Schema(description = "表单编号", required = true, example = "1024")
+    @Schema(description = "表单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
     private Long id;
 
-    @Schema(description = "表单的配置-JSON 字符串", required = true)
+    @Schema(description = "表单名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
+    @NotNull(message = "表单名称不能为空")
+    private String name;
+
+    @Schema(description = "表单的配置-JSON 字符串", requiredMode = Schema.RequiredMode.REQUIRED)
     @NotNull(message = "表单的配置不能为空")
     private String conf;
 
-    @Schema(description = "表单项的数组-JSON 字符串的数组", required = true)
+    @Schema(description = "表单项的数组-JSON 字符串的数组", requiredMode = Schema.RequiredMode.REQUIRED)
     @NotNull(message = "表单项的数组不能为空")
     private List<String> fields;
 
-    @Schema(description = "创建时间", required = true)
+    @Schema(description = "表单状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @NotNull(message = "表单状态不能为空")
+    private Integer status; // 参见 CommonStatusEnum 枚举
+
+    @Schema(description = "备注", example = "我是备注")
+    private String remark;
+
+    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
     private LocalDateTime createTime;
 
 }

+ 0 - 16
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormSimpleRespVO.java

@@ -1,16 +0,0 @@
-package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-@Schema(description = "管理后台 - 流程表单精简 Response VO")
-@Data
-public class BpmFormSimpleRespVO {
-
-    @Schema(description = "表单编号", required = true, example = "1024")
-    private Long id;
-
-    @Schema(description = "表单名称", required = true, example = "芋道")
-    private String name;
-
-}

+ 0 - 25
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormUpdateReqVO.java

@@ -1,25 +0,0 @@
-package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.*;
-import javax.validation.constraints.*;
-import java.util.List;
-
-@Schema(description = "管理后台 - 动态表单更新 Request VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class BpmFormUpdateReqVO extends BpmFormBaseVO {
-
-    @Schema(description = "表单编号", required = true, example = "1024")
-    @NotNull(message = "表单编号不能为空")
-    private Long id;
-
-    @Schema(description = "表单的配置-JSON 字符串", required = true)
-    @NotNull(message = "表单的配置不能为空")
-    private String conf;
-
-    @Schema(description = "表单项的数组-JSON 字符串的数组", required = true)
-    @NotNull(message = "表单项的数组不能为空")
-    private List<String> fields;
-
-}

+ 0 - 30
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupBaseVO.java

@@ -1,30 +0,0 @@
-package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.*;
-import java.util.*;
-import javax.validation.constraints.*;
-
-/**
-* 用户组 Base VO,提供给添加、修改、详细的子 VO 使用
-* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
-*/
-@Data
-public class BpmUserGroupBaseVO {
-
-    @Schema(description = "组名", required = true, example = "芋道")
-    @NotNull(message = "组名不能为空")
-    private String name;
-
-    @Schema(description = "描述", required = true, example = "芋道源码")
-    @NotNull(message = "描述不能为空")
-    private String description;
-
-    @Schema(description = "成员编号数组", required = true, example = "1,2,3")
-    @NotNull(message = "成员编号数组不能为空")
-    private Set<Long> memberUserIds;
-
-    @Schema(description = "状态", required = true, example = "1")
-    @NotNull(message = "状态不能为空")
-    private Integer status;
-
-}

+ 0 - 11
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupCreateReqVO.java

@@ -1,11 +0,0 @@
-package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.*;
-
-@Schema(description = "管理后台 - 用户组创建 Request VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class BpmUserGroupCreateReqVO extends BpmUserGroupBaseVO {
-
-}

+ 3 - 2
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupPageReqVO.java

@@ -12,10 +12,11 @@ import java.time.LocalDateTime;
 
 @Schema(description = "管理后台 - 用户组分页 Request VO")
 @Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
 public class BpmUserGroupPageReqVO extends PageParam {
 
+    @Schema(description = "编号", example = "1024")
+    private Long id;
+
     @Schema(description = "组名", example = "芋道")
     private String name;
 

+ 18 - 7
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupRespVO.java

@@ -1,20 +1,31 @@
 package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group;
+
 import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.*;
+import lombok.Data;
 
 import java.time.LocalDateTime;
-
+import java.util.Set;
 
 @Schema(description = "管理后台 - 用户组 Response VO")
 @Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class BpmUserGroupRespVO extends BpmUserGroupBaseVO {
+public class BpmUserGroupRespVO {
 
-    @Schema(description = "编号", required = true, example = "1024")
+    @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
     private Long id;
 
-    @Schema(description = "创建时间", required = true)
+    @Schema(description = "组名", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
+    private String name;
+
+    @Schema(description = "描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道源码")
+    private String description;
+
+    @Schema(description = "成员编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "1,2,3")
+    private Set<Long> memberUserIds;
+
+    @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    private Integer status;
+
+    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
     private LocalDateTime createTime;
 
 }

+ 0 - 20
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupSimpleRespVO.java

@@ -1,20 +0,0 @@
-package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-@Schema(description = "管理后台 - 用户组精简信息 Response VO")
-@Data
-@NoArgsConstructor
-@AllArgsConstructor
-public class BpmUserGroupSimpleRespVO {
-
-    @Schema(description = "用户组编号", required = true, example = "1024")
-    private Long id;
-
-    @Schema(description = "用户组名字", required = true, example = "芋道")
-    private String name;
-
-}

+ 0 - 16
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupUpdateReqVO.java

@@ -1,16 +0,0 @@
-package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.*;
-import javax.validation.constraints.*;
-
-@Schema(description = "管理后台 - 用户组更新 Request VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class BpmUserGroupUpdateReqVO extends BpmUserGroupBaseVO {
-
-    @Schema(description = "编号", required = true, example = "1024")
-    @NotNull(message = "编号不能为空")
-    private Long id;
-
-}

+ 1 - 3
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModeImportReqVO.java

@@ -10,11 +10,9 @@ import javax.validation.constraints.NotNull;
 
 @Schema(description = "管理后台 - 流程模型的导入 Request VO 相比流程模型的新建来说,只是多了一个 bpmnFile 文件")
 @Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
 public class BpmModeImportReqVO extends BpmModelCreateReqVO {
 
-    @Schema(description = "BPMN 文件", required = true)
+    @Schema(description = "BPMN 文件", requiredMode = Schema.RequiredMode.REQUIRED)
     @NotNull(message = "BPMN 文件不能为空")
     private MultipartFile bpmnFile;
 

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

@@ -1,40 +0,0 @@
-package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-import javax.validation.constraints.NotEmpty;
-
-/**
-* 流程模型 Base VO,提供给添加、修改、详细的子 VO 使用
-* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
-*/
-@Data
-public class BpmModelBaseVO {
-
-    @Schema(description = "流程标识", required = true, example = "process_yudao")
-    @NotEmpty(message = "流程标识不能为空")
-    private String key;
-
-    @Schema(description = "流程名称", required = true, example = "芋道")
-    @NotEmpty(message = "流程名称不能为空")
-    private String name;
-
-    @Schema(description = "流程描述", example = "我是描述")
-    private String description;
-
-    @Schema(description = "流程分类-参见 bpm_model_category 数据字典", example = "1")
-    @NotEmpty(message = "流程分类不能为空")
-    private String category;
-
-    @Schema(description = "表单类型-参见 bpm_model_form_type 数据字典", example = "1")
-    private Integer formType;
-    @Schema(description = "表单编号-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", example = "1024")
-    private Long formId;
-    @Schema(description = "自定义表单的提交路径,使用 Vue 的路由地址-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空",
-            example = "/bpm/oa/leave/create")
-    private String formCustomCreatePath;
-    @Schema(description = "自定义表单的查看路径,使用 Vue 的路由地址-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空",
-            example = "/bpm/oa/leave/view")
-    private String formCustomViewPath;
-
-}

+ 2 - 2
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelCreateReqVO.java

@@ -11,11 +11,11 @@ import javax.validation.constraints.NotEmpty;
 @Data
 public class BpmModelCreateReqVO {
 
-    @Schema(description = "流程标识", required = true, example = "process_yudao")
+    @Schema(description = "流程标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "process_yudao")
     @NotEmpty(message = "流程标识不能为空")
     private String key;
 
-    @Schema(description = "流程名称", required = true, example = "芋道")
+    @Schema(description = "流程名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
     @NotEmpty(message = "流程名称不能为空")
     private String name;
 

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

@@ -1,48 +0,0 @@
-package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
-
-import java.time.LocalDateTime;
-
-@Schema(description = "管理后台 - 流程模型的分页的每一项 Response VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class BpmModelPageItemRespVO extends BpmModelBaseVO {
-
-    @Schema(description = "编号", required = true, example = "1024")
-    private String id;
-
-    @Schema(description = "表单名字", example = "请假表单")
-    private String formName;
-
-    @Schema(description = "创建时间", required = true)
-    private LocalDateTime createTime;
-
-    /**
-     * 最新部署的流程定义
-     */
-    private ProcessDefinition processDefinition;
-
-    @Schema(description = "流程定义")
-    @Data
-    public static class ProcessDefinition {
-
-        @Schema(description = "编号", required = true, example = "1024")
-        private String id;
-
-        @Schema(description = "版本", required = true, example = "1")
-        private Integer version;
-
-        @Schema(description = "部署时间", required = true)
-        private LocalDateTime deploymentTime;
-
-        @Schema(description = "中断状态-参见 SuspensionState 枚举", required = true, example = "1")
-        private Integer suspensionState;
-
-    }
-
-}

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

@@ -9,17 +9,15 @@ import lombok.ToString;
 
 @Schema(description = "管理后台 - 流程模型分页 Request VO")
 @Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
 public class BpmModelPageReqVO extends PageParam {
 
-    @Schema(description = "标识-精准匹配", example = "process1641042089407")
+    @Schema(description = "标识精准匹配", example = "process1641042089407")
     private String key;
 
-    @Schema(description = "名字-模糊匹配", example = "芋道")
+    @Schema(description = "名字模糊匹配", example = "芋道")
     private String name;
 
-    @Schema(description = "流程分类-参见 bpm_model_category 数据字典", example = "1")
+    @Schema(description = "流程分类", example = "1")
     private String category;
 
 }

+ 42 - 10
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelRespVO.java

@@ -1,25 +1,57 @@
 package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model;
 
+import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
 
 import java.time.LocalDateTime;
 
-@Schema(description = "管理后台 - 流程模型的创建 Request VO")
+@Schema(description = "管理后台 - 流程模型 Response VO")
 @Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class BpmModelRespVO extends BpmModelBaseVO {
+public class BpmModelRespVO {
 
-    @Schema(description = "编号", required = true, example = "1024")
+    @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
     private String id;
 
-    @Schema(description = "BPMN XML", required = true)
-    private String bpmnXml;
+    @Schema(description = "流程标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "process_yudao")
+    private String key;
+
+    @Schema(description = "流程名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
+    private String name;
+
+    @Schema(description = "流程图标", example = "https://www.iocoder.cn/yudao.jpg")
+    private String icon;
+
+    @Schema(description = "流程描述", example = "我是描述")
+    private String description;
+
+    @Schema(description = "流程分类编码", example = "1")
+    private String category;
+    @Schema(description = "流程分类名字", example = "请假")
+    private String categoryName;
+
+    @Schema(description = "表单类型-参见 bpm_model_form_type 数据字典", example = "1")
+    private Integer formType;
 
-    @Schema(description = "创建时间", required = true)
+    @Schema(description = "表单编号", example = "1024")
+    private Long formId; // 在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空
+    @Schema(description = "表单名字", example = "请假表单")
+    private String formName;
+
+    @Schema(description = "自定义表单的提交路径", example = "/bpm/oa/leave/create")
+    private String formCustomCreatePath; // 使用 Vue 的路由地址-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空
+    @Schema(description = "自定义表单的查看路径", example = "/bpm/oa/leave/view")
+    private String formCustomViewPath; // ,使用 Vue 的路由地址-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空
+
+    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
     private LocalDateTime createTime;
 
+    @Schema(description = "BPMN XML", requiredMode = Schema.RequiredMode.REQUIRED)
+    private String bpmnXml;
+
+    /**
+     * 最新部署的流程定义
+     */
+    private BpmProcessDefinitionRespVO processDefinition;
+
 }

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

@@ -1,7 +1,10 @@
 package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model;
 
+import cn.iocoder.yudao.framework.common.validation.InEnum;
+import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
+import org.hibernate.validator.constraints.URL;
 
 import javax.validation.constraints.NotEmpty;
 
@@ -9,23 +12,28 @@ import javax.validation.constraints.NotEmpty;
 @Data
 public class BpmModelUpdateReqVO {
 
-    @Schema(description = "编号", required = true, example = "1024")
+    @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
     @NotEmpty(message = "编号不能为空")
     private String id;
 
     @Schema(description = "流程名称", example = "芋道")
     private String name;
 
+    @Schema(description = "流程图标", example = "https://www.iocoder.cn/yudao.jpg")
+    @URL(message = "流程图标格式不正确")
+    private String icon;
+
     @Schema(description = "流程描述", example = "我是描述")
     private String description;
 
-    @Schema(description = "流程分类-参见 bpm_model_category 数据字典", example = "1")
+    @Schema(description = "流程分类", example = "1")
     private String category;
 
-    @Schema(description = "BPMN XML", required = true)
+    @Schema(description = "BPMN XML", requiredMode = Schema.RequiredMode.REQUIRED)
     private String bpmnXml;
 
     @Schema(description = "表单类型-参见 bpm_model_form_type 数据字典", example = "1")
+    @InEnum(BpmModelFormTypeEnum.class)
     private Integer formType;
     @Schema(description = "表单编号-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", example = "1024")
     private Long formId;

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

@@ -9,12 +9,12 @@ import javax.validation.constraints.NotNull;
 @Data
 public class BpmModelUpdateStateReqVO {
 
-    @Schema(description = "编号", required = true, example = "1024")
+    @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
     @NotNull(message = "编号不能为空")
     private String id;
 
-    @Schema(description = "状态-见 SuspensionState 枚举", required = true, example = "1")
+    @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
     @NotNull(message = "状态不能为空")
-    private Integer state;
+    private Integer state; // 参见 Flowable SuspensionState 枚举
 
 }

+ 0 - 18
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionListReqVO.java

@@ -1,18 +0,0 @@
-package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process;
-
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
-
-@Schema(description = "管理后台 - 流程定义列表 Request VO")
-@Data
-@ToString(callSuper = true)
-@EqualsAndHashCode(callSuper = true)
-public class BpmProcessDefinitionListReqVO extends PageParam {
-
-    @Schema(description = "中断状态-参见 SuspensionState 枚举", example = "1")
-    private Integer suspensionState;
-
-}

+ 0 - 22
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageItemRespVO.java

@@ -1,22 +0,0 @@
-package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
-
-import java.time.LocalDateTime;
-
-@Schema(description = "管理后台 - 流程定义的分页的每一项 Response VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class BpmProcessDefinitionPageItemRespVO extends BpmProcessDefinitionRespVO {
-
-    @Schema(description = "表单名字", example = "请假表单")
-    private String formName;
-
-    @Schema(description = "部署时间", required = true)
-    private LocalDateTime deploymentTime;
-
-}

+ 0 - 2
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageReqVO.java

@@ -8,8 +8,6 @@ import lombok.ToString;
 
 @Schema(description = "管理后台 - 流程定义分页 Request VO")
 @Data
-@ToString(callSuper = true)
-@EqualsAndHashCode(callSuper = true)
 public class BpmProcessDefinitionPageReqVO extends PageParam {
 
     @Schema(description = "标识-精准匹配", example = "process1641042089407")

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

@@ -3,38 +3,45 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
-import javax.validation.constraints.NotEmpty;
-import javax.validation.constraints.NotNull;
+import java.time.LocalDateTime;
 import java.util.List;
 
 @Schema(description = "管理后台 - 流程定义 Response VO")
 @Data
 public class BpmProcessDefinitionRespVO {
 
-    @Schema(description = "编号", required = true, example = "1024")
+    @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
     private String id;
 
-    @Schema(description = "版本", required = true, example = "1")
+    @Schema(description = "版本", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
     private Integer version;
 
-    @Schema(description = "流程名称", required = true, example = "芋道")
-    @NotEmpty(message = "流程名称不能为空")
+    @Schema(description = "流程名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
     private String name;
 
+    @Schema(description = "流程标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "yudao")
+    private String key;
+
+    @Schema(description = "流程图标", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/yudao.jpg")
+    private String icon;
+
     @Schema(description = "流程描述", example = "我是描述")
     private String description;
 
-    @Schema(description = "流程分类-参见 bpm_model_category 数据字典", example = "1")
-    @NotEmpty(message = "流程分类不能为空")
+    @Schema(description = "流程分类", example = "1")
     private String category;
+    @Schema(description = "流程分类名字", example = "请假")
+    private String categoryName;
 
     @Schema(description = "表单类型-参见 bpm_model_form_type 数据字典", example = "1")
     private Integer formType;
     @Schema(description = "表单编号-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", example = "1024")
     private Long formId;
-    @Schema(description = "表单的配置-JSON 字符串。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", required = true)
+    @Schema(description = "表单名字", example = "请假表单")
+    private String formName;
+    @Schema(description = "表单的配置-JSON 字符串。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", requiredMode = Schema.RequiredMode.REQUIRED)
     private String formConf;
-    @Schema(description = "表单项的数组-JSON 字符串的数组。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", required = true)
+    @Schema(description = "表单项的数组-JSON 字符串的数组。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", requiredMode = Schema.RequiredMode.REQUIRED)
     private List<String> formFields;
     @Schema(description = "自定义表单的提交路径,使用 Vue 的路由地址-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空",
             example = "/bpm/oa/leave/create")
@@ -43,7 +50,28 @@ public class BpmProcessDefinitionRespVO {
             example = "/bpm/oa/leave/view")
     private String formCustomViewPath;
 
-    @Schema(description = "中断状态-参见 SuspensionState 枚举", required = true, example = "1")
-    private Integer suspensionState;
+    @Schema(description = "中断状态-参见 SuspensionState 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    private Integer suspensionState; // 参见 SuspensionState 枚举
+
+    @Schema(description = "部署时间")
+    private LocalDateTime deploymentTime; // 需要从对应的 Deployment 读取,非必须返回
+
+    @Schema(description = "BPMN XML")
+    private String bpmnXml; // 需要从对应的 BpmnModel 读取,非必须返回
+
+    @Schema(description = "发起用户需要选择审批人的任务数组")
+    private List<UserTask> startUserSelectTasks; // 需要从对应的 BpmnModel 读取,非必须返回
+
+    @Schema(description = "BPMN UserTask 用户任务")
+    @Data
+    public static class UserTask {
+
+        @Schema(description = "任务标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "sudo")
+        private String id;
+
+        @Schema(description = "任务名", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
+        private String name;
+
+    }
 
 }

+ 0 - 24
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleBaseVO.java

@@ -1,24 +0,0 @@
-package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-import javax.validation.constraints.NotEmpty;
-import javax.validation.constraints.NotNull;
-import java.util.Set;
-
-/**
- * 流程任务分配规则 Base VO,提供给添加、修改、详细的子 VO 使用
- * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
- */
-@Data
-public class BpmTaskAssignRuleBaseVO {
-
-    @Schema(description = "规则类型", required = true, example = "bpm_task_assign_rule_type")
-    @NotNull(message = "规则类型不能为空")
-    private Integer type;
-
-    @Schema(description = "规则值数组", required = true, example = "1,2,3")
-    @NotNull(message = "规则值数组不能为空")
-    private Set<Long> options;
-
-}

+ 0 - 24
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleCreateReqVO.java

@@ -1,24 +0,0 @@
-package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
-
-import javax.validation.constraints.NotEmpty;
-
-@Schema(description = "管理后台 - 流程任务分配规则的创建 Request VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class BpmTaskAssignRuleCreateReqVO extends BpmTaskAssignRuleBaseVO {
-
-    @Schema(description = "流程模型的编号", required = true, example = "1024")
-    @NotEmpty(message = "流程模型的编号不能为空")
-    private String modelId;
-
-    @Schema(description = "流程任务定义的编号", required = true, example = "2048")
-    @NotEmpty(message = "流程任务定义的编号不能为空")
-    private String taskDefinitionKey;
-
-}

+ 0 - 28
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleRespVO.java

@@ -1,28 +0,0 @@
-package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
-
-@Schema(description = "管理后台 - 流程任务分配规则的 Response VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class BpmTaskAssignRuleRespVO extends BpmTaskAssignRuleBaseVO {
-
-    @Schema(description = "任务分配规则的编号", required = true, example = "1024")
-    private Long id;
-
-    @Schema(description = "流程模型的编号", required = true, example = "2048")
-    private String modelId;
-
-    @Schema(description = "流程定义的编号", required = true, example = "4096")
-    private String processDefinitionId;
-
-    @Schema(description = "流程任务定义的编号", required = true, example = "2048")
-    private String taskDefinitionKey;
-    @Schema(description = "流程任务定义的名字", required = true, example = "关注芋道")
-    private String taskDefinitionName;
-
-}

+ 0 - 20
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleUpdateReqVO.java

@@ -1,20 +0,0 @@
-package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
-
-import javax.validation.constraints.NotNull;
-
-@Schema(description = "管理后台 - 流程任务分配规则的更新 Request VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class BpmTaskAssignRuleUpdateReqVO extends BpmTaskAssignRuleBaseVO {
-
-    @Schema(description = "任务分配规则的编号", required = true, example = "1024")
-    @NotNull(message = "任务分配规则的编号不能为空")
-    private Long id;
-
-}

+ 7 - 7
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOALeaveController.java

@@ -1,16 +1,16 @@
 package cn.iocoder.yudao.module.bpm.controller.admin.oa;
 
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOALeaveCreateReqVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOALeavePageReqVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOALeaveRespVO;
-import cn.iocoder.yudao.module.bpm.convert.oa.BpmOALeaveConvert;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOALeaveDO;
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.bpm.service.oa.BpmOALeaveService;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
@@ -49,7 +49,7 @@ public class BpmOALeaveController {
     @Parameter(name = "id", description = "编号", required = true, example = "1024")
     public CommonResult<BpmOALeaveRespVO> getLeave(@RequestParam("id") Long id) {
         BpmOALeaveDO leave = leaveService.getLeave(id);
-        return success(BpmOALeaveConvert.INSTANCE.convert(leave));
+        return success(BeanUtils.toBean(leave, BpmOALeaveRespVO.class));
     }
 
     @GetMapping("/page")
@@ -57,7 +57,7 @@ public class BpmOALeaveController {
     @Operation(summary = "获得请假申请分页")
     public CommonResult<PageResult<BpmOALeaveRespVO>> getLeavePage(@Valid BpmOALeavePageReqVO pageVO) {
         PageResult<BpmOALeaveDO> pageResult = leaveService.getLeavePage(getLoginUserId(), pageVO);
-        return success(BpmOALeaveConvert.INSTANCE.convertPage(pageResult));
+        return success(BeanUtils.toBean(pageResult, BpmOALeaveRespVO.class));
     }
 
 }

+ 0 - 32
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveBaseVO.java

@@ -1,32 +0,0 @@
-package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.*;
-import java.time.LocalDateTime;
-import javax.validation.constraints.*;
-import org.springframework.format.annotation.DateTimeFormat;
-
-import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
-
-/**
-* 请假申请 Base VO,提供给添加、修改、详细的子 VO 使用
-* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
-*/
-@Data
-public class BpmOALeaveBaseVO {
-
-    @Schema(description = "请假的开始时间", required = true)
-    @NotNull(message = "开始时间不能为空")
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    private LocalDateTime startTime;
-    @Schema(description = "请假的结束时间", required = true)
-    @NotNull(message = "结束时间不能为空")
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    private LocalDateTime endTime;
-
-    @Schema(description = "请假类型-参见 bpm_oa_type 枚举", required = true, example = "1")
-    private Integer type;
-
-    @Schema(description = "原因", required = true, example = "阅读芋道源码")
-    private String reason;
-
-}

+ 28 - 5
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveCreateReqVO.java

@@ -1,16 +1,39 @@
 package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo;
+
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
+import org.springframework.format.annotation.DateTimeFormat;
 
 import javax.validation.constraints.AssertTrue;
+import javax.validation.constraints.NotNull;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
 
 @Schema(description = "管理后台 - 请假申请创建 Request VO")
 @Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class BpmOALeaveCreateReqVO extends BpmOALeaveBaseVO {
+public class BpmOALeaveCreateReqVO {
+
+    @Schema(description = "请假的开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotNull(message = "开始时间不能为空")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime startTime;
+
+    @Schema(description = "请假的结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotNull(message = "结束时间不能为空")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime endTime;
+
+    @Schema(description = "请假类型-参见 bpm_oa_type 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    private Integer type;
+
+    @Schema(description = "原因", requiredMode = Schema.RequiredMode.REQUIRED, example = "阅读芋道源码")
+    private String reason;
+
+    @Schema(description = "发起人自选审批人 Map", example = "{taskKey1: [1, 2]}")
+    private Map<String, List<Long>> startUserSelectAssignees;
 
     @AssertTrue(message = "结束时间,需要在开始时间之后")
     public boolean isEndTimeValid() {

+ 11 - 9
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeavePageReqVO.java

@@ -1,25 +1,27 @@
 package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.*;
-import java.time.LocalDateTime;
+
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
 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 = "管理后台 - 请假申请分页 Request VO")
 @Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
 public class BpmOALeavePageReqVO extends PageParam {
 
-    @Schema(description = "状态-参见 bpm_process_instance_result 枚举", example = "1")
-    private Integer result;
+    @Schema(description = "状态", example = "1")
+    private Integer status; // 参见 BpmProcessInstanceResultEnum 枚举
 
-    @Schema(description = "请假类型-参见 bpm_oa_type", example = "1")
+    @Schema(description = "请假类型参见 bpm_oa_type", example = "1")
     private Integer type;
 
-    @Schema(description = "原因-模糊匹配", example = "阅读芋道源码")
+    @Schema(description = "原因模糊匹配", example = "阅读芋道源码")
     private String reason;
 
     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)

+ 20 - 15
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveRespVO.java

@@ -1,31 +1,36 @@
 package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo;
+
 import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.*;
-import org.springframework.format.annotation.DateTimeFormat;
+import lombok.Data;
 
-import javax.validation.constraints.NotNull;
 import java.time.LocalDateTime;
 
-import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
-
 @Schema(description = "管理后台 - 请假申请 Response VO")
 @Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class BpmOALeaveRespVO extends BpmOALeaveBaseVO {
+public class BpmOALeaveRespVO {
 
-    @Schema(description = "请假表单主键", required = true, example = "1024")
+    @Schema(description = "请假表单主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
     private Long id;
 
-    @Schema(description = "状态-参见 bpm_process_instance_result 枚举", required = true, example = "1")
-    private Integer result;
+    @Schema(description = "请假类型,参见 bpm_oa_type 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    private Integer type;
+
+    @Schema(description = "原因", requiredMode = Schema.RequiredMode.REQUIRED, example = "阅读芋道源码")
+    private String reason;
 
-    @Schema(description = "申请时间", required = true)
-    @NotNull(message = "申请时间不能为空")
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @Schema(description = "申请时间", requiredMode = Schema.RequiredMode.REQUIRED)
     private LocalDateTime createTime;
 
-    @Schema(description = "流程id")
+    @Schema(description = "请假的开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
+    private LocalDateTime startTime;
+
+    @Schema(description = "请假的结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
+    private LocalDateTime endTime;
+
+    @Schema(description = "流程编号")
     private String processInstanceId;
 
+    @Schema(description = "审批结果", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    private Integer status; // 参见 BpmProcessInstanceStatusEnum 枚举
+
 }

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

@@ -1,20 +1,43 @@
 package cn.iocoder.yudao.module.bpm.controller.admin.task;
 
+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.module.bpm.controller.admin.task.vo.instance.*;
+import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
+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;
+import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
+import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryService;
+import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
 import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import io.swagger.v3.oas.annotations.Parameter;
+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 io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+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.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
 import javax.validation.Valid;
+import java.util.List;
+import java.util.Map;
 
 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.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 
 @Tag(name = "管理后台 - 流程实例") // 流程实例,通过流程定义创建的一次“申请”
@@ -25,13 +48,65 @@ public class BpmProcessInstanceController {
 
     @Resource
     private BpmProcessInstanceService processInstanceService;
+    @Resource
+    private BpmTaskService taskService;
+    @Resource
+    private BpmProcessDefinitionService processDefinitionService;
+    @Resource
+    private BpmCategoryService categoryService;
+
+    @Resource
+    private AdminUserApi adminUserApi;
+    @Resource
+    private DeptApi deptApi;
 
     @GetMapping("/my-page")
     @Operation(summary = "获得我的实例分页列表", description = "在【我的流程】菜单中,进行调用")
     @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
-    public CommonResult<PageResult<BpmProcessInstancePageItemRespVO>> getMyProcessInstancePage(
-            @Valid BpmProcessInstanceMyPageReqVO pageReqVO) {
-        return success(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()));
+        }
+
+        // 拼接返回
+        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));
+        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")
@@ -46,14 +121,43 @@ public class BpmProcessInstanceController {
     @Parameter(name = "id", description = "流程实例的编号", required = true)
     @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
     public CommonResult<BpmProcessInstanceRespVO> getProcessInstance(@RequestParam("id") String id) {
-        return success(processInstanceService.getProcessInstanceVO(id));
+        HistoricProcessInstance processInstance = processInstanceService.getHistoricProcessInstance(id);
+        if (processInstance == null) {
+            return success(null);
+        }
+
+        // 拼接返回
+        ProcessDefinition processDefinition = processDefinitionService.getProcessDefinition(
+                processInstance.getProcessDefinitionId());
+        BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.getProcessDefinitionInfo(
+                processInstance.getProcessDefinitionId());
+        String bpmnXml = BpmnModelUtils.getBpmnXml(
+                processDefinitionService.getProcessDefinitionBpmnModel(processInstance.getProcessDefinitionId()));
+        AdminUserRespDTO startUser = adminUserApi.getUser(NumberUtils.parseLong(processInstance.getStartUserId()));
+        DeptRespDTO dept = null;
+        if (startUser != null) {
+            dept = deptApi.getDept(startUser.getDeptId());
+        }
+        return success(BpmProcessInstanceConvert.INSTANCE.buildProcessInstance(processInstance,
+                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);
+    }
+
 }

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

@@ -1,22 +1,41 @@
 package cn.iocoder.yudao.module.bpm.controller.admin.task;
 
+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.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.service.definition.BpmFormService;
+import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
 import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import io.swagger.v3.oas.annotations.Parameter;
+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 io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.flowable.bpmn.model.UserTask;
+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.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
 import javax.validation.Valid;
-
+import java.util.Collections;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Stream;
 
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
 import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId;
 
 @Tag(name = "管理后台 - 流程任务实例")
@@ -27,19 +46,69 @@ public class BpmTaskController {
 
     @Resource
     private BpmTaskService taskService;
+    @Resource
+    private BpmProcessInstanceService processInstanceService;
+    @Resource
+    private BpmFormService formService;
+
+    @Resource
+    private AdminUserApi adminUserApi;
+    @Resource
+    private DeptApi deptApi;
 
     @GetMapping("todo-page")
     @Operation(summary = "获取 Todo 待办任务分页")
     @PreAuthorize("@ss.hasPermission('bpm:task:query')")
-    public CommonResult<PageResult<BpmTaskTodoPageItemRespVO>> getTodoTaskPage(@Valid BpmTaskTodoPageReqVO pageVO) {
-        return success(taskService.getTodoTaskPage(getLoginUserId(), pageVO));
+    public CommonResult<PageResult<BpmTaskRespVO>> getTaskTodoPage(@Valid BpmTaskPageReqVO pageVO) {
+        PageResult<Task> pageResult = taskService.getTaskTodoPage(getLoginUserId(), pageVO);
+        if (CollUtil.isEmpty(pageResult.getList())) {
+            return success(PageResult.empty());
+        }
+
+        // 拼接数据
+        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));
     }
 
     @GetMapping("done-page")
     @Operation(summary = "获取 Done 已办任务分页")
     @PreAuthorize("@ss.hasPermission('bpm:task:query')")
-    public CommonResult<PageResult<BpmTaskDonePageItemRespVO>> getDoneTaskPage(@Valid BpmTaskDonePageReqVO pageVO) {
-        return success(taskService.getDoneTaskPage(getLoginUserId(), pageVO));
+    public CommonResult<PageResult<BpmTaskRespVO>> getTaskDonePage(@Valid BpmTaskPageReqVO pageVO) {
+        PageResult<HistoricTaskInstance> pageResult = taskService.getTaskDonePage(getLoginUserId(), pageVO);
+        if (CollUtil.isEmpty(pageResult.getList())) {
+            return success(PageResult.empty());
+        }
+
+        // 拼接数据
+        Map<String, HistoricProcessInstance> processInstanceMap = processInstanceService.getHistoricProcessInstanceMap(
+                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));
+    }
+
+    @GetMapping("manager-page")
+    @Operation(summary = "获取全部任务的分页", description = "用于【流程任务】菜单")
+    @PreAuthorize("@ss.hasPermission('bpm:task:mananger-query')")
+    public CommonResult<PageResult<BpmTaskRespVO>> getTaskManagerPage(@Valid BpmTaskPageReqVO pageVO) {
+        PageResult<HistoricTaskInstance> pageResult = taskService.getTaskPage(getLoginUserId(), pageVO);
+        if (CollUtil.isEmpty(pageResult.getList())) {
+            return success(PageResult.empty());
+        }
+
+        // 拼接数据
+        Map<String, HistoricProcessInstance> processInstanceMap = processInstanceService.getHistoricProcessInstanceMap(
+                convertSet(pageResult.getList(), HistoricTaskInstance::getProcessInstanceId));
+        // 获得 User 和 Dept Map
+        Set<Long> userIds = convertSet(processInstanceMap.values(), instance -> Long.valueOf(instance.getStartUserId()));
+        userIds.addAll(convertSet(pageResult.getList(), task -> NumberUtils.parseLong(task.getAssignee())));
+        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));
     }
 
     @GetMapping("/list-by-process-instance-id")
@@ -47,8 +116,26 @@ public class BpmTaskController {
     @Parameter(name = "processInstanceId", description = "流程实例的编号", required = true)
     @PreAuthorize("@ss.hasPermission('bpm:task:query')")
     public CommonResult<List<BpmTaskRespVO>> getTaskListByProcessInstanceId(
-        @RequestParam("processInstanceId") String processInstanceId) {
-        return success(taskService.getTaskListByProcessInstanceId(processInstanceId));
+            @RequestParam("processInstanceId") String processInstanceId) {
+        List<HistoricTaskInstance> taskList = taskService.getTaskListByProcessInstanceId(processInstanceId);
+        if (CollUtil.isEmpty(taskList)) {
+            return success(Collections.emptyList());
+        }
+
+        // 拼接数据
+        HistoricProcessInstance processInstance = processInstanceService.getHistoricProcessInstance(processInstanceId);
+        // 获得 User 和 Dept Map
+        Set<Long> userIds = convertSetByFlatMap(taskList, task ->
+                Stream.of(NumberUtils.parseLong(task.getAssignee()), NumberUtils.parseLong(task.getOwner())));
+        userIds.add(NumberUtils.parseLong(processInstance.getStartUserId()));
+        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);
+        Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(
+                convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
+        // 获得 Form Map
+        Map<Long, BpmFormDO> formMap = formService.getFormMap(
+                convertSet(taskList, task -> NumberUtils.parseLong(task.getFormKey())));
+        return success(BpmTaskConvert.INSTANCE.buildTaskListByProcessInstanceId(taskList, processInstance,
+                formMap, userMap, deptMap));
     }
 
     @PutMapping("/approve")
@@ -67,12 +154,71 @@ public class BpmTaskController {
         return success(true);
     }
 
-    @PutMapping("/update-assignee")
-    @Operation(summary = "更新任务的负责人", description = "用于【流程详情】的【转派】按钮")
+    @GetMapping("/list-by-return")
+    @Operation(summary = "获取所有可回退的节点", description = "用于【流程详情】的【回退】按钮")
+    @Parameter(name = "taskId", description = "当前任务ID", required = true)
+    @PreAuthorize("@ss.hasPermission('bpm:task:update')")
+    public CommonResult<List<BpmTaskRespVO>> getTaskListByReturn(@RequestParam("id") String id) {
+        List<UserTask> userTaskList = taskService.getUserTaskListByReturn(id);
+        return success(convertList(userTaskList, userTask -> // 只返回 id 和 name
+                new BpmTaskRespVO().setName(userTask.getName()).setTaskDefinitionKey(userTask.getId())));
+    }
+
+    @PutMapping("/return")
+    @Operation(summary = "回退任务", description = "用于【流程详情】的【回退】按钮")
+    @PreAuthorize("@ss.hasPermission('bpm:task:update')")
+    public CommonResult<Boolean> returnTask(@Valid @RequestBody BpmTaskReturnReqVO reqVO) {
+        taskService.returnTask(getLoginUserId(), reqVO);
+        return success(true);
+    }
+
+    @PutMapping("/delegate")
+    @Operation(summary = "委派任务", description = "用于【流程详情】的【委派】按钮")
+    @PreAuthorize("@ss.hasPermission('bpm:task:update')")
+    public CommonResult<Boolean> delegateTask(@Valid @RequestBody BpmTaskDelegateReqVO reqVO) {
+        taskService.delegateTask(getLoginUserId(), reqVO);
+        return success(true);
+    }
+
+    @PutMapping("/transfer")
+    @Operation(summary = "转派任务", description = "用于【流程详情】的【转派】按钮")
     @PreAuthorize("@ss.hasPermission('bpm:task:update')")
-    public CommonResult<Boolean> updateTaskAssignee(@Valid @RequestBody BpmTaskUpdateAssigneeReqVO reqVO) {
-        taskService.updateTaskAssignee(getLoginUserId(), reqVO);
+    public CommonResult<Boolean> transferTask(@Valid @RequestBody BpmTaskTransferReqVO reqVO) {
+        taskService.transferTask(getLoginUserId(), reqVO);
         return success(true);
     }
 
+    @PutMapping("/create-sign")
+    @Operation(summary = "加签", description = "before 前加签,after 后加签")
+    @PreAuthorize("@ss.hasPermission('bpm:task:update')")
+    public CommonResult<Boolean> createSignTask(@Valid @RequestBody BpmTaskSignCreateReqVO reqVO) {
+        taskService.createSignTask(getLoginUserId(), reqVO);
+        return success(true);
+    }
+
+    @DeleteMapping("/delete-sign")
+    @Operation(summary = "减签")
+    @PreAuthorize("@ss.hasPermission('bpm:task:update')")
+    public CommonResult<Boolean> deleteSignTask(@Valid @RequestBody BpmTaskSignDeleteReqVO reqVO) {
+        taskService.deleteSignTask(getLoginUserId(), reqVO);
+        return success(true);
+    }
+
+    @GetMapping("/list-by-parent-task-id")
+    @Operation(summary = "获得指定父级任务的子任务列表") // 目前用于,减签的时候,获得子任务列表
+    @Parameter(name = "parentTaskId", description = "父级任务编号", required = true)
+    @PreAuthorize("@ss.hasPermission('bpm:task:query')")
+    public CommonResult<List<BpmTaskRespVO>> getTaskListByParentTaskId(@RequestParam("parentTaskId") String parentTaskId) {
+        List<Task> taskList = taskService.getTaskListByParentTaskId(parentTaskId);
+        if (CollUtil.isEmpty(taskList)) {
+            return success(Collections.emptyList());
+        }
+        // 拼接数据
+        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertSetByFlatMap(taskList,
+                user -> Stream.of(NumberUtils.parseLong(user.getAssignee()), NumberUtils.parseLong(user.getOwner()))));
+        Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(
+                convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
+        return success(BpmTaskConvert.INSTANCE.buildTaskListByParentTaskId(taskList, userMap, deptMap));
+    }
+
 }

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

@@ -9,17 +9,17 @@ import java.time.LocalDateTime;
 @Data
 public class BpmActivityRespVO {
 
-    @Schema(description = "流程活动的标识", required = true, example = "1024")
+    @Schema(description = "流程活动的标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
     private String key;
-    @Schema(description = "流程活动的类型", required = true, example = "StartEvent")
+    @Schema(description = "流程活动的类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "StartEvent")
     private String type;
 
-    @Schema(description = "流程活动的开始时间", required = true)
+    @Schema(description = "流程活动的开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
     private LocalDateTime startTime;
-    @Schema(description = "流程活动的结束时间", required = true)
+    @Schema(description = "流程活动的结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
     private LocalDateTime endTime;
 
-    @Schema(description = "关联的流程任务的编号-关联的流程任务,只有 UserTask 等类型才有", example = "2048")
-    private String taskId;
+    @Schema(description = "关联的流程任务的编号", example = "2048")
+    private String taskId; // 关联的流程任务,只有 UserTask 等类型才有
 
 }

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

@@ -4,18 +4,16 @@ import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
 import javax.validation.constraints.NotEmpty;
-import javax.validation.constraints.NotNull;
-import java.util.Map;
 
 @Schema(description = "管理后台 - 流程实例的取消 Request VO")
 @Data
 public class BpmProcessInstanceCancelReqVO {
 
-    @Schema(description = "流程实例的编号", required = true, example = "1024")
+    @Schema(description = "流程实例的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
     @NotEmpty(message = "流程实例的编号不能为空")
     private String id;
 
-    @Schema(description = "取消原因", required = true, example = "不请假了!")
+    @Schema(description = "取消原因", requiredMode = Schema.RequiredMode.REQUIRED, example = "不请假了!")
     @NotEmpty(message = "取消原因不能为空")
     private String reason;
 

+ 6 - 2
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCreateReqVO.java

@@ -4,17 +4,21 @@ import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
 import javax.validation.constraints.NotEmpty;
+import java.util.List;
 import java.util.Map;
 
 @Schema(description = "管理后台 - 流程实例的创建 Request VO")
 @Data
 public class BpmProcessInstanceCreateReqVO {
 
-    @Schema(description = "流程定义的编号", required = true, example = "1024")
+    @Schema(description = "流程定义的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
     @NotEmpty(message = "流程定义编号不能为空")
     private String processDefinitionId;
 
-    @Schema(description = "变量实例")
+    @Schema(description = "变量实例(动态表单)")
     private Map<String, Object> variables;
 
+    @Schema(description = "发起人自选审批人 Map", example = "{taskKey1: [1, 2]}")
+    private Map<String, List<Long>> startUserSelectAssignees;
+
 }

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

@@ -1,39 +0,0 @@
-package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance;
-
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
-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")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class BpmProcessInstanceMyPageReqVO extends PageParam {
-
-    @Schema(description = "流程名称", example = "芋道")
-    private String name;
-
-    @Schema(description = "流程定义的编号", example = "2048")
-    private String processDefinitionId;
-
-    @Schema(description = "流程实例的状态-参见 bpm_process_instance_status", example = "1")
-    private Integer status;
-
-    @Schema(description = "流程实例的结果-参见 bpm_process_instance_result", example = "2")
-    private Integer result;
-
-    @Schema(description = "流程分类-参见 bpm_model_category 数据字典", example = "1")
-    private String category;
-
-    @Schema(description = "创建时间")
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    private LocalDateTime[] createTime;
-
-}

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

@@ -1,54 +0,0 @@
-package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-import java.time.LocalDateTime;
-import java.util.List;
-
-@Schema(description = "管理后台 - 流程实例的分页 Item Response VO")
-@Data
-public class BpmProcessInstancePageItemRespVO {
-
-    @Schema(description = "流程实例的编号", required = true, example = "1024")
-    private String id;
-
-    @Schema(description = "流程名称", required = true, example = "芋道")
-    private String name;
-
-    @Schema(description = "流程定义的编号", required = true, example = "2048")
-    private String processDefinitionId;
-
-    @Schema(description = "流程分类-参见 bpm_model_category 数据字典", required = true, example = "1")
-    private String category;
-
-    @Schema(description = "流程实例的状态-参见 bpm_process_instance_status", required = true, example = "1")
-    private Integer status;
-
-    @Schema(description = "流程实例的结果-参见 bpm_process_instance_result", required = true, example = "2")
-    private Integer result;
-
-    @Schema(description = "提交时间", required = true)
-    private LocalDateTime createTime;
-
-    @Schema(description = "结束时间", required = true)
-    private LocalDateTime endTime;
-
-    /**
-     * 当前任务
-     */
-    private List<Task> tasks;
-
-    @Schema(description = "流程任务")
-    @Data
-    public static class Task {
-
-        @Schema(description = "流程任务的编号", required = true, example = "1024")
-        private String id;
-
-        @Schema(description = "任务名称", required = true, example = "芋道")
-        private String name;
-
-    }
-
-}

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

@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance;
 
+import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
@@ -11,28 +12,30 @@ import java.util.Map;
 @Data
 public class BpmProcessInstanceRespVO {
 
-    @Schema(description = "流程实例的编号", required = true, example = "1024")
+    @Schema(description = "流程实例的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
     private String id;
 
-    @Schema(description = "流程名称", required = true, example = "芋道")
+    @Schema(description = "流程名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
     private String name;
 
-    @Schema(description = "流程分类-参见 bpm_model_category 数据字典", required = true, example = "1")
+    @Schema(description = "流程分类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
     private String category;
+    @Schema(description = "流程分类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "请假")
+    private String categoryName;
 
-    @Schema(description = "流程实例的状态-参见 bpm_process_instance_status", required = true, example = "1")
-    private Integer status;
+    @Schema(description = "流程实例的状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    private Integer status; // 参见 BpmProcessInstanceStatusEnum 枚举
 
-    @Schema(description = "流程实例的结果-参见 bpm_process_instance_result", required = true, example = "2")
-    private Integer result;
+    @Schema(description = "发起时间", requiredMode = Schema.RequiredMode.REQUIRED)
+    private LocalDateTime startTime;
 
-    @Schema(description = "提交时间", required = true)
-    private LocalDateTime createTime;
-
-    @Schema(description = "结束时间", required = true)
+    @Schema(description = "结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
     private LocalDateTime endTime;
 
-    @Schema(description = "提交的表单值", required = true)
+    @Schema(description = "持续时间", example = "1000")
+    private Long durationInMillis;
+
+    @Schema(description = "提交的表单值", requiredMode = Schema.RequiredMode.REQUIRED)
     private Map<String, Object> formVariables;
 
     @Schema(description = "业务的唯一标识-例如说,请假申请的编号", example = "1")
@@ -43,51 +46,43 @@ public class BpmProcessInstanceRespVO {
      */
     private User startUser;
 
+    @Schema(description = "流程定义的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048")
+    private String processDefinitionId;
     /**
      * 流程定义
      */
-    private ProcessDefinition processDefinition;
+    private BpmProcessDefinitionRespVO processDefinition;
+
+    /**
+     * 当前审批中的任务
+     */
+    private List<Task> tasks; // 仅在流程实例分页才返回
 
     @Schema(description = "用户信息")
     @Data
     public static class User {
 
-        @Schema(description = "用户编号", required = true, example = "1")
+        @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
         private Long id;
-        @Schema(description = "用户昵称", required = true, example = "芋艿")
+        @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
         private String nickname;
 
-        @Schema(description = "部门编号", required = true, example = "1")
+        @Schema(description = "部门编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
         private Long deptId;
-        @Schema(description = "部门名称", required = true, example = "研发部")
+        @Schema(description = "部门名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "研发部")
         private String deptName;
 
     }
 
-    @Schema(description = "流程定义信息")
+    @Schema(description = "流程任务")
     @Data
-    public static class ProcessDefinition {
+    public static class Task {
 
-        @Schema(description = "编号", required = true, example = "1024")
+        @Schema(description = "流程任务的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
         private String id;
 
-        @Schema(description = "表单类型-参见 bpm_model_form_type 数据字典", example = "1")
-        private Integer formType;
-        @Schema(description = "表单编号-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", example = "1024")
-        private Long formId;
-        @Schema(description = "表单的配置-JSON 字符串。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", required = true)
-        private String formConf;
-        @Schema(description = "表单项的数组-JSON 字符串的数组。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", required = true)
-        private List<String> formFields;
-        @Schema(description = "自定义表单的提交路径,使用 Vue 的路由地址-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空",
-                example = "/bpm/oa/leave/create")
-        private String formCustomCreatePath;
-        @Schema(description = "自定义表单的查看路径,使用 Vue 的路由地址-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空",
-                example = "/bpm/oa/leave/view")
-        private String formCustomViewPath;
-
-        @Schema(description = "BPMN XML", required = true)
-        private String bpmnXml;
+        @Schema(description = "任务名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
+        private String name;
 
     }
 

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

@@ -4,17 +4,25 @@ import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
 import javax.validation.constraints.NotEmpty;
+import java.util.Collection;
+import java.util.Map;
 
 @Schema(description = "管理后台 - 通过流程任务的 Request VO")
 @Data
 public class BpmTaskApproveReqVO {
 
-    @Schema(description = "任务编号", required = true, example = "1024")
+    @Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
     @NotEmpty(message = "任务编号不能为空")
     private String id;
 
-    @Schema(description = "审批意见", required = true, example = "不错不错!")
+    @Schema(description = "审批意见", requiredMode = Schema.RequiredMode.REQUIRED, example = "不错不错!")
     @NotEmpty(message = "审批意见不能为空")
     private String reason;
 
+    @Schema(description = "抄送的用户编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "1,2")
+    private Collection<Long> copyUserIds;
+
+    @Schema(description = "变量实例(动态表单)", requiredMode = Schema.RequiredMode.REQUIRED)
+    private Map<String, Object> variables;
+
 }

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

@@ -1,26 +0,0 @@
-package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
-
-import java.time.LocalDateTime;
-
-@Schema(description = "管理后台 - 流程任务的 Done 已完成的分页项 Response VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class BpmTaskDonePageItemRespVO extends BpmTaskTodoPageItemRespVO {
-
-    @Schema(description = "结束时间", required = true)
-    private LocalDateTime endTime;
-    @Schema(description = "持续时间", required = true, example = "1000")
-    private Long durationInMillis;
-
-    @Schema(description = "任务结果-参见 bpm_process_instance_result", required = true, example = "2")
-    private Integer result;
-    @Schema(description = "审批建议", required = true, example = "不请假了!")
-    private String reason;
-
-}

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

@@ -1,31 +0,0 @@
-package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task;
-
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
-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 = "管理后台 - 流程任务的 Done 已办的分页 Request VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class BpmTaskDonePageReqVO extends PageParam {
-
-    @Schema(description = "流程任务名", example = "芋道")
-    private String name;
-
-    @Schema(description = "开始的创建收间")
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    private LocalDateTime beginCreateTime;
-
-    @Schema(description = "结束的创建时间")
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    private LocalDateTime endCreateTime;
-
-}

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

@@ -9,11 +9,11 @@ import javax.validation.constraints.NotEmpty;
 @Data
 public class BpmTaskRejectReqVO {
 
-    @Schema(description = "任务编号", required = true, example = "1024")
+    @Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
     @NotEmpty(message = "任务编号不能为空")
     private String id;
 
-    @Schema(description = "审批意见", required = true, example = "不错不错!")
+    @Schema(description = "审批意见", requiredMode = Schema.RequiredMode.REQUIRED, example = "不错不错!")
     @NotEmpty(message = "审批意见不能为空")
     private String reason;
 

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

@@ -1,37 +1,94 @@
 package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task;
 
+import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
 
-@Schema(description = "管理后台 - 流程任务的 Response VO")
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+
+@Schema(description = "管理后台 - 流程任务 Response VO")
 @Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class BpmTaskRespVO extends BpmTaskDonePageItemRespVO {
+public class BpmTaskRespVO {
+
+    @Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    private String id;
+
+    @Schema(description = "任务名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
+    private String name;
+
+    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+    private LocalDateTime createTime;
+
+    @Schema(description = "结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
+    private LocalDateTime endTime;
 
-    @Schema(description = "任务定义的标识", required = true, example = "user-001")
-    private String definitionKey;
+    @Schema(description = "持续时间", example = "1000")
+    private Long durationInMillis;
+
+    @Schema(description = "任务状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
+    private Integer status; // 参见 BpmTaskStatusEnum 枚举
+
+    @Schema(description = "审批理由", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
+    private String reason;
 
+    /**
+     * 负责人的用户信息
+     */
+    private BpmProcessInstanceRespVO.User ownerUser;
     /**
      * 审核的用户信息
      */
-    private User assigneeUser;
+    private BpmProcessInstanceRespVO.User assigneeUser;
+
+    @Schema(description = "任务定义的标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "Activity_one")
+    private String taskDefinitionKey;
+
+    @Schema(description = "所属流程实例编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "8888")
+    private String processInstanceId;
+    /**
+     * 所属流程实例
+     */
+    private ProcessInstance processInstance;
+
+    @Schema(description = "父任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    private String parentTaskId;
+    @Schema(description = "子任务列表(由加签生成)", requiredMode = Schema.RequiredMode.REQUIRED, example = "childrenTask")
+    private List<BpmTaskRespVO> children;
+
+    @Schema(description = "表单编号", example = "1024")
+    private Long formId;
+    @Schema(description = "表单名字", example = "请假表单")
+    private String formName;
+    @Schema(description = "表单的配置-JSON 字符串")
+    private String formConf;
+    @Schema(description = "表单项的数组")
+    private List<String> formFields;
+    @Schema(description = "提交的表单值", requiredMode = Schema.RequiredMode.REQUIRED)
+    private Map<String, Object> formVariables;
 
-    @Schema(description = "用户信息")
     @Data
-    public static class User {
+    @Schema(description = "流程实例")
+    public static class ProcessInstance {
 
-        @Schema(description = "用户编号", required = true, example = "1")
-        private Long id;
-        @Schema(description = "用户昵称", required = true, example = "芋艿")
-        private String nickname;
+        @Schema(description = "流程实例编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+        private String id;
 
-        @Schema(description = "部门编号", required = true, example = "1")
-        private Long deptId;
-        @Schema(description = "部门名称", required = true, example = "研发部")
-        private String deptName;
+        @Schema(description = "流程实例名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
+        private String name;
+
+        @Schema(description = "提交时间", requiredMode = Schema.RequiredMode.REQUIRED)
+        private LocalDateTime createTime;
+
+        @Schema(description = "流程定义的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048")
+        private String processDefinitionId;
+
+        /**
+         * 发起人的用户信息
+         */
+        private BpmProcessInstanceRespVO.User startUser;
 
     }
+
 }

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

@@ -1,53 +0,0 @@
-package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-import java.time.LocalDateTime;
-
-@Schema(description = "管理后台 - 流程任务的 Running 进行中的分页项 Response VO")
-@Data
-public class BpmTaskTodoPageItemRespVO {
-
-    @Schema(description = "任务编号", required = true, example = "1024")
-    private String id;
-
-    @Schema(description = "任务名字", required = true, example = "芋道")
-    private String name;
-
-    @Schema(description = "接收时间", required = true)
-    private LocalDateTime claimTime;
-
-    @Schema(description = "创建时间", required = true)
-    private LocalDateTime createTime;
-
-    @Schema(description = "激活状态-参见 SuspensionState 枚举", required = true, example = "1")
-    private Integer suspensionState;
-
-    /**
-     * 所属流程实例
-     */
-    private ProcessInstance processInstance;
-
-    @Data
-    @Schema(description = "流程实例")
-    public static class ProcessInstance {
-
-        @Schema(description = "流程实例编号", required = true, example = "1024")
-        private String id;
-
-        @Schema(description = "流程实例名称", required = true, example = "芋道")
-        private String name;
-
-        @Schema(description = "发起人的用户编号", required = true, example = "1024")
-        private Long startUserId;
-
-        @Schema(description = "发起人的用户昵称", required = true, example = "芋艿")
-        private String startUserNickname;
-
-        @Schema(description = "流程定义的编号", required = true, example = "2048")
-        private String processDefinitionId;
-
-    }
-
-}

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

@@ -1,28 +0,0 @@
-package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task;
-
-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;
-
-import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
-
-@Schema(description = "管理后台 - 流程任务的 TODO 待办的分页 Request VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class BpmTaskTodoPageReqVO extends PageParam {
-
-    @Schema(description = "流程任务名", example = "芋道")
-    private String name;
-
-    @Schema(description = "创建时间")
-    @DateTimeFormat(pattern = DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    private LocalDateTime[] createTime;
-
-}

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

@@ -1,24 +0,0 @@
-package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
-import net.bytebuddy.implementation.bind.annotation.Empty;
-
-import javax.validation.constraints.NotEmpty;
-import javax.validation.constraints.NotNull;
-
-@Schema(description = "管理后台 - 流程任务的更新负责人的 Request VO")
-@Data
-public class BpmTaskUpdateAssigneeReqVO {
-
-    @Schema(description = "任务编号", required = true, example = "1024")
-    @NotEmpty(message = "任务编号不能为空")
-    private String id;
-
-    @Schema(description = "新审批人的用户编号", required = true, example = "2048")
-    @NotNull(message = "新审批人的用户编号不能为空")
-    private Long assigneeUserId;
-
-}

+ 0 - 34
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmFormConvert.java

@@ -1,34 +0,0 @@
-package cn.iocoder.yudao.module.bpm.convert.definition;
-
-import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormCreateReqVO;
-import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormRespVO;
-import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormSimpleRespVO;
-import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormUpdateReqVO;
-import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import org.mapstruct.Mapper;
-import org.mapstruct.factory.Mappers;
-
-import java.util.List;
-
-/**
- * 动态表单 Convert
- *
- * @author 芋艿
- */
-@Mapper
-public interface BpmFormConvert {
-
-    BpmFormConvert INSTANCE = Mappers.getMapper(BpmFormConvert.class);
-
-    BpmFormDO convert(BpmFormCreateReqVO bean);
-
-    BpmFormDO convert(BpmFormUpdateReqVO bean);
-
-    BpmFormRespVO convert(BpmFormDO bean);
-
-    List<BpmFormSimpleRespVO> convertList2(List<BpmFormDO> list);
-
-    PageResult<BpmFormRespVO> convertPage(PageResult<BpmFormDO> page);
-
-}

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

@@ -1,19 +1,24 @@
 package cn.iocoder.yudao.module.bpm.convert.definition;
 
+import cn.hutool.core.util.ArrayUtil;
 import cn.hutool.core.util.StrUtil;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.framework.common.util.date.DateUtils;
 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
-import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelCreateReqVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelRespVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelUpdateReqVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
+import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
 import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO;
-import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
 import org.flowable.common.engine.impl.db.SuspensionState;
 import org.flowable.engine.repository.Deployment;
 import org.flowable.engine.repository.Model;
 import org.flowable.engine.repository.ProcessDefinition;
 import org.mapstruct.Mapper;
-import org.mapstruct.MappingTarget;
 import org.mapstruct.factory.Mappers;
 
 import java.util.List;
@@ -30,103 +35,89 @@ public interface BpmModelConvert {
 
     BpmModelConvert INSTANCE = Mappers.getMapper(BpmModelConvert.class);
 
-    default List<BpmModelPageItemRespVO> convertList(List<Model> list, Map<Long, BpmFormDO> formMap,
-                                                     Map<String, Deployment> deploymentMap,
-                                                     Map<String, ProcessDefinition> processDefinitionMap) {
-        return CollectionUtils.convertList(list, model -> {
-            BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
+    default PageResult<BpmModelRespVO> buildModelPage(PageResult<Model> pageResult,
+                                                      Map<Long, BpmFormDO> formMap,
+                                                      Map<String, BpmCategoryDO> categoryMap, Map<String, Deployment> deploymentMap,
+                                                      Map<String, ProcessDefinition> processDefinitionMap) {
+        List<BpmModelRespVO> list = CollectionUtils.convertList(pageResult.getList(), model -> {
+            BpmModelMetaInfoRespDTO metaInfo = buildMetaInfo(model);
             BpmFormDO form = metaInfo != null ? formMap.get(metaInfo.getFormId()) : null;
+            BpmCategoryDO category = categoryMap.get(model.getCategory());
             Deployment deployment = model.getDeploymentId() != null ? deploymentMap.get(model.getDeploymentId()) : null;
             ProcessDefinition processDefinition = model.getDeploymentId() != null ? processDefinitionMap.get(model.getDeploymentId()) : null;
-            return convert(model, form, deployment, processDefinition);
+            return buildModel0(model, metaInfo, form, category, deployment, processDefinition);
         });
+        return new PageResult<>(list, pageResult.getTotal());
     }
 
-    default BpmModelPageItemRespVO convert(Model model, BpmFormDO form, Deployment deployment, ProcessDefinition processDefinition) {
-        BpmModelPageItemRespVO modelRespVO = new BpmModelPageItemRespVO();
-        modelRespVO.setId(model.getId());
-        modelRespVO.setCreateTime(DateUtils.of(model.getCreateTime()));
-        // 通用 copy
-        copyTo(model, modelRespVO);
+    default BpmModelRespVO buildModel(Model model,
+                                     byte[] bpmnBytes) {
+        BpmModelMetaInfoRespDTO metaInfo = buildMetaInfo(model);
+        BpmModelRespVO modelVO = buildModel0(model, metaInfo, null, null, null, null);
+        if (ArrayUtil.isNotEmpty(bpmnBytes)) {
+            modelVO.setBpmnXml(new String(bpmnBytes));
+        }
+        return modelVO;
+    }
+
+    default BpmModelRespVO buildModel0(Model model,
+                                      BpmModelMetaInfoRespDTO metaInfo, BpmFormDO form, BpmCategoryDO category,
+                                      Deployment deployment, ProcessDefinition processDefinition) {
+        BpmModelRespVO modelRespVO = new BpmModelRespVO().setId(model.getId()).setName(model.getName())
+                .setKey(model.getKey()).setCategory(model.getCategory())
+                .setCreateTime(DateUtils.of(model.getCreateTime()));
         // Form
+        if (metaInfo != null) {
+            modelRespVO.setFormType(metaInfo.getFormType()).setFormId(metaInfo.getFormId())
+                    .setFormCustomCreatePath(metaInfo.getFormCustomCreatePath())
+                    .setFormCustomViewPath(metaInfo.getFormCustomViewPath());
+            modelRespVO.setIcon(metaInfo.getIcon()).setDescription(metaInfo.getDescription());
+        }
         if (form != null) {
-            modelRespVO.setFormId(form.getId());
-            modelRespVO.setFormName(form.getName());
+            modelRespVO.setFormId(form.getId()).setFormName(form.getName());
+        }
+        // Category
+        if (category != null) {
+            modelRespVO.setCategoryName(category.getName());
         }
         // ProcessDefinition
-        modelRespVO.setProcessDefinition(this.convert(processDefinition));
-        if (modelRespVO.getProcessDefinition() != null) {
+        if (processDefinition != null) {
+            modelRespVO.setProcessDefinition(BeanUtils.toBean(processDefinition, BpmProcessDefinitionRespVO.class));
             modelRespVO.getProcessDefinition().setSuspensionState(processDefinition.isSuspended() ?
                     SuspensionState.SUSPENDED.getStateCode() : SuspensionState.ACTIVE.getStateCode());
-            modelRespVO.getProcessDefinition().setDeploymentTime(DateUtils.of(deployment.getDeploymentTime()));
+            if (deployment != null) {
+                modelRespVO.getProcessDefinition().setDeploymentTime(DateUtils.of(deployment.getDeploymentTime()));
+            }
         }
         return modelRespVO;
     }
 
-    default BpmModelRespVO convert(Model model) {
-        BpmModelRespVO modelRespVO = new BpmModelRespVO();
-        modelRespVO.setId(model.getId());
-        modelRespVO.setCreateTime(DateUtils.of(model.getCreateTime()));
-        // 通用 copy
-        copyTo(model, modelRespVO);
-        return modelRespVO;
-    }
-
-    default void copyTo(Model model, BpmModelBaseVO to) {
-        to.setName(model.getName());
-        to.setKey(model.getKey());
-        to.setCategory(model.getCategory());
-        // metaInfo
-        BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
-        copyTo(metaInfo, to);
-    }
-
-    BpmModelCreateReqVO convert(BpmModeImportReqVO bean);
-
-    default BpmProcessDefinitionCreateReqDTO convert2(Model model, BpmFormDO form) {
-        BpmProcessDefinitionCreateReqDTO createReqDTO = new BpmProcessDefinitionCreateReqDTO();
-        createReqDTO.setModelId(model.getId());
-        createReqDTO.setName(model.getName());
-        createReqDTO.setKey(model.getKey());
-        createReqDTO.setCategory(model.getCategory());
-        BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
-        // metaInfo
-        copyTo(metaInfo, createReqDTO);
-        // form
-        if (form != null) {
-            createReqDTO.setFormConf(form.getConf());
-            createReqDTO.setFormFields(form.getFields());
-        }
-        return createReqDTO;
-    }
-
-    void copyTo(BpmModelMetaInfoRespDTO from, @MappingTarget BpmProcessDefinitionCreateReqDTO to);
-
-    void copyTo(BpmModelMetaInfoRespDTO from, @MappingTarget BpmModelBaseVO to);
-
-    BpmModelPageItemRespVO.ProcessDefinition convert(ProcessDefinition bean);
-
-    default void copy(Model model, BpmModelCreateReqVO bean) {
+    default void copyToCreateModel(Model model, BpmModelCreateReqVO bean) {
         model.setName(bean.getName());
         model.setKey(bean.getKey());
-        model.setMetaInfo(buildMetaInfoStr(null, bean.getDescription(), null, null,
-                null, null));
+        model.setMetaInfo(buildMetaInfoStr(null,
+                null, bean.getDescription(),
+                null, null, null, null));
     }
 
-    default void copy(Model model, BpmModelUpdateReqVO bean) {
+    default void copyToUpdateModel(Model model, BpmModelUpdateReqVO bean) {
         model.setName(bean.getName());
         model.setCategory(bean.getCategory());
-        model.setMetaInfo(buildMetaInfoStr(JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class),
-                bean.getDescription(), bean.getFormType(), bean.getFormId(),
-                bean.getFormCustomCreatePath(), bean.getFormCustomViewPath()));
+        model.setMetaInfo(buildMetaInfoStr(buildMetaInfo(model),
+                bean.getIcon(), bean.getDescription(),
+                bean.getFormType(), bean.getFormId(), bean.getFormCustomCreatePath(), bean.getFormCustomViewPath()));
     }
 
-    default String buildMetaInfoStr(BpmModelMetaInfoRespDTO metaInfo, String description, Integer formType,
-                                    Long formId, String formCustomCreatePath, String formCustomViewPath) {
+    default String buildMetaInfoStr(BpmModelMetaInfoRespDTO metaInfo,
+                                    String icon, String description,
+                                    Integer formType, Long formId, String formCustomCreatePath, String formCustomViewPath) {
         if (metaInfo == null) {
             metaInfo = new BpmModelMetaInfoRespDTO();
         }
         // 只有非空,才进行设置,避免更新时的覆盖
+        if (StrUtil.isNotEmpty(icon)) {
+            metaInfo.setIcon(icon);
+        }
         if (StrUtil.isNotEmpty(description)) {
             metaInfo.setDescription(description);
         }
@@ -138,4 +129,9 @@ public interface BpmModelConvert {
         }
         return JsonUtils.toJsonString(metaInfo);
     }
+
+    default BpmModelMetaInfoRespDTO buildMetaInfo(Model model) {
+        return JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
+    }
+
 }

+ 57 - 43
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java

@@ -1,20 +1,23 @@
 package cn.iocoder.yudao.module.bpm.convert.definition;
 
 import cn.hutool.core.date.LocalDateTimeUtil;
+import cn.hutool.core.map.MapUtil;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
-import cn.iocoder.yudao.framework.common.util.date.DateUtils;
-import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
+import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
 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.dto.BpmProcessDefinitionCreateReqDTO;
+import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
+import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
+import org.flowable.bpmn.model.BpmnModel;
+import org.flowable.bpmn.model.UserTask;
 import org.flowable.common.engine.impl.db.SuspensionState;
 import org.flowable.engine.repository.Deployment;
 import org.flowable.engine.repository.ProcessDefinition;
 import org.mapstruct.Mapper;
 import org.mapstruct.Mapping;
 import org.mapstruct.MappingTarget;
-import org.mapstruct.Named;
 import org.mapstruct.factory.Mappers;
 
 import java.util.List;
@@ -30,55 +33,66 @@ public interface BpmProcessDefinitionConvert {
 
     BpmProcessDefinitionConvert INSTANCE = Mappers.getMapper(BpmProcessDefinitionConvert.class);
 
-    BpmProcessDefinitionPageItemRespVO convert(ProcessDefinition bean);
-
-    BpmProcessDefinitionExtDO convert2(BpmProcessDefinitionCreateReqDTO bean);
-
-    default List<BpmProcessDefinitionPageItemRespVO> convertList(List<ProcessDefinition> list, Map<String, Deployment> deploymentMap,
-                                                                 Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap, Map<Long, BpmFormDO> formMap) {
-        return CollectionUtils.convertList(list, definition -> {
-            Deployment deployment = definition.getDeploymentId() != null ? deploymentMap.get(definition.getDeploymentId()) : null;
-            BpmProcessDefinitionExtDO definitionDO = processDefinitionDOMap.get(definition.getId());
-            BpmFormDO form = definitionDO != null ? formMap.get(definitionDO.getFormId()) : null;
-            return convert(definition, deployment, definitionDO, form);
-        });
+    default PageResult<BpmProcessDefinitionRespVO> buildProcessDefinitionPage(PageResult<ProcessDefinition> page,
+                                                                              Map<String, Deployment> deploymentMap,
+                                                                              Map<String, BpmProcessDefinitionInfoDO> processDefinitionInfoMap,
+                                                                              Map<Long, BpmFormDO> formMap,
+                                                                              Map<String, BpmCategoryDO> categoryMap) {
+        List<BpmProcessDefinitionRespVO> list = buildProcessDefinitionList(page.getList(), deploymentMap, processDefinitionInfoMap, formMap, categoryMap);
+        return new PageResult<>(list, page.getTotal());
     }
 
-    default List<BpmProcessDefinitionRespVO> convertList3(List<ProcessDefinition> list,
-                                                          Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap) {
-        return CollectionUtils.convertList(list, processDefinition -> {
-            BpmProcessDefinitionRespVO respVO = convert3(processDefinition);
-            BpmProcessDefinitionExtDO processDefinitionExtDO = processDefinitionDOMap.get(processDefinition.getId());
-            // 复制通用属性
-            copyTo(processDefinitionExtDO, respVO);
-            return respVO;
+    default List<BpmProcessDefinitionRespVO> buildProcessDefinitionList(List<ProcessDefinition> list,
+                                                                        Map<String, Deployment> deploymentMap,
+                                                                        Map<String, BpmProcessDefinitionInfoDO> processDefinitionInfoMap,
+                                                                        Map<Long, BpmFormDO> formMap,
+                                                                        Map<String, BpmCategoryDO> categoryMap) {
+        return CollectionUtils.convertList(list, definition -> {
+            Deployment deployment = MapUtil.get(deploymentMap, definition.getDeploymentId(), Deployment.class);
+            BpmProcessDefinitionInfoDO processDefinitionInfo = MapUtil.get(processDefinitionInfoMap, definition.getId(), BpmProcessDefinitionInfoDO.class);
+            BpmFormDO form = null;
+            if (processDefinitionInfo != null) {
+                form = MapUtil.get(formMap, processDefinitionInfo.getFormId(), BpmFormDO.class);
+            }
+            BpmCategoryDO category = MapUtil.get(categoryMap, definition.getCategory(), BpmCategoryDO.class);
+            return buildProcessDefinition(definition, deployment, processDefinitionInfo, form, category, null, null);
         });
     }
 
-    @Mapping(source = "suspended", target = "suspensionState", qualifiedByName = "convertSuspendedToSuspensionState")
-    BpmProcessDefinitionRespVO convert3(ProcessDefinition bean);
-
-    @Named("convertSuspendedToSuspensionState")
-    default Integer convertSuspendedToSuspensionState(boolean suspended) {
-        return suspended ? SuspensionState.SUSPENDED.getStateCode() :
-                SuspensionState.ACTIVE.getStateCode();
-    }
-
-    default BpmProcessDefinitionPageItemRespVO convert(ProcessDefinition bean, Deployment deployment,
-                                                       BpmProcessDefinitionExtDO processDefinitionExtDO, BpmFormDO form) {
-        BpmProcessDefinitionPageItemRespVO respVO = convert(bean);
-        respVO.setSuspensionState(bean.isSuspended() ? SuspensionState.SUSPENDED.getStateCode() : SuspensionState.ACTIVE.getStateCode());
+    default BpmProcessDefinitionRespVO buildProcessDefinition(ProcessDefinition definition,
+                                                              Deployment deployment,
+                                                              BpmProcessDefinitionInfoDO processDefinitionInfo,
+                                                              BpmFormDO form,
+                                                              BpmCategoryDO category,
+                                                              BpmnModel bpmnModel,
+                                                              List<UserTask> startUserSelectUserTaskList) {
+        BpmProcessDefinitionRespVO respVO = BeanUtils.toBean(definition, BpmProcessDefinitionRespVO.class);
+        respVO.setSuspensionState(definition.isSuspended() ? SuspensionState.SUSPENDED.getStateCode() : SuspensionState.ACTIVE.getStateCode());
+        // Deployment
         if (deployment != null) {
             respVO.setDeploymentTime(LocalDateTimeUtil.of(deployment.getDeploymentTime()));
         }
-        if (form != null) {
-            respVO.setFormName(form.getName());
+        // BpmProcessDefinitionInfoDO
+        if (processDefinitionInfo != null) {
+            copyTo(processDefinitionInfo, respVO);
+            // Form
+            if (form != null) {
+                respVO.setFormName(form.getName());
+            }
+        }
+        // Category
+        if (category != null) {
+            respVO.setCategoryName(category.getName());
+        }
+        // BpmnModel
+        if (bpmnModel != null) {
+            respVO.setBpmnXml(BpmnModelUtils.getBpmnXml(bpmnModel));
+            respVO.setStartUserSelectTasks(BeanUtils.toBean(startUserSelectUserTaskList, BpmProcessDefinitionRespVO.UserTask.class));
         }
-        // 复制通用属性
-        copyTo(processDefinitionExtDO, respVO);
         return respVO;
     }
 
     @Mapping(source = "from.id", target = "to.id", ignore = true)
-    void copyTo(BpmProcessDefinitionExtDO from, @MappingTarget BpmProcessDefinitionRespVO to);
+    void copyTo(BpmProcessDefinitionInfoDO from, @MappingTarget BpmProcessDefinitionRespVO to);
+
 }

+ 0 - 40
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmTaskAssignRuleConvert.java

@@ -1,40 +0,0 @@
-package cn.iocoder.yudao.module.bpm.convert.definition;
-
-import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
-import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO;
-import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO;
-import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO;
-import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
-import org.flowable.bpmn.model.UserTask;
-import org.mapstruct.Mapper;
-import org.mapstruct.factory.Mappers;
-
-import java.util.List;
-import java.util.Map;
-
-@Mapper
-public interface BpmTaskAssignRuleConvert {
-    BpmTaskAssignRuleConvert INSTANCE = Mappers.getMapper(BpmTaskAssignRuleConvert.class);
-
-    default List<BpmTaskAssignRuleRespVO> convertList(List<UserTask> tasks, List<BpmTaskAssignRuleDO> rules) {
-        Map<String, BpmTaskAssignRuleDO> ruleMap = CollectionUtils.convertMap(rules, BpmTaskAssignRuleDO::getTaskDefinitionKey);
-        // 以 UserTask 为主维度,原因是:流程图编辑后,一些规则实际就没用了。
-        return CollectionUtils.convertList(tasks, task -> {
-            BpmTaskAssignRuleRespVO respVO = convert(ruleMap.get(task.getId()));
-            if (respVO == null) {
-                respVO = new BpmTaskAssignRuleRespVO();
-                respVO.setTaskDefinitionKey(task.getId());
-            }
-            respVO.setTaskDefinitionName(task.getName());
-            return respVO;
-        });
-    }
-
-    BpmTaskAssignRuleRespVO convert(BpmTaskAssignRuleDO bean);
-
-    BpmTaskAssignRuleDO convert(BpmTaskAssignRuleCreateReqVO bean);
-
-    BpmTaskAssignRuleDO convert(BpmTaskAssignRuleUpdateReqVO bean);
-
-    List<BpmTaskAssignRuleDO> convertList2(List<BpmTaskAssignRuleRespVO> list);
-}

+ 0 - 38
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmUserGroupConvert.java

@@ -1,38 +0,0 @@
-package cn.iocoder.yudao.module.bpm.convert.definition;
-
-import java.util.*;
-
-import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupCreateReqVO;
-import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupRespVO;
-import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group.BpmUserGroupUpdateReqVO;
-import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-
-import org.mapstruct.Mapper;
-import org.mapstruct.Named;
-import org.mapstruct.factory.Mappers;
-
-/**
- * 用户组 Convert
- *
- * @author 芋道源码
- */
-@Mapper
-public interface BpmUserGroupConvert {
-
-    BpmUserGroupConvert INSTANCE = Mappers.getMapper(BpmUserGroupConvert.class);
-
-    BpmUserGroupDO convert(BpmUserGroupCreateReqVO bean);
-
-    BpmUserGroupDO convert(BpmUserGroupUpdateReqVO bean);
-
-    BpmUserGroupRespVO convert(BpmUserGroupDO bean);
-
-    List<BpmUserGroupRespVO> convertList(List<BpmUserGroupDO> list);
-
-    PageResult<BpmUserGroupRespVO> convertPage(PageResult<BpmUserGroupDO> page);
-
-    @Named("convertList2")
-    List<BpmUserGroupRespVO> convertList2(List<BpmUserGroupDO> list);
-
-}

+ 0 - 30
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/oa/BpmOALeaveConvert.java

@@ -1,30 +0,0 @@
-package cn.iocoder.yudao.module.bpm.convert.oa;
-
-import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOALeaveCreateReqVO;
-import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOALeaveRespVO;
-import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOALeaveDO;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import org.mapstruct.Mapper;
-import org.mapstruct.factory.Mappers;
-
-import java.util.List;
-
-/**
- * 请假申请 Convert
- *
- * @author 芋艿
- */
-@Mapper
-public interface BpmOALeaveConvert {
-
-    BpmOALeaveConvert INSTANCE = Mappers.getMapper(BpmOALeaveConvert.class);
-
-    BpmOALeaveDO convert(BpmOALeaveCreateReqVO bean);
-
-    BpmOALeaveRespVO convert(BpmOALeaveDO bean);
-
-    List<BpmOALeaveRespVO> convertList(List<BpmOALeaveDO> list);
-
-    PageResult<BpmOALeaveRespVO> convertPage(PageResult<BpmOALeaveDO> page);
-
-}

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

@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.module.bpm.convert.task;
 
+import cn.iocoder.yudao.framework.common.util.date.DateUtils;
 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity.BpmActivityRespVO;
 import org.flowable.engine.history.HistoricActivityInstance;
 import org.mapstruct.Mapper;
@@ -14,7 +15,7 @@ import java.util.List;
  *
  * @author 芋道源码
  */
-@Mapper
+@Mapper(uses = DateUtils.class)
 public interface BpmActivityConvert {
 
     BpmActivityConvert INSTANCE = Mappers.getMapper(BpmActivityConvert.class);

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

@@ -1,12 +1,15 @@
 package cn.iocoder.yudao.module.bpm.convert.task;
 
 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;
-import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstancePageItemRespVO;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
-import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
-import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
-import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEvent;
+import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
+import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
+import cn.iocoder.yudao.module.bpm.event.BpmProcessInstanceStatusEvent;
+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;
@@ -33,32 +36,48 @@ public interface BpmProcessInstanceConvert {
 
     BpmProcessInstanceConvert INSTANCE = Mappers.getMapper(BpmProcessInstanceConvert.class);
 
-    default PageResult<BpmProcessInstancePageItemRespVO> convertPage(PageResult<BpmProcessInstanceExtDO> page,
-                                                                     Map<String, List<Task>> taskMap) {
-        List<BpmProcessInstancePageItemRespVO> list = convertList(page.getList());
-        list.forEach(respVO -> respVO.setTasks(convertList2(taskMap.get(respVO.getId()))));
-        return new PageResult<>(list, page.getTotal());
+    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);
+            respVO.setStatus(FlowableUtils.getProcessInstanceStatus(pageResult.getList().get(i)));
+            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));
+            // user
+            if (userMap != null) {
+                AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(pageResult.getList().get(i).getStartUserId()));
+                if (startUser != null) {
+                    respVO.setStartUser(BeanUtils.toBean(startUser, BpmProcessInstanceRespVO.User.class));
+                    MapUtils.findAndThen(deptMap, startUser.getDeptId(), dept -> respVO.getStartUser().setDeptName(dept.getName()));
+                }
+            }
+        }
+        return vpPageResult;
     }
 
-    List<BpmProcessInstancePageItemRespVO> convertList(List<BpmProcessInstanceExtDO> list);
-
-    @Mapping(source = "processInstanceId", target = "id")
-    BpmProcessInstancePageItemRespVO convert(BpmProcessInstanceExtDO bean);
-
-    List<BpmProcessInstancePageItemRespVO.Task> convertList2(List<Task> tasks);
-
-    default BpmProcessInstanceRespVO convert2(HistoricProcessInstance processInstance, BpmProcessInstanceExtDO processInstanceExt,
-                                              ProcessDefinition processDefinition, BpmProcessDefinitionExtDO processDefinitionExt,
-                                              String bpmnXml, AdminUserRespDTO startUser, DeptRespDTO dept) {
-        BpmProcessInstanceRespVO respVO = convert2(processInstance);
-        copyTo(processInstanceExt, respVO);
+    default BpmProcessInstanceRespVO buildProcessInstance(HistoricProcessInstance processInstance,
+                                                          ProcessDefinition processDefinition,
+                                                          BpmProcessDefinitionInfoDO processDefinitionExt,
+                                                          String bpmnXml,
+                                                          AdminUserRespDTO startUser,
+                                                          DeptRespDTO dept) {
+        BpmProcessInstanceRespVO respVO = BeanUtils.toBean(processInstance, BpmProcessInstanceRespVO.class);
+        respVO.setStatus(FlowableUtils.getProcessInstanceStatus(processInstance));
+        respVO.setFormVariables(FlowableUtils.getProcessInstanceFormVariable(processInstance));
         // definition
-        respVO.setProcessDefinition(convert2(processDefinition));
+        respVO.setProcessDefinition(BeanUtils.toBean(processDefinition, BpmProcessDefinitionRespVO.class));
         copyTo(processDefinitionExt, respVO.getProcessDefinition());
         respVO.getProcessDefinition().setBpmnXml(bpmnXml);
         // user
         if (startUser != null) {
-            respVO.setStartUser(convert2(startUser));
+            respVO.setStartUser(BeanUtils.toBean(startUser, BpmProcessInstanceRespVO.User.class));
             if (dept != null) {
                 respVO.getStartUser().setDeptName(dept.getName());
             }
@@ -66,44 +85,27 @@ public interface BpmProcessInstanceConvert {
         return respVO;
     }
 
-    BpmProcessInstanceRespVO convert2(HistoricProcessInstance bean);
-
     @Mapping(source = "from.id", target = "to.id", ignore = true)
-    void copyTo(BpmProcessInstanceExtDO from, @MappingTarget BpmProcessInstanceRespVO to);
-
-    BpmProcessInstanceRespVO.ProcessDefinition convert2(ProcessDefinition bean);
-
-    @Mapping(source = "from.id", target = "to.id", ignore = true)
-    void copyTo(BpmProcessDefinitionExtDO from, @MappingTarget BpmProcessInstanceRespVO.ProcessDefinition to);
-
-    BpmProcessInstanceRespVO.User convert2(AdminUserRespDTO bean);
+    void copyTo(BpmProcessDefinitionInfoDO from, @MappingTarget BpmProcessDefinitionRespVO to);
 
-    default BpmProcessInstanceResultEvent convert(Object source, HistoricProcessInstance instance, Integer result) {
-        BpmProcessInstanceResultEvent event = new BpmProcessInstanceResultEvent(source);
-        event.setId(instance.getId());
-        event.setProcessDefinitionKey(instance.getProcessDefinitionKey());
-        event.setBusinessKey(instance.getBusinessKey());
-        event.setResult(result);
-        return event;
+    default BpmProcessInstanceStatusEvent buildProcessInstanceStatusEvent(Object source, HistoricProcessInstance instance, Integer status) {
+        return new BpmProcessInstanceStatusEvent(source).setId(instance.getId()).setStatus(status)
+                .setProcessDefinitionKey(instance.getProcessDefinitionKey()).setBusinessKey(instance.getBusinessKey());
     }
 
-    default BpmProcessInstanceResultEvent convert(Object source, ProcessInstance instance, Integer result) {
-        BpmProcessInstanceResultEvent event = new BpmProcessInstanceResultEvent(source);
-        event.setId(instance.getId());
-        event.setProcessDefinitionKey(instance.getProcessDefinitionKey());
-        event.setBusinessKey(instance.getBusinessKey());
-        event.setResult(result);
-        return event;
+    default BpmProcessInstanceStatusEvent buildProcessInstanceStatusEvent(Object source, ProcessInstance instance, Integer status) {;
+        return new BpmProcessInstanceStatusEvent(source).setId(instance.getId()).setStatus(status)
+                .setProcessDefinitionKey(instance.getProcessDefinitionKey()).setBusinessKey(instance.getBusinessKey());
     }
 
-    default BpmMessageSendWhenProcessInstanceApproveReqDTO convert2ApprovedReq(ProcessInstance instance){
-        return  new BpmMessageSendWhenProcessInstanceApproveReqDTO()
+    default BpmMessageSendWhenProcessInstanceApproveReqDTO buildProcessInstanceApproveMessage(ProcessInstance instance) {
+        return new BpmMessageSendWhenProcessInstanceApproveReqDTO()
                 .setStartUserId(NumberUtils.parseLong(instance.getStartUserId()))
                 .setProcessInstanceId(instance.getId())
                 .setProcessInstanceName(instance.getName());
     }
 
-    default BpmMessageSendWhenProcessInstanceRejectReqDTO convert2RejectReq(ProcessInstance instance, String reason) {
+    default BpmMessageSendWhenProcessInstanceRejectReqDTO buildProcessInstanceRejectMessage(ProcessInstance instance, String reason) {
         return new BpmMessageSendWhenProcessInstanceRejectReqDTO()
             .setProcessInstanceName(instance.getName())
             .setProcessInstanceId(instance.getId())

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

@@ -1,28 +1,32 @@
 package cn.iocoder.yudao.module.bpm.convert.task;
 
-import cn.hutool.core.date.LocalDateTimeUtil;
+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.number.NumberUtils;
-import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskDonePageItemRespVO;
+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.controller.admin.task.vo.task.BpmTaskTodoPageItemRespVO;
-import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO;
+import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
+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.common.engine.impl.db.SuspensionState;
 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.mapstruct.*;
+import org.flowable.task.service.impl.persistence.entity.TaskEntityImpl;
+import org.mapstruct.Mapper;
 import org.mapstruct.factory.Mappers;
-import org.springframework.beans.BeanUtils;
 
-import java.util.Collections;
+import java.util.Date;
 import java.util.List;
 import java.util.Map;
-import java.util.stream.Collectors;
+
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
+import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
 
 /**
  * Bpm 任务 Convert
@@ -34,138 +38,139 @@ public interface BpmTaskConvert {
 
     BpmTaskConvert INSTANCE = Mappers.getMapper(BpmTaskConvert.class);
 
-    /**
-     * 复制对象
-     *
-     * @param source 源 要复制的对象
-     * @param target 目标 复制到此对象
-     * @param <T>
-     *
-     * @return
-     */
-    public static <T> T copy(Object source, Class<T> target) {
-        if (source == null || target == null) {
-            return null;
-        }
-        try {
-            T newInstance = target.getDeclaredConstructor().newInstance();
-            BeanUtils.copyProperties(source, newInstance);
-            return newInstance;
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    default <T, K> List<K> copyList(List<T> source, Class<K> target) {
-        if (null == source || source.isEmpty()) {
-            return Collections.emptyList();
-        }
-        return source.stream().map(e -> copy(e, target)).collect(Collectors.toList());
-    }
-
-    default List<BpmTaskTodoPageItemRespVO> convertList1(List<Task> tasks,
-        Map<String, ProcessInstance> processInstanceMap, Map<Long, AdminUserRespDTO> userMap) {
-        return CollectionUtils.convertList(tasks, task -> {
-            BpmTaskTodoPageItemRespVO respVO = convert1(task);
-            ProcessInstance processInstance = processInstanceMap.get(task.getProcessInstanceId());
-            if (processInstance != null) {
-                AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));
-                respVO.setProcessInstance(convert(processInstance, startUser));
+    default PageResult<BpmTaskRespVO> buildTodoTaskPage(PageResult<Task> pageResult,
+                                                        Map<String, ProcessInstance> processInstanceMap,
+                                                        Map<Long, AdminUserRespDTO> userMap) {
+        return BeanUtils.toBean(pageResult, BpmTaskRespVO.class, taskVO -> {
+            ProcessInstance processInstance = processInstanceMap.get(taskVO.getProcessInstanceId());
+            if (processInstance == null) {
+                return;
             }
-            return respVO;
+            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));
         });
     }
 
-    @Mapping(source = "suspended", target = "suspensionState", qualifiedByName = "convertSuspendedToSuspensionState")
-    @Mapping(target = "claimTime", expression = "java(bean.getClaimTime()==null?null: LocalDateTime.ofInstant(bean.getClaimTime().toInstant(),ZoneId.systemDefault()))")
-    @Mapping(target = "createTime", expression = "java(bean.getCreateTime()==null?null:LocalDateTime.ofInstant(bean.getCreateTime().toInstant(),ZoneId.systemDefault()))")
-    BpmTaskTodoPageItemRespVO convert1(Task bean);
-
-    @Named("convertSuspendedToSuspensionState")
-    default Integer convertSuspendedToSuspensionState(boolean suspended) {
-        return suspended ? SuspensionState.SUSPENDED.getStateCode() : SuspensionState.ACTIVE.getStateCode();
-    }
-
-    default List<BpmTaskDonePageItemRespVO> convertList2(List<HistoricTaskInstance> tasks,
-        Map<String, BpmTaskExtDO> bpmTaskExtDOMap, Map<String, HistoricProcessInstance> historicProcessInstanceMap,
-        Map<Long, AdminUserRespDTO> userMap) {
-        return CollectionUtils.convertList(tasks, task -> {
-            BpmTaskDonePageItemRespVO respVO = convert2(task);
-            BpmTaskExtDO taskExtDO = bpmTaskExtDOMap.get(task.getId());
-            copyTo(taskExtDO, respVO);
-            HistoricProcessInstance processInstance = historicProcessInstanceMap.get(task.getProcessInstanceId());
+    default PageResult<BpmTaskRespVO> buildTaskPage(PageResult<HistoricTaskInstance> pageResult,
+                                                    Map<String, HistoricProcessInstance> processInstanceMap,
+                                                    Map<Long, AdminUserRespDTO> userMap,
+                                                    Map<Long, DeptRespDTO> deptMap) {
+        List<BpmTaskRespVO> taskVOList = CollectionUtils.convertList(pageResult.getList(), task -> {
+            BpmTaskRespVO taskVO = BeanUtils.toBean(task, BpmTaskRespVO.class);
+            taskVO.setStatus(FlowableUtils.getTaskStatus(task)).setReason(FlowableUtils.getTaskReason(task));
+            // 用户信息
+            AdminUserRespDTO assignUser = userMap.get(NumberUtils.parseLong(task.getAssignee()));
+            if (assignUser != null) {
+                taskVO.setAssigneeUser(BeanUtils.toBean(assignUser, BpmProcessInstanceRespVO.User.class));
+                findAndThen(deptMap, assignUser.getDeptId(), dept -> taskVO.getAssigneeUser().setDeptName(dept.getName()));
+            }
+            // 流程实例
+            HistoricProcessInstance processInstance = processInstanceMap.get(taskVO.getProcessInstanceId());
             if (processInstance != null) {
                 AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));
-                respVO.setProcessInstance(convert(processInstance, startUser));
+                taskVO.setProcessInstance(BeanUtils.toBean(processInstance, BpmTaskRespVO.ProcessInstance.class));
+                taskVO.getProcessInstance().setStartUser(BeanUtils.toBean(startUser, BpmProcessInstanceRespVO.User.class));
             }
-            return respVO;
+            return taskVO;
         });
+        return new PageResult<>(taskVOList, pageResult.getTotal());
     }
 
-    BpmTaskDonePageItemRespVO convert2(HistoricTaskInstance bean);
+    default List<BpmTaskRespVO> buildTaskListByProcessInstanceId(List<HistoricTaskInstance> taskList,
+                                                                 HistoricProcessInstance processInstance,
+                                                                 Map<Long, BpmFormDO> formMap,
+                                                                 Map<Long, AdminUserRespDTO> userMap,
+                                                                 Map<Long, DeptRespDTO> deptMap) {
+        List<BpmTaskRespVO> taskVOList = CollectionUtils.convertList(taskList, task -> {
+            BpmTaskRespVO taskVO = BeanUtils.toBean(task, BpmTaskRespVO.class);
+            taskVO.setStatus(FlowableUtils.getTaskStatus(task)).setReason(FlowableUtils.getTaskReason(task));
+            // 流程实例
+            AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));
+            taskVO.setProcessInstance(BeanUtils.toBean(processInstance, BpmTaskRespVO.ProcessInstance.class));
+            taskVO.getProcessInstance().setStartUser(BeanUtils.toBean(startUser, BpmProcessInstanceRespVO.User.class));
+            // 表单信息
+            BpmFormDO form = MapUtil.get(formMap, NumberUtils.parseLong(task.getFormKey()), BpmFormDO.class);
+            if (form != null) {
+                taskVO.setFormId(form.getId()).setFormName(form.getName()).setFormConf(form.getConf())
+                        .setFormFields(form.getFields()).setFormVariables(FlowableUtils.getTaskFormVariable(task));
+            }
+            // 用户信息
+            AdminUserRespDTO assignUser = userMap.get(NumberUtils.parseLong(task.getAssignee()));
+            if (assignUser != null) {
+                taskVO.setAssigneeUser(BeanUtils.toBean(assignUser, BpmProcessInstanceRespVO.User.class));
+                findAndThen(deptMap, assignUser.getDeptId(), dept -> taskVO.getAssigneeUser().setDeptName(dept.getName()));
+            }
+            AdminUserRespDTO ownerUser = userMap.get(NumberUtils.parseLong(task.getOwner()));
+            if (ownerUser != null) {
+                taskVO.setOwnerUser(BeanUtils.toBean(ownerUser, BpmProcessInstanceRespVO.User.class));
+                findAndThen(deptMap, ownerUser.getDeptId(), dept -> taskVO.getOwnerUser().setDeptName(dept.getName()));
+            }
+            return taskVO;
+        });
 
-    @Mappings({@Mapping(source = "processInstance.id", target = "id"),
-        @Mapping(source = "processInstance.name", target = "name"),
-        @Mapping(source = "processInstance.startUserId", target = "startUserId"),
-        @Mapping(source = "processInstance.processDefinitionId", target = "processDefinitionId"),
-        @Mapping(source = "startUser.nickname", target = "startUserNickname")})
-    BpmTaskTodoPageItemRespVO.ProcessInstance convert(ProcessInstance processInstance, AdminUserRespDTO startUser);
+        // 拼接父子关系
+        Map<String, List<BpmTaskRespVO>> childrenTaskMap = convertMultiMap(
+                filterList(taskVOList, r -> StrUtil.isNotEmpty(r.getParentTaskId())),
+                BpmTaskRespVO::getParentTaskId);
+        for (BpmTaskRespVO taskVO : taskVOList) {
+            taskVO.setChildren(childrenTaskMap.get(taskVO.getId()));
+        }
+        return filterList(taskVOList, r -> StrUtil.isEmpty(r.getParentTaskId()));
+    }
 
-    default List<BpmTaskRespVO> convertList3(List<HistoricTaskInstance> tasks,
-        Map<String, BpmTaskExtDO> bpmTaskExtDOMap, HistoricProcessInstance processInstance,
-        Map<Long, AdminUserRespDTO> userMap, Map<Long, DeptRespDTO> deptMap) {
-        return CollectionUtils.convertList(tasks, task -> {
-            BpmTaskRespVO respVO = convert3(task);
-            BpmTaskExtDO taskExtDO = bpmTaskExtDOMap.get(task.getId());
-            copyTo(taskExtDO, respVO);
-            if (processInstance != null) {
-                AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));
-                respVO.setProcessInstance(convert(processInstance, startUser));
-            }
+    default List<BpmTaskRespVO> buildTaskListByParentTaskId(List<Task> taskList,
+                                                            Map<Long, AdminUserRespDTO> userMap,
+                                                            Map<Long, DeptRespDTO> deptMap) {
+        return convertList(taskList, task -> BeanUtils.toBean(task, BpmTaskRespVO.class, taskVO -> {
             AdminUserRespDTO assignUser = userMap.get(NumberUtils.parseLong(task.getAssignee()));
             if (assignUser != null) {
-                respVO.setAssigneeUser(convert3(assignUser));
+                taskVO.setAssigneeUser(BeanUtils.toBean(assignUser, BpmProcessInstanceRespVO.User.class));
                 DeptRespDTO dept = deptMap.get(assignUser.getDeptId());
                 if (dept != null) {
-                    respVO.getAssigneeUser().setDeptName(dept.getName());
+                    taskVO.getAssigneeUser().setDeptName(dept.getName());
                 }
             }
-            return respVO;
-        });
-    }
-
-    @Mapping(source = "taskDefinitionKey", target = "definitionKey")
-    BpmTaskRespVO convert3(HistoricTaskInstance bean);
-
-    BpmTaskRespVO.User convert3(AdminUserRespDTO bean);
-
-    @Mapping(target = "id", ignore = true)
-    void copyTo(BpmTaskExtDO from, @MappingTarget BpmTaskDonePageItemRespVO to);
-
-    @Mappings({@Mapping(source = "processInstance.id", target = "id"),
-        @Mapping(source = "processInstance.name", target = "name"),
-        @Mapping(source = "processInstance.startUserId", target = "startUserId"),
-        @Mapping(source = "processInstance.processDefinitionId", target = "processDefinitionId"),
-        @Mapping(source = "startUser.nickname", target = "startUserNickname")})
-    BpmTaskTodoPageItemRespVO.ProcessInstance convert(HistoricProcessInstance processInstance,
-        AdminUserRespDTO startUser);
-
-    default BpmTaskExtDO convert2TaskExt(Task task) {
-        BpmTaskExtDO taskExtDO = new BpmTaskExtDO().setTaskId(task.getId())
-            .setAssigneeUserId(NumberUtils.parseLong(task.getAssignee())).setName(task.getName())
-            .setProcessDefinitionId(task.getProcessDefinitionId()).setProcessInstanceId(task.getProcessInstanceId());
-        taskExtDO.setCreateTime(LocalDateTimeUtil.of(task.getCreateTime()));
-        return taskExtDO;
+            AdminUserRespDTO ownerUser = userMap.get(NumberUtils.parseLong(task.getOwner()));
+            if (ownerUser != null) {
+                taskVO.setOwnerUser(BeanUtils.toBean(ownerUser, BpmProcessInstanceRespVO.User.class));
+                findAndThen(deptMap, ownerUser.getDeptId(), dept -> taskVO.getOwnerUser().setDeptName(dept.getName()));
+            }
+        }));
     }
 
     default BpmMessageSendWhenTaskCreatedReqDTO convert(ProcessInstance processInstance, AdminUserRespDTO startUser,
-        Task task) {
+                                                        Task task) {
         BpmMessageSendWhenTaskCreatedReqDTO reqDTO = new BpmMessageSendWhenTaskCreatedReqDTO();
         reqDTO.setProcessInstanceId(processInstance.getProcessInstanceId())
-            .setProcessInstanceName(processInstance.getName()).setStartUserId(startUser.getId())
-            .setStartUserNickname(startUser.getNickname()).setTaskId(task.getId()).setTaskName(task.getName())
-            .setAssigneeUserId(NumberUtils.parseLong(task.getAssignee()));
+                .setProcessInstanceName(processInstance.getName()).setStartUserId(startUser.getId())
+                .setStartUserNickname(startUser.getNickname()).setTaskId(task.getId()).setTaskName(task.getName())
+                .setAssigneeUserId(NumberUtils.parseLong(task.getAssignee()));
         return reqDTO;
     }
 
+    /**
+     * 将父任务的属性,拷贝到子任务(加签任务)
+     *
+     * 为什么不使用 mapstruct 映射?因为 TaskEntityImpl 还有很多其他属性,这里我们只设置我们需要的。
+     * 使用 mapstruct 会将里面嵌套的各个属性值都设置进去,会出现意想不到的问题。
+     *
+     * @param parentTask 父任务
+     * @param childTask 加签任务
+     */
+    default void copyTo(TaskEntityImpl parentTask, TaskEntityImpl childTask) {
+        childTask.setName(parentTask.getName());
+        childTask.setDescription(parentTask.getDescription());
+        childTask.setCategory(parentTask.getCategory());
+        childTask.setParentTaskId(parentTask.getId());
+        childTask.setProcessDefinitionId(parentTask.getProcessDefinitionId());
+        childTask.setProcessInstanceId(parentTask.getProcessInstanceId());
+//        childTask.setExecutionId(parentTask.getExecutionId()); // TODO 芋艿:新加的,不太确定;尴尬,不加时,子任务不通过会失败(报错);加了,子任务审批通过会失败(报错)
+        childTask.setTaskDefinitionKey(parentTask.getTaskDefinitionKey());
+        childTask.setTaskDefinitionId(parentTask.getTaskDefinitionId());
+        childTask.setPriority(parentTask.getPriority());
+        childTask.setCreateTime(new Date());
+        childTask.setTenantId(parentTask.getTenantId());
+    }
+
 }

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

@@ -1 +0,0 @@
-package cn.iocoder.yudao.module.bpm.convert.task;

+ 1 - 3
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmFormDO.java

@@ -10,15 +10,13 @@ import lombok.*;
 import java.util.List;
 
 /**
- * 工作流的表单定义
+ * BPM 工作流的表单定义
  * 用于工作流的申请表单,需要动态配置的场景
  *
  * @author 芋道源码
  */
 @TableName(value = "bpm_form", autoResultMap = true)
 @Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
 @Builder
 @NoArgsConstructor
 @AllArgsConstructor

+ 0 - 90
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessDefinitionExtDO.java

@@ -1,90 +0,0 @@
-package cn.iocoder.yudao.module.bpm.dal.dataobject.definition;
-
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
-import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
-import lombok.*;
-
-import java.util.List;
-
-/**
- * Bpm 流程定义的拓展表
- * 主要解决 Activiti {@link ProcessDefinition} 不支持拓展字段,所以新建拓展表
- *
- * @author 芋道源码
- */
-@TableName(value = "bpm_process_definition_ext", autoResultMap = true)
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-@Builder
-@NoArgsConstructor
-@AllArgsConstructor
-public class BpmProcessDefinitionExtDO extends BaseDO {
-
-    /**
-     * 编号
-     */
-    @TableId
-    private Long id;
-    /**
-     * 流程定义的编号
-     *
-     * 关联 ProcessDefinition 的 id 属性
-     */
-    private String processDefinitionId;
-    /**
-     * 流程模型的编号
-     *
-     * 关联 Model 的 id 属性
-     */
-    private String modelId;
-    /**
-     * 描述
-     */
-    private String description;
-
-    /**
-     * 表单类型
-     *
-     * 关联 {@link BpmModelFormTypeEnum}
-     */
-    private Integer formType;
-    /**
-     * 动态表单编号
-     * 在表单类型为 {@link BpmModelFormTypeEnum#NORMAL} 时
-     *
-     * 关联 {@link BpmFormDO#getId()}
-     */
-    private Long formId;
-    /**
-     * 表单的配置
-     * 在表单类型为 {@link BpmModelFormTypeEnum#NORMAL} 时
-     *
-     * 冗余 {@link BpmFormDO#getConf()}
-     */
-    private String formConf;
-    /**
-     * 表单项的数组
-     * 在表单类型为 {@link BpmModelFormTypeEnum#NORMAL} 时
-     *
-     * 冗余 {@link BpmFormDO#getFields()} ()}
-     */
-    @TableField(typeHandler = JacksonTypeHandler.class)
-    private List<String> formFields;
-    /**
-     * 自定义表单的提交路径,使用 Vue 的路由地址
-     * 在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时
-     */
-    private String formCustomCreatePath;
-    /**
-     * 自定义表单的查看路径,使用 Vue 的路由地址
-     * 在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时
-     */
-    private String formCustomViewPath;
-
-
-}

+ 0 - 83
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmTaskAssignRuleDO.java

@@ -1,83 +0,0 @@
-package cn.iocoder.yudao.module.bpm.dal.dataobject.definition;
-
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
-import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler;
-import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum;
-import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.*;
-
-import java.util.Set;
-
-/**
- * Bpm 任务分配的规则表,用于自定义配置每个任务的负责人、候选人的分配规则。
- * 也就是说,废弃 BPMN 原本的 UserTask 设置的 assignee、candidateUsers 等配置,而是通过使用该规则进行计算对应的负责人。
- *
- * 1. 默认情况下,{@link #processDefinitionId} 为 {@link #PROCESS_DEFINITION_ID_NULL} 值,表示贵改则与流程模型关联
- * 2. 在流程模型部署后,会将他的所有规则记录,复制出一份新部署出来的流程定义,通过设置 {@link #processDefinitionId} 为新的流程定义的编号进行关联
- *
- * @author 芋道源码
- */
-@TableName(value = "bpm_task_assign_rule", autoResultMap = true)
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-@Builder
-@NoArgsConstructor
-@AllArgsConstructor
-public class BpmTaskAssignRuleDO extends BaseDO {
-
-    /**
-     * {@link #processDefinitionId} 空串,用于标识属于流程模型,而不属于流程定义
-     */
-    public static final String PROCESS_DEFINITION_ID_NULL = "";
-
-    /**
-     * 编号
-     */
-    @TableId
-    private Long id;
-
-    /**
-     * 流程模型编号
-     *
-     * 关联 Model 的 id 属性
-     */
-    private String modelId;
-    /**
-     * 流程定义编号
-     *
-     * 关联 ProcessDefinition 的 id 属性
-     */
-    private String processDefinitionId;
-    /**
-     * 流程任务的定义 Key
-     *
-     * 关联 Task 的 taskDefinitionKey 属性
-     */
-    private String taskDefinitionKey;
-
-    /**
-     * 规则类型
-     *
-     * 枚举 {@link BpmTaskAssignRuleTypeEnum}
-     */
-    @TableField("`type`")
-    private Integer type;
-    /**
-     * 规则值数组,一般关联指定表的编号
-     * 根据 type 不同,对应的值是不同的:
-     *
-     * 1. {@link BpmTaskAssignRuleTypeEnum#ROLE} 时:角色编号
-     * 2. {@link BpmTaskAssignRuleTypeEnum#DEPT_MEMBER} 时:部门编号
-     * 3. {@link BpmTaskAssignRuleTypeEnum#DEPT_LEADER} 时:部门编号
-     * 4. {@link BpmTaskAssignRuleTypeEnum#USER} 时:用户编号
-     * 5. {@link BpmTaskAssignRuleTypeEnum#USER_GROUP} 时:用户组编号
-     * 6. {@link BpmTaskAssignRuleTypeEnum#SCRIPT} 时:脚本编号,目前通过 {@link BpmTaskRuleScriptEnum#getId()} 标识
-     */
-    @TableField(typeHandler = JsonLongSetTypeHandler.class)
-    private Set<Long> options;
-
-}

+ 0 - 5
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmTaskMessageRuleDO.java

@@ -1,5 +0,0 @@
-package cn.iocoder.yudao.module.bpm.dal.dataobject.definition;
-
-// TODO 芋艿:先埋个坑。任务消息的配置规则。说白了,就是不同的
-public class BpmTaskMessageRuleDO {
-}

+ 1 - 3
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmUserGroupDO.java

@@ -11,14 +11,12 @@ import lombok.*;
 import java.util.Set;
 
 /**
- * Bpm 用户组
+ * BPM 用户组
  *
  * @author 芋道源码
  */
 @TableName(value = "bpm_user_group", autoResultMap = true)
 @Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
 @Builder
 @NoArgsConstructor
 @AllArgsConstructor

+ 9 - 10
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/oa/BpmOALeaveDO.java

@@ -1,10 +1,12 @@
 package cn.iocoder.yudao.module.bpm.dal.dataobject.oa;
 
-import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.*;
+
 import java.time.LocalDateTime;
-import com.baomidou.mybatisplus.annotation.*;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
 
 /**
  * OA 请假申请 DO
@@ -16,8 +18,6 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  */
 @TableName("bpm_oa_leave")
 @Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
 @Builder
 @NoArgsConstructor
 @AllArgsConstructor
@@ -37,7 +37,6 @@ public class BpmOALeaveDO extends BaseDO {
     /**
      * 请假类型
      */
-    @TableField("`type`")
     private String type;
     /**
      * 原因
@@ -56,12 +55,12 @@ public class BpmOALeaveDO extends BaseDO {
      */
     private Long day;
     /**
-     * 请假的结果
+     * 审批结果
      *
-     * 枚举 {@link BpmProcessInstanceResultEnum}
-     * 考虑到简单,所以直接复用了 BpmProcessInstanceResultEnum 枚举,也可以自己定义一个枚举哈
+     * 枚举 {@link BpmTaskStatusEnum}
+     * 考虑到简单,所以直接复用了 BpmProcessInstanceStatusEnum 枚举,也可以自己定义一个枚举哈
      */
-    private Integer result;
+    private Integer status;
 
     /**
      * 对应的流程编号

+ 0 - 105
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmActivityDO.java

@@ -1,105 +0,0 @@
-package cn.iocoder.yudao.module.bpm.dal.dataobject.task;
-
-import com.fasterxml.jackson.annotation.JsonFormat;
-import lombok.*;
-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;
-import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT;
-
-/**
- * 任务流程关联表
- *
- * @author kemengkai
- * @create 2022-05-09 10:33
- */
-@Data
-@AllArgsConstructor
-@NoArgsConstructor
-public class BpmActivityDO {
-
-    /**
-     * 任务流程关联id
-     */
-    private String id;
-
-    /**
-     * 审批结果
-     */
-    private Integer rev;
-
-    /**
-     * 任务流程部署id
-     */
-    private String procDefId;
-
-    /**
-     * 任务流程id
-     */
-    private String processInstanceId;
-
-    /**
-     * 任务执行id
-     */
-    private String executionId;
-
-    /**
-     * 任务key
-     */
-    private String activityId;
-
-    /**
-     * 任务id
-     */
-    private String taskId;
-
-    /**
-     * 调用流程id
-     */
-    private String callProcInstId;
-
-    /**
-     * 任务名称
-     */
-    private String activityName;
-
-    /**
-     * 任务类型
-     */
-    private String activityType;
-
-    /**
-     * 任务审批人id
-     */
-    private String assignee;
-
-    /**
-     * 任务开始时间
-     */
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
-    private LocalDateTime startTime;
-
-    /**
-     * 任务结束时间
-     */
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
-    private LocalDateTime endTime;
-
-    private Integer transactionOrder;
-
-    private LocalDateTime duration;
-
-    /**
-     * 删除结果
-     */
-    private String deleteReason;
-
-    /**
-     * 租户id
-     */
-    private String tenantId;
-}

+ 0 - 90
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmProcessInstanceExtDO.java

@@ -1,90 +0,0 @@
-package cn.iocoder.yudao.module.bpm.dal.dataobject.task;
-
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
-import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
-import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
-
-import java.time.LocalDateTime;
-import java.util.Map;
-
-/**
- * Bpm 流程实例的拓展表
- * 主要解决 Activiti ProcessInstance 和 HistoricProcessInstance 不支持拓展字段,所以新建拓展表
- *
- * @author 芋道源码
- */
-@TableName(value = "bpm_process_instance_ext", autoResultMap = true)
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class BpmProcessInstanceExtDO extends BaseDO {
-
-    /**
-     * 编号,自增
-     */
-    @TableId
-    private Long id;
-    /**
-     * 发起流程的用户编号
-     *
-     * 冗余 HistoricProcessInstance 的 startUserId 属性
-     */
-    private Long startUserId;
-    /**
-     * 流程实例的名字
-     *
-     * 冗余 ProcessInstance 的 name 属性,用于筛选
-     */
-    private String name;
-    /**
-     * 流程实例的编号
-     *
-     * 关联 ProcessInstance 的 id 属性
-     */
-    private String processInstanceId;
-    /**
-     * 流程定义的编号
-     *
-     * 关联 ProcessDefinition 的 id 属性
-     */
-    private String processDefinitionId;
-    /**
-     * 流程分类
-     *
-     * 冗余 ProcessDefinition 的 category 属性
-     * 数据字典 bpm_model_category
-     */
-    private String category;
-    /**
-     * 流程实例的状态
-     *
-     * 枚举 {@link BpmProcessInstanceStatusEnum}
-     */
-    private Integer status;
-    /**
-     * 流程实例的结果
-     *
-     * 枚举 {@link BpmProcessInstanceResultEnum}
-     */
-    private Integer result;
-    /**
-     * 结束时间
-     *
-     * 冗余 HistoricProcessInstance 的 endTime 属性
-     */
-    private LocalDateTime endTime;
-
-    /**
-     * 提交的表单值
-     */
-    @TableField(typeHandler = JacksonTypeHandler.class)
-    private Map<String, Object> formVariables;
-
-}

+ 0 - 85
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmTaskExtDO.java

@@ -1,85 +0,0 @@
-package cn.iocoder.yudao.module.bpm.dal.dataobject.task;
-
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
-import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
-
-import java.time.LocalDateTime;
-
-/**
- * Bpm 流程任务的拓展表
- * 主要解决 Flowable Task 和 HistoricTaskInstance 不支持拓展字段,所以新建拓展表
- *
- * @author 芋道源码
- */
-@TableName(value = "bpm_task_ext", autoResultMap = true)
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class BpmTaskExtDO extends BaseDO {
-
-    /**
-     * 编号,自增
-     */
-    @TableId
-    private Long id;
-
-    /**
-     * 任务的审批人
-     *
-     * 冗余 Task 的 assignee 属性
-     */
-    private Long assigneeUserId;
-    /**
-     * 任务的名字
-     *
-     * 冗余 Task 的 name 属性,为了筛选
-     */
-    private String name;
-    /**
-     * 任务的编号
-     *
-     * 关联 Task 的 id 属性
-     */
-    private String taskId;
-//    /**
-//     * 任务的标识
-//     *
-//     * 关联 {@link Task#getTaskDefinitionKey()}
-//     */
-//    private String definitionKey;
-    /**
-     * 任务的结果
-     *
-     * 枚举 {@link BpmProcessInstanceResultEnum}
-     */
-    private Integer result;
-    /**
-     * 审批建议
-     */
-    private String reason;
-    /**
-     * 任务的结束时间
-     *
-     * 冗余 HistoricTaskInstance 的 endTime  属性
-     */
-    private LocalDateTime endTime;
-
-    /**
-     * 流程实例的编号
-     *
-     * 关联 ProcessInstance 的 id 属性
-     */
-    private String processInstanceId;
-    /**
-     * 流程定义的编号
-     *
-     * 关联 ProcessDefinition 的 id 属性
-     */
-    private String processDefinitionId;
-
-}

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

@@ -1,22 +0,0 @@
-package cn.iocoder.yudao.module.bpm.dal.mysql.definition;
-
-import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
-import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
-import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
-import org.apache.ibatis.annotations.Mapper;
-
-import java.util.Collection;
-import java.util.List;
-
-@Mapper
-public interface BpmProcessDefinitionExtMapper extends BaseMapperX<BpmProcessDefinitionExtDO> {
-
-    default List<BpmProcessDefinitionExtDO> selectListByProcessDefinitionIds(Collection<String> processDefinitionIds) {
-        return selectList("process_definition_id", processDefinitionIds);
-    }
-
-    default BpmProcessDefinitionExtDO selectByProcessDefinitionId(String processDefinitionId) {
-        return selectOne("process_definition_id", processDefinitionId);
-    }
-
-}

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

@@ -1,37 +0,0 @@
-package cn.iocoder.yudao.module.bpm.dal.mysql.definition;
-
-import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
-import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
-import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
-import org.apache.ibatis.annotations.Mapper;
-import org.springframework.lang.Nullable;
-
-import java.util.List;
-
-@Mapper
-public interface BpmTaskAssignRuleMapper extends BaseMapperX<BpmTaskAssignRuleDO> {
-
-    default List<BpmTaskAssignRuleDO> selectListByProcessDefinitionId(String processDefinitionId,
-                                                                      @Nullable String taskDefinitionKey) {
-        return selectList(new QueryWrapperX<BpmTaskAssignRuleDO>()
-                .eq("process_definition_id", processDefinitionId)
-                .eqIfPresent("task_definition_key", taskDefinitionKey));
-    }
-
-    default List<BpmTaskAssignRuleDO> selectListByModelId(String modelId) {
-        return selectList(new QueryWrapperX<BpmTaskAssignRuleDO>()
-                .eq("model_id", modelId)
-                .eq("process_definition_id", BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL));
-    }
-
-    default BpmTaskAssignRuleDO selectListByModelIdAndTaskDefinitionKey(String modelId,
-                                                                        String taskDefinitionKey) {
-        return selectOne(new QueryWrapperX<BpmTaskAssignRuleDO>()
-                .eq("model_id", modelId)
-                .eq("process_definition_id", BpmTaskAssignRuleDO.PROCESS_DEFINITION_ID_NULL)
-                .eq("task_definition_key", taskDefinitionKey));
-    }
-
-
-
-}

+ 1 - 1
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/oa/BpmOALeaveMapper.java

@@ -19,7 +19,7 @@ public interface BpmOALeaveMapper extends BaseMapperX<BpmOALeaveDO> {
     default PageResult<BpmOALeaveDO> selectPage(Long userId, BpmOALeavePageReqVO reqVO) {
         return selectPage(reqVO, new LambdaQueryWrapperX<BpmOALeaveDO>()
                 .eqIfPresent(BpmOALeaveDO::getUserId, userId)
-                .eqIfPresent(BpmOALeaveDO::getResult, reqVO.getResult())
+                .eqIfPresent(BpmOALeaveDO::getStatus, reqVO.getStatus())
                 .eqIfPresent(BpmOALeaveDO::getType, reqVO.getType())
                 .likeIfPresent(BpmOALeaveDO::getReason, reqVO.getReason())
                 .betweenIfPresent(BpmOALeaveDO::getCreateTime, reqVO.getCreateTime())

+ 0 - 34
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmProcessInstanceExtMapper.java

@@ -1,34 +0,0 @@
-package cn.iocoder.yudao.module.bpm.dal.mysql.task;
-
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
-import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
-import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceMyPageReqVO;
-import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
-import org.apache.ibatis.annotations.Mapper;
-
-@Mapper
-public interface BpmProcessInstanceExtMapper extends BaseMapperX<BpmProcessInstanceExtDO> {
-
-    default PageResult<BpmProcessInstanceExtDO> selectPage(Long userId, BpmProcessInstanceMyPageReqVO reqVO) {
-        return selectPage(reqVO, new LambdaQueryWrapperX<BpmProcessInstanceExtDO>()
-                .eqIfPresent(BpmProcessInstanceExtDO::getStartUserId, userId)
-                .likeIfPresent(BpmProcessInstanceExtDO::getName, reqVO.getName())
-                .eqIfPresent(BpmProcessInstanceExtDO::getProcessDefinitionId, reqVO.getProcessDefinitionId())
-                .eqIfPresent(BpmProcessInstanceExtDO::getCategory, reqVO.getCategory())
-                .eqIfPresent(BpmProcessInstanceExtDO::getStatus, reqVO.getStatus())
-                .eqIfPresent(BpmProcessInstanceExtDO::getResult, reqVO.getResult())
-                .betweenIfPresent(BpmProcessInstanceExtDO::getCreateTime, reqVO.getCreateTime())
-                .orderByDesc(BpmProcessInstanceExtDO::getId));
-    }
-
-    default BpmProcessInstanceExtDO selectByProcessInstanceId(String processInstanceId) {
-        return selectOne(BpmProcessInstanceExtDO::getProcessInstanceId, processInstanceId);
-    }
-
-    default void updateByProcessInstanceId(BpmProcessInstanceExtDO updateObj) {
-        update(updateObj, new LambdaQueryWrapperX<BpmProcessInstanceExtDO>()
-                .eq(BpmProcessInstanceExtDO::getProcessInstanceId, updateObj.getProcessInstanceId()));
-    }
-
-}

+ 0 - 26
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmTaskExtMapper.java

@@ -1,26 +0,0 @@
-package cn.iocoder.yudao.module.bpm.dal.mysql.task;
-
-import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
-import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import org.apache.ibatis.annotations.Mapper;
-
-import java.util.Collection;
-import java.util.List;
-
-@Mapper
-public interface BpmTaskExtMapper extends BaseMapperX<BpmTaskExtDO> {
-
-    default void updateByTaskId(BpmTaskExtDO entity) {
-        update(entity, new LambdaQueryWrapper<BpmTaskExtDO>().eq(BpmTaskExtDO::getTaskId, entity.getTaskId()));
-    }
-
-    default List<BpmTaskExtDO> selectListByTaskIds(Collection<String> taskIds) {
-        return selectList(BpmTaskExtDO::getTaskId, taskIds);
-    }
-
-    default BpmTaskExtDO selectByTaskId(String taskId) {
-        return selectOne(BpmTaskExtDO::getTaskId, taskId);
-    }
-
-}

+ 0 - 19
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/config/BpmCommonConfiguration.java

@@ -1,19 +0,0 @@
-package cn.iocoder.yudao.module.bpm.framework.bpm.config;
-
-import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEventPublisher;
-import org.springframework.context.ApplicationEventPublisher;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-/**
- * BPM 通用的 Configuration 配置类,提供给 Activiti 和 Flowable
- */
-@Configuration(proxyBeanMethods = false)
-public class BpmCommonConfiguration {
-
-    @Bean
-    public BpmProcessInstanceResultEventPublisher processInstanceResultEventPublisher(ApplicationEventPublisher publisher) {
-        return new BpmProcessInstanceResultEventPublisher(publisher);
-    }
-
-}

+ 0 - 28
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/config/BpmSecurityConfiguration.java

@@ -1,28 +0,0 @@
-package cn.iocoder.yudao.module.bpm.framework.bpm.config;
-
-import cn.iocoder.yudao.framework.security.config.AuthorizeRequestsCustomizer;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
-
-/**
- * @author kemengkai
- * @create 2022-05-07 08:15
- */
-@Configuration("bpmSecurityConfiguration")
-public class BpmSecurityConfiguration {
-
-    @Bean("bpmAuthorizeRequestsCustomizer")
-    public AuthorizeRequestsCustomizer authorizeRequestsCustomizer() {
-        return new AuthorizeRequestsCustomizer() {
-
-            @Override
-            public void customize(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) {
-                // 任务回退接口
-                registry.antMatchers(buildAdminApi("/bpm/task/back")).permitAll();
-            }
-
-        };
-    }
-}

+ 0 - 44
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/event/BpmProcessInstanceResultEvent.java

@@ -1,44 +0,0 @@
-package cn.iocoder.yudao.module.bpm.framework.bpm.core.event;
-
-import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
-import lombok.Data;
-import org.springframework.context.ApplicationEvent;
-
-import javax.validation.constraints.NotNull;
-
-/**
- * 流程实例的结果发生变化的 Event
- * 定位:由于额外增加了 {@link BpmProcessInstanceExtDO#getResult()} 结果,所以增加该事件
- *
- * @author 芋道源码
- */
-@SuppressWarnings("ALL")
-@Data
-public class BpmProcessInstanceResultEvent extends ApplicationEvent {
-
-    /**
-     * 流程实例的编号
-     */
-    @NotNull(message = "流程实例的编号不能为空")
-    private String id;
-    /**
-     * 流程实例的 key
-     */
-    @NotNull(message = "流程实例的 key 不能为空")
-    private String processDefinitionKey;
-    /**
-     * 流程实例的结果
-     */
-    @NotNull(message = "流程实例的结果不能为空")
-    private Integer result;
-    /**
-     * 流程实例对应的业务标识
-     * 例如说,请假
-     */
-    private String businessKey;
-
-    public BpmProcessInstanceResultEvent(Object source) {
-        super(source);
-    }
-
-}

+ 0 - 34
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/event/BpmProcessInstanceResultEventListener.java

@@ -1,34 +0,0 @@
-package cn.iocoder.yudao.module.bpm.framework.bpm.core.event;
-
-import cn.hutool.core.util.StrUtil;
-import org.springframework.context.ApplicationListener;
-
-/**
- * {@link BpmProcessInstanceResultEvent} 的监听器
- *
- * @author 芋道源码
- */
-public abstract class BpmProcessInstanceResultEventListener
-        implements ApplicationListener<BpmProcessInstanceResultEvent> {
-
-    @Override
-    public final void onApplicationEvent(BpmProcessInstanceResultEvent event) {
-        if (!StrUtil.equals(event.getProcessDefinitionKey(), getProcessDefinitionKey())) {
-            return;
-        }
-        onEvent(event);
-    }
-
-    /**
-     * @return 返回监听的流程定义 Key
-     */
-    protected abstract String getProcessDefinitionKey();
-
-    /**
-     * 处理事件
-     *
-     * @param event 事件
-     */
-    protected abstract void onEvent(BpmProcessInstanceResultEvent event);
-
-}

+ 0 - 24
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/event/BpmProcessInstanceResultEventPublisher.java

@@ -1,24 +0,0 @@
-package cn.iocoder.yudao.module.bpm.framework.bpm.core.event;
-
-import lombok.AllArgsConstructor;
-import org.springframework.context.ApplicationEventPublisher;
-import org.springframework.validation.annotation.Validated;
-
-import javax.validation.Valid;
-
-/**
- * {@link BpmProcessInstanceResultEvent} 的生产者
- *
- * @author 芋道源码
- */
-@AllArgsConstructor
-@Validated
-public class BpmProcessInstanceResultEventPublisher {
-
-    private final ApplicationEventPublisher publisher;
-
-    public void sendProcessInstanceResultEvent(@Valid BpmProcessInstanceResultEvent event) {
-        publisher.publishEvent(event);
-    }
-
-}

+ 0 - 6
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/event/package-info.java

@@ -1,6 +0,0 @@
-/**
- * 自定义 Event 实现,提供方便业务接入的 Listener!
- *
- * @author 芋道源码
- */
-package cn.iocoder.yudao.module.bpm.framework.bpm.core.event;

+ 0 - 4
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/core/package-info.java

@@ -1,4 +0,0 @@
-/**
- * 占位
- */
-package cn.iocoder.yudao.module.bpm.framework.bpm.core;

+ 0 - 6
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/package-info.java

@@ -1,6 +0,0 @@
-/**
- * 提供给 Activiti 和 Flowable 的通用封装
- *
- * @author 芋道源码
- */
-package cn.iocoder.yudao.module.bpm.framework.bpm;

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

@@ -2,13 +2,22 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.config;
 
 import cn.hutool.core.collection.ListUtil;
 import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.BpmActivityBehaviorFactory;
-import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService;
+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.BpmProcessInstanceEventPublisher;
+import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
 import org.flowable.common.engine.api.delegate.event.FlowableEventListener;
 import org.flowable.spring.SpringProcessEngineConfiguration;
 import org.flowable.spring.boot.EngineConfigurationConfigurer;
 import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.core.task.AsyncListenableTaskExecutor;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.util.List;
 
 /**
  * BPM 模块的 Flowable 配置类
@@ -18,6 +27,26 @@ import org.springframework.context.annotation.Configuration;
 @Configuration(proxyBeanMethods = false)
 public class BpmFlowableConfiguration {
 
+    /**
+     * 参考 {@link org.flowable.spring.boot.FlowableJobConfiguration} 类,创建对应的 AsyncListenableTaskExecutor Bean
+     *
+     * 如果不创建,会导致项目启动时,Flowable 报错的问题
+     */
+    @Bean(name = "applicationTaskExecutor")
+    @ConditionalOnMissingBean(name = "applicationTaskExecutor")
+    public AsyncListenableTaskExecutor taskExecutor() {
+        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        executor.setCorePoolSize(8);
+        executor.setMaxPoolSize(8);
+        executor.setQueueCapacity(100);
+        executor.setThreadNamePrefix("flowable-task-Executor-");
+        executor.setAwaitTerminationSeconds(30);
+        executor.setWaitForTasksToCompleteOnShutdown(true);
+        executor.setAllowCoreThreadTimeOut(true);
+        executor.initialize();
+        return executor;
+    }
+
     /**
      * BPM 模块的 ProcessEngineConfigurationConfigurer 实现类:
      *
@@ -36,11 +65,27 @@ public class BpmFlowableConfiguration {
         };
     }
 
+    // =========== 审批人相关的 Bean ==========
+
     @Bean
-    public BpmActivityBehaviorFactory bpmActivityBehaviorFactory(BpmTaskAssignRuleService taskRuleService) {
+    public BpmActivityBehaviorFactory bpmActivityBehaviorFactory(BpmTaskCandidateInvoker bpmTaskCandidateInvoker) {
         BpmActivityBehaviorFactory bpmActivityBehaviorFactory = new BpmActivityBehaviorFactory();
-        bpmActivityBehaviorFactory.setBpmTaskRuleService(taskRuleService);
+        bpmActivityBehaviorFactory.setTaskCandidateInvoker(bpmTaskCandidateInvoker);
         return bpmActivityBehaviorFactory;
     }
 
-}
+    @Bean
+    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") // adminUserApi 可以注入成功
+    public BpmTaskCandidateInvoker bpmTaskCandidateInvoker(List<BpmTaskCandidateStrategy> strategyList,
+                                                           AdminUserApi adminUserApi) {
+        return new BpmTaskCandidateInvoker(strategyList, adminUserApi);
+    }
+
+    // =========== 自己拓展的 Bean ==========
+
+    @Bean
+    public BpmProcessInstanceEventPublisher processInstanceEventPublisher(ApplicationEventPublisher publisher) {
+        return new BpmProcessInstanceEventPublisher(publisher);
+    }
+
+}

+ 14 - 14
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmActivityBehaviorFactory.java

@@ -1,14 +1,12 @@
 package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior;
 
-import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
+import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateInvoker;
 import lombok.Setter;
-import lombok.ToString;
 import org.flowable.bpmn.model.Activity;
 import org.flowable.bpmn.model.UserTask;
 import org.flowable.engine.impl.bpmn.behavior.AbstractBpmnActivityBehavior;
 import org.flowable.engine.impl.bpmn.behavior.ParallelMultiInstanceBehavior;
+import org.flowable.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior;
 import org.flowable.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
 import org.flowable.engine.impl.bpmn.parser.factory.DefaultActivityBehaviorFactory;
 
@@ -18,27 +16,29 @@ import org.flowable.engine.impl.bpmn.parser.factory.DefaultActivityBehaviorFacto
  *
  * @author 芋道源码
  */
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
+@Setter
 public class BpmActivityBehaviorFactory extends DefaultActivityBehaviorFactory {
 
-    @Setter
-    private BpmTaskAssignRuleService bpmTaskRuleService;
+    private BpmTaskCandidateInvoker taskCandidateInvoker;
 
     @Override
     public UserTaskActivityBehavior createUserTaskActivityBehavior(UserTask userTask) {
         return new BpmUserTaskActivityBehavior(userTask)
-                .setBpmTaskRuleService(bpmTaskRuleService);
+                .setTaskCandidateInvoker(taskCandidateInvoker);
     }
 
     @Override
     public ParallelMultiInstanceBehavior createParallelMultiInstanceBehavior(Activity activity,
-                                                                             AbstractBpmnActivityBehavior innerActivityBehavior) {
-        return new BpmParallelMultiInstanceBehavior(activity, innerActivityBehavior)
-                .setBpmTaskRuleService(bpmTaskRuleService);
+                                                                             AbstractBpmnActivityBehavior behavior) {
+        return new BpmParallelMultiInstanceBehavior(activity, behavior)
+                .setTaskCandidateInvoker(taskCandidateInvoker);
     }
 
-    // TODO @ke:SequentialMultiInstanceBehavior 这个抽空也可以看看
+    @Override
+    public SequentialMultiInstanceBehavior createSequentialMultiInstanceBehavior(Activity activity,
+                                                                                 AbstractBpmnActivityBehavior behavior) {
+        return new BpmSequentialMultiInstanceBehavior(activity, behavior)
+                .setTaskCandidateInvoker(taskCandidateInvoker);
+    }
 
 }

+ 8 - 10
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmParallelMultiInstanceBehavior.java

@@ -1,9 +1,8 @@
 package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior;
 
-import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils;
-import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService;
+import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
+import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateInvoker;
 import lombok.Setter;
-import lombok.extern.slf4j.Slf4j;
 import org.flowable.bpmn.model.Activity;
 import org.flowable.engine.delegate.DelegateExecution;
 import org.flowable.engine.impl.bpmn.behavior.AbstractBpmnActivityBehavior;
@@ -17,13 +16,12 @@ import java.util.Set;
  * 第二步,将【多个】任务候选人们,设置到 DelegateExecution 的 collectionVariable 变量中,以便 BpmUserTaskActivityBehavior 使用它
  *
  * @author kemengkai
- * @date 2022-04-21 16:57
+ * @since 2022-04-21 16:57
  */
-@Slf4j
+@Setter
 public class BpmParallelMultiInstanceBehavior extends ParallelMultiInstanceBehavior {
 
-    @Setter
-    private BpmTaskAssignRuleService bpmTaskRuleService;
+    private BpmTaskCandidateInvoker taskCandidateInvoker;
 
     public BpmParallelMultiInstanceBehavior(Activity activity,
                                             AbstractBpmnActivityBehavior innerActivityBehavior) {
@@ -45,12 +43,12 @@ public class BpmParallelMultiInstanceBehavior extends ParallelMultiInstanceBehav
         // 第一步,设置 collectionVariable 和 CollectionVariable
         // 从  execution.getVariable() 读取所有任务处理人的 key
         super.collectionExpression = null; // collectionExpression 和 collectionVariable 是互斥的
-        super.collectionVariable = FlowableUtils.formatCollectionVariable(execution.getCurrentActivityId());
+        super.collectionVariable = FlowableUtils.formatExecutionCollectionVariable(execution.getCurrentActivityId());
         // 从 execution.getVariable() 读取当前所有任务处理的人的 key
-        super.collectionElementVariable = FlowableUtils.formatCollectionElementVariable(execution.getCurrentActivityId());
+        super.collectionElementVariable = FlowableUtils.formatExecutionCollectionElementVariable(execution.getCurrentActivityId());
 
         // 第二步,获取任务的所有处理人
-        Set<Long> assigneeUserIds = bpmTaskRuleService.calculateTaskCandidateUsers(execution);
+        Set<Long> assigneeUserIds = taskCandidateInvoker.calculateUsers(execution);
         execution.setVariable(super.collectionVariable, assigneeUserIds);
         return assigneeUserIds.size();
     }

+ 5 - 4
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmUserTaskActivityBehavior.java

@@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.lang.Assert;
 import cn.hutool.core.util.RandomUtil;
-import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService;
+import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateInvoker;
 import lombok.Setter;
 import lombok.extern.slf4j.Slf4j;
 import org.flowable.bpmn.model.UserTask;
@@ -29,7 +29,7 @@ import java.util.Set;
 public class BpmUserTaskActivityBehavior extends UserTaskActivityBehavior {
 
     @Setter
-    private BpmTaskAssignRuleService bpmTaskRuleService;
+    private BpmTaskCandidateInvoker taskCandidateInvoker;
 
     public BpmUserTaskActivityBehavior(UserTask userTask) {
         super(userTask);
@@ -47,14 +47,15 @@ public class BpmUserTaskActivityBehavior extends UserTaskActivityBehavior {
     }
 
     private Long calculateTaskCandidateUsers(DelegateExecution execution) {
-        // 情况一,如果是多实例的任务,例如说会签、或签等情况,则从 Variable 中获取。它的任务处理人在 BpmParallelMultiInstanceBehavior 中已经被分配了
+        // 情况一,如果是多实例的任务,例如说会签、或签等情况,则从 Variable 中获取。
+        // 顺序审批可见 BpmSequentialMultiInstanceBehavior,并发审批可见 BpmSequentialMultiInstanceBehavior
         if (super.multiInstanceActivityBehavior != null) {
             return execution.getVariable(super.multiInstanceActivityBehavior.getCollectionElementVariable(), Long.class);
         }
 
         // 情况二,如果非多实例的任务,则计算任务处理人
         // 第一步,先计算可处理该任务的处理人们
-        Set<Long> candidateUserIds = bpmTaskRuleService.calculateTaskCandidateUsers(execution);
+        Set<Long> candidateUserIds = taskCandidateInvoker.calculateUsers(execution);
         // 第二步,后随机选择一个任务的处理人
         // 疑问:为什么一定要选择一个任务处理人?
         // 解答:项目对 bpm 的任务是责任到人,所以每个任务有且仅有一个处理人。

+ 0 - 34
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/BpmTaskAssignScript.java

@@ -1,34 +0,0 @@
-package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script;
-
-import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum;
-import org.flowable.engine.delegate.DelegateExecution;
-
-import java.util.Set;
-
-/**
- * Bpm 任务分配的自定义 Script 脚本
- * 使用场景:
- * 1. 设置审批人为发起人
- * 2. 设置审批人为发起人的 Leader
- * 3. 甚至审批人为发起人的 Leader 的 Leader
- *
- * @author 芋道源码
- */
-public interface BpmTaskAssignScript {
-
-    /**
-     * 基于执行任务,获得任务的候选用户们
-     *
-     * @param execution 执行任务
-     * @return 候选人用户的编号数组
-     */
-    Set<Long> calculateTaskCandidateUsers(DelegateExecution execution);
-
-    /**
-     * 获得枚举值
-     *
-     * @return 枚举值
-     */
-    BpmTaskRuleScriptEnum getEnum();
-}
-

+ 0 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderAbstractScript.java


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