【代码评审】BPM:review 快搭的实现

This commit is contained in:
YunaiV 2024-06-17 18:45:54 +08:00
parent 8585e05772
commit 41b9ab2ba5
27 changed files with 78 additions and 89 deletions

View File

@ -4,7 +4,6 @@ import cn.hutool.core.util.ArrayUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
// TODO @芋艿审批方式的名字可能要看下
/**
* BPM 多人审批方式的枚举
*

View File

@ -13,6 +13,7 @@ import lombok.Getter;
@AllArgsConstructor
public enum BpmFieldPermissionEnum {
// TODO @jason这个顺序要不要改下和页面保持一致只读1编辑2隐藏3
WRITE(1, "可编辑"),
READ(2, "只读"),
NONE(3, "隐藏");

View File

@ -13,8 +13,10 @@ import lombok.Getter;
@AllArgsConstructor
public enum BpmUserTaskRejectHandlerType {
// TODO @jason是不是收敛成 2 FINISH_PROCESS => 1. 直接结束流程RETURN_PRE_USER_TASK => 2. 驳回到指定节点RETURN_USER_TASK去掉 PRE
FINISH_PROCESS(1, "终止流程"),
RETURN_PRE_USER_TASK(2, "驳回到指定任务节点"),
FINISH_PROCESS_BY_REJECT_NUMBER(3, "按拒绝人数终止流程"), // 用于会签
FINISH_TASK(4, "结束任务"); // 待实现可能会用于意见分支
@ -24,4 +26,5 @@ public enum BpmUserTaskRejectHandlerType {
public static BpmUserTaskRejectHandlerType typeOf(Integer type) {
return ArrayUtil.firstMatch(item -> item.getType().equals(type), values());
}
}

View File

@ -149,6 +149,7 @@ public class BpmModelController {
// ========== 仿钉钉/飞书的精简模型 =========
// TODO @jasonmodelId => id 一般属于自己的模块可以简化命名
@GetMapping("/simple/get")
@Operation(summary = "获得仿钉钉流程设计模型")
@Parameter(name = "modelId", description = "流程模型编号", required = true, example = "a2c5eee0-eb6c-11ee-abf4-0c37967c420a")

View File

@ -43,6 +43,7 @@ public class BpmSimpleModelNodeVO {
@Schema(description = "节点的属性")
private Map<String, Object> attributes; // TODO @jason建议是字段分拆下类似说
// TODO @jason看看是不是可以简化
/**
* 附加节点 Id, 该节点不从前端传入 由程序生成. 由于当个节点无法完成功能 需要附加节点来完成
* 例如 会签时需要按拒绝人数来终止流程 需要 userTask + ServiceTask 两个节点配合完成 serviceTask 由后端生成
@ -52,12 +53,13 @@ public class BpmSimpleModelNodeVO {
// Map<String, Integer> formPermissions; 表单权限仅发起审批抄送节点会使用
// Integer approveMethod; 审批方式仅审批节点会使用
// TODO @jason 后面和前端一起调整一下
// TODO @芋艿审批人的选择
// TODO @芋艿没有人的策略
// TODO @芋艿审批拒绝的策略
// TODO @芋艿配置的可操作列表
// TODO @芋艿超时配置要支持指定时间点指定时间间隔
// TODO @jason 后面和前端一起调整一下下面的 是优先级
// TODO @芋艿 审批人的选择
// TODO @芋艿 没有人的策略
// TODO @芋艿 审批拒绝的策略
// TODO @芋艿 配置的可操作列表操作权限
// TODO @芋艿 表单的权限列表
// TODO @芋艿 超时配置要支持指定时间点指定时间间隔
// TODO @芋艿条件建议可以固化的一些选项然后有个表达式兜底要支持
}

View File

@ -11,6 +11,7 @@ import lombok.Data;
@Data
public class BpmSimpleModelUpdateReqVO {
// TODO @jason=> id
@Schema(description = "流程模型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotEmpty(message = "流程模型编号不能为空")
private String modelId; // 对应 Flowable act_re_model ID_ 字段

View File

@ -28,9 +28,6 @@ public class BpmTaskCandidateStartUserStrategy implements BpmTaskCandidateStrate
return BpmTaskCandidateStrategyEnum.START_USER;
}
/**
* 无需校验参数
*/
@Override
public void validateParam(String param) {}
@ -40,11 +37,9 @@ public class BpmTaskCandidateStartUserStrategy implements BpmTaskCandidateStrate
return SetUtils.asSet(Long.valueOf(startUserId));
}
/**
* 不需要参数
*/
@Override
public boolean isParamRequired() {
return false;
}
}

