mirror of
				https://github.com/YunaiV/ruoyi-vue-pro.git
				synced 2025-10-31 10:37:41 +08:00 
			
		
		
		
	【功能新增】工作流:审批类型,区分人工审批、自动通过、自动拒绝
This commit is contained in:
		| @ -14,7 +14,7 @@ import java.util.Arrays; | |||||||
|  */ |  */ | ||||||
| @Getter | @Getter | ||||||
| @AllArgsConstructor | @AllArgsConstructor | ||||||
| public enum BpmApproveMethodEnum implements IntArrayValuable { | public enum BpmUserTaskApproveMethodEnum implements IntArrayValuable { | ||||||
| 
 | 
 | ||||||
|     RANDOM(1, "随机挑选一人审批"), |     RANDOM(1, "随机挑选一人审批"), | ||||||
|     RATIO(2, "多人会签(按通过比例)"), // 会签(按通过比例) |     RATIO(2, "多人会签(按通过比例)"), // 会签(按通过比例) | ||||||
| @ -31,9 +31,9 @@ public enum BpmApproveMethodEnum implements IntArrayValuable { | |||||||
|      */ |      */ | ||||||
|     private final String name; |     private final String name; | ||||||
| 
 | 
 | ||||||
|     public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BpmApproveMethodEnum::getMethod).toArray(); |     public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BpmUserTaskApproveMethodEnum::getMethod).toArray(); | ||||||
| 
 | 
 | ||||||
|     public static BpmApproveMethodEnum valueOf(Integer method) { |     public static BpmUserTaskApproveMethodEnum valueOf(Integer method) { | ||||||
|         return ArrayUtil.firstMatch(item -> item.getMethod().equals(method), values()); |         return ArrayUtil.firstMatch(item -> item.getMethod().equals(method), values()); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -0,0 +1,31 @@ | |||||||
|  | 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; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 用户任务的审批类型枚举 | ||||||
|  |  * | ||||||
|  |  * @author 芋道源码 | ||||||
|  |  */ | ||||||
|  | @Getter | ||||||
|  | @AllArgsConstructor | ||||||
|  | public enum BpmUserTaskApproveTypeEnum implements IntArrayValuable { | ||||||
|  |  | ||||||
|  |     USER(1), // 人工审批 | ||||||
|  |     AUTO_APPROVE(2), // 自动通过 | ||||||
|  |     AUTO_REJECT(3); // 自动拒绝 | ||||||
|  |  | ||||||
|  |     public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BpmUserTaskApproveTypeEnum::getType).toArray(); | ||||||
|  |  | ||||||
|  |     private final Integer type; | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public int[] array() { | ||||||
|  |         return ARRAYS; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @ -4,6 +4,8 @@ import cn.iocoder.yudao.framework.common.core.IntArrayValuable; | |||||||
| import lombok.Getter; | import lombok.Getter; | ||||||
| import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||||
|  |  | ||||||
|  | import java.util.Arrays; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * BPM 用户任务的审批人为空时,处理类型枚举 |  * BPM 用户任务的审批人为空时,处理类型枚举 | ||||||
|  * |  * | ||||||
| @ -19,11 +21,13 @@ public enum BpmUserTaskAssignEmptyHandlerTypeEnum implements IntArrayValuable { | |||||||
|     ASSIGN_ADMIN(4), // 转交给流程管理员 |     ASSIGN_ADMIN(4), // 转交给流程管理员 | ||||||
|     ; |     ; | ||||||
|  |  | ||||||
|  |     public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BpmUserTaskAssignEmptyHandlerTypeEnum::getType).toArray(); | ||||||
|  |  | ||||||
|     private final Integer type; |     private final Integer type; | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public int[] array() { |     public int[] array() { | ||||||
|         return new int[0]; |         return ARRAYS; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -4,6 +4,8 @@ import cn.iocoder.yudao.framework.common.core.IntArrayValuable; | |||||||
| import lombok.Getter; | import lombok.Getter; | ||||||
| import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||||
|  |  | ||||||
|  | import java.util.Arrays; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * BPM 用户任务的审批人与发起人相同时,处理类型枚举 |  * BPM 用户任务的审批人与发起人相同时,处理类型枚举 | ||||||
|  * |  * | ||||||
| @ -17,11 +19,13 @@ public enum BpmUserTaskAssignStartUserHandlerTypeEnum implements IntArrayValuabl | |||||||
|     SKIP(2), // 自动跳过【参考飞书】:1)如果当前节点还有其他审批人,则交由其他审批人进行审批;2)如果当前节点没有其他审批人,则该节点自动通过 |     SKIP(2), // 自动跳过【参考飞书】:1)如果当前节点还有其他审批人,则交由其他审批人进行审批;2)如果当前节点没有其他审批人,则该节点自动通过 | ||||||
|     TRANSFER_DEPT_LEADER(3); // 转交给部门负责人审批【参考飞书】:若部门负责人为空,则自动通过 |     TRANSFER_DEPT_LEADER(3); // 转交给部门负责人审批【参考飞书】:若部门负责人为空,则自动通过 | ||||||
|  |  | ||||||
|  |     public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BpmUserTaskAssignStartUserHandlerTypeEnum::getType).toArray(); | ||||||
|  |  | ||||||
|     private final Integer type; |     private final Integer type; | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public int[] array() { |     public int[] array() { | ||||||
|         return new int[0]; |         return ARRAYS; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -30,6 +30,8 @@ public enum BpmReasonEnum { | |||||||
|     ASSIGN_START_USER_TRANSFER_DEPT_LEADER("审批人与提交人为同一人时,转交给部门负责人审批"), |     ASSIGN_START_USER_TRANSFER_DEPT_LEADER("审批人与提交人为同一人时,转交给部门负责人审批"), | ||||||
|     ASSIGN_EMPTY_APPROVE("审批人为空,自动通过"), |     ASSIGN_EMPTY_APPROVE("审批人为空,自动通过"), | ||||||
|     ASSIGN_EMPTY_REJECT("审批人为空,自动不通过"), |     ASSIGN_EMPTY_REJECT("审批人为空,自动不通过"), | ||||||
|  |     APPROVE_TYPE_AUTO_APPROVE("非人工审核,自动通过"), | ||||||
|  |     APPROVE_TYPE_AUTO_REJECT("非人工审核,自动不通过"), | ||||||
|     ; |     ; | ||||||
|  |  | ||||||
|     private final String reason; |     private final String reason; | ||||||
|  | |||||||
| @ -59,8 +59,12 @@ public class BpmSimpleModelNodeVO { | |||||||
|     @Schema(description = "候选人参数") |     @Schema(description = "候选人参数") | ||||||
|     private String candidateParam; // 用于审批,抄送节点 |     private String candidateParam; // 用于审批,抄送节点 | ||||||
|  |  | ||||||
|  |     @Schema(description = "审批节点类型", example = "1") | ||||||
|  |     @InEnum(BpmUserTaskApproveTypeEnum.class) | ||||||
|  |     private Integer approveType; // 用于审批节点 | ||||||
|  |  | ||||||
|     @Schema(description = "多人审批方式", example = "1") |     @Schema(description = "多人审批方式", example = "1") | ||||||
|     @InEnum(BpmApproveMethodEnum.class) |     @InEnum(BpmUserTaskApproveMethodEnum.class) | ||||||
|     private Integer approveMethod; // 用于审批节点 |     private Integer approveMethod; // 用于审批节点 | ||||||
|  |  | ||||||
|     @Schema(description = "通过比例", example = "100") |     @Schema(description = "通过比例", example = "100") | ||||||
| @ -155,8 +159,6 @@ public class BpmSimpleModelNodeVO { | |||||||
|         private Boolean enable; |         private Boolean enable; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Map<String, Integer> formPermissions; 表单权限;仅发起、审批、抄送节点会使用 |  | ||||||
|     // TODO @芋艿:⑥ 没有人的策略? |  | ||||||
|     // TODO @芋艿:条件;建议可以固化的一些选项;然后有个表达式兜底;要支持 |     // TODO @芋艿:条件;建议可以固化的一些选项;然后有个表达式兜底;要支持 | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -2,8 +2,8 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior; | |||||||
|  |  | ||||||
| import cn.hutool.core.collection.CollUtil; | import cn.hutool.core.collection.CollUtil; | ||||||
| import cn.iocoder.yudao.framework.common.util.collection.SetUtils; | import cn.iocoder.yudao.framework.common.util.collection.SetUtils; | ||||||
| import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils; |  | ||||||
| import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateInvoker; | import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateInvoker; | ||||||
|  | import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils; | ||||||
| import lombok.Setter; | import lombok.Setter; | ||||||
| import org.flowable.bpmn.model.Activity; | import org.flowable.bpmn.model.Activity; | ||||||
| import org.flowable.engine.delegate.DelegateExecution; | import org.flowable.engine.delegate.DelegateExecution; | ||||||
| @ -52,7 +52,9 @@ public class BpmParallelMultiInstanceBehavior extends ParallelMultiInstanceBehav | |||||||
|         // 第二步,获取任务的所有处理人 |         // 第二步,获取任务的所有处理人 | ||||||
|         Set<Long> assigneeUserIds = taskCandidateInvoker.calculateUsers(execution); |         Set<Long> assigneeUserIds = taskCandidateInvoker.calculateUsers(execution); | ||||||
|         if (CollUtil.isEmpty(assigneeUserIds)) { |         if (CollUtil.isEmpty(assigneeUserIds)) { | ||||||
|             // 特殊:如果没有处理人的情况下,至少有一个 null 空元素,保证在 BpmUserTaskActivityBehavior 至少创建出一个 Task 任务,避免自动通过! |             // 特殊:如果没有处理人的情况下,至少有一个 null 空元素,避免自动通过! | ||||||
|  |             // 这样,保证在 BpmUserTaskActivityBehavior 至少创建出一个 Task 任务 | ||||||
|  |             // 用途:1)审批人为空时;2)审批类型为自动通过、自动拒绝时 | ||||||
|             assigneeUserIds = SetUtils.asSet((Long) null); |             assigneeUserIds = SetUtils.asSet((Long) null); | ||||||
|         } |         } | ||||||
|         execution.setVariable(super.collectionVariable, assigneeUserIds); |         execution.setVariable(super.collectionVariable, assigneeUserIds); | ||||||
|  | |||||||
| @ -2,15 +2,14 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior; | |||||||
|  |  | ||||||
| import cn.hutool.core.collection.CollUtil; | import cn.hutool.core.collection.CollUtil; | ||||||
| import cn.iocoder.yudao.framework.common.util.collection.SetUtils; | import cn.iocoder.yudao.framework.common.util.collection.SetUtils; | ||||||
| import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils; |  | ||||||
| import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateInvoker; | import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateInvoker; | ||||||
|  | import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils; | ||||||
| import lombok.Setter; | import lombok.Setter; | ||||||
| import org.flowable.bpmn.model.Activity; | import org.flowable.bpmn.model.Activity; | ||||||
| import org.flowable.engine.delegate.DelegateExecution; | import org.flowable.engine.delegate.DelegateExecution; | ||||||
| import org.flowable.engine.impl.bpmn.behavior.AbstractBpmnActivityBehavior; | import org.flowable.engine.impl.bpmn.behavior.AbstractBpmnActivityBehavior; | ||||||
| import org.flowable.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior; | import org.flowable.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior; | ||||||
|  |  | ||||||
| import java.util.LinkedHashSet; |  | ||||||
| import java.util.Set; | import java.util.Set; | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @ -44,9 +43,11 @@ public class BpmSequentialMultiInstanceBehavior extends SequentialMultiInstanceB | |||||||
|         super.collectionElementVariable = FlowableUtils.formatExecutionCollectionElementVariable(execution.getCurrentActivityId()); |         super.collectionElementVariable = FlowableUtils.formatExecutionCollectionElementVariable(execution.getCurrentActivityId()); | ||||||
|  |  | ||||||
|         // 第二步,获取任务的所有处理人 |         // 第二步,获取任务的所有处理人 | ||||||
|         Set<Long> assigneeUserIds = new LinkedHashSet<>(taskCandidateInvoker.calculateUsers(execution)); // 保证有序!!! |         Set<Long> assigneeUserIds = taskCandidateInvoker.calculateUsers(execution); | ||||||
|         if (CollUtil.isEmpty(assigneeUserIds)) { |         if (CollUtil.isEmpty(assigneeUserIds)) { | ||||||
|             // 特殊:如果没有处理人的情况下,至少有一个 null 空元素,保证在 BpmUserTaskActivityBehavior 至少创建出一个 Task 任务,避免自动通过! |             // 特殊:如果没有处理人的情况下,至少有一个 null 空元素,避免自动通过! | ||||||
|  |             // 这样,保证在 BpmUserTaskActivityBehavior 至少创建出一个 Task 任务 | ||||||
|  |             // 用途:1)审批人为空时;2)审批类型为自动通过、自动拒绝时 | ||||||
|             assigneeUserIds = SetUtils.asSet((Long) null); |             assigneeUserIds = SetUtils.asSet((Long) null); | ||||||
|         } |         } | ||||||
|         execution.setVariable(super.collectionVariable, assigneeUserIds); |         execution.setVariable(super.collectionVariable, assigneeUserIds); | ||||||
|  | |||||||
| @ -6,6 +6,7 @@ import cn.hutool.core.util.RandomUtil; | |||||||
| import cn.hutool.extra.spring.SpringUtil; | import cn.hutool.extra.spring.SpringUtil; | ||||||
| import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskApproveReqVO; | import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskApproveReqVO; | ||||||
| import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRejectReqVO; | import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRejectReqVO; | ||||||
|  | import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskApproveTypeEnum; | ||||||
| import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskAssignEmptyHandlerTypeEnum; | import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskAssignEmptyHandlerTypeEnum; | ||||||
| import cn.iocoder.yudao.module.bpm.enums.task.BpmReasonEnum; | import cn.iocoder.yudao.module.bpm.enums.task.BpmReasonEnum; | ||||||
| import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateInvoker; | import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateInvoker; | ||||||
| @ -56,12 +57,15 @@ public class BpmUserTaskActivityBehavior extends UserTaskActivityBehavior { | |||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         // 特殊:审批人为空,根据配置是否要自动通过、自动拒绝 |         // 特殊:处理需要自动通过、不通过的情况 | ||||||
|  |         Integer approveType = BpmnModelUtils.parseApproveType(userTask); | ||||||
|         Integer assignEmptyHandlerType = BpmnModelUtils.parseAssignEmptyHandlerType(userTask); |         Integer assignEmptyHandlerType = BpmnModelUtils.parseAssignEmptyHandlerType(userTask); | ||||||
|         TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { |         TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { | ||||||
|  |  | ||||||
|             @Override |             @Override | ||||||
|             public void afterCommit() { |             public void afterCommit() { | ||||||
|  |                 // 特殊情况一:【人工审核】审批人为空,根据配置是否要自动通过、自动拒绝 | ||||||
|  |                 if (ObjectUtil.equal(approveType, BpmUserTaskApproveTypeEnum.USER.getType())) { | ||||||
|                     if (ObjectUtil.equal(assignEmptyHandlerType, BpmUserTaskAssignEmptyHandlerTypeEnum.APPROVE.getType())) { |                     if (ObjectUtil.equal(assignEmptyHandlerType, BpmUserTaskAssignEmptyHandlerTypeEnum.APPROVE.getType())) { | ||||||
|                         SpringUtil.getBean(BpmTaskService.class).approveTask(null, new BpmTaskApproveReqVO() |                         SpringUtil.getBean(BpmTaskService.class).approveTask(null, new BpmTaskApproveReqVO() | ||||||
|                                 .setId(task.getId()).setReason(BpmReasonEnum.ASSIGN_EMPTY_APPROVE.getReason())); |                                 .setId(task.getId()).setReason(BpmReasonEnum.ASSIGN_EMPTY_APPROVE.getReason())); | ||||||
| @ -69,6 +73,16 @@ public class BpmUserTaskActivityBehavior extends UserTaskActivityBehavior { | |||||||
|                         SpringUtil.getBean(BpmTaskService.class).rejectTask(null, new BpmTaskRejectReqVO() |                         SpringUtil.getBean(BpmTaskService.class).rejectTask(null, new BpmTaskRejectReqVO() | ||||||
|                                 .setId(task.getId()).setReason(BpmReasonEnum.ASSIGN_EMPTY_REJECT.getReason())); |                                 .setId(task.getId()).setReason(BpmReasonEnum.ASSIGN_EMPTY_REJECT.getReason())); | ||||||
|                     } |                     } | ||||||
|  |                 // 特殊情况二:【自动审核】审批类型为自动通过、不通过 | ||||||
|  |                 } else { | ||||||
|  |                     if (ObjectUtil.equal(approveType, BpmUserTaskApproveTypeEnum.AUTO_APPROVE.getType())) { | ||||||
|  |                         SpringUtil.getBean(BpmTaskService.class).approveTask(null, new BpmTaskApproveReqVO() | ||||||
|  |                                 .setId(task.getId()).setReason(BpmReasonEnum.APPROVE_TYPE_AUTO_APPROVE.getReason())); | ||||||
|  |                     } else if (ObjectUtil.equal(approveType, BpmUserTaskApproveTypeEnum.AUTO_REJECT.getType())) { | ||||||
|  |                         SpringUtil.getBean(BpmTaskService.class).rejectTask(null, new BpmTaskRejectReqVO() | ||||||
|  |                                 .setId(task.getId()).setReason(BpmReasonEnum.APPROVE_TYPE_AUTO_REJECT.getReason())); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |  | ||||||
|             } |             } | ||||||
|  |  | ||||||
|  | |||||||
| @ -6,7 +6,9 @@ import cn.hutool.core.util.ObjectUtil; | |||||||
| import cn.hutool.core.util.StrUtil; | import cn.hutool.core.util.StrUtil; | ||||||
| import cn.hutool.extra.spring.SpringUtil; | import cn.hutool.extra.spring.SpringUtil; | ||||||
| import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | ||||||
|  | import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; | ||||||
| import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission; | import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission; | ||||||
|  | import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskApproveTypeEnum; | ||||||
| import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskAssignStartUserHandlerTypeEnum; | import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskAssignStartUserHandlerTypeEnum; | ||||||
| import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum; | import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum; | ||||||
| import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils; | import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils; | ||||||
| @ -20,10 +22,7 @@ import org.flowable.bpmn.model.UserTask; | |||||||
| import org.flowable.engine.delegate.DelegateExecution; | import org.flowable.engine.delegate.DelegateExecution; | ||||||
| import org.flowable.engine.runtime.ProcessInstance; | import org.flowable.engine.runtime.ProcessInstance; | ||||||
|  |  | ||||||
| import java.util.HashMap; | import java.util.*; | ||||||
| import java.util.List; |  | ||||||
| import java.util.Map; |  | ||||||
| import java.util.Set; |  | ||||||
|  |  | ||||||
| import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | ||||||
| import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.MODEL_DEPLOY_FAIL_TASK_CANDIDATE_NOT_CONFIG; | import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.MODEL_DEPLOY_FAIL_TASK_CANDIDATE_NOT_CONFIG; | ||||||
| @ -61,7 +60,14 @@ public class BpmTaskCandidateInvoker { | |||||||
|         List<UserTask> userTaskList = BpmnModelUtils.getBpmnModelElements(bpmnModel, UserTask.class); |         List<UserTask> userTaskList = BpmnModelUtils.getBpmnModelElements(bpmnModel, UserTask.class); | ||||||
|         // 遍历所有的 UserTask,校验审批人配置 |         // 遍历所有的 UserTask,校验审批人配置 | ||||||
|         userTaskList.forEach(userTask -> { |         userTaskList.forEach(userTask -> { | ||||||
|             // 1. 非空校验 |             // 1.1 非人工审批,无需校验审批人配置 | ||||||
|  |             Integer approveType = BpmnModelUtils.parseApproveType(userTask); | ||||||
|  |             if (ObjectUtils.equalsAny(approveType, | ||||||
|  |                     BpmUserTaskApproveTypeEnum.AUTO_APPROVE.getType(), | ||||||
|  |                     BpmUserTaskApproveTypeEnum.AUTO_REJECT.getType())) { | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |             // 1.2 非空校验 | ||||||
|             Integer strategy = BpmnModelUtils.parseCandidateStrategy(userTask); |             Integer strategy = BpmnModelUtils.parseCandidateStrategy(userTask); | ||||||
|             String param = BpmnModelUtils.parseCandidateParam(userTask); |             String param = BpmnModelUtils.parseCandidateParam(userTask); | ||||||
|             if (strategy == null) { |             if (strategy == null) { | ||||||
| @ -84,6 +90,14 @@ public class BpmTaskCandidateInvoker { | |||||||
|      */ |      */ | ||||||
|     @DataPermission(enable = false) // 忽略数据权限,避免因为过滤,导致找不到候选人 |     @DataPermission(enable = false) // 忽略数据权限,避免因为过滤,导致找不到候选人 | ||||||
|     public Set<Long> calculateUsers(DelegateExecution execution) { |     public Set<Long> calculateUsers(DelegateExecution execution) { | ||||||
|  |         // 审批类型非人工审核时,不进行计算候选人。原因是:后续会自动通过、不通过 | ||||||
|  |         Integer approveType = BpmnModelUtils.parseApproveType(execution.getCurrentFlowElement()); | ||||||
|  |         if (ObjectUtils.equalsAny(approveType, | ||||||
|  |                 BpmUserTaskApproveTypeEnum.AUTO_APPROVE.getType(), | ||||||
|  |                 BpmUserTaskApproveTypeEnum.AUTO_REJECT.getType())) { | ||||||
|  |             return new HashSet<>(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|         Integer strategy = BpmnModelUtils.parseCandidateStrategy(execution.getCurrentFlowElement()); |         Integer strategy = BpmnModelUtils.parseCandidateStrategy(execution.getCurrentFlowElement()); | ||||||
|         String param = BpmnModelUtils.parseCandidateParam(execution.getCurrentFlowElement()); |         String param = BpmnModelUtils.parseCandidateParam(execution.getCurrentFlowElement()); | ||||||
|         // 1.1 计算任务的候选人 |         // 1.1 计算任务的候选人 | ||||||
|  | |||||||
| @ -56,12 +56,16 @@ public interface BpmnModelConstants { | |||||||
|      */ |      */ | ||||||
|     String USER_TASK_REJECT_RETURN_TASK_ID = "rejectReturnTaskId"; |     String USER_TASK_REJECT_RETURN_TASK_ID = "rejectReturnTaskId"; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * BPMN UserTask 的扩展属性,用于标记用户任务的审批类型 | ||||||
|  |      */ | ||||||
|  |     String USER_TASK_APPROVE_TYPE = "approveType"; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * BPMN UserTask 的扩展属性,用于标记用户任务的审批方式 |      * BPMN UserTask 的扩展属性,用于标记用户任务的审批方式 | ||||||
|      */ |      */ | ||||||
|     String USER_TASK_APPROVE_METHOD = "approveMethod"; |     String USER_TASK_APPROVE_METHOD = "approveMethod"; | ||||||
|  |  | ||||||
|     // TODO @jason:这个命名,可能有个 fieldsPermissions 更合适点。可能 formPermissions 会更更合适。 |  | ||||||
|     /** |     /** | ||||||
|      * BPMN ExtensionElement 流程表单字段权限元素, 用于标记字段权限 |      * BPMN ExtensionElement 流程表单字段权限元素, 用于标记字段权限 | ||||||
|      */ |      */ | ||||||
| @ -76,6 +80,7 @@ public interface BpmnModelConstants { | |||||||
|      */ |      */ | ||||||
|     String FORM_FIELD_PERMISSION_ELEMENT_PERMISSION_ATTRIBUTE = "permission"; |     String FORM_FIELD_PERMISSION_ELEMENT_PERMISSION_ATTRIBUTE = "permission"; | ||||||
|  |  | ||||||
|  |     // TODO @jason:上面是 fieldsPermission,然后这里是 buttonsSettings;感觉有点不统一。然后 BpmSimpleModelNodeVO 里面是 fieldsPermission、buttonsSetting; | ||||||
|     /** |     /** | ||||||
|      * BPMN ExtensionElement 操作按钮设置元素, 用于审批节点操作按钮设置 |      * BPMN ExtensionElement 操作按钮设置元素, 用于审批节点操作按钮设置 | ||||||
|      */ |      */ | ||||||
|  | |||||||
| @ -45,6 +45,10 @@ public class BpmnModelUtils { | |||||||
|         return candidateParam; |         return candidateParam; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public static Integer parseApproveType(FlowElement userTask) { | ||||||
|  |         return NumberUtils.parseInt(parseExtensionElement(userTask, BpmnModelConstants.USER_TASK_APPROVE_TYPE)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public static BpmUserTaskRejectHandlerType parseRejectHandlerType(FlowElement userTask) { |     public static BpmUserTaskRejectHandlerType parseRejectHandlerType(FlowElement userTask) { | ||||||
|         Integer rejectHandlerType = NumberUtils.parseInt(parseExtensionElement(userTask, USER_TASK_REJECT_HANDLER_TYPE)); |         Integer rejectHandlerType = NumberUtils.parseInt(parseExtensionElement(userTask, USER_TASK_REJECT_HANDLER_TYPE)); | ||||||
|         return BpmUserTaskRejectHandlerType.typeOf(rejectHandlerType); |         return BpmUserTaskRejectHandlerType.typeOf(rejectHandlerType); | ||||||
|  | |||||||
| @ -9,10 +9,7 @@ import cn.hutool.core.util.*; | |||||||
| import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | ||||||
| import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO; | import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO; | ||||||
| import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO.RejectHandler; | import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO.RejectHandler; | ||||||
| import cn.iocoder.yudao.module.bpm.enums.definition.BpmApproveMethodEnum; | import cn.iocoder.yudao.module.bpm.enums.definition.*; | ||||||
| import cn.iocoder.yudao.module.bpm.enums.definition.BpmBoundaryEventType; |  | ||||||
| import cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModeConditionType; |  | ||||||
| import cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeType; |  | ||||||
| import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants; | import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants; | ||||||
| import cn.iocoder.yudao.module.bpm.framework.flowable.core.simplemodel.SimpleModelConditionGroups; | import cn.iocoder.yudao.module.bpm.framework.flowable.core.simplemodel.SimpleModelConditionGroups; | ||||||
| import org.flowable.bpmn.BpmnAutoLayout; | import org.flowable.bpmn.BpmnAutoLayout; | ||||||
| @ -448,9 +445,11 @@ public class SimpleModelUtils { | |||||||
|         UserTask userTask = new UserTask(); |         UserTask userTask = new UserTask(); | ||||||
|         userTask.setId(node.getId()); |         userTask.setId(node.getId()); | ||||||
|         userTask.setName(node.getName()); |         userTask.setName(node.getName()); | ||||||
|         //  设置审批任务的截止时间 |  | ||||||
|         if (node.getTimeoutHandler() != null && node.getTimeoutHandler().getEnable()) { |         // 如果不是审批人节点,则直接返回 | ||||||
|             userTask.setDueDate(node.getTimeoutHandler().getTimeDuration()); |         addExtensionElement(userTask, USER_TASK_APPROVE_TYPE, StrUtil.toStringOrNull(node.getApproveType())); | ||||||
|  |         if (ObjectUtil.notEqual(node.getApproveType(), BpmUserTaskApproveTypeEnum.USER.getType())) { | ||||||
|  |             return userTask; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         // 添加候选人元素 |         // 添加候选人元素 | ||||||
| @ -467,6 +466,10 @@ public class SimpleModelUtils { | |||||||
|         addAssignStartUserHandlerType(node.getAssignStartUserHandlerType(), userTask); |         addAssignStartUserHandlerType(node.getAssignStartUserHandlerType(), userTask); | ||||||
|         // 添加用户任务的空处理元素 |         // 添加用户任务的空处理元素 | ||||||
|         addAssignEmptyHandlerType(node.getAssignEmptyHandler(), userTask); |         addAssignEmptyHandlerType(node.getAssignEmptyHandler(), userTask); | ||||||
|  |         //  设置审批任务的截止时间 | ||||||
|  |         if (node.getTimeoutHandler() != null && node.getTimeoutHandler().getEnable()) { | ||||||
|  |             userTask.setDueDate(node.getTimeoutHandler().getTimeDuration()); | ||||||
|  |         } | ||||||
|         return userTask; |         return userTask; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -494,8 +497,8 @@ public class SimpleModelUtils { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     private static void processMultiInstanceLoopCharacteristics(Integer approveMethod, Integer approveRatio, UserTask userTask) { |     private static void processMultiInstanceLoopCharacteristics(Integer approveMethod, Integer approveRatio, UserTask userTask) { | ||||||
|         BpmApproveMethodEnum bpmApproveMethodEnum = BpmApproveMethodEnum.valueOf(approveMethod); |         BpmUserTaskApproveMethodEnum approveMethodEnum = BpmUserTaskApproveMethodEnum.valueOf(approveMethod); | ||||||
|         if (bpmApproveMethodEnum == null || bpmApproveMethodEnum == BpmApproveMethodEnum.RANDOM) { |         if (approveMethodEnum == null || approveMethodEnum == BpmUserTaskApproveMethodEnum.RANDOM) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         // 添加审批方式的扩展属性 |         // 添加审批方式的扩展属性 | ||||||
| @ -504,19 +507,19 @@ public class SimpleModelUtils { | |||||||
|         MultiInstanceLoopCharacteristics multiInstanceCharacteristics = new MultiInstanceLoopCharacteristics(); |         MultiInstanceLoopCharacteristics multiInstanceCharacteristics = new MultiInstanceLoopCharacteristics(); | ||||||
|         // 设置 collectionVariable。本系统用不到。仅仅为了 Flowable 校验不报错。 |         // 设置 collectionVariable。本系统用不到。仅仅为了 Flowable 校验不报错。 | ||||||
|         multiInstanceCharacteristics.setInputDataItem("${coll_userList}"); |         multiInstanceCharacteristics.setInputDataItem("${coll_userList}"); | ||||||
|         if (bpmApproveMethodEnum == BpmApproveMethodEnum.ANY) { |         if (approveMethodEnum == BpmUserTaskApproveMethodEnum.ANY) { | ||||||
|             multiInstanceCharacteristics.setCompletionCondition(ANY_OF_APPROVE_COMPLETE_EXPRESSION); |             multiInstanceCharacteristics.setCompletionCondition(ANY_OF_APPROVE_COMPLETE_EXPRESSION); | ||||||
|             multiInstanceCharacteristics.setSequential(false); |             multiInstanceCharacteristics.setSequential(false); | ||||||
|             userTask.setLoopCharacteristics(multiInstanceCharacteristics); |             userTask.setLoopCharacteristics(multiInstanceCharacteristics); | ||||||
|         } else if (bpmApproveMethodEnum == BpmApproveMethodEnum.SEQUENTIAL) { |         } else if (approveMethodEnum == BpmUserTaskApproveMethodEnum.SEQUENTIAL) { | ||||||
|             multiInstanceCharacteristics.setCompletionCondition(ALL_APPROVE_COMPLETE_EXPRESSION); |             multiInstanceCharacteristics.setCompletionCondition(ALL_APPROVE_COMPLETE_EXPRESSION); | ||||||
|             multiInstanceCharacteristics.setSequential(true); |             multiInstanceCharacteristics.setSequential(true); | ||||||
|             multiInstanceCharacteristics.setLoopCardinality("1"); |             multiInstanceCharacteristics.setLoopCardinality("1"); | ||||||
|             userTask.setLoopCharacteristics(multiInstanceCharacteristics); |             userTask.setLoopCharacteristics(multiInstanceCharacteristics); | ||||||
|         } else if (bpmApproveMethodEnum == BpmApproveMethodEnum.RATIO) { |         } else if (approveMethodEnum == BpmUserTaskApproveMethodEnum.RATIO) { | ||||||
|             Assert.notNull(approveRatio, "通过比例不能为空"); |             Assert.notNull(approveRatio, "通过比例不能为空"); | ||||||
|             double approvePct = approveRatio / (double) 100; |             multiInstanceCharacteristics.setCompletionCondition( | ||||||
|             multiInstanceCharacteristics.setCompletionCondition(String.format(APPROVE_BY_RATIO_COMPLETE_EXPRESSION, String.format("%.2f", approvePct))); |                     String.format(APPROVE_BY_RATIO_COMPLETE_EXPRESSION, String.format("%.2f", approveRatio / (double) 100))); | ||||||
|             multiInstanceCharacteristics.setSequential(false); |             multiInstanceCharacteristics.setSequential(false); | ||||||
|         } |         } | ||||||
|         userTask.setLoopCharacteristics(multiInstanceCharacteristics); |         userTask.setLoopCharacteristics(multiInstanceCharacteristics); | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 YunaiV
					YunaiV