Merge remote-tracking branch 'origin/feature/bpm' into feature/bpm
This commit is contained in:
commit
d36fc98f01
|
@ -128,7 +128,7 @@ public class YudaoWebSecurityConfigurerAdapter {
|
|||
// ①:全局共享规则
|
||||
.authorizeHttpRequests(c -> c
|
||||
// 1.1 静态资源,可匿名访问
|
||||
.requestMatchers(HttpMethod.GET, "/*.html", "/*.html", "/*.css", "/*.js").permitAll()
|
||||
.requestMatchers(HttpMethod.GET, "/*.html", "/*.css", "/*.js").permitAll()
|
||||
// 1.2 设置 @PermitAll 无需认证
|
||||
.requestMatchers(HttpMethod.GET, permitAllUrls.get(HttpMethod.GET).toArray(new String[0])).permitAll()
|
||||
.requestMatchers(HttpMethod.POST, permitAllUrls.get(HttpMethod.POST).toArray(new String[0])).permitAll()
|
||||
|
|
|
@ -38,6 +38,7 @@ public interface ErrorCodeConstants {
|
|||
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, "任务({})的候选人({})不存在");
|
||||
ErrorCode PROCESS_INSTANCE_START_USER_CAN_START = new ErrorCode(1_009_004_005, "发起流程失败,你没有权限发起该流程");
|
||||
ErrorCode PROCESS_INSTANCE_CANCEL_FAIL_NOT_ALLOW = new ErrorCode(1_009_004_005, "流程取消失败,该流程不允许取消");
|
||||
|
||||
// ========== 流程任务 1-009-005-000 ==========
|
||||
ErrorCode TASK_OPERATE_FAIL_ASSIGN_NOT_SELF = new ErrorCode(1_009_005_001, "操作失败,原因:该任务的审批人不是你");
|
||||
|
@ -55,6 +56,7 @@ public interface ErrorCodeConstants {
|
|||
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, "操作失败,原因:找不到任务的审批人!");
|
||||
ErrorCode TASK_SIGNATURE_NOT_EXISTS = new ErrorCode(1_009_005_015, "签名不能为空!");
|
||||
ErrorCode TASK_REASON_REQUIRE = new ErrorCode(1_009_005_016, "审批意见不能为空!");
|
||||
|
||||
// ========== 动态表单模块 1-009-010-000 ==========
|
||||
ErrorCode FORM_NOT_EXISTS = new ErrorCode(1_009_010_000, "动态表单不存在");
|
||||
|
|
|
@ -161,6 +161,15 @@ public class BpmModelController {
|
|||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/clean")
|
||||
@Operation(summary = "清理模型")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:model:clean')")
|
||||
public CommonResult<Boolean> cleanModel(@RequestParam("id") String id) {
|
||||
modelService.cleanModel(getLoginUserId(), id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
// ========== 仿钉钉/飞书的精简模型 =========
|
||||
|
||||
@GetMapping("/simple/get")
|
||||
|
|
|
@ -62,4 +62,7 @@ public class BpmModelMetaInfoVO {
|
|||
@Schema(description = "排序", example = "1")
|
||||
private Long sort; // 创建时,后端自动生成
|
||||
|
||||
@Schema(description = "允许撤销审批中的申请", example = "true")
|
||||
private Boolean allowCancelRunningProcess;
|
||||
|
||||
}
|
||||
|
|
|
@ -63,6 +63,9 @@ public class BpmSimpleModelNodeVO {
|
|||
@Schema(description = "是否需要签名", example = "false")
|
||||
private Boolean signEnable;
|
||||
|
||||
@Schema(description = "是否填写审批意见", example = "false")
|
||||
private Boolean reasonRequire;
|
||||
|
||||
/**
|
||||
* 审批节点拒绝处理
|
||||
*/
|
||||
|
|
|
@ -101,9 +101,8 @@ public class BpmApprovalDetailRespVO {
|
|||
@Schema(description = "审批意见", example = "同意")
|
||||
private String reason;
|
||||
|
||||
// TODO @lesan:改成 signPicUrl 会好点
|
||||
@Schema(description = "签名", example = "https://www.iocoder.cn/sign.png")
|
||||
private String sign;
|
||||
private String signPicUrl;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -14,13 +14,11 @@ public class BpmTaskApproveReqVO {
|
|||
@NotEmpty(message = "任务编号不能为空")
|
||||
private String id;
|
||||
|
||||
@Schema(description = "审批意见", requiredMode = Schema.RequiredMode.REQUIRED, example = "不错不错!")
|
||||
@NotEmpty(message = "审批意见不能为空")
|
||||
@Schema(description = "审批意见", example = "不错不错!")
|
||||
private String reason;
|
||||
|
||||
// TODO @lesan:改成 signPicUrl 会好点
|
||||
@Schema(description = "签名", example = "https://www.iocoder.cn/sign.png")
|
||||
private String sign;
|
||||
private String signPicUrl;
|
||||
|
||||
@Schema(description = "变量实例(动态表单)", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Map<String, Object> variables;
|
||||
|
|
|
@ -14,7 +14,6 @@ public class BpmTaskRejectReqVO {
|
|||
private String id;
|
||||
|
||||
@Schema(description = "审批意见", requiredMode = Schema.RequiredMode.REQUIRED, example = "不错不错!")
|
||||
@NotEmpty(message = "审批意见不能为空")
|
||||
private String reason;
|
||||
|
||||
}
|
||||
|
|
|
@ -78,9 +78,12 @@ public class BpmTaskRespVO {
|
|||
@Schema(description = "操作按钮设置值")
|
||||
private Map<Integer, OperationButtonSetting> buttonsSetting;
|
||||
|
||||
@Schema(description = "是否需要签名")
|
||||
@Schema(description = "是否需要签名", example = "false")
|
||||
private Boolean signEnable;
|
||||
|
||||
@Schema(description = "是否填写审批意见", example = "false")
|
||||
private Boolean reasonRequire;
|
||||
|
||||
@Data
|
||||
@Schema(description = "流程实例")
|
||||
public static class ProcessInstance {
|
||||
|
|
|
@ -187,7 +187,7 @@ public interface BpmProcessInstanceConvert {
|
|||
}
|
||||
return BeanUtils.toBean(task, BpmApprovalDetailRespVO.ActivityNodeTask.class)
|
||||
.setStatus(FlowableUtils.getTaskStatus(task)).setReason(FlowableUtils.getTaskReason(task))
|
||||
.setSign(FlowableUtils.getTaskSign(task));
|
||||
.setSignPicUrl(FlowableUtils.getTaskSignPicUrl(task));
|
||||
}
|
||||
|
||||
default Set<Long> parseUserIds(HistoricProcessInstance processInstance,
|
||||
|
|
|
@ -150,4 +150,9 @@ public class BpmProcessDefinitionInfoDO extends BaseDO {
|
|||
@TableField(typeHandler = StringListTypeHandler.class) // 为了可以使用 find_in_set 进行过滤
|
||||
private List<Long> managerUserIds;
|
||||
|
||||
/**
|
||||
* 是否允许撤销审批中的申请
|
||||
*/
|
||||
private Boolean allowCancelRunningProcess;
|
||||
|
||||
}
|
||||
|
|
|
@ -115,4 +115,9 @@ public interface BpmnModelConstants {
|
|||
*/
|
||||
String SIGN_ENABLE = "signEnable";
|
||||
|
||||
/**
|
||||
* 审批意见是否必填
|
||||
*/
|
||||
String REASON_REQUIRE = "reasonRequire";
|
||||
|
||||
}
|
||||
|
|
|
@ -43,6 +43,13 @@ public class BpmnVariableConstants {
|
|||
* @see ProcessInstance#getProcessVariables()
|
||||
*/
|
||||
public static final String PROCESS_INSTANCE_VARIABLE_RETURN_FLAG = "RETURN_FLAG_%s";
|
||||
/**
|
||||
* 流程实例的变量 - 是否跳过表达式
|
||||
*
|
||||
* @see ProcessInstance#getProcessVariables()
|
||||
* @see <a href="https://blog.csdn.net/weixin_42065235/article/details/126039993">Flowable/Activiti之SkipExpression 完成自动审批</a>
|
||||
*/
|
||||
public static final String PROCESS_INSTANCE_SKIP_EXPRESSION_ENABLED = "_FLOWABLE_SKIP_EXPRESSION_ENABLED";
|
||||
|
||||
/**
|
||||
* 任务的变量 - 状态
|
||||
|
@ -58,8 +65,9 @@ public class BpmnVariableConstants {
|
|||
* @see org.flowable.task.api.Task#getTaskLocalVariables()
|
||||
*/
|
||||
public static final String TASK_VARIABLE_REASON = "TASK_REASON";
|
||||
|
||||
// TODO @lesan:TASK_SIGN_PIC_URL 。。。虽然长一点,嘿嘿
|
||||
public static final String TASK_VARIABLE_SIGN = "TASK_SIGN";
|
||||
/**
|
||||
* 任务变量 - 签名图片 URL
|
||||
*/
|
||||
public static final String TASK_SIGN_PIC_URL = "TASK_SIGN_PIC_URL";
|
||||
|
||||
}
|
||||
|
|
|
@ -39,10 +39,10 @@ public class BpmProcessInstanceEventListener extends AbstractFlowableEngineEvent
|
|||
processInstanceService.processProcessInstanceCompleted((ProcessInstance)event.getEntity());
|
||||
}
|
||||
|
||||
@Override
|
||||
// 特殊情况:当跳转到 EndEvent 流程实例未结束, 会执行 deleteProcessInstance 方法。
|
||||
@Override // 特殊情况:当跳转到 EndEvent 流程实例未结束, 会执行 deleteProcessInstance 方法
|
||||
protected void processCancelled(FlowableCancelledEvent event) {
|
||||
ProcessInstance processInstance = processInstanceService.getProcessInstance(event.getProcessInstanceId());
|
||||
processInstanceService.processProcessInstanceCompleted(processInstance);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -365,6 +365,23 @@ public class BpmnModelUtils {
|
|||
return Convert.toBool(extensionElements.get(0).getElementText(), false);
|
||||
}
|
||||
|
||||
public static void addReasonRequire(Boolean reasonRequire, FlowElement userTask) {
|
||||
addExtensionElement(userTask, REASON_REQUIRE,
|
||||
ObjUtil.isNotNull(reasonRequire) ? reasonRequire.toString() : Boolean.FALSE.toString());
|
||||
}
|
||||
|
||||
public static Boolean parseReasonRequire(BpmnModel bpmnModel, String flowElementId) {
|
||||
FlowElement flowElement = getFlowElementById(bpmnModel, flowElementId);
|
||||
if (flowElement == null) {
|
||||
return false;
|
||||
}
|
||||
List<ExtensionElement> extensionElements = flowElement.getExtensionElements().get(REASON_REQUIRE);
|
||||
if (CollUtil.isEmpty(extensionElements)) {
|
||||
return false;
|
||||
}
|
||||
return Convert.toBool(extensionElements.get(0).getElementText(), false);
|
||||
}
|
||||
|
||||
public static void addListenerConfig(FlowableListener flowableListener, BpmSimpleModelNodeVO.ListenerHandler handler) {
|
||||
FieldExtension fieldExtension = new FieldExtension();
|
||||
fieldExtension.setFieldName("listenerConfig");
|
||||
|
|
|
@ -213,9 +213,14 @@ public class FlowableUtils {
|
|||
return (String) task.getTaskLocalVariables().get(BpmnVariableConstants.TASK_VARIABLE_REASON);
|
||||
}
|
||||
|
||||
// TODO @lesan:这个方法名,也改咧
|
||||
public static String getTaskSign(TaskInfo task) {
|
||||
return (String) task.getTaskLocalVariables().get(BpmnVariableConstants.TASK_VARIABLE_SIGN);
|
||||
/**
|
||||
* 获得任务的签名图片 URL
|
||||
*
|
||||
* @param task 任务
|
||||
* @return 签名图片 URL
|
||||
*/
|
||||
public static String getTaskSignPicUrl(TaskInfo task) {
|
||||
return (String) task.getTaskLocalVariables().get(BpmnVariableConstants.TASK_SIGN_PIC_URL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -441,6 +441,8 @@ public class SimpleModelUtils {
|
|||
addUserTaskListener(node, userTask);
|
||||
// 添加是否需要签名
|
||||
addSignEnable(node.getSignEnable(), userTask);
|
||||
// 审批意见
|
||||
addReasonRequire(node.getReasonRequire(), userTask);
|
||||
return userTask;
|
||||
}
|
||||
|
||||
|
|
|
@ -88,6 +88,14 @@ public interface BpmModelService {
|
|||
*/
|
||||
void deleteModel(Long userId, String id);
|
||||
|
||||
/**
|
||||
* 清理模型,包括流程实例
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param id 编号
|
||||
*/
|
||||
void cleanModel(Long userId, String id);
|
||||
|
||||
/**
|
||||
* 修改模型的状态,实际更新的部署的流程定义的状态
|
||||
*
|
||||
|
|
|
@ -14,6 +14,7 @@ import cn.iocoder.yudao.module.bpm.convert.definition.BpmModelConvert;
|
|||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
|
||||
import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum;
|
||||
import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelTypeEnum;
|
||||
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.util.BpmnModelUtils;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
|
||||
|
@ -25,10 +26,14 @@ import org.flowable.bpmn.model.BpmnModel;
|
|||
import org.flowable.bpmn.model.StartEvent;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.flowable.common.engine.impl.db.SuspensionState;
|
||||
import org.flowable.engine.HistoryService;
|
||||
import org.flowable.engine.RepositoryService;
|
||||
import org.flowable.engine.RuntimeService;
|
||||
import org.flowable.engine.history.HistoricProcessInstance;
|
||||
import org.flowable.engine.repository.Model;
|
||||
import org.flowable.engine.repository.ModelQuery;
|
||||
import org.flowable.engine.repository.ProcessDefinition;
|
||||
import org.flowable.engine.runtime.ProcessInstance;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
@ -63,6 +68,11 @@ public class BpmModelServiceImpl implements BpmModelService {
|
|||
@Resource
|
||||
private BpmTaskCandidateInvoker taskCandidateInvoker;
|
||||
|
||||
@Resource
|
||||
private HistoryService historyService;
|
||||
@Resource
|
||||
private RuntimeService runtimeService;
|
||||
|
||||
@Override
|
||||
public List<Model> getModelList(String name) {
|
||||
ModelQuery modelQuery = repositoryService.createModelQuery();
|
||||
|
@ -246,6 +256,31 @@ public class BpmModelServiceImpl implements BpmModelService {
|
|||
updateProcessDefinitionSuspended(model.getDeploymentId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanModel(Long userId, String id) {
|
||||
// 1. 校验流程模型存在
|
||||
Model model = validateModelManager(id, userId);
|
||||
|
||||
// 2. 清理所有流程数据
|
||||
// TODO @芋艿:这里没有找到批量操作的方法,会不会有性能问题~;
|
||||
// TODO @lesan:建议按照顺序?1)List<ProcessInstance> processInstances 循环处理;然后删除删除一个示实例,接着删除它的 history;
|
||||
// 2.1 先取消所有正在运行的流程
|
||||
List<ProcessInstance> processInstances = runtimeService.createProcessInstanceQuery()
|
||||
.processDefinitionKey(model.getKey()).list();
|
||||
processInstances.forEach(processInstance -> {
|
||||
runtimeService.deleteProcessInstance(processInstance.getId(),
|
||||
BpmReasonEnum.CANCEL_BY_SYSTEM.getReason());
|
||||
});
|
||||
// 2.2 再从历史中删除所有相关的流程数据
|
||||
List<HistoricProcessInstance> historicProcessInstances = historyService.createHistoricProcessInstanceQuery()
|
||||
.processDefinitionKey(model.getKey()).list();
|
||||
historicProcessInstances.forEach(historicProcessInstance -> {
|
||||
historyService.deleteHistoricProcessInstance(historicProcessInstance.getId());
|
||||
});
|
||||
// TODO @lesan:流程任务,是不是也要清理哈?
|
||||
// TODO @lesan:抄送是不是也要清理;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateModelState(Long userId, String id, Integer state) {
|
||||
// 1.1 校验流程模型存在
|
||||
|
|
|
@ -595,6 +595,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
|||
variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_ID, userId); // 设置流程变量,发起人 ID
|
||||
variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS, // 流程实例状态:审批中
|
||||
BpmProcessInstanceStatusEnum.RUNNING.getStatus());
|
||||
variables.put(BpmnVariableConstants.PROCESS_INSTANCE_SKIP_EXPRESSION_ENABLED, true); // 跳过表达式需要添加此变量为 true,不影响没配置 skipExpression 的节点
|
||||
if (CollUtil.isNotEmpty(startUserSelectAssignees)) {
|
||||
variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_SELECT_ASSIGNEES, startUserSelectAssignees);
|
||||
}
|
||||
|
@ -641,6 +642,13 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
|||
if (!Objects.equals(instance.getStartUserId(), String.valueOf(userId))) {
|
||||
throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF);
|
||||
}
|
||||
// 1.3 校验允许撤销审批中的申请
|
||||
BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.getProcessDefinitionInfo(instance.getProcessDefinitionId());
|
||||
Assert.notNull(processDefinitionInfo, "流程定义({})不存在", processDefinitionInfo);
|
||||
if (processDefinitionInfo.getAllowCancelRunningProcess() != null // 防止未配置 AllowCancelRunningProcess , 默认为可取消
|
||||
&& Boolean.FALSE.equals(processDefinitionInfo.getAllowCancelRunningProcess())) {
|
||||
throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_ALLOW);
|
||||
}
|
||||
|
||||
// 2. 取消流程
|
||||
updateProcessInstanceCancel(cancelReqVO.getId(),
|
||||
|
|
|
@ -64,6 +64,7 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU
|
|||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
|
||||
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
|
||||
import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_RETURN_FLAG;
|
||||
import static cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils.parseReasonRequire;
|
||||
import static cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils.parseSignEnable;
|
||||
|
||||
/**
|
||||
|
@ -163,6 +164,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||
Map<Integer, BpmTaskRespVO.OperationButtonSetting> buttonsSetting = BpmnModelUtils.parseButtonsSetting(
|
||||
bpmnModel, todoTask.getTaskDefinitionKey());
|
||||
Boolean signEnable = parseSignEnable(bpmnModel, todoTask.getTaskDefinitionKey());
|
||||
Boolean reasonRequire = parseReasonRequire(bpmnModel, todoTask.getTaskDefinitionKey());
|
||||
|
||||
// 4. 任务表单
|
||||
BpmFormDO taskForm = null;
|
||||
|
@ -171,7 +173,8 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||
}
|
||||
|
||||
return BpmTaskConvert.INSTANCE.buildTodoTask(todoTask, childrenTasks, buttonsSetting, taskForm)
|
||||
.setSignEnable(signEnable);
|
||||
.setSignEnable(signEnable)
|
||||
.setReasonRequire(reasonRequire);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -485,9 +488,14 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||
// 1.3 校验签名
|
||||
BpmnModel bpmnModel = modelService.getBpmnModelByDefinitionId(task.getProcessDefinitionId());
|
||||
Boolean signEnable = parseSignEnable(bpmnModel, task.getTaskDefinitionKey());
|
||||
if (signEnable && StrUtil.isEmpty(reqVO.getSign())) {
|
||||
if (signEnable && StrUtil.isEmpty(reqVO.getSignPicUrl())) {
|
||||
throw exception(TASK_SIGNATURE_NOT_EXISTS);
|
||||
}
|
||||
// 1.4 校验审批意见
|
||||
Boolean reasonRequire = parseReasonRequire(bpmnModel, task.getTaskDefinitionKey());
|
||||
if (reasonRequire && StrUtil.isEmpty(reqVO.getReason())) {
|
||||
throw exception(TASK_REASON_REQUIRE);
|
||||
}
|
||||
|
||||
// 情况一:被委派的任务,不调用 complete 去完成任务
|
||||
if (DelegationState.PENDING.equals(task.getDelegationState())) {
|
||||
|
@ -505,7 +513,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||
// 2.1 更新 task 状态、原因、签字
|
||||
updateTaskStatusAndReason(task.getId(), BpmTaskStatusEnum.APPROVE.getStatus(), reqVO.getReason());
|
||||
if (signEnable) {
|
||||
taskService.setVariableLocal(task.getId(), BpmnVariableConstants.TASK_VARIABLE_SIGN, reqVO.getSign());
|
||||
taskService.setVariableLocal(task.getId(), BpmnVariableConstants.TASK_SIGN_PIC_URL, reqVO.getSignPicUrl());
|
||||
}
|
||||
// 2.2 添加评论
|
||||
taskService.addComment(task.getId(), task.getProcessInstanceId(), BpmCommentTypeEnum.APPROVE.getType(),
|
||||
|
@ -859,10 +867,11 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||
.moveActivityIdsToSingleActivityId(activityIds, endEvent.getId())
|
||||
.changeState();
|
||||
|
||||
// 3. 如果跳转到 EndEvent 流程还未结束, 执行 deleteProcessInstance 方法。
|
||||
List<Execution> executionList = runtimeService.createExecutionQuery().processInstanceId(processInstanceId).list();
|
||||
if (CollUtil.isNotEmpty(executionList)) {
|
||||
log.warn("执行跳转到 EndEvent 后, 流程实例未结束。执行 [deleteProcessInstance] 方法");
|
||||
// 3. 特殊:如果跳转到 EndEvent 流程还未结束, 执行 deleteProcessInstance 方法
|
||||
// TODO 芋艿:目前发现并行分支情况下,会存在这个情况,后续看看有没更好的方案;
|
||||
List<Execution> executions = runtimeService.createExecutionQuery().processInstanceId(processInstanceId).list();
|
||||
if (CollUtil.isNotEmpty(executions)) {
|
||||
log.warn("[moveTaskToEnd][执行跳转到 EndEvent 后, 流程实例未结束,强制执行 deleteProcessInstance 方法]");
|
||||
runtimeService.deleteProcessInstance(processInstanceId, reason);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ import static cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WxPayClient
|
|||
/**
|
||||
* 微信支付抽象类,实现微信统一的接口、以及部分实现(退款)
|
||||
*
|
||||
* @author 遇到源码
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Slf4j
|
||||
public abstract class AbstractWxPayClient extends AbstractPayClient<WxPayClientConfig> {
|
||||
|
|
Loading…
Reference in New Issue