update - 开发选人的逻辑架构, 等待 API 模型定义好后接入.新增 mock 选人组件,方便开发时调整不同的审批人.

This commit is contained in:
wangli 2023-11-17 18:53:15 +08:00
parent db38849be5
commit 614939a152
30 changed files with 579 additions and 275 deletions

View File

@ -342,9 +342,9 @@ API:
API:
**(添加评论)**: cn.axzo.workflow.core.service.BpmnTaskService.commentTask
**(添加评论)**: cn.axzo.workflow.core.service.BpmnProcessTaskService.commentTask
**(添加附件)**: cn.axzo.workflow.core.service.BpmnTaskService.attachmentTask
**(添加附件)**: cn.axzo.workflow.core.service.BpmnProcessTaskService.attachmentTask
操作的库表:

View File

@ -60,6 +60,11 @@
<artifactId>workflow-engine-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>cn.axzo.maokai</groupId>
<artifactId>maokai-api</artifactId>
<version>${axzo-dependencies.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>

View File

@ -0,0 +1,25 @@
package cn.axzo.workflow.client.feign.bpmn;
import cn.azxo.framework.common.model.CommonResponse;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import javax.validation.constraints.NotBlank;
/**
* 流程活动的 API
*
* @author wangli
* @since 2023/11/17 16:28
*/
@FeignClient(name = "workflow-engine", url = "${axzo.service.workflow-engine:http://workflow-engine:8080}")
public interface ProcessActivityApi {
/**
* 业务节点唤醒
*/
@GetMapping("/api/process/activity/trigger")
CommonResponse<Boolean> trigger(@NotBlank(message = "活动 ID 不能为空") @RequestParam String processActivityId);
}

View File

@ -4,7 +4,7 @@ import lombok.Data;
import lombok.experimental.Accessors;
/**
* TODO
* 按钮元数据
*
* @author wangli
* @since 2023/11/14 23:53

View File

@ -84,5 +84,9 @@
<groupId>cn.axzo.workflow</groupId>
<artifactId>workflow-engine-common</artifactId>
</dependency>
<dependency>
<groupId>cn.axzo.maokai</groupId>
<artifactId>maokai-api</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -389,7 +389,7 @@ public final class BpmnJsonConverterUtil {
mainProcess.addFlowElement(flowElement);
if (Lists.newArrayList(preNodeIds).isEmpty()) {
// first time entrance, nothing to do.
// first time entrance, do nothing.
} else if (Lists.newArrayList(preNodeIds).size() == 1 && !NODE_CONDITION.equals(bpmnJsonNode.getType())) {
mainProcess.addFlowElement(convertJsonToElement(SequenceFlow.class, bpmnJsonNode, mainProcess));
} else {

View File

@ -0,0 +1,64 @@
package cn.axzo.workflow.core.deletage;
import cn.axzo.framework.domain.web.result.ApiResult;
import cn.axzo.maokai.api.client.OrganizationalNodeUserApi;
import cn.axzo.maokai.api.vo.request.FlowTaskAssignerReq;
import cn.axzo.maokai.api.vo.response.FlowTaskAssigner;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.http.HttpStatus;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.UserTask;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.function.Supplier;
/**
* 抽象的流程任务审批人选择器
*
* @author wangli
* @since 2023/11/17 11:35
*/
@Slf4j
public abstract class AbstractBpmnTaskAssigneeSelector implements BpmnTaskAssigneeSelector {
@Resource
private OrganizationalNodeUserApi nodeUserApi;
protected abstract FlowTaskAssignerReq buildQuery(UserTask userTask);
@Override
public final List<BpmnTaskDelegateAssigner> select(UserTask userTask) {
FlowTaskAssignerReq query = buildQuery(userTask);
List<FlowTaskAssigner> flowTaskAssigners = null;
try {
flowTaskAssigners = parseApiResult(() ->
nodeUserApi.listFlowTaskAssigner(query), "根据配置查询审批候选人", query);
} catch (Exception e) {
throw new WorkflowEngineException("调用 API 查询审批候选人出现异常: " + e.getMessage());
}
if (CollectionUtils.isEmpty(flowTaskAssigners)) {
return Collections.emptyList();
}
return BeanUtil.copyToList(flowTaskAssigners, BpmnTaskDelegateAssigner.class);
}
private <T> T parseApiResult(Supplier<ApiResult<T>> supplier, String operatorDesc, Object... param) {
log.info(operatorDesc + "-Param: " + JSONUtil.toJsonStr(param));
ApiResult<T> result = supplier.get();
log.info(operatorDesc + "-Result: " + JSONUtil.toJsonStr(result));
Assert.notNull(result, "服务调用异常");
// 200自定义处理
if (HttpStatus.HTTP_OK != result.getCode()) {
throw new WorkflowEngineException(result.getMsg());
}
return result.getData();
}
}

View File

@ -1,12 +1,10 @@
package cn.axzo.workflow.core.deletage;
import cn.axzo.maokai.api.vo.request.FlowTaskAssignerReq;
import cn.axzo.workflow.common.enums.ApproverEmptyHandleTypeEnum;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import org.flowable.bpmn.model.UserTask;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 基于"转交给管理员"查询审批人
*
@ -14,14 +12,16 @@ import java.util.List;
* @since 2023/11/16 11:44
*/
@Component
public class AdminTaskAssigneeSelector implements BpmnTaskAssigneeSelector {
public class AdminTaskAssigneeSelector extends AbstractBpmnTaskAssigneeSelector {
@Override
public boolean support(String param) {
return ApproverEmptyHandleTypeEnum.transferToAdmin.getType().equals(param);
}
@Override
public List<BpmnTaskDelegateAssigner> select(UserTask userTask) {
protected FlowTaskAssignerReq buildQuery(UserTask userTask) {
return null;
}
}

View File

@ -1,21 +0,0 @@
package cn.axzo.workflow.core.deletage;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.JavaDelegate;
import org.springframework.stereotype.Component;
/**
* TODO
*
* @author wangli
* @since 2023/7/31 20:20
*/
@Component
@Slf4j
public class CheckDueDateDelegate implements JavaDelegate {
@Override
public void execute(DelegateExecution execution) {
log.info("cycle exec...");
}
}

View File

@ -1,12 +1,10 @@
package cn.axzo.workflow.core.deletage;
import cn.axzo.maokai.api.vo.request.FlowTaskAssignerReq;
import cn.axzo.workflow.common.enums.ApproverSpecifyEnum;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import org.flowable.bpmn.model.UserTask;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 基于"身份"查询审批人
*
@ -14,14 +12,15 @@ import java.util.List;
* @since 2023/11/16 11:38
*/
@Component
public class IdentityTaskAssigneeSelector implements BpmnTaskAssigneeSelector {
public class IdentityTaskAssigneeSelector extends AbstractBpmnTaskAssigneeSelector {
@Override
public boolean support(String param) {
return ApproverSpecifyEnum.identity.getType().equals(param);
}
@Override
public List<BpmnTaskDelegateAssigner> select(UserTask userTask) {
protected FlowTaskAssignerReq buildQuery(UserTask userTask) {
return null;
}
}

View File

@ -1,12 +1,10 @@
package cn.axzo.workflow.core.deletage;
import cn.axzo.maokai.api.vo.request.FlowTaskAssignerReq;
import cn.axzo.workflow.common.enums.ApproverSpecifyEnum;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import org.flowable.bpmn.model.UserTask;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 给予"发起人多级主管"查询审批人
*
@ -14,14 +12,15 @@ import java.util.List;
* @since 2023/11/16 11:42
*/
@Component
public class InitiatorLeaderRecursionTaskAssigneeSelector implements BpmnTaskAssigneeSelector {
public class InitiatorLeaderRecursionTaskAssigneeSelector extends AbstractBpmnTaskAssigneeSelector {
@Override
public boolean support(String param) {
return ApproverSpecifyEnum.initiatorLeaderRecursion.getType().equals(param);
}
@Override
public List<BpmnTaskDelegateAssigner> select(UserTask userTask) {
protected FlowTaskAssignerReq buildQuery(UserTask userTask) {
return null;
}
}

View File

@ -1,12 +1,10 @@
package cn.axzo.workflow.core.deletage;
import cn.axzo.maokai.api.vo.request.FlowTaskAssignerReq;
import cn.axzo.workflow.common.enums.ApproverSpecifyEnum;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import org.flowable.bpmn.model.UserTask;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 基于"发起人多级主管"查询审批人
*
@ -14,14 +12,14 @@ import java.util.List;
* @since 2023/11/16 11:41
*/
@Component
public class InitiatorLeaderTaskAssigneeSelector implements BpmnTaskAssigneeSelector {
public class InitiatorLeaderTaskAssigneeSelector extends AbstractBpmnTaskAssigneeSelector {
@Override
public boolean support(String param) {
return ApproverSpecifyEnum.initiatorLeader.getType().equals(param);
}
@Override
public List<BpmnTaskDelegateAssigner> select(UserTask userTask) {
protected FlowTaskAssignerReq buildQuery(UserTask userTask) {
return null;
}
}

View File

@ -0,0 +1,27 @@
package cn.axzo.workflow.core.deletage;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import org.flowable.bpmn.model.UserTask;
import java.util.ArrayList;
import java.util.List;
/**
* 开发阶段的模拟审批人查询
*
* @author wangli
* @since 2023/11/17 13:40
*/
public class MockTaskAssigneeSelector implements BpmnTaskAssigneeSelector {
@Override
public boolean support(String param) {
return true;
}
@Override
public List<BpmnTaskDelegateAssigner> select(UserTask userTask) {
List<BpmnTaskDelegateAssigner> users = new ArrayList<>();
return users;
}
}

View File

@ -1,12 +1,10 @@
package cn.axzo.workflow.core.deletage;
import cn.axzo.maokai.api.vo.request.FlowTaskAssignerReq;
import cn.axzo.workflow.common.enums.ApproverSpecifyEnum;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import org.flowable.bpmn.model.UserTask;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 基于"岗位"查询审批人
*
@ -14,14 +12,14 @@ import java.util.List;
* @since 2023/11/16 11:35
*/
@Component
public class PositionTaskAssigneeSelector implements BpmnTaskAssigneeSelector {
public class PositionTaskAssigneeSelector extends AbstractBpmnTaskAssigneeSelector {
@Override
public boolean support(String param) {
return ApproverSpecifyEnum.position.getType().equals(param);
}
@Override
public List<BpmnTaskDelegateAssigner> select(UserTask userTask) {
protected FlowTaskAssignerReq buildQuery(UserTask userTask) {
return null;
}
}

View File

@ -1,12 +1,10 @@
package cn.axzo.workflow.core.deletage;
import cn.axzo.maokai.api.vo.request.FlowTaskAssignerReq;
import cn.axzo.workflow.common.enums.ApproverSpecifyEnum;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import org.flowable.bpmn.model.UserTask;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 基于"角色"查询审批人
*
@ -14,14 +12,14 @@ import java.util.List;
* @since 2023/11/16 11:37
*/
@Component
public class RoleTaskAssigneeSelector implements BpmnTaskAssigneeSelector {
public class RoleTaskAssigneeSelector extends AbstractBpmnTaskAssigneeSelector {
@Override
public boolean support(String param) {
return ApproverSpecifyEnum.role.getType().equals(param);
}
@Override
public List<BpmnTaskDelegateAssigner> select(UserTask userTask) {
protected FlowTaskAssignerReq buildQuery(UserTask userTask) {
return null;
}
}

View File

@ -32,7 +32,7 @@ import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import java.util.List;
/**
* TODO
* 自定义的用户审批任务节点行为处理器
*
* @author wangli
* @since 2023/7/29 01:11

View File

@ -4,9 +4,17 @@ import cn.axzo.framework.jackson.utility.JSON;
import cn.axzo.workflow.core.listener.BpmnActivityEventListener;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.api.delegate.event.AbstractFlowableEventListener;
import org.flowable.common.engine.api.delegate.event.FlowableEvent;
import org.flowable.common.engine.api.delegate.event.FlowableEventType;
import org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener;
import org.flowable.engine.delegate.event.FlowableActivityCancelledEvent;
import org.flowable.engine.delegate.event.FlowableActivityEvent;
import org.flowable.engine.delegate.event.FlowableErrorEvent;
import org.flowable.engine.delegate.event.FlowableMessageEvent;
import org.flowable.engine.delegate.event.FlowableMultiInstanceActivityCancelledEvent;
import org.flowable.engine.delegate.event.FlowableMultiInstanceActivityCompletedEvent;
import org.flowable.engine.delegate.event.FlowableMultiInstanceActivityEvent;
import org.flowable.engine.delegate.event.FlowableSignalEvent;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.stereotype.Component;
@ -15,10 +23,20 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ACTIVITY_CANCELLED;
import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ACTIVITY_COMPENSATE;
import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ACTIVITY_COMPLETED;
import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ACTIVITY_ERROR_RECEIVED;
import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ACTIVITY_MESSAGE_CANCELLED;
import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ACTIVITY_MESSAGE_RECEIVED;
import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ACTIVITY_MESSAGE_WAITING;
import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ACTIVITY_SIGNALED;
import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ACTIVITY_SIGNAL_WAITING;
import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ACTIVITY_STARTED;
import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.MULTI_INSTANCE_ACTIVITY_CANCELLED;
import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.MULTI_INSTANCE_ACTIVITY_COMPLETED;
import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.MULTI_INSTANCE_ACTIVITY_COMPLETED_WITH_CONDITION;
import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.MULTI_INSTANCE_ACTIVITY_STARTED;
/**
* 活动节点完成事件
@ -28,7 +46,7 @@ import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventT
*/
@Slf4j
@Component
public class EngineActivityEventListener extends AbstractFlowableEventListener {
public class EngineActivityEventListener extends AbstractFlowableEngineEventListener {
@Resource
ObjectProvider<List<BpmnActivityEventListener>> activityListeners;
@ -37,12 +55,97 @@ public class EngineActivityEventListener extends AbstractFlowableEventListener {
public Collection<? extends FlowableEventType> getTypes() {
return Lists.newArrayList(ACTIVITY_STARTED,
ACTIVITY_COMPLETED,
ACTIVITY_CANCELLED,
MULTI_INSTANCE_ACTIVITY_STARTED,
MULTI_INSTANCE_ACTIVITY_COMPLETED,
MULTI_INSTANCE_ACTIVITY_COMPLETED_WITH_CONDITION);
MULTI_INSTANCE_ACTIVITY_COMPLETED_WITH_CONDITION,
MULTI_INSTANCE_ACTIVITY_CANCELLED,
ACTIVITY_SIGNAL_WAITING,
ACTIVITY_SIGNALED,
ACTIVITY_COMPENSATE,
ACTIVITY_MESSAGE_WAITING,
ACTIVITY_MESSAGE_RECEIVED,
ACTIVITY_MESSAGE_CANCELLED,
ACTIVITY_ERROR_RECEIVED);
}
@Override
protected void activityStarted(FlowableActivityEvent event) {
// TODO 业务节点通过发送这个事件给业务, 必须要传输 activity instance id, 业务则通过这个 id 来推动工作流继续流转
super.activityStarted(event);
}
@Override
protected void activityCompleted(FlowableActivityEvent event) {
// TODO 以前老的 TaskListener 事件实际上都是不标准的, 因为一个任务节点可能有多个人审批, 而多人审批就会有会签/或签模型,
// 让业务监听任务的完成状态本身就有问题, 统一替换成 Activity 相关的事件
super.activityCompleted(event);
}
@Override
protected void activityCancelled(FlowableActivityCancelledEvent event) {
super.activityCancelled(event);
}
@Override
protected void multiInstanceActivityStarted(FlowableMultiInstanceActivityEvent event) {
super.multiInstanceActivityStarted(event);
}
@Override
protected void multiInstanceActivityCompleted(FlowableMultiInstanceActivityCompletedEvent event) {
super.multiInstanceActivityCompleted(event);
}
@Override
protected void multiInstanceActivityCompletedWithCondition(FlowableMultiInstanceActivityCompletedEvent event) {
super.multiInstanceActivityCompletedWithCondition(event);
}
@Override
protected void multiInstanceActivityCancelled(FlowableMultiInstanceActivityCancelledEvent event) {
super.multiInstanceActivityCancelled(event);
}
@Override
protected void activitySignalWaiting(FlowableSignalEvent event) {
super.activitySignalWaiting(event);
}
@Override
protected void activitySignaled(FlowableSignalEvent event) {
super.activitySignaled(event);
}
@Override
protected void activityCompensate(FlowableActivityEvent event) {
super.activityCompensate(event);
}
@Override
protected void activityMessageWaiting(FlowableMessageEvent event) {
super.activityMessageWaiting(event);
}
@Override
protected void activityMessageReceived(FlowableMessageEvent event) {
super.activityMessageReceived(event);
}
@Override
protected void activityMessageCancelled(FlowableMessageEvent event) {
super.activityMessageCancelled(event);
}
@Override
protected void activityErrorReceived(FlowableErrorEvent event) {
super.activityErrorReceived(event);
}
@Override
public void onEvent(FlowableEvent event) {
super.onEvent(event);
getOrderedListeners().forEach(i -> i.onEvent(event));
}

View File

@ -8,6 +8,7 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.core.deletage.BpmnTaskAssigneeSelector;
import cn.axzo.workflow.core.deletage.BpmnTaskCalculateDTO;
import cn.axzo.workflow.core.deletage.BpmnTaskDelegate;
import cn.axzo.workflow.core.deletage.MockTaskAssigneeSelector;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.Process;
@ -30,6 +31,7 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.BPM_ALLOW_SKIP_USER
import static cn.axzo.workflow.common.constant.BpmnConstants.FLOW_SERVER_VERSION_121;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_BUSINESS;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_TASK;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApprovalMethod;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApproverEmptyHandleType;
@ -52,14 +54,15 @@ public class EngineExecutionStartListener implements ExecutionListener {
private ObjectProvider<BpmnTaskDelegate> bpmTaskDelegate;
@Resource
private List<BpmnTaskAssigneeSelector> selectors;
@Resource
private ObjectProvider<MockTaskAssigneeSelector> objectProvider;
@Override
public void notify(DelegateExecution execution) {
log.info("execution Start: {}", JSON.toJSONString(execution));
String currentActivityId = execution.getCurrentActivityId();
String assigneeListVariableName = INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO + currentActivityId;
List<String> assigneeList = (List<String>) execution.getVariable(assigneeListVariableName);
if (!CollectionUtils.isEmpty(assigneeList)) {
if (execution.hasVariable(assigneeListVariableName)) {
return;
}
@ -67,17 +70,19 @@ public class EngineExecutionStartListener implements ExecutionListener {
UserTask userTask = (UserTask) mainProcess.getFlowElement(currentActivityId);
// version=1.2.1-SNAPSHOT 开始才给 process 节点增加了 serverVersion 属性
getProcessServerVersion(mainProcess).ifPresent(version -> {
Optional<String> processServerVersion = getProcessServerVersion(mainProcess);
if (processServerVersion.isPresent()) {
Optional<BpmnFlowNodeType> nodeType = getNodeType(userTask);
if (Objects.equals(FLOW_SERVER_VERSION_121, version)
if (Objects.equals(FLOW_SERVER_VERSION_121, processServerVersion.get())
&& nodeType.isPresent()
&& Objects.equals(NODE_TASK, nodeType.get())) {
&& (Objects.equals(NODE_TASK, nodeType.get()) || Objects.equals(NODE_BUSINESS, nodeType.get()))) {
getApprovalMethod(userTask).ifPresent(method -> {
List<String> assigneeIdList = new ArrayList<>();
switch (method) {
case autoPassed:
case autoRejection:
// nothing to do
// Do nothing
// TODO 不要调用查询审批人的接口只需要保证该节点在实际运行过程中能自动通过和拒绝即可
// 通过的功能可以参考下面枢智的方法拒绝还需研究可以结合 task 相关的事件去处理
break;
@ -91,19 +96,25 @@ public class EngineExecutionStartListener implements ExecutionListener {
// 查询审批候选人
emptyAssigneeHandle(assigners, userTask, execution);
List<String> assigneeIdList = new ArrayList<>();
for (BpmnTaskDelegateAssigner user : assigners) {
assigneeIdList.add(user.buildAssigneeId());
}
// UserTask 多实例, 该变量用于引擎
execution.setVariable(assigneeListVariableName, assigneeIdList);
execution.setVariableLocal(INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + currentActivityId,
assigners);
break;
}
});
}
});
} else {
defaultCalcTaskAssigner(execution, userTask, currentActivityId, assigneeListVariableName);
}
}
private void emptyAssigneeHandle(List<BpmnTaskDelegateAssigner> assigners, UserTask userTask,
DelegateExecution execution) {
// 审批人为空并且当前节点设置了自动跳过条件
@ -137,11 +148,15 @@ public class EngineExecutionStartListener implements ExecutionListener {
*/
private List<BpmnTaskDelegateAssigner> approverSelect(String type, UserTask userTask) {
List<BpmnTaskDelegateAssigner> assigners = new ArrayList<>();
if (Objects.nonNull(objectProvider.getIfAvailable())) {
objectProvider.ifAvailable(selector -> assigners.addAll(selector.select(userTask)));
} else {
selectors.forEach(select -> {
if (select.support(type)) {
assigners.addAll(select.select(userTask));
}
});
}
return assigners;
}

View File

@ -0,0 +1,17 @@
package cn.axzo.workflow.core.service;
/**
* 流程活动的 Service
*
* @author wangli
* @since 2023/11/17 16:37
*/
public interface BpmnProcessActivityService {
/**
* 唤醒业务节点
*
* @param processActivityId 活动 ID
*/
void trigger(String processActivityId);
}

View File

@ -1,6 +1,11 @@
package cn.axzo.workflow.core.service;
import cn.axzo.workflow.common.model.request.bpmn.task.*;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAssigneeDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAttachmentDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCommentDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCountersignDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskPageSearchDTO;
import cn.axzo.workflow.common.model.response.BpmPageResult;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceGroupVO;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceVO;
@ -11,7 +16,7 @@ import org.flowable.form.api.FormInfo;
import java.util.List;
public interface BpmnTaskService {
public interface BpmnProcessTaskService {
/**
* 待审核列表

View File

@ -0,0 +1,29 @@
package cn.axzo.workflow.core.service.impl;
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
import cn.axzo.workflow.core.service.BpmnProcessActivityService;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.runtime.ActivityInstance;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Objects;
@Service
@Slf4j
public class BpmnProcessActivityServiceImpl implements BpmnProcessActivityService {
@Resource
private RuntimeService runtimeService;
@Override
public void trigger(String processActivityId) {
ActivityInstance activityInstance =
runtimeService.createActivityInstanceQuery().activityInstanceId(processActivityId).singleResult();
if (Objects.isNull(activityInstance)) {
throw new WorkflowEngineException("");
}
runtimeService.trigger(activityInstance.getExecutionId());
}
}

View File

@ -3,13 +3,27 @@ package cn.axzo.workflow.core.service.impl;
import cn.axzo.framework.core.util.StringUtil;
import cn.axzo.workflow.common.enums.BpmnCountersignType;
import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
import cn.axzo.workflow.common.model.request.bpmn.task.*;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAssigneeDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAttachmentDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCommentDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCountersignDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskPageSearchDTO;
import cn.axzo.workflow.common.model.response.BpmPageResult;
import cn.axzo.workflow.common.model.response.bpmn.task.*;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceGroupVO;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceVO;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskDonePageItemVO;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskInstanceVO;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskTodoPageItemVO;
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
import cn.axzo.workflow.core.engine.id.TimeBasedIdGenerator;
import cn.axzo.workflow.core.service.BpmnTaskService;
import cn.axzo.workflow.core.service.converter.*;
import cn.axzo.workflow.core.service.BpmnProcessTaskService;
import cn.axzo.workflow.core.service.converter.BpmnHistoricCommentConverter;
import cn.axzo.workflow.core.service.converter.BpmnHistoricTaskInstanceConverter;
import cn.axzo.workflow.core.service.converter.BpmnTaskConverter;
import cn.axzo.workflow.core.service.converter.BpmnTaskDonePageItemConverter;
import cn.axzo.workflow.core.service.converter.BpmnTaskTodoPageItemConverter;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.google.common.collect.Lists;
@ -19,7 +33,11 @@ import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.UserTask;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.engine.*;
import org.flowable.engine.HistoryService;
import org.flowable.engine.ManagementService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.history.HistoricProcessInstanceQuery;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
@ -41,13 +59,43 @@ import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import static cn.axzo.workflow.common.constant.BpmnConstants.*;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.*;
import static cn.axzo.workflow.core.common.enums.BpmnErrorCode.*;
import static cn.axzo.workflow.common.constant.BpmnConstants.APPROVAL_ENDS_AUTOMATICALLY;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE;
import static cn.axzo.workflow.common.constant.BpmnConstants.COUNTERSIGN_ORIGIN_ASSIGNER;
import static cn.axzo.workflow.common.constant.BpmnConstants.COUNTERSIGN_REMAIN_ASSIGNER_LIST;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_DELETE_PROCESS_FLAG;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_END_TENANT_ID;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_END_USER_ID;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_END_USER_NAME;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_PROCESS_TYPE_REJECT;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_SPECIFY_NEXT_APPROVER;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_INFO_SNAPSHOT;
import static cn.axzo.workflow.common.constant.BpmnConstants.MULTI_INSTANCE_LOOP_COUNTER;
import static cn.axzo.workflow.common.constant.BpmnConstants.NUMBER_OF_INSTANCES;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.APPROVED;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.CANCELLED;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.PROCESSING;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.REJECTED;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.valueOfStatus;
import static cn.axzo.workflow.core.common.enums.BpmnErrorCode.PROCESS_INSTANCE_ID_NOT_EXISTS;
import static cn.axzo.workflow.core.common.enums.BpmnErrorCode.PROCESS_INSTANCE_NOT_EXISTS;
import static cn.axzo.workflow.core.common.enums.BpmnErrorCode.TASK_APOSTILLE_NOT_SUPPORT;
import static cn.axzo.workflow.core.common.enums.BpmnErrorCode.TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF;
import static cn.axzo.workflow.core.common.enums.BpmnErrorCode.TASK_COMPLETE_FAIL_NOT_EXISTS;
import static cn.axzo.workflow.core.common.utils.BpmnCollectionUtils.convertSet;
import static cn.axzo.workflow.core.common.utils.BpmnNativeQueryUtil.countSql;
import static cn.axzo.workflow.core.common.utils.BpmnNativeQueryUtil.sqlConnectors;
@ -55,7 +103,7 @@ import static org.flowable.engine.impl.persistence.entity.CommentEntity.TYPE_COM
@Service
@Slf4j
public class BpmnTaskServiceImpl implements BpmnTaskService {
public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
@Resource
private TaskService taskService;
@ -573,8 +621,7 @@ public class BpmnTaskServiceImpl implements BpmnTaskService {
* @param taskId 任务ID
*/
private Task checkTask(String tenantId, String assignee, String taskId) {
Task task = getTask(taskId, assignee, tenantId);
Task task = getTask(taskId, null, null);
if (Objects.nonNull(task) && !Objects.equals(assignee, task.getAssignee())) {
throw new WorkflowEngineException(TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF);
}

View File

@ -110,7 +110,7 @@ public class FlowNodeForecastService implements InitializingBean {
public List<FlowElement> performProcessForecasting(@Nullable String processInstanceId,
@Nullable ProcessInstance instance) {
if (Objects.nonNull(instance)) {
// nothing to do
// Do nothing
} else if (!StringUtils.hasLength(processInstanceId)) {
throw new WorkflowEngineException(PROCESS_INSTANCE_NOT_EXISTS);
} else {

View File

@ -1,74 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:flowable="http://flowable.org/bpmn"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"
typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath"
targetNamespace="http://www.flowable.org/test">
<process id="DESC1234616312350093314" name="文档借阅" isExecutable="true">
<startEvent id="startEventNode"></startEvent>
<userTask id="NODE1639041346796_0.5413743892974803_0" name="发起">
<extensionElements>
<flowable:executionListener event="start"
delegateExpression="${engineExecutionStartListener}"></flowable:executionListener>
<flowable:taskListener event="all"
delegateExpression="${engineTaskEventListener}"></flowable:taskListener>
</extensionElements>
</userTask>
<sequenceFlow id="sequenceFlow_b3da60bc0b404ddf9b871d2c2ed2d396" sourceRef="startEventNode"
targetRef="NODE1639041346796_0.5413743892974803_0"></sequenceFlow>
<userTask id="NODE1687933854432_0.45762305710855467_1" name="审批人">
<extensionElements>
<flowable:executionListener event="start"
delegateExpression="${engineExecutionStartListener}"></flowable:executionListener>
<flowable:taskListener event="all"
delegateExpression="${engineTaskEventListener}"></flowable:taskListener>
</extensionElements>
</userTask>
<sequenceFlow id="sequenceFlow_5c4c308bd9b144cd9440a6f2dfd6af99"
sourceRef="NODE1639041346796_0.5413743892974803_0"
targetRef="NODE1687933854432_0.45762305710855467_1"></sequenceFlow>
<endEvent id="endEventNode"></endEvent>
<sequenceFlow id="sequenceFlow_b6ebf56f49bf43f295533ab8e10d09a7"
sourceRef="NODE1687933854432_0.45762305710855467_1" targetRef="endEventNode"></sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_DESC1234616312350093314">
<bpmndi:BPMNPlane bpmnElement="DESC1234616312350093314" id="BPMNPlane_DESC1234616312350093314">
<bpmndi:BPMNShape bpmnElement="NODE1687933854432_0.45762305710855467_1"
id="BPMNShape_NODE1687933854432_0.45762305710855467_1">
<omgdc:Bounds height="60.0" width="100.0" x="230.0" y="0.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="startEventNode" id="BPMNShape_startEventNode">
<omgdc:Bounds height="30.0" width="30.0" x="0.0" y="15.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="NODE1639041346796_0.5413743892974803_0"
id="BPMNShape_NODE1639041346796_0.5413743892974803_0">
<omgdc:Bounds height="60.0" width="100.0" x="80.0" y="0.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endEventNode" id="BPMNShape_endEventNode">
<omgdc:Bounds height="30.0" width="30.0" x="380.0" y="15.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_b3da60bc0b404ddf9b871d2c2ed2d396"
id="BPMNEdge_sequenceFlow_b3da60bc0b404ddf9b871d2c2ed2d396">
<omgdi:waypoint x="30.0" y="30.0"></omgdi:waypoint>
<omgdi:waypoint x="42.0" y="30.0"></omgdi:waypoint>
<omgdi:waypoint x="42.0" y="30.000000000000007"></omgdi:waypoint>
<omgdi:waypoint x="80.0" y="30.000000000000007"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_b6ebf56f49bf43f295533ab8e10d09a7"
id="BPMNEdge_sequenceFlow_b6ebf56f49bf43f295533ab8e10d09a7">
<omgdi:waypoint x="330.0" y="30.0"></omgdi:waypoint>
<omgdi:waypoint x="342.0" y="30.0"></omgdi:waypoint>
<omgdi:waypoint x="342.0" y="30.000000000000004"></omgdi:waypoint>
<omgdi:waypoint x="380.0" y="30.000000000000004"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_5c4c308bd9b144cd9440a6f2dfd6af99"
id="BPMNEdge_sequenceFlow_5c4c308bd9b144cd9440a6f2dfd6af99">
<omgdi:waypoint x="180.0" y="30.0"></omgdi:waypoint>
<omgdi:waypoint x="192.0" y="30.0"></omgdi:waypoint>
<omgdi:waypoint x="192.0" y="30.000000000000007"></omgdi:waypoint>
<omgdi:waypoint x="230.0" y="30.000000000000007"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>

View File

@ -9,7 +9,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
@MapperScan({"cn.axzo.workflow.core.**.mapper"})
@ComponentScan({"cn.axzo.workflow"})
@ComponentScan({"cn.axzo.workflow", "cn.axzo.maokai"})
@SpringBootApplication(exclude = RabbitAutoConfiguration.class)
@EnableTransactionManagement
public class WorkflowEnginApplication {

View File

@ -0,0 +1,22 @@
package cn.axzo.workflow.server.conf;
import cn.axzo.workflow.core.deletage.MockTaskAssigneeSelector;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Workflow Engine Application Global Configuration
*
* @author wangli
* @since 2023/11/17 14:27
*/
@Configuration(proxyBeanMethods = false)
public class WorkflowEngineConfiguration {
@Bean
@ConditionalOnProperty(prefix = "workflow", name = "mock", havingValue = "true")
public MockTaskAssigneeSelector mockTaskAssigneeSelector() {
return new MockTaskAssigneeSelector();
}
}

View File

@ -0,0 +1,37 @@
package cn.axzo.workflow.server.controller.web.bpmn;
import cn.axzo.workflow.client.feign.bpmn.ProcessActivityApi;
import cn.axzo.workflow.core.service.BpmnProcessActivityService;
import cn.azxo.framework.common.model.CommonResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;
/**
* 流程活动相关控制器
*
* @author wangli
* @since 2023/11/17 16:33
*/
@Slf4j
@RequestMapping({"/web/v1/api/process/activity", "/api/process/activity"})
@RestController
@Validated
public class BpmnProcessActivityController implements ProcessActivityApi {
@Resource
private BpmnProcessActivityService bpmnProcessActivityService;
@GetMapping("/trigger")
@Override
public CommonResponse<Boolean> trigger(@NotBlank(message = "活动 ID 不能为空") @RequestParam String processActivityId) {
bpmnProcessActivityService.trigger(processActivityId);
return CommonResponse.success(true);
}
}

View File

@ -14,7 +14,7 @@ import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskDonePageItemVO;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskInstanceVO;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskTodoPageItemVO;
import cn.axzo.workflow.common.valid.group.ValidGroup;
import cn.axzo.workflow.core.service.BpmnTaskService;
import cn.axzo.workflow.core.service.BpmnProcessTaskService;
import cn.azxo.framework.common.model.CommonResponse;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
@ -39,10 +39,10 @@ import static cn.azxo.framework.common.model.CommonResponse.success;
@RequestMapping({"/web/v1/api/process/task", "/api/process/task"})
@RestController
@Validated
public class BpmnTaskController implements ProcessTaskApi {
public class BpmnProcessTaskController implements ProcessTaskApi {
@Resource
private BpmnTaskService bpmnTaskService;
private BpmnProcessTaskService bpmnProcessTaskService;
/**
@ -52,7 +52,7 @@ public class BpmnTaskController implements ProcessTaskApi {
@Override
public CommonResponse<BpmPageResult<BpmnTaskTodoPageItemVO>> getTodoTaskPage(@Validated @RequestBody BpmnTaskPageSearchDTO dto) {
log.info("待审核列表 getTodoTaskPage===>>>参数:{}", dto);
return success(bpmnTaskService.getTodoTaskPage(dto));
return success(bpmnProcessTaskService.getTodoTaskPage(dto));
}
/**
@ -62,7 +62,7 @@ public class BpmnTaskController implements ProcessTaskApi {
@Override
public CommonResponse<BpmPageResult<BpmnTaskDonePageItemVO>> getDoneTaskPage(@Validated @RequestBody BpmnTaskPageSearchDTO dto) {
log.info("已完成的审批列表 getDoneTaskPage===>>>参数:{}", dto);
return success(bpmnTaskService.getDoneTaskPage(dto));
return success(bpmnProcessTaskService.getDoneTaskPage(dto));
}
@ -73,7 +73,7 @@ public class BpmnTaskController implements ProcessTaskApi {
@Override
public CommonResponse<Boolean> approveTask(@Validated(ValidGroup.Insert.class) @RequestBody BpmnTaskAuditDTO dto) {
log.info("同意 approveTask===>>>参数:{}", dto);
bpmnTaskService.approveTask(dto);
bpmnProcessTaskService.approveTask(dto);
return success(true);
}
@ -84,7 +84,7 @@ public class BpmnTaskController implements ProcessTaskApi {
@Override
public CommonResponse<Boolean> rejectTask(@Validated(ValidGroup.Update.class) @RequestBody BpmnTaskAuditDTO dto) {
log.info("拒绝 rejectTask===>>>参数:{}", dto);
bpmnTaskService.rejectTask(dto);
bpmnProcessTaskService.rejectTask(dto);
return success(true);
}
@ -95,7 +95,7 @@ public class BpmnTaskController implements ProcessTaskApi {
@PutMapping("/assignee")
@Override
public CommonResponse<Boolean> assigneeTask(@Validated @RequestBody BpmnTaskAssigneeDTO dto) {
bpmnTaskService.assigneeTask(dto);
bpmnProcessTaskService.assigneeTask(dto);
return success(true);
}
@ -104,7 +104,7 @@ public class BpmnTaskController implements ProcessTaskApi {
*/
@Override
public CommonResponse<Boolean> commentTask(BpmnTaskCommentDTO commentDTO) {
bpmnTaskService.commentTask(commentDTO);
bpmnProcessTaskService.commentTask(commentDTO);
return success(true);
}
@ -115,7 +115,7 @@ public class BpmnTaskController implements ProcessTaskApi {
@Override
@PutMapping("/countersign")
public CommonResponse<Boolean> countersignTask(BpmnTaskCountersignDTO countersignDTO) {
bpmnTaskService.countersignTask(countersignDTO);
bpmnProcessTaskService.countersignTask(countersignDTO);
return success(true);
}
@ -151,7 +151,7 @@ public class BpmnTaskController implements ProcessTaskApi {
@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId,
@Nullable @RequestParam(required = false) String tenantId) {
log.info("获取历史已审批的列表详情 getTaskListFlatByProcessInstanceId===>>>参数:{}", processInstanceId);
return success(bpmnTaskService.getHistoricTaskListByProcessInstanceId(processInstanceId, tenantId));
return success(bpmnProcessTaskService.getHistoricTaskListByProcessInstanceId(processInstanceId, tenantId));
}
/**
@ -165,7 +165,7 @@ public class BpmnTaskController implements ProcessTaskApi {
@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId,
@Nullable @RequestParam(required = false) String tenantId) {
log.info("获取历史已审批的列表详情 getTaskListGroupByProcessInstanceId===>>>参数:{}", processInstanceId);
return success(bpmnTaskService.getHistoricTaskListGroupByProcessInstanceId(processInstanceId, tenantId));
return success(bpmnProcessTaskService.getHistoricTaskListGroupByProcessInstanceId(processInstanceId, tenantId));
}
/**
@ -177,18 +177,18 @@ public class BpmnTaskController implements ProcessTaskApi {
@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId,
@NotBlank(message = "租户不能为空") @RequestParam String tenantId) {
log.info(" 获取实例正在审核的人列表 getActiveTasksByProcessInstanceId===>>>参数:{}", processInstanceId);
return success(bpmnTaskService.getActiveTasksByProcessInstanceId(processInstanceId, tenantId));
return success(bpmnProcessTaskService.getActiveTasksByProcessInstanceId(processInstanceId, tenantId));
}
@GetMapping("/form")
public CommonResponse<FormInfo> getTaskForm(@NotBlank(message = "任务 ID 不能为空") @RequestParam String taskId,
@NotBlank(message = "租户不能为空") @RequestParam String tenantId) {
return success(bpmnTaskService.getTaskFormModel(taskId, tenantId));
return success(bpmnProcessTaskService.getTaskFormModel(taskId, tenantId));
}
@PostMapping("/attachment/add")
public CommonResponse<Void> addAttachment(@Validated @RequestBody BpmnTaskAttachmentDTO dto) {
bpmnTaskService.attachmentTask(dto);
bpmnProcessTaskService.attachmentTask(dto);
return success();
}

View File

@ -606,7 +606,7 @@
],
"isMultiTask": "true",
"multiMode": "AND",
"approverEmptyHandleType": "autoPassed",
"approverEmptyHandleType": "transferToAdmin",
"fieldPermission": null,
"buttonPermission": {
"initiator": [

File diff suppressed because one or more lines are too long