mirror of
				https://github.com/YunaiV/ruoyi-vue-pro.git
				synced 2025-10-31 02:28:03 +08:00 
			
		
		
		
	【代码评审】BPM:review 快搭的实现
This commit is contained in:
		| @ -4,7 +4,6 @@ import cn.hutool.core.util.ArrayUtil; | |||||||
| import lombok.AllArgsConstructor; | import lombok.AllArgsConstructor; | ||||||
| import lombok.Getter; | import lombok.Getter; | ||||||
|  |  | ||||||
| // TODO @芋艿:审批方式的名字,可能要看下; |  | ||||||
| /** | /** | ||||||
|  * BPM 多人审批方式的枚举 |  * BPM 多人审批方式的枚举 | ||||||
|  * |  * | ||||||
|  | |||||||
| @ -13,6 +13,7 @@ import lombok.Getter; | |||||||
| @AllArgsConstructor | @AllArgsConstructor | ||||||
| public enum BpmFieldPermissionEnum { | public enum BpmFieldPermissionEnum { | ||||||
|  |  | ||||||
|  |     // TODO @jason:这个顺序要不要改下,和页面保持一致;只读(1)、编辑(2)、隐藏(3) | ||||||
|     WRITE(1, "可编辑"), |     WRITE(1, "可编辑"), | ||||||
|     READ(2, "只读"), |     READ(2, "只读"), | ||||||
|     NONE(3, "隐藏"); |     NONE(3, "隐藏"); | ||||||
|  | |||||||
| @ -13,8 +13,10 @@ import lombok.Getter; | |||||||
| @AllArgsConstructor | @AllArgsConstructor | ||||||
| public enum BpmUserTaskRejectHandlerType { | public enum BpmUserTaskRejectHandlerType { | ||||||
|  |  | ||||||
|  |     // TODO @jason:是不是收敛成 2 个:FINISH_PROCESS => 1. 直接结束流程;RETURN_PRE_USER_TASK => 2. 驳回到指定节点(RETURN_USER_TASK【去掉 PRE】) | ||||||
|     FINISH_PROCESS(1, "终止流程"), |     FINISH_PROCESS(1, "终止流程"), | ||||||
|     RETURN_PRE_USER_TASK(2, "驳回到指定任务节点"), |     RETURN_PRE_USER_TASK(2, "驳回到指定任务节点"), | ||||||
|  |  | ||||||
|     FINISH_PROCESS_BY_REJECT_NUMBER(3, "按拒绝人数终止流程"), // 用于会签 |     FINISH_PROCESS_BY_REJECT_NUMBER(3, "按拒绝人数终止流程"), // 用于会签 | ||||||
|     FINISH_TASK(4, "结束任务"); // 待实现,可能会用于意见分支 |     FINISH_TASK(4, "结束任务"); // 待实现,可能会用于意见分支 | ||||||
|  |  | ||||||
| @ -24,4 +26,5 @@ public enum BpmUserTaskRejectHandlerType { | |||||||
|     public static BpmUserTaskRejectHandlerType typeOf(Integer type) { |     public static BpmUserTaskRejectHandlerType typeOf(Integer type) { | ||||||
|         return ArrayUtil.firstMatch(item -> item.getType().equals(type), values()); |         return ArrayUtil.firstMatch(item -> item.getType().equals(type), values()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -149,6 +149,7 @@ public class BpmModelController { | |||||||
|  |  | ||||||
|     // ========== 仿钉钉/飞书的精简模型 ========= |     // ========== 仿钉钉/飞书的精简模型 ========= | ||||||
|  |  | ||||||
|  |     // TODO @jason:modelId => id 哈。一般属于自己的模块,可以简化命名。 | ||||||
|     @GetMapping("/simple/get") |     @GetMapping("/simple/get") | ||||||
|     @Operation(summary = "获得仿钉钉流程设计模型") |     @Operation(summary = "获得仿钉钉流程设计模型") | ||||||
|     @Parameter(name = "modelId", description = "流程模型编号", required = true, example = "a2c5eee0-eb6c-11ee-abf4-0c37967c420a") |     @Parameter(name = "modelId", description = "流程模型编号", required = true, example = "a2c5eee0-eb6c-11ee-abf4-0c37967c420a") | ||||||
|  | |||||||
| @ -43,6 +43,7 @@ public class BpmSimpleModelNodeVO { | |||||||
|     @Schema(description = "节点的属性") |     @Schema(description = "节点的属性") | ||||||
|     private Map<String, Object> attributes; // TODO @jason:建议是字段分拆下;类似说: |     private Map<String, Object> attributes; // TODO @jason:建议是字段分拆下;类似说: | ||||||
|  |  | ||||||
|  |     // TODO @jason:看看是不是可以简化; | ||||||
|     /** |     /** | ||||||
|      * 附加节点 Id, 该节点不从前端传入。 由程序生成. 由于当个节点无法完成功能。 需要附加节点来完成。 |      * 附加节点 Id, 该节点不从前端传入。 由程序生成. 由于当个节点无法完成功能。 需要附加节点来完成。 | ||||||
|      * 例如: 会签时需要按拒绝人数来终止流程。 需要 userTask + ServiceTask 两个节点配合完成。 serviceTask 由后端生成。 |      * 例如: 会签时需要按拒绝人数来终止流程。 需要 userTask + ServiceTask 两个节点配合完成。 serviceTask 由后端生成。 | ||||||
| @ -52,12 +53,13 @@ public class BpmSimpleModelNodeVO { | |||||||
|  |  | ||||||
|     // Map<String, Integer> formPermissions; 表单权限;仅发起、审批、抄送节点会使用 |     // Map<String, Integer> formPermissions; 表单权限;仅发起、审批、抄送节点会使用 | ||||||
|     // Integer approveMethod; 审批方式;仅审批节点会使用 |     // Integer approveMethod; 审批方式;仅审批节点会使用 | ||||||
|     // TODO @jason 后面和前端一起调整一下 |     // TODO @jason 后面和前端一起调整一下;下面的 ①、②、③ 是优先级 | ||||||
|     // TODO @芋艿:审批人的选择; |     // TODO @芋艿:① 审批人的选择; | ||||||
|     // TODO @芋艿:没有人的策略? |     // TODO @芋艿:⑥ 没有人的策略? | ||||||
|     // TODO @芋艿:审批拒绝的策略? |     // TODO @芋艿:② 审批拒绝的策略? | ||||||
|     // TODO @芋艿:配置的可操作列表? |     // TODO @芋艿:③ 配置的可操作列表?(操作权限) | ||||||
|     // TODO @芋艿:超时配置;要支持指定时间点、指定时间间隔; |     // TODO @芋艿:④ 表单的权限列表? | ||||||
|  |     // TODO @芋艿:⑨ 超时配置;要支持指定时间点、指定时间间隔; | ||||||
|     // TODO @芋艿:条件;建议可以固化的一些选项;然后有个表达式兜底;要支持 |     // TODO @芋艿:条件;建议可以固化的一些选项;然后有个表达式兜底;要支持 | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -11,6 +11,7 @@ import lombok.Data; | |||||||
| @Data | @Data | ||||||
| public class BpmSimpleModelUpdateReqVO { | public class BpmSimpleModelUpdateReqVO { | ||||||
|  |  | ||||||
|  |     // TODO @jason:=> id | ||||||
|     @Schema(description = "流程模型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |     @Schema(description = "流程模型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | ||||||
|     @NotEmpty(message = "流程模型编号不能为空") |     @NotEmpty(message = "流程模型编号不能为空") | ||||||
|     private String modelId; // 对应 Flowable act_re_model 表 ID_ 字段 |     private String modelId; // 对应 Flowable act_re_model 表 ID_ 字段 | ||||||
|  | |||||||
| @ -28,9 +28,6 @@ public class BpmTaskCandidateStartUserStrategy implements BpmTaskCandidateStrate | |||||||
|         return BpmTaskCandidateStrategyEnum.START_USER; |         return BpmTaskCandidateStrategyEnum.START_USER; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 无需校验参数 |  | ||||||
|      */ |  | ||||||
|     @Override |     @Override | ||||||
|     public void validateParam(String param) {} |     public void validateParam(String param) {} | ||||||
|  |  | ||||||
| @ -40,11 +37,9 @@ public class BpmTaskCandidateStartUserStrategy implements BpmTaskCandidateStrate | |||||||
|         return SetUtils.asSet(Long.valueOf(startUserId)); |         return SetUtils.asSet(Long.valueOf(startUserId)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 不需要参数 |  | ||||||
|      */ |  | ||||||
|     @Override |     @Override | ||||||
|     public boolean isParamRequired() { |     public boolean isParamRequired() { | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,5 +1,6 @@ | |||||||
| package cn.iocoder.yudao.module.bpm.framework.flowable.core.custom.delegate; | package cn.iocoder.yudao.module.bpm.framework.flowable.core.custom.delegate; | ||||||
|  |  | ||||||
|  | import cn.hutool.core.collection.CollUtil; | ||||||
| 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.service.task.BpmProcessInstanceCopyService; | import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceCopyService; | ||||||
| import jakarta.annotation.Resource; | import jakarta.annotation.Resource; | ||||||
| @ -10,23 +11,29 @@ import org.springframework.stereotype.Service; | |||||||
|  |  | ||||||
| import java.util.Set; | import java.util.Set; | ||||||
|  |  | ||||||
|  | // TODO @jason:类名可以改成 BpmCopyTaskDelegate | ||||||
| /** | /** | ||||||
|  * 处理抄送用户的代理 |  * 处理抄送用户的 {@link JavaDelegate} 的实现类 | ||||||
|  * |  * | ||||||
|  * @author jason |  * @author jason | ||||||
|  */ |  */ | ||||||
| @Service | @Service // TODO @jason:这种注解,建议用 @Component | ||||||
| public class CopyUserDelegate implements JavaDelegate  { | public class CopyUserDelegate implements JavaDelegate  { | ||||||
|  |  | ||||||
|     @Resource |     @Resource | ||||||
|     private BpmTaskCandidateInvoker taskCandidateInvoker; |     private BpmTaskCandidateInvoker taskCandidateInvoker; | ||||||
|  |  | ||||||
|     @Resource |     @Resource | ||||||
|     private BpmProcessInstanceCopyService processInstanceCopyService; |     private BpmProcessInstanceCopyService processInstanceCopyService; | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void execute(DelegateExecution execution) { |     public void execute(DelegateExecution execution) { | ||||||
|         // TODO @芋艿:可能要考虑,系统抄送,没有 taskId 的情况。 |         // 1. 获得抄送人 | ||||||
|         Set<Long> userIds = taskCandidateInvoker.calculateUsers(execution); |         Set<Long> userIds = taskCandidateInvoker.calculateUsers(execution); | ||||||
|  |         if (CollUtil.isEmpty(userIds)) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         // 2. 执行抄送 | ||||||
|         FlowElement currentFlowElement = execution.getCurrentFlowElement(); |         FlowElement currentFlowElement = execution.getCurrentFlowElement(); | ||||||
|         processInstanceCopyService.createProcessInstanceCopy(userIds, execution.getProcessInstanceId(), |         processInstanceCopyService.createProcessInstanceCopy(userIds, execution.getProcessInstanceId(), | ||||||
|                 currentFlowElement.getId(), currentFlowElement.getName()); |                 currentFlowElement.getId(), currentFlowElement.getName()); | ||||||
|  | |||||||
| @ -10,6 +10,7 @@ import org.flowable.engine.delegate.DelegateExecution; | |||||||
| import org.flowable.engine.delegate.JavaDelegate; | import org.flowable.engine.delegate.JavaDelegate; | ||||||
| import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||||
|  |  | ||||||
|  | // TODO @jason:微信已经讨论,简化哈 | ||||||
| /** | /** | ||||||
|  * 处理会签 Service Task 代理 |  * 处理会签 Service Task 代理 | ||||||
|  * |  * | ||||||
| @ -25,7 +26,7 @@ public class MultiInstanceServiceTaskDelegate implements JavaDelegate { | |||||||
|     public void execute(DelegateExecution execution) { |     public void execute(DelegateExecution execution) { | ||||||
|  |  | ||||||
|         String attachUserTaskId = BpmnModelUtils.parseExtensionElement(execution.getCurrentFlowElement(), |         String attachUserTaskId = BpmnModelUtils.parseExtensionElement(execution.getCurrentFlowElement(), | ||||||
|                 BpmnModelConstants.SERVICE_TASK_ATTACH_USER_TASK_ID); |                 BpmnModelConstants.SERVICE_TASK_ATTACH_USER_TASK_ID); // TODO @jason:上面不需要加空行哈; | ||||||
|         Assert.notNull(attachUserTaskId, "附属的用户任务 Id 不能为空"); |         Assert.notNull(attachUserTaskId, "附属的用户任务 Id 不能为空"); | ||||||
|         // 获取会签任务是否被拒绝 |         // 获取会签任务是否被拒绝 | ||||||
|         Boolean userTaskRejected = execution.getVariable(String.format("%s_reject", attachUserTaskId), Boolean.class); |         Boolean userTaskRejected = execution.getVariable(String.format("%s_reject", attachUserTaskId), Boolean.class); | ||||||
|  | |||||||
| @ -19,6 +19,7 @@ import static cn.iocoder.yudao.module.bpm.enums.definition.BpmApproveMethodEnum. | |||||||
| import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.USER_TASK_APPROVE_METHOD; | import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.USER_TASK_APPROVE_METHOD; | ||||||
| import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.USER_TASK_APPROVE_RATIO; | import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.USER_TASK_APPROVE_RATIO; | ||||||
|  |  | ||||||
|  | // TODO @jason:微信已经讨论,简化哈 | ||||||
| /** | /** | ||||||
|  * 按拒绝人数计算会签的完成条件的流程表达式实现 |  * 按拒绝人数计算会签的完成条件的流程表达式实现 | ||||||
|  * |  * | ||||||
|  | |||||||
| @ -4,6 +4,7 @@ import org.flowable.common.engine.api.variable.VariableContainer; | |||||||
| import org.flowable.common.engine.impl.el.function.AbstractFlowableVariableExpressionFunction; | import org.flowable.common.engine.impl.el.function.AbstractFlowableVariableExpressionFunction; | ||||||
| import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||||
|  |  | ||||||
|  | // TODO @jason:这个自定义转换的原因是啥呀? | ||||||
| /** | /** | ||||||
|  * 根据流程变量 variable 的类型, 转换参数的值 |  * 根据流程变量 variable 的类型, 转换参数的值 | ||||||
|  * |  * | ||||||
|  | |||||||
| @ -40,6 +40,7 @@ public interface BpmnModelConstants { | |||||||
|      */ |      */ | ||||||
|     String USER_TASK_TIMEOUT_HANDLER_ACTION = "timeoutAction"; |     String USER_TASK_TIMEOUT_HANDLER_ACTION = "timeoutAction"; | ||||||
|  |  | ||||||
|  |     // TODO @jason:1)是不是上面的 timeoutAction 改成 timeoutHandler;2)rejectHandlerType 改成 rejectHandler 哇? | ||||||
|     /** |     /** | ||||||
|      * BPMN ExtensionElement 的扩展属性,用于标记用户任务拒绝处理类型 |      * BPMN ExtensionElement 的扩展属性,用于标记用户任务拒绝处理类型 | ||||||
|      */ |      */ | ||||||
|  | |||||||
| @ -73,6 +73,7 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener { | |||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     // TODO @jason:这块如果不需要,可以删除掉~~~ | ||||||
| //    @Override | //    @Override | ||||||
| //    protected void activityMessageReceived(FlowableMessageEvent event) { | //    protected void activityMessageReceived(FlowableMessageEvent event) { | ||||||
| //        BpmnModel bpmnModel = bpmModelService.getBpmnModelByDefinitionId(event.getProcessDefinitionId()); | //        BpmnModel bpmnModel = bpmModelService.getBpmnModelByDefinitionId(event.getProcessDefinitionId()); | ||||||
|  | |||||||
| @ -29,6 +29,7 @@ import org.springframework.stereotype.Component; | |||||||
| import java.util.List; | import java.util.List; | ||||||
| import java.util.Set; | import java.util.Set; | ||||||
|  |  | ||||||
|  | // TODO @芋艿:这块需要仔细再瞅瞅 | ||||||
| /** | /** | ||||||
|  * 监听定时器触发事件 |  * 监听定时器触发事件 | ||||||
|  * |  * | ||||||
| @ -96,7 +97,6 @@ public class BpmTimerFiredEventListener extends AbstractFlowableEngineEventListe | |||||||
|                     BpmTaskApproveReqVO req = new BpmTaskApproveReqVO().setId(task.getId()) |                     BpmTaskApproveReqVO req = new BpmTaskApproveReqVO().setId(task.getId()) | ||||||
|                             .setReason("超时系统自动同意"); |                             .setReason("超时系统自动同意"); | ||||||
|                     bpmTaskService.approveTask(Long.parseLong(task.getAssignee()), req); |                     bpmTaskService.approveTask(Long.parseLong(task.getAssignee()), req); | ||||||
|  |  | ||||||
|                 } |                 } | ||||||
|                 // 自动拒绝 |                 // 自动拒绝 | ||||||
|                 if (userTaskTimeoutAction == BpmUserTaskTimeoutActionEnum.AUTO_REJECT) { |                 if (userTaskTimeoutAction == BpmUserTaskTimeoutActionEnum.AUTO_REJECT) { | ||||||
|  | |||||||
| @ -7,6 +7,7 @@ import org.springframework.context.ApplicationContext; | |||||||
| import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||||
| import org.springframework.validation.annotation.Validated; | import org.springframework.validation.annotation.Validated; | ||||||
|  |  | ||||||
|  | // TODO @jason:建议直接调用 BpmMessageService 哈;更简化一点~ | ||||||
| /** | /** | ||||||
|  * 待办任务提醒 Producer |  * 待办任务提醒 Producer | ||||||
|  * |  * | ||||||
| @ -22,4 +23,5 @@ public class TodoTaskReminderProducer { | |||||||
|     public void sendReminderMessage(@Valid TodoTaskReminderMessage message) { |     public void sendReminderMessage(@Valid TodoTaskReminderMessage message) { | ||||||
|         applicationContext.publishEvent(message); |         applicationContext.publishEvent(message); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| package cn.iocoder.yudao.module.bpm.framework.flowable.core.simple; | package cn.iocoder.yudao.module.bpm.framework.flowable.core.simplemodel; | ||||||
| 
 | 
 | ||||||
| import lombok.Data; | import lombok.Data; | ||||||
| 
 | 
 | ||||||
| @ -1,4 +1,4 @@ | |||||||
| package cn.iocoder.yudao.module.bpm.framework.flowable.core.simple; | package cn.iocoder.yudao.module.bpm.framework.flowable.core.simplemodel; | ||||||
| 
 | 
 | ||||||
| import cn.iocoder.yudao.module.bpm.enums.definition.BpmApproveMethodEnum; | import cn.iocoder.yudao.module.bpm.enums.definition.BpmApproveMethodEnum; | ||||||
| import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskRejectHandlerType; | import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskRejectHandlerType; | ||||||
| @ -18,12 +18,11 @@ public class SimpleModelUserTaskConfig { | |||||||
|     /** |     /** | ||||||
|      * 候选人策略 |      * 候选人策略 | ||||||
|      */ |      */ | ||||||
|     private  Integer candidateStrategy; |     private Integer candidateStrategy; | ||||||
| 
 |  | ||||||
|     /** |     /** | ||||||
|      * 候选人参数 |      * 候选人参数 | ||||||
|      */ |      */ | ||||||
|     private  String candidateParam; |     private String candidateParam; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * 字段权限 |      * 字段权限 | ||||||
| @ -34,11 +33,11 @@ public class SimpleModelUserTaskConfig { | |||||||
|      * 审批方式 {@link BpmApproveMethodEnum } |      * 审批方式 {@link BpmApproveMethodEnum } | ||||||
|      */ |      */ | ||||||
|     private  Integer approveMethod; |     private  Integer approveMethod; | ||||||
| 
 |  | ||||||
|     /** |     /** | ||||||
|      * 通过比例  当审批方式为 多人会签(按通过比例) 需设置 |      * 通过比例  当审批方式为 多人会签(按通过比例) 需设置 | ||||||
|      */ |      */ | ||||||
|     private Integer approveRatio; |     private Integer approveRatio; | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * 超时处理 |      * 超时处理 | ||||||
|      */ |      */ | ||||||
| @ -15,7 +15,7 @@ import java.util.Map; | |||||||
|  |  | ||||||
| import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.FORM_FIELD_PERMISSION_ELEMENT_FIELD_ATTRIBUTE; | import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.FORM_FIELD_PERMISSION_ELEMENT_FIELD_ATTRIBUTE; | ||||||
|  |  | ||||||
|  | // TODO @芋艿:这块去研究下! | ||||||
| /** | /** | ||||||
|  *  Bpmn 流程表单相关工具方法 |  *  Bpmn 流程表单相关工具方法 | ||||||
|  * |  * | ||||||
|  | |||||||
| @ -27,6 +27,7 @@ public class BpmnModelUtils { | |||||||
|         // TODO @芋艿 尝试从 ExtensionElement 取. 后续相关扩展是否都可以 存 extensionElement。 如表单权限。 按钮权限 |         // TODO @芋艿 尝试从 ExtensionElement 取. 后续相关扩展是否都可以 存 extensionElement。 如表单权限。 按钮权限 | ||||||
|         if (candidateStrategy == null) { |         if (candidateStrategy == null) { | ||||||
|             ExtensionElement element = CollUtil.getFirst(userTask.getExtensionElements().get(BpmnModelConstants.USER_TASK_CANDIDATE_STRATEGY)); |             ExtensionElement element = CollUtil.getFirst(userTask.getExtensionElements().get(BpmnModelConstants.USER_TASK_CANDIDATE_STRATEGY)); | ||||||
|  |             // TODO @jason:这里可以改成 element != null 看着会简单点 element != null ? NumberUtils.parseInt(element.getElementText()) : null; | ||||||
|             candidateStrategy = NumberUtils.parseInt(Optional.ofNullable(element).map(ExtensionElement::getElementText).orElse(null)); |             candidateStrategy = NumberUtils.parseInt(Optional.ofNullable(element).map(ExtensionElement::getElementText).orElse(null)); | ||||||
|         } |         } | ||||||
|         return candidateStrategy; |         return candidateStrategy; | ||||||
| @ -37,6 +38,7 @@ public class BpmnModelUtils { | |||||||
|                 BpmnModelConstants.NAMESPACE, BpmnModelConstants.USER_TASK_CANDIDATE_PARAM); |                 BpmnModelConstants.NAMESPACE, BpmnModelConstants.USER_TASK_CANDIDATE_PARAM); | ||||||
|         if (candidateParam == null) { |         if (candidateParam == null) { | ||||||
|             ExtensionElement element = CollUtil.getFirst(userTask.getExtensionElements().get(BpmnModelConstants.USER_TASK_CANDIDATE_PARAM)); |             ExtensionElement element = CollUtil.getFirst(userTask.getExtensionElements().get(BpmnModelConstants.USER_TASK_CANDIDATE_PARAM)); | ||||||
|  |             // TODO @jason:这里可以改成 element != null 看着会简单点 element != null ? element.getElementText() : null; | ||||||
|             candidateParam = Optional.ofNullable(element).map(ExtensionElement::getElementText).orElse(null); |             candidateParam = Optional.ofNullable(element).map(ExtensionElement::getElementText).orElse(null); | ||||||
|         } |         } | ||||||
|         return candidateParam; |         return candidateParam; | ||||||
|  | |||||||
| @ -12,9 +12,9 @@ import cn.iocoder.yudao.module.bpm.enums.definition.BpmApproveMethodEnum; | |||||||
| import cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModeConditionType; | import cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModeConditionType; | ||||||
| import cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeType; | 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.simple.SimpleModelConditionGroups; | import cn.iocoder.yudao.module.bpm.framework.flowable.core.simplemodel.SimpleModelConditionGroups; | ||||||
| import cn.iocoder.yudao.module.bpm.framework.flowable.core.simple.SimpleModelUserTaskConfig; | import cn.iocoder.yudao.module.bpm.framework.flowable.core.simplemodel.SimpleModelUserTaskConfig; | ||||||
| import cn.iocoder.yudao.module.bpm.framework.flowable.core.simple.SimpleModelUserTaskConfig.RejectHandler; | import cn.iocoder.yudao.module.bpm.framework.flowable.core.simplemodel.SimpleModelUserTaskConfig.RejectHandler; | ||||||
| import org.flowable.bpmn.BpmnAutoLayout; | import org.flowable.bpmn.BpmnAutoLayout; | ||||||
| import org.flowable.bpmn.model.Process; | import org.flowable.bpmn.model.Process; | ||||||
| import org.flowable.bpmn.model.*; | import org.flowable.bpmn.model.*; | ||||||
| @ -253,33 +253,26 @@ public class SimpleModelUtils { | |||||||
|         return sequenceFlow; |         return sequenceFlow; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // TODO-DONE @jason:要不改成 recursionNode 递归节点,然后把 build 名字让出来,专门用于构建各种 Node |     // TODO @芋艿 改成了 traverseNodeToBuildFlowNode, 连线的叫 traverseNodeToBuildSequenceFlow | ||||||
|     // @芋艿 改成了 traverseNodeToBuildFlowNode, 连线的叫 traverseNodeToBuildSequenceFlow |  | ||||||
|     // TODO-DONE @jason:node 改成 node,process 改成 process;更符合递归的感觉哈,处理当前节点 |  | ||||||
|     private static void traverseNodeToBuildFlowNode(BpmSimpleModelNodeVO node, Process process) { |     private static void traverseNodeToBuildFlowNode(BpmSimpleModelNodeVO node, Process process) { | ||||||
|         // 判断是否有效节点 |         // 判断是否有效节点 | ||||||
|         // TODO-DONE @jason:是不是写个 isValidNode 方法:判断是否为有效节点; |  | ||||||
|         if (!isValidNode(node)) { |         if (!isValidNode(node)) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         BpmSimpleModelNodeType nodeType = BpmSimpleModelNodeType.valueOf(node.getType()); |         BpmSimpleModelNodeType nodeType = BpmSimpleModelNodeType.valueOf(node.getType()); | ||||||
|         Assert.notNull(nodeType, "模型节点类型不支持"); |         Assert.notNull(nodeType, "模型节点类型不支持"); | ||||||
|  |  | ||||||
|         // TODO-DONE @jason:要不抽个 buildNode 方法,然后返回一个 List<FlowElement>,之后这个方法 addFlowElement;原因是,让当前这个方法,有主干逻辑;不然现在太长了; |  | ||||||
|         List<FlowElement> flowElements = buildFlowNode(node, nodeType); |         List<FlowElement> flowElements = buildFlowNode(node, nodeType); | ||||||
|         flowElements.forEach(process::addFlowElement); |         flowElements.forEach(process::addFlowElement); | ||||||
|  |  | ||||||
|         // 如果不是网关类型的接口, 并且chileNode为空退出 |         // 如果不是网关类型的接口, 并且chileNode为空退出 | ||||||
|         // TODO-DONE @jason:建议这个判断去掉,可以更简洁一点;因为往下走;如果不成功,本身也就会结束哈;主要是,这里多了一个这样的判断,增加了理解成本; |  | ||||||
|         // 如果是“分支”节点,则递归处理条件 |         // 如果是“分支”节点,则递归处理条件 | ||||||
|         if (BpmSimpleModelNodeType.isBranchNode(node.getType()) |         if (BpmSimpleModelNodeType.isBranchNode(node.getType()) | ||||||
|                 && ArrayUtil.isNotEmpty(node.getConditionNodes())) { |                 && ArrayUtil.isNotEmpty(node.getConditionNodes())) { | ||||||
|             // TODO-DONE @jason:可以搞成 stream 写成一行哈 |  | ||||||
|             node.getConditionNodes().forEach(item -> traverseNodeToBuildFlowNode(item.getChildNode(), process)); |             node.getConditionNodes().forEach(item -> traverseNodeToBuildFlowNode(item.getChildNode(), process)); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         // 如果有“子”节点,则递归处理子节点 |         // 如果有“子”节点,则递归处理子节点 | ||||||
|         // TODO-DONE @jason:这个,是不是不写判断,直接继续调用;因为本身 buildAndAddBpmnFlowNode 就会最开始判断了哈,就不重复判断了; |  | ||||||
|         traverseNodeToBuildFlowNode(node.getChildNode(), process); |         traverseNodeToBuildFlowNode(node.getChildNode(), process); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -291,16 +284,13 @@ public class SimpleModelUtils { | |||||||
|         List<FlowElement> list = new ArrayList<>(); |         List<FlowElement> list = new ArrayList<>(); | ||||||
|         switch (nodeType) { |         switch (nodeType) { | ||||||
|             case START_NODE: { |             case START_NODE: { | ||||||
|                 // TODO-DONE @jason:每个 nodeType,buildXXX 方法要不更明确,并且去掉 Bpmn; |  | ||||||
|                 // @芋艿 改成 convert 是不是好理解一点 |                 // @芋艿 改成 convert 是不是好理解一点 | ||||||
|                 StartEvent startEvent = convertStartNode(node); |                 StartEvent startEvent = convertStartNode(node); | ||||||
|                 list.add(startEvent); |                 list.add(startEvent); | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|             case APPROVE_NODE: { |             case APPROVE_NODE: { | ||||||
|                 // TODO-DONE @jason:这个,搞成一个 buildUserTask,然后把下面这 2 种节点,搞在一起实现类;这样 buildNode 里面可以更简洁; |                 // TODO @芋艿 改成 convertXXXNode, , 方面里面使用 buildBpmnXXXNode. 是否更好理解 | ||||||
|                 // TODO-DONE @jason:这里还有个想法,是不是可以所有的都叫 buildXXXNode,然后里面有一些是 bpmn 相关的构建,叫做 buildBpmnUserTask,用于区分; |  | ||||||
|                 // @芋艿 改成 convertXXXNode, , 方面里面使用 buildBpmnXXXNode. 是否更好理解 |  | ||||||
|                 // 转换审批节点 |                 // 转换审批节点 | ||||||
|                 List<FlowElement> flowElements = convertApproveNode(node); |                 List<FlowElement> flowElements = convertApproveNode(node); | ||||||
|                 list.addAll(flowElements); |                 list.addAll(flowElements); | ||||||
|  | |||||||
| @ -50,31 +50,6 @@ public interface BpmModelService { | |||||||
|      */ |      */ | ||||||
|     byte[] getModelBpmnXML(String id); |     byte[] getModelBpmnXML(String id); | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 保存流程模型的 BPMN XML |  | ||||||
|      * |  | ||||||
|      * @param id       编号 |  | ||||||
|      * @param xmlBytes BPMN XML bytes |  | ||||||
|      */ |  | ||||||
|     // TODO @芋艿:感觉可以不修改这个方法,而是额外加一个方法;传入 id,bpmn,json; |  | ||||||
|     void saveModelBpmnXml(String id, byte[] xmlBytes); |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 获得仿钉钉快搭模型的 JSON 数据 |  | ||||||
|      * |  | ||||||
|      * @param id 编号 |  | ||||||
|      * @return JSON bytes |  | ||||||
|      */ |  | ||||||
|     byte[] getModelSimpleJson(String id); |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 保存仿钉钉快搭模型的 JSON 数据 |  | ||||||
|      * |  | ||||||
|      * @param id        编号 |  | ||||||
|      * @param jsonBytes JSON bytes |  | ||||||
|      */ |  | ||||||
|     void saveModelSimpleJson(String id, byte[] jsonBytes); |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 修改流程模型 |      * 修改流程模型 | ||||||
|      * |      * | ||||||
| @ -129,6 +104,6 @@ public interface BpmModelService { | |||||||
|      */ |      */ | ||||||
|     void updateSimpleModel(@Valid BpmSimpleModelUpdateReqVO reqVO); |     void updateSimpleModel(@Valid BpmSimpleModelUpdateReqVO reqVO); | ||||||
|  |  | ||||||
|     // TODO @jason:另外个问题,因为是存储到 modelExtra 里,那需要 deploy 存储出快照。和 bpmn xml 一样。目前我想到的,就是存储到 BpmProcessDefinitionInfoDO 加一个 simple_model 字段,text 类型。可以看看还有啥方案? |     // TODO @jason:另外个问题,因为是存储到 modelExtra 里,那需要 deploy 存储出快照。和 bpmn xml 一样。目前我想到的,就是存储到 BpmProcessDefinitionInfoDO 加一个 simple_model 字段,text 类型。可以看看还有啥方案?【重要】 | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -107,7 +107,7 @@ public class BpmModelServiceImpl implements BpmModelService { | |||||||
|         // 保存流程定义 |         // 保存流程定义 | ||||||
|         repositoryService.saveModel(model); |         repositoryService.saveModel(model); | ||||||
|         // 保存 BPMN XML |         // 保存 BPMN XML | ||||||
|         saveModelBpmnXml(model.getId(), StrUtil.utf8Bytes(bpmnXml)); |         saveModelBpmnXml(model.getId(), bpmnXml); | ||||||
|         return model.getId(); |         return model.getId(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -125,7 +125,7 @@ public class BpmModelServiceImpl implements BpmModelService { | |||||||
|         // 更新模型 |         // 更新模型 | ||||||
|         repositoryService.saveModel(model); |         repositoryService.saveModel(model); | ||||||
|         // 更新 BPMN XML |         // 更新 BPMN XML | ||||||
|         saveModelBpmnXml(model.getId(), StrUtil.utf8Bytes(updateReqVO.getBpmnXml())); |         saveModelBpmnXml(model.getId(), updateReqVO.getBpmnXml()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
| @ -218,23 +218,24 @@ public class BpmModelServiceImpl implements BpmModelService { | |||||||
|         if (model == null) { |         if (model == null) { | ||||||
|             throw exception(MODEL_NOT_EXISTS); |             throw exception(MODEL_NOT_EXISTS); | ||||||
|         } |         } | ||||||
|         // 通过 ACT_RE_MODEL 表 EDITOR_SOURCE_EXTRA_VALUE_ID_  获取 仿钉钉快搭模型的JSON 数据 |         // 通过 ACT_RE_MODEL 表 EDITOR_SOURCE_EXTRA_VALUE_ID_ ,获取仿钉钉快搭模型的 JSON 数据 | ||||||
|         byte[] jsonBytes = getModelSimpleJson(model.getId()); |         byte[] jsonBytes = getModelSimpleJson(model.getId()); | ||||||
|         return JsonUtils.parseObject(jsonBytes, BpmSimpleModelNodeVO.class); |         return JsonUtils.parseObject(jsonBytes, BpmSimpleModelNodeVO.class); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void updateSimpleModel(BpmSimpleModelUpdateReqVO reqVO) { |     public void updateSimpleModel(BpmSimpleModelUpdateReqVO reqVO) { | ||||||
|         // 1.1 校验流程模型存在 |         // 1. 校验流程模型存在 | ||||||
|         Model model = getModel(reqVO.getModelId()); |         Model model = getModel(reqVO.getModelId()); | ||||||
|         if (model == null) { |         if (model == null) { | ||||||
|             throw exception(MODEL_NOT_EXISTS); |             throw exception(MODEL_NOT_EXISTS); | ||||||
|         } |         } | ||||||
|         // 1.2 JSON 转换成 bpmnModel |  | ||||||
|  |         // 2.1 JSON 转换成 bpmnModel | ||||||
|         BpmnModel bpmnModel = SimpleModelUtils.buildBpmnModel(model.getKey(), model.getName(), reqVO.getSimpleModel()); |         BpmnModel bpmnModel = SimpleModelUtils.buildBpmnModel(model.getKey(), model.getName(), reqVO.getSimpleModel()); | ||||||
|         // 2.1 保存 Bpmn XML |         // 2.2 保存 Bpmn XML | ||||||
|         saveModelBpmnXml(model.getId(), StrUtil.utf8Bytes(BpmnModelUtils.getBpmnXml(bpmnModel))); |         saveModelBpmnXml(model.getId(), BpmnModelUtils.getBpmnXml(bpmnModel)); | ||||||
|         // 2.2 保存 JSON 数据 |         // 2.3 保存 JSON 数据 | ||||||
|         saveModelSimpleJson(model.getId(), JsonUtils.toJsonByte(reqVO.getSimpleModel())); |         saveModelSimpleJson(model.getId(), JsonUtils.toJsonByte(reqVO.getSimpleModel())); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -266,21 +267,18 @@ public class BpmModelServiceImpl implements BpmModelService { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     private void saveModelBpmnXml(String id, String bpmnXml) { | ||||||
|     public void saveModelBpmnXml(String id,  byte[] xmlBytes) { |         if (StrUtil.isEmpty(bpmnXml)) { | ||||||
|         if (ArrayUtil.isEmpty(xmlBytes)) { |  | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         repositoryService.addModelEditorSource(id, xmlBytes); |         repositoryService.addModelEditorSource(id, StrUtil.utf8Bytes(bpmnXml)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     private byte[] getModelSimpleJson(String id) { | ||||||
|     public byte[] getModelSimpleJson(String id) { |  | ||||||
|         return repositoryService.getModelEditorSourceExtra(id); |         return repositoryService.getModelEditorSourceExtra(id); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     private void saveModelSimpleJson(String id, byte[] jsonBytes) { | ||||||
|     public void saveModelSimpleJson(String id, byte[] jsonBytes) { |  | ||||||
|         if (ArrayUtil.isEmpty(jsonBytes)) { |         if (ArrayUtil.isEmpty(jsonBytes)) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -13,6 +13,8 @@ import java.util.Collection; | |||||||
|  */ |  */ | ||||||
| public interface BpmProcessInstanceCopyService { | public interface BpmProcessInstanceCopyService { | ||||||
|  |  | ||||||
|  |     // TODO @jason:要不把 createProcessInstanceCopy 搞 2 个方法,一个方法参数是之前的 userIds、taskId;一个方法是现在 userIds、processInstanceId、taskId、taskName; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 流程实例的抄送 |      * 流程实例的抄送 | ||||||
|      * |      * | ||||||
|  | |||||||
| @ -127,23 +127,23 @@ public interface BpmProcessInstanceService { | |||||||
|     void updateProcessInstanceWhenCancel(FlowableCancelledEvent event); |     void updateProcessInstanceWhenCancel(FlowableCancelledEvent event); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 更新 ProcessInstance 拓展记录为完成 |      * 更新 ProcessInstance 为完成 | ||||||
|      * |      * | ||||||
|      * @param instance 流程任务 |      * @param instance 流程任务 | ||||||
|      */ |      */ | ||||||
|     void updateProcessInstanceWhenApprove(ProcessInstance instance); |     void updateProcessInstanceWhenApprove(ProcessInstance instance); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 更新 ProcessInstance 拓展记录为不通过 |      * 更新 ProcessInstance 为不通过 | ||||||
|      * |      * | ||||||
|      * @param id     流程编号 |      * @param id     流程编号 | ||||||
|      * @param currentActivityId  当前的活动Id |      * @param currentActivityId  当前的活动编号 | ||||||
|      * @param reason 理由。例如说,审批不通过时,需要传递该值 |      * @param reason 理由。例如说,审批不通过时,需要传递该值 | ||||||
|      */ |      */ | ||||||
|     void updateProcessInstanceReject(String id, String currentActivityId,  String reason); |     void updateProcessInstanceReject(String id, String currentActivityId,  String reason); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 当流程结束时候。 更新 ProcessInstance |      * 当流程结束时候,更新 ProcessInstance 为通过 | ||||||
|      * |      * | ||||||
|      * @param instance 流程任务 |      * @param instance 流程任务 | ||||||
|      */ |      */ | ||||||
|  | |||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -129,6 +129,7 @@ public interface BpmTaskService { | |||||||
|      */ |      */ | ||||||
|     Task getTask(String id); |     Task getTask(String id); | ||||||
|  |  | ||||||
|  |     // TODO @jason:jason:这个貌似可以去掉了。 | ||||||
|     /** |     /** | ||||||
|      * 根据条件查询已经分配的用户任务列表 |      * 根据条件查询已经分配的用户任务列表 | ||||||
|      * @param processInstanceId 流程实例编号,不允许为空 |      * @param processInstanceId 流程实例编号,不允许为空 | ||||||
|  | |||||||
| @ -335,14 +335,18 @@ public class BpmTaskServiceImpl implements BpmTaskService { | |||||||
|         // 2.2 添加评论 |         // 2.2 添加评论 | ||||||
|         taskService.addComment(task.getId(), task.getProcessInstanceId(), BpmCommentTypeEnum.REJECT.getType(), |         taskService.addComment(task.getId(), task.getProcessInstanceId(), BpmCommentTypeEnum.REJECT.getType(), | ||||||
|                 BpmCommentTypeEnum.REJECT.formatComment(reqVO.getReason())); |                 BpmCommentTypeEnum.REJECT.formatComment(reqVO.getReason())); | ||||||
|  |  | ||||||
|         // 3.1 解析用户任务的拒绝处理类型 |         // 3.1 解析用户任务的拒绝处理类型 | ||||||
|         BpmnModel bpmnModel = bpmModelService.getBpmnModelByDefinitionId(task.getProcessDefinitionId()); |         BpmnModel bpmnModel = bpmModelService.getBpmnModelByDefinitionId(task.getProcessDefinitionId()); | ||||||
|  |         // TODO @jason:342 到 344 最好抽象一个方法出来哈。放在 BpmnModelUtils,参照类似 parseCandidateStrategy | ||||||
|         UserTask flowElement = (UserTask) BpmnModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey()); |         UserTask flowElement = (UserTask) BpmnModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey()); | ||||||
|         Integer rejectHandlerType = NumberUtils.parseInt(BpmnModelUtils.parseExtensionElement(flowElement, USER_TASK_REJECT_HANDLER_TYPE)); |         Integer rejectHandlerType = NumberUtils.parseInt(BpmnModelUtils.parseExtensionElement(flowElement, USER_TASK_REJECT_HANDLER_TYPE)); | ||||||
|         BpmUserTaskRejectHandlerType userTaskRejectHandlerType = BpmUserTaskRejectHandlerType.typeOf(rejectHandlerType); |         BpmUserTaskRejectHandlerType userTaskRejectHandlerType = BpmUserTaskRejectHandlerType.typeOf(rejectHandlerType); | ||||||
|         // 3.2 类型为驳回到指定的任务节点 |         // 3.2 类型为驳回到指定的任务节点 TODO @jason:下面这种判断,最好是 JSON | ||||||
|         if (userTaskRejectHandlerType == BpmUserTaskRejectHandlerType.RETURN_PRE_USER_TASK) { |         if (userTaskRejectHandlerType == BpmUserTaskRejectHandlerType.RETURN_PRE_USER_TASK) { | ||||||
|  |             // TODO @jason:348 最好抽象一个方法出来哈。放在 BpmnModelUtils,参照类似 parseCandidateStrategy | ||||||
|             String returnTaskId = BpmnModelUtils.parseExtensionElement(flowElement, USER_TASK_REJECT_RETURN_TASK_ID); |             String returnTaskId = BpmnModelUtils.parseExtensionElement(flowElement, USER_TASK_REJECT_RETURN_TASK_ID); | ||||||
|  |             // TODO @jason:这里如果找不到,直接抛出系统异常;因为说白了,已经不是业务异常啦。 | ||||||
|             if (returnTaskId == null) { |             if (returnTaskId == null) { | ||||||
|                 throw exception(TASK_RETURN_NOT_ASSIGN_TARGET_TASK_ID); |                 throw exception(TASK_RETURN_NOT_ASSIGN_TARGET_TASK_ID); | ||||||
|             } |             } | ||||||
| @ -351,6 +355,7 @@ public class BpmTaskServiceImpl implements BpmTaskService { | |||||||
|             returnTask(userId, returnReq); |             returnTask(userId, returnReq); | ||||||
|             return; |             return; | ||||||
|         } else if (userTaskRejectHandlerType == BpmUserTaskRejectHandlerType.FINISH_PROCESS_BY_REJECT_NUMBER) { |         } else if (userTaskRejectHandlerType == BpmUserTaskRejectHandlerType.FINISH_PROCESS_BY_REJECT_NUMBER) { | ||||||
|  |             // TODO @jason:微信沟通,去掉类似的逻辑; | ||||||
|             // 3.3 按拒绝人数终止流程 |             // 3.3 按拒绝人数终止流程 | ||||||
|             if (!flowElement.hasMultiInstanceLoopCharacteristics()) { |             if (!flowElement.hasMultiInstanceLoopCharacteristics()) { | ||||||
|                 log.error("[rejectTask] 按拒绝人数终止流程类型,只能用于会签任务. 当前任务【{}】不是会签任务", task.getId()); |                 log.error("[rejectTask] 按拒绝人数终止流程类型,只能用于会签任务. 当前任务【{}】不是会签任务", task.getId()); | ||||||
| @ -362,7 +367,8 @@ public class BpmTaskServiceImpl implements BpmTaskService { | |||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         // 3.4 其他情况 终止流程。 |         // 3.4 其他情况 终止流程。 | ||||||
|         processInstanceService.updateProcessInstanceReject(instance.getProcessInstanceId(), task.getTaskDefinitionKey(),  reqVO.getReason()); |         processInstanceService.updateProcessInstanceReject(instance.getProcessInstanceId(), | ||||||
|  |                 task.getTaskDefinitionKey(), reqVO.getReason()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 YunaiV
					YunaiV