View File

@ -1,5 +1,6 @@
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.service.task.BpmProcessInstanceCopyService;
import jakarta.annotation.Resource;
@ -10,23 +11,29 @@ import org.springframework.stereotype.Service;
import java.util.Set;
// TODO @jason类名可以改成 BpmCopyTaskDelegate
/**
* 处理抄送用户的代理
* 处理抄送用户的 {@link JavaDelegate} 的实现类
*
* @author jason
*/
@Service
@Service // TODO @jason这种注解建议用 @Component
public class CopyUserDelegate implements JavaDelegate {
@Resource
private BpmTaskCandidateInvoker taskCandidateInvoker;
@Resource
private BpmProcessInstanceCopyService processInstanceCopyService;
@Override
public void execute(DelegateExecution execution) {
// TODO @芋艿可能要考虑系统抄送没有 taskId 的情况
// 1. 获得抄送人
Set<Long> userIds = taskCandidateInvoker.calculateUsers(execution);
if (CollUtil.isEmpty(userIds)) {
return;
}
// 2. 执行抄送
FlowElement currentFlowElement = execution.getCurrentFlowElement();
processInstanceCopyService.createProcessInstanceCopy(userIds, execution.getProcessInstanceId(),
currentFlowElement.getId(), currentFlowElement.getName());

View File

@ -10,6 +10,7 @@ import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.JavaDelegate;
import org.springframework.stereotype.Component;
// TODO @jason微信已经讨论简化哈
/**
* 处理会签 Service Task 代理
*
@ -25,7 +26,7 @@ public class MultiInstanceServiceTaskDelegate implements JavaDelegate {
public void execute(DelegateExecution execution) {
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 不能为空");
// 获取会签任务是否被拒绝
Boolean userTaskRejected = execution.getVariable(String.format("%s_reject", attachUserTaskId), Boolean.class);

View File

@ -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_RATIO;
// TODO @jason微信已经讨论简化哈
/**
* 按拒绝人数计算会签的完成条件的流程表达式实现
*

View File

@ -4,6 +4,7 @@ import org.flowable.common.engine.api.variable.VariableContainer;
import org.flowable.common.engine.impl.el.function.AbstractFlowableVariableExpressionFunction;
import org.springframework.stereotype.Component;
// TODO @jason这个自定义转换的原因是啥呀
/**
* 根据流程变量 variable 的类型, 转换参数的值
*

View File

@ -40,6 +40,7 @@ public interface BpmnModelConstants {
*/
String USER_TASK_TIMEOUT_HANDLER_ACTION = "timeoutAction";
// TODO @jason1是不是上面的 timeoutAction 改成 timeoutHandler2rejectHandlerType 改成 rejectHandler
/**
* BPMN ExtensionElement 的扩展属性用于标记用户任务拒绝处理类型
*/

View File

@ -73,6 +73,7 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener {
});
}
// TODO @jason这块如果不需要可以删除掉~~~
// @Override
// protected void activityMessageReceived(FlowableMessageEvent event) {
// BpmnModel bpmnModel = bpmModelService.getBpmnModelByDefinitionId(event.getProcessDefinitionId());

View File

@ -29,6 +29,7 @@ import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Set;
// TODO @芋艿这块需要仔细再瞅瞅
/**
* 监听定时器触发事件
*
@ -96,7 +97,6 @@ public class BpmTimerFiredEventListener extends AbstractFlowableEngineEventListe
BpmTaskApproveReqVO req = new BpmTaskApproveReqVO().setId(task.getId())
.setReason("超时系统自动同意");
bpmTaskService.approveTask(Long.parseLong(task.getAssignee()), req);
}
// 自动拒绝
if (userTaskTimeoutAction == BpmUserTaskTimeoutActionEnum.AUTO_REJECT) {

View File

@ -7,6 +7,7 @@ import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
// TODO @jason建议直接调用 BpmMessageService 更简化一点~
/**
* 待办任务提醒 Producer
*
@ -22,4 +23,5 @@ public class TodoTaskReminderProducer {
public void sendReminderMessage(@Valid TodoTaskReminderMessage message) {
applicationContext.publishEvent(message);
}
}

View File

@ -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.BpmUserTaskRejectHandlerType;
@ -19,7 +19,6 @@ public class SimpleModelUserTaskConfig {
* 候选人策略
*/
private Integer candidateStrategy;
/**
* 候选人参数
*/
@ -34,11 +33,11 @@ public class SimpleModelUserTaskConfig {
* 审批方式 {@link BpmApproveMethodEnum }
*/
private Integer approveMethod;
/**
* 通过比例 当审批方式为 多人会签(按通过比例) 需设置
*/
private Integer approveRatio;
/**
* 超时处理
*/

View File

@ -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;
// TODO @芋艿这块去研究下
/**
* Bpmn 流程表单相关工具方法
*

View File

@ -27,6 +27,7 @@ public class BpmnModelUtils {
// TODO @芋艿 尝试从 ExtensionElement . 后续相关扩展是否都可以 extensionElement 如表单权限 按钮权限
if (candidateStrategy == null) {
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));
}
return candidateStrategy;
@ -37,6 +38,7 @@ public class BpmnModelUtils {
BpmnModelConstants.NAMESPACE, BpmnModelConstants.USER_TASK_CANDIDATE_PARAM);
if (candidateParam == null) {
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);
}
return candidateParam;

View File

@ -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.BpmSimpleModelNodeType;
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.simple.SimpleModelUserTaskConfig;
import cn.iocoder.yudao.module.bpm.framework.flowable.core.simple.SimpleModelUserTaskConfig.RejectHandler;
import cn.iocoder.yudao.module.bpm.framework.flowable.core.simplemodel.SimpleModelConditionGroups;
import cn.iocoder.yudao.module.bpm.framework.flowable.core.simplemodel.SimpleModelUserTaskConfig;
import cn.iocoder.yudao.module.bpm.framework.flowable.core.simplemodel.SimpleModelUserTaskConfig.RejectHandler;
import org.flowable.bpmn.BpmnAutoLayout;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.*;
@ -253,33 +253,26 @@ public class SimpleModelUtils {
return sequenceFlow;
}
// TODO-DONE @jason要不改成 recursionNode 递归节点然后把 build 名字让出来专门用于构建各种 Node
// @芋艿 改成了 traverseNodeToBuildFlowNode 连线的叫 traverseNodeToBuildSequenceFlow
// TODO-DONE @jasonnode 改成 nodeprocess 改成 process更符合递归的感觉哈处理当前节点
// TODO @芋艿 改成了 traverseNodeToBuildFlowNode 连线的叫 traverseNodeToBuildSequenceFlow
private static void traverseNodeToBuildFlowNode(BpmSimpleModelNodeVO node, Process process) {
// 判断是否有效节点
// TODO-DONE @jason是不是写个 isValidNode 方法判断是否为有效节点
if (!isValidNode(node)) {
return;
}
BpmSimpleModelNodeType nodeType = BpmSimpleModelNodeType.valueOf(node.getType());
Assert.notNull(nodeType, "模型节点类型不支持");
// TODO-DONE @jason要不抽个 buildNode 方法然后返回一个 List<FlowElement>之后这个方法 addFlowElement原因是让当前这个方法有主干逻辑不然现在太长了
List<FlowElement> flowElements = buildFlowNode(node, nodeType);
flowElements.forEach(process::addFlowElement);
// 如果不是网关类型的接口 并且chileNode为空退出
// TODO-DONE @jason建议这个判断去掉可以更简洁一点因为往下走如果不成功本身也就会结束哈主要是这里多了一个这样的判断增加了理解成本
// 如果是分支节点则递归处理条件
if (BpmSimpleModelNodeType.isBranchNode(node.getType())
&& ArrayUtil.isNotEmpty(node.getConditionNodes())) {
// TODO-DONE @jason可以搞成 stream 写成一行哈
node.getConditionNodes().forEach(item -> traverseNodeToBuildFlowNode(item.getChildNode(), process));
}
// 如果有节点则递归处理子节点
// TODO-DONE @jason这个是不是不写判断直接继续调用因为本身 buildAndAddBpmnFlowNode 就会最开始判断了哈就不重复判断了
traverseNodeToBuildFlowNode(node.getChildNode(), process);
}
@ -291,16 +284,13 @@ public class SimpleModelUtils {
List<FlowElement> list = new ArrayList<>();
switch (nodeType) {
case START_NODE: {
// TODO-DONE @jason每个 nodeTypebuildXXX 方法要不更明确并且去掉 Bpmn
// @芋艿 改成 convert 是不是好理解一点
StartEvent startEvent = convertStartNode(node);
list.add(startEvent);
break;
}
case APPROVE_NODE: {
// TODO-DONE @jason这个搞成一个 buildUserTask然后把下面这 2 种节点搞在一起实现类这样 buildNode 里面可以更简洁
// TODO-DONE @jason这里还有个想法是不是可以所有的都叫 buildXXXNode然后里面有一些是 bpmn 相关的构建叫做 buildBpmnUserTask用于区分
// @芋艿 改成 convertXXXNode, 方面里面使用 buildBpmnXXXNode. 是否更好理解
// TODO @芋艿 改成 convertXXXNode, 方面里面使用 buildBpmnXXXNode. 是否更好理解
// 转换审批节点
List<FlowElement> flowElements = convertApproveNode(node);
list.addAll(flowElements);

View File

@ -50,31 +50,6 @@ public interface BpmModelService {
*/
byte[] getModelBpmnXML(String id);
/**
* 保存流程模型的 BPMN XML
*
* @param id 编号
* @param xmlBytes BPMN XML bytes
*/
// TODO @芋艿感觉可以不修改这个方法而是额外加一个方法传入 idbpmnjson
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);
// TODO @jason另外个问题因为是存储到 modelExtra 那需要 deploy 存储出快照 bpmn xml 一样目前我想到的就是存储到 BpmProcessDefinitionInfoDO 加一个 simple_model 字段text 类型可以看看还有啥方案
// TODO @jason另外个问题因为是存储到 modelExtra 那需要 deploy 存储出快照 bpmn xml 一样目前我想到的就是存储到 BpmProcessDefinitionInfoDO 加一个 simple_model 字段text 类型可以看看还有啥方案重要
}

View File

@ -107,7 +107,7 @@ public class BpmModelServiceImpl implements BpmModelService {
// 保存流程定义
repositoryService.saveModel(model);
// 保存 BPMN XML
saveModelBpmnXml(model.getId(), StrUtil.utf8Bytes(bpmnXml));
saveModelBpmnXml(model.getId(), bpmnXml);
return model.getId();
}
@ -125,7 +125,7 @@ public class BpmModelServiceImpl implements BpmModelService {
// 更新模型
repositoryService.saveModel(model);
// 更新 BPMN XML
saveModelBpmnXml(model.getId(), StrUtil.utf8Bytes(updateReqVO.getBpmnXml()));
saveModelBpmnXml(model.getId(), updateReqVO.getBpmnXml());
}
@Override
@ -218,23 +218,24 @@ public class BpmModelServiceImpl implements BpmModelService {
if (model == null) {
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());
return JsonUtils.parseObject(jsonBytes, BpmSimpleModelNodeVO.class);
}
@Override
public void updateSimpleModel(BpmSimpleModelUpdateReqVO reqVO) {
// 1.1 校验流程模型存在
// 1. 校验流程模型存在
Model model = getModel(reqVO.getModelId());
if (model == null) {
throw exception(MODEL_NOT_EXISTS);
}
// 1.2 JSON 转换成 bpmnModel
// 2.1 JSON 转换成 bpmnModel
BpmnModel bpmnModel = SimpleModelUtils.buildBpmnModel(model.getKey(), model.getName(), reqVO.getSimpleModel());
// 2.1 保存 Bpmn XML
saveModelBpmnXml(model.getId(), StrUtil.utf8Bytes(BpmnModelUtils.getBpmnXml(bpmnModel)));
// 2.2 保存 JSON 数据
// 2.2 保存 Bpmn XML
saveModelBpmnXml(model.getId(), BpmnModelUtils.getBpmnXml(bpmnModel));
// 2.3 保存 JSON 数据
saveModelSimpleJson(model.getId(), JsonUtils.toJsonByte(reqVO.getSimpleModel()));
}
@ -266,21 +267,18 @@ public class BpmModelServiceImpl implements BpmModelService {
}
}
@Override
public void saveModelBpmnXml(String id, byte[] xmlBytes) {
if (ArrayUtil.isEmpty(xmlBytes)) {
private void saveModelBpmnXml(String id, String bpmnXml) {
if (StrUtil.isEmpty(bpmnXml)) {
return;
}
repositoryService.addModelEditorSource(id, xmlBytes);
repositoryService.addModelEditorSource(id, StrUtil.utf8Bytes(bpmnXml));
}
@Override
public byte[] getModelSimpleJson(String id) {
private byte[] getModelSimpleJson(String id) {
return repositoryService.getModelEditorSourceExtra(id);
}
@Override
public void saveModelSimpleJson(String id, byte[] jsonBytes) {
private void saveModelSimpleJson(String id, byte[] jsonBytes) {
if (ArrayUtil.isEmpty(jsonBytes)) {
return;
}

View File

@ -13,6 +13,8 @@ import java.util.Collection;
*/
public interface BpmProcessInstanceCopyService {
// TODO @jason要不把 createProcessInstanceCopy 2 个方法一个方法参数是之前的 userIdstaskId一个方法是现在 userIdsprocessInstanceIdtaskIdtaskName
/**
* 流程实例的抄送
*

View File

@ -127,23 +127,23 @@ public interface BpmProcessInstanceService {
void updateProcessInstanceWhenCancel(FlowableCancelledEvent event);
/**
* 更新 ProcessInstance 拓展记录为完成
* 更新 ProcessInstance 为完成
*
* @param instance 流程任务
*/
void updateProcessInstanceWhenApprove(ProcessInstance instance);
/**
* 更新 ProcessInstance 拓展记录为不通过
* 更新 ProcessInstance 为不通过
*
* @param id 流程编号
* @param currentActivityId 当前的活动Id
* @param currentActivityId 当前的活动编号
* @param reason 理由例如说审批不通过时需要传递该值
*/
void updateProcessInstanceReject(String id, String currentActivityId, String reason);
/**
* 当流程结束时候 更新 ProcessInstance
* 当流程结束时候更新 ProcessInstance 为通过
*
* @param instance 流程任务
*/

View File

@ -129,6 +129,7 @@ public interface BpmTaskService {
*/
Task getTask(String id);
// TODO @jasonjason这个貌似可以去掉了
/**
* 根据条件查询已经分配的用户任务列表
* @param processInstanceId 流程实例编号不允许为空

View File

@ -335,14 +335,18 @@ public class BpmTaskServiceImpl implements BpmTaskService {
// 2.2 添加评论
taskService.addComment(task.getId(), task.getProcessInstanceId(), BpmCommentTypeEnum.REJECT.getType(),
BpmCommentTypeEnum.REJECT.formatComment(reqVO.getReason()));
// 3.1 解析用户任务的拒绝处理类型
BpmnModel bpmnModel = bpmModelService.getBpmnModelByDefinitionId(task.getProcessDefinitionId());
// TODO @jason342 344 最好抽象一个方法出来哈放在 BpmnModelUtils参照类似 parseCandidateStrategy
UserTask flowElement = (UserTask) BpmnModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey());
Integer rejectHandlerType = NumberUtils.parseInt(BpmnModelUtils.parseExtensionElement(flowElement, USER_TASK_REJECT_HANDLER_TYPE));
BpmUserTaskRejectHandlerType userTaskRejectHandlerType = BpmUserTaskRejectHandlerType.typeOf(rejectHandlerType);
// 3.2 类型为驳回到指定的任务节点
// 3.2 类型为驳回到指定的任务节点 TODO @jason下面这种判断最好是 JSON
if (userTaskRejectHandlerType == BpmUserTaskRejectHandlerType.RETURN_PRE_USER_TASK) {
// TODO @jason348 最好抽象一个方法出来哈放在 BpmnModelUtils参照类似 parseCandidateStrategy
String returnTaskId = BpmnModelUtils.parseExtensionElement(flowElement, USER_TASK_REJECT_RETURN_TASK_ID);
// TODO @jason这里如果找不到直接抛出系统异常因为说白了已经不是业务异常啦
if (returnTaskId == null) {
throw exception(TASK_RETURN_NOT_ASSIGN_TARGET_TASK_ID);
}
@ -351,6 +355,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
returnTask(userId, returnReq);
return;
} else if (userTaskRejectHandlerType == BpmUserTaskRejectHandlerType.FINISH_PROCESS_BY_REJECT_NUMBER) {
// TODO @jason微信沟通去掉类似的逻辑
// 3.3 按拒绝人数终止流程
if (!flowElement.hasMultiInstanceLoopCharacteristics()) {
log.error("[rejectTask] 按拒绝人数终止流程类型,只能用于会签任务. 当前任务【{}】不是会签任务", task.getId());
@ -362,7 +367,8 @@ public class BpmTaskServiceImpl implements BpmTaskService {
return;
}
// 3.4 其他情况 终止流程
processInstanceService.updateProcessInstanceReject(instance.getProcessInstanceId(), task.getTaskDefinitionKey(), reqVO.getReason());
processInstanceService.updateProcessInstanceReject(instance.getProcessInstanceId(),
task.getTaskDefinitionKey(), reqVO.getReason());
}
/**