assigneeList = runtimeService.getVariable(taskEntity.getProcessInstanceId(), "[_ACTIVITY_INFO_SNAPSHOT_]" + taskEntity.getTaskDefinitionKey(), List.class);
+ ListUtils.emptyIfNull(assigneeList).stream().filter(e -> Objects.equals(e.buildAssigneeId(), taskEntity.getAssignee())).findAny()
+ .ifPresent(assignee -> {
+ log.error("审批人: {}", JSON.toJSONString(assignee));
+ ExtAxProcessLog queryLog = new ExtAxProcessLog();
+ queryLog.setProcessInstanceId(taskEntity.getProcessInstanceId());
+ queryLog.setTaskId(taskEntity.getId());
+ processLogService.updateAssignee(queryLog, assignee);
+ });
+ }
+ }
+
+ private void onInitialized(TaskEntity taskEntity) {
+ log.error("onInitialized");
+ }
+
+ private void onCreate(TaskEntity taskEntity) {
+ log.error("onCreate");
+ ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
+ RuntimeService runtimeService = processEngineConfiguration.getRuntimeService();
+ BpmnTaskDelegateAssigner assignee;
+
+ // 记录发起人
+ boolean isNodeStarter = Objects.equals(taskEntity.getTaskDefinitionKey(), NODE_STARTER.getType());
+ if (isNodeStarter) {
+ assignee = BpmnTaskDelegateAssigner.toObjectCompatible(runtimeService.getVariable(taskEntity.getProcessInstanceId(),
+ INTERNAL_INITIATOR));
+ if (Objects.isNull(assignee)) {
+ // 兼容历史数据
+ assignee = BpmnTaskDelegateAssigner.toObjectCompatible(runtimeService.getVariable(taskEntity.getProcessInstanceId(), OLD_INTERNAL_INITIATOR));
+ }
+ } else {
+ assignee = BpmnTaskDelegateAssigner.toObjectCompatible(runtimeService.getVariable(taskEntity.getProcessInstanceId(), INTERNAL_TASK_RELATION_ASSIGNEE_INFO + taskEntity.getId()));
+ }
+
+ RepositoryService repositoryService = processEngineConfiguration.getRepositoryService();
+ BpmnModel bpmnModel = repositoryService.getBpmnModel(taskEntity.getProcessDefinitionId());
+ FlowElement flowElement = bpmnModel.getFlowElement(taskEntity.getTaskDefinitionKey());
+
+ ExtAxProcessLog log = new ExtAxProcessLog();
+ log.setProcessInstanceId(taskEntity.getProcessInstanceId());
+ log.setTenantId(taskEntity.getTenantId());
+ log.setActivityId(taskEntity.getTaskDefinitionKey());
+ log.setActivityName(taskEntity.getName());
+ log.setApprovalMethod((isNodeStarter ? nobody : getApprovalMethod(flowElement).orElse(nobody)).getType());
+ if (Objects.equals(log.getApprovalMethod(), nobody.getType()) || Objects.equals(log.getApprovalMethod(), bizSpecify.getType())) {
+ log.setOperationDesc("待处理");
+ }
+ log.setNodeType((getNodeType(flowElement).orElse(BpmnFlowNodeType.NODE_EMPTY)).getType());
+ log.setNodeMode((isNodeStarter ? BpmnFlowNodeMode.GENERAL : getNodeMode(flowElement)).getType());
+ log.setTaskId(taskEntity.getId());
+ if (Objects.nonNull(assignee)) {
+ // FIXME 应该还有逻辑来拼接
+ log.setOperationDesc(isNodeStarter ? assignee.getAssignerName() : null);
+
+ log.setAssigneeFull(assignee);
+ log.setAssigneeId(Long.valueOf(assignee.getPersonId()));
+ log.setAssigneeTenantId(assignee.getTenantId());
+ log.setAssigneeName(assignee.getAssignerName());
+ log.setAssigneeOuId(assignee.getOuId());
+ }
+ log.setStartTime(taskEntity.getCreateTime());
+ log.setStatus(PROCESSING.getStatus());
+ processLogService.insert(log);
+ }
+
+ private BpmnFlowNodeMode getNodeMode(FlowElement flowElement) {
+ BpmnFlowNodeMode node = GENERAL;
+ if (flowElement instanceof UserTask) {
+ UserTask userTask = (UserTask) flowElement;
+ if (userTask.getBehavior() instanceof MultiInstanceActivityBehavior) {
+ MultiInstanceActivityBehavior behavior =
+ (MultiInstanceActivityBehavior) userTask.getBehavior();
+ node = Objects.equals(AND_SIGN_EXPRESSION, behavior.getCompletionCondition()) ? AND : OR;
+ }
+ }
+ return node;
+ }
+
+ @Override
+ public boolean isFailOnException() {
+ return true;
+ }
+}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/listener/impl/InternalExtAxTaskInstEvent_lo_1_Listener.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/listener/impl/InternalExtAxTaskInstEvent_lo_1_Listener.java
new file mode 100644
index 000000000..602ba4841
--- /dev/null
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/listener/impl/InternalExtAxTaskInstEvent_lo_1_Listener.java
@@ -0,0 +1,93 @@
+package cn.axzo.workflow.core.listener.impl;
+
+import cn.axzo.workflow.common.enums.BpmnFlowNodeMode;
+import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
+import cn.axzo.workflow.core.common.context.TaskOperationContext;
+import cn.axzo.workflow.core.listener.AbstractBpmnEventListener;
+import cn.axzo.workflow.core.listener.BpmnTaskEventListener;
+import cn.axzo.workflow.core.service.ExtAxProcessLogService;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.flowable.bpmn.model.BpmnModel;
+import org.flowable.bpmn.model.FlowElement;
+import org.flowable.bpmn.model.UserTask;
+import org.flowable.engine.RepositoryService;
+import org.flowable.engine.RuntimeService;
+import org.flowable.engine.impl.bpmn.behavior.MultiInstanceActivityBehavior;
+import org.flowable.task.service.delegate.DelegateTask;
+
+import java.util.Objects;
+
+import static cn.axzo.workflow.common.constant.BpmnConstants.AND_SIGN_EXPRESSION;
+import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_INITIATOR;
+import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_INFO;
+import static cn.axzo.workflow.common.constant.BpmnConstants.OLD_INTERNAL_INITIATOR;
+import static cn.axzo.workflow.common.enums.BpmnFlowNodeMode.AND;
+import static cn.axzo.workflow.common.enums.BpmnFlowNodeMode.GENERAL;
+import static cn.axzo.workflow.common.enums.BpmnFlowNodeMode.OR;
+import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_STARTER;
+
+/**
+ * Core 包内置的,可共用与 Jar 包集成和微服务集成
+ *
+ * 该类主要处理新版的日志表
+ *
+ * @author wangli
+ * @since 2023/12/9 22:56
+ */
+@Slf4j
+//@Component
+//@Scope("prototype")
+@AllArgsConstructor
+public class InternalExtAxTaskInstEvent_lo_1_Listener extends AbstractBpmnEventListener implements BpmnTaskEventListener {
+ private final RuntimeService runtimeService;
+ private final RepositoryService repositoryService;
+ private final ExtAxProcessLogService processLogService;
+
+ @Override
+ public int getOrder() {
+ return Integer.MIN_VALUE + 1;
+ }
+
+ /**
+ * Assigned 事件先于 Create 事件,所以在此事件中, 只要任务逻辑上应该有人,那么这里的数据就有人, 仅创建日志的初始状态
+ *
+ * @param delegateTask
+ */
+ @Override
+ public void onCreated(DelegateTask delegateTask) {
+ BpmnTaskDelegateAssigner assignee;
+ // 记录发起人
+ boolean isNodeStarter = Objects.equals(delegateTask.getTaskDefinitionKey(), NODE_STARTER.getType());
+ if (isNodeStarter) {
+ assignee = getContext().getInitiator(() ->
+ BpmnTaskDelegateAssigner.toObjectCompatible(runtimeService.getVariable(delegateTask.getProcessInstanceId(),
+ INTERNAL_INITIATOR)));
+ if (Objects.isNull(assignee)) {
+ // 兼容历史数据
+ assignee = getContext().getInitiator(() ->
+ BpmnTaskDelegateAssigner.toObjectCompatible(runtimeService.getVariable(delegateTask.getProcessInstanceId(), OLD_INTERNAL_INITIATOR)));
+ }
+ } else {
+ assignee = BpmnTaskDelegateAssigner.toObjectCompatible(runtimeService.getVariable(delegateTask.getProcessInstanceId(), INTERNAL_TASK_RELATION_ASSIGNEE_INFO + delegateTask.getId()));
+ }
+
+ BpmnModel bpmnModel = repositoryService.getBpmnModel(delegateTask.getProcessDefinitionId());
+ FlowElement flowElement = bpmnModel.getFlowElement(delegateTask.getTaskDefinitionKey());
+
+ }
+
+
+ private BpmnFlowNodeMode getNodeMode(FlowElement flowElement) {
+ BpmnFlowNodeMode node = GENERAL;
+ if (flowElement instanceof UserTask) {
+ UserTask userTask = (UserTask) flowElement;
+ if (userTask.getBehavior() instanceof MultiInstanceActivityBehavior) {
+ MultiInstanceActivityBehavior behavior =
+ (MultiInstanceActivityBehavior) userTask.getBehavior();
+ node = Objects.equals(AND_SIGN_EXPRESSION, behavior.getCompletionCondition()) ? AND : OR;
+ }
+ }
+ return node;
+ }
+}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/listener/impl/InternalExtAxTaskInstEvent_lo_Listener.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/listener/impl/InternalExtAxTaskInstEvent_lo_Listener.java
index 24052586e..e34dd85fc 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/listener/impl/InternalExtAxTaskInstEvent_lo_Listener.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/listener/impl/InternalExtAxTaskInstEvent_lo_Listener.java
@@ -44,12 +44,6 @@ public class InternalExtAxTaskInstEvent_lo_Listener extends AbstractBpmnEventLis
return Integer.MIN_VALUE;
}
- @Override
- public void onAssigned(DelegateTask delegateTask) {
- // 用于创建该流程实例发起人的日志
- BpmnTaskEventListener.super.onAssigned(delegateTask);
- }
-
@Override
public void onCreated(DelegateTask delegateTask) {
String assignee;
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/repository/entity/ExtAxProcessLog.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/repository/entity/ExtAxProcessLog.java
index 01b7db77d..179b8d732 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/repository/entity/ExtAxProcessLog.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/repository/entity/ExtAxProcessLog.java
@@ -1,12 +1,109 @@
package cn.axzo.workflow.core.repository.entity;
import cn.axzo.framework.data.mybatisplus.model.BaseEntity;
+import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+import java.util.Date;
/**
- * TODO
+ * 审批日志
*
* @author wangli
* @since 2024-08-30 15:29
*/
+@EqualsAndHashCode(callSuper = true)
+@TableName(value = "ext_ax_process_log", autoResultMap = true)
+@Data
+@ToString(callSuper = true)
public class ExtAxProcessLog extends BaseEntity {
+
+ /**
+ * 流程实例 ID
+ */
+ private String processInstanceId;
+ /**
+ * 实例归属租户
+ */
+ private String tenantId;
+ /**
+ * 活动节点 ID
+ */
+ private String activityId;
+ /**
+ * 活动节点名称
+ */
+ private String activityName;
+ /**
+ * 审批方式:配置审批人/业务指定/业务触发(不含人)
+ */
+ private String approvalMethod;
+ /**
+ * 节点类型:审批节点/业务节点/评论节点/抄送节点
+ */
+ private String nodeType;
+ /**
+ * 节点模式:会签/或签
+ */
+ private String nodeMode;
+ /**
+ * 任务 ID
+ */
+ private String taskId;
+ /**
+ * 操作建议
+ */
+ private String advice;
+ /**
+ * 操作描述
+ */
+ private String operationDesc;
+ /**
+ * 审批人对象信息
+ */
+ @TableField(typeHandler = JacksonTypeHandler.class)
+ private BpmnTaskDelegateAssigner assigneeFull;
+ /**
+ * 审批人标识
+ */
+ private Long assigneeId;
+ /**
+ * 审批人归属租户
+ */
+ private String assigneeTenantId;
+ /**
+ * 审批人姓名
+ */
+ private String assigneeName;
+ /**
+ * 审批人归属单位
+ */
+ private String assigneeOuId;
+ /**
+ * 任务开始时间
+ */
+ private Date startTime;
+ /**
+ * 任务结束时间
+ */
+ private Date endTime;
+ /**
+ * 已回退标志
+ */
+ private Boolean returned;
+ /**
+ * 任务状态:审批中/通过/驳回/转交/加签/退回
+ */
+ private String status;
+ /**
+ * 扩展字段
+ */
+ @TableField(typeHandler = JacksonTypeHandler.class)
+ private JSONObject extra;
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/repository/mapper/ExtAxProcessLogMapper.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/repository/mapper/ExtAxProcessLogMapper.java
new file mode 100644
index 000000000..cf9ebd84f
--- /dev/null
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/repository/mapper/ExtAxProcessLogMapper.java
@@ -0,0 +1,8 @@
+package cn.axzo.workflow.core.repository.mapper;
+
+import cn.axzo.workflow.core.repository.entity.ExtAxProcessLog;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface ExtAxProcessLogMapper extends BaseMapperX {
+}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/ExtAxProcessLogService.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/ExtAxProcessLogService.java
new file mode 100644
index 000000000..7cee90d03
--- /dev/null
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/ExtAxProcessLogService.java
@@ -0,0 +1,37 @@
+package cn.axzo.workflow.core.service;
+
+import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
+import cn.axzo.workflow.core.repository.entity.ExtAxProcessLog;
+
+/**
+ * Api Log 表操作服务
+ *
+ * @author wangli
+ * @since 2024/4/3 10:40
+ */
+public interface ExtAxProcessLogService {
+ /**
+ * 新增审批流程日志
+ *
+ * @param log
+ * @return
+ */
+ Long insert(ExtAxProcessLog log);
+
+ /**
+ * 根据参数删除指定任务
+ *
+ * @param deleteLog
+ */
+ void delete(ExtAxProcessLog deleteLog);
+
+ /**
+ * 更新指定任务的审批人
+ *
+ * @param updateLog
+ * @param assignee
+ */
+ void updateAssignee(ExtAxProcessLog updateLog, BpmnTaskDelegateAssigner assignee);
+
+ void updateAssignee(ExtAxProcessLog updateLog, BpmnTaskDelegateAssigner assignee, String operationDesc);
+}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/ExtAxProcessLogServiceImpl.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/ExtAxProcessLogServiceImpl.java
new file mode 100644
index 000000000..5f491349a
--- /dev/null
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/ExtAxProcessLogServiceImpl.java
@@ -0,0 +1,76 @@
+package cn.axzo.workflow.core.service.impl;
+
+import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
+import cn.axzo.workflow.core.repository.entity.ExtAxProcessLog;
+import cn.axzo.workflow.core.repository.mapper.ExtAxProcessLogMapper;
+import cn.axzo.workflow.core.service.ExtAxProcessLogService;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.google.common.collect.Lists;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.Objects;
+
+import static cn.axzo.workflow.common.constant.BpmnConstants.DUMMY_ASSIGNEE_ID;
+import static cn.axzo.workflow.common.constant.BpmnConstants.HIDDEN_ASSIGNEE_ID;
+import static cn.axzo.workflow.common.constant.BpmnConstants.NO_ASSIGNEE;
+import static cn.axzo.workflow.common.constant.BpmnConstants.ROBOT_ASSIGNEE_ID;
+
+/**
+ * Api Log 表操服务实现
+ *
+ * @author wangli
+ * @since 2024/4/3 10:41
+ */
+@Service
+@Slf4j
+public class ExtAxProcessLogServiceImpl implements ExtAxProcessLogService {
+ @Resource
+ private ExtAxProcessLogMapper extAxProcessLogMapper;
+
+ @Override
+ public Long insert(ExtAxProcessLog log) {
+ extAxProcessLogMapper.insert(log);
+ return log.getId();
+ }
+
+ @Override
+ public void delete(ExtAxProcessLog deleteLog) {
+ extAxProcessLogMapper.delete(buildQueryWrapper(deleteLog));
+ }
+
+ @Override
+ public void updateAssignee(ExtAxProcessLog queryLog, BpmnTaskDelegateAssigner assignee) {
+ updateAssignee(queryLog, assignee, assignee.getAssignerName());
+ }
+
+ @Override
+ public void updateAssignee(ExtAxProcessLog queryLog, BpmnTaskDelegateAssigner assignee, String operationDesc) {
+ List filterAssignee = Lists.newArrayList(NO_ASSIGNEE, HIDDEN_ASSIGNEE_ID, ROBOT_ASSIGNEE_ID,
+ DUMMY_ASSIGNEE_ID);
+ if (Objects.isNull(assignee) || filterAssignee.contains(assignee.buildAssigneeId())) {
+ return;
+ }
+ ExtAxProcessLog update = new ExtAxProcessLog();
+ update.setOperationDesc(StringUtils.hasText(operationDesc) ? operationDesc : assignee.getAssignerName());
+ update.setAssigneeFull(assignee);
+ update.setAssigneeId(Long.valueOf(assignee.getPersonId()));
+ update.setAssigneeTenantId(assignee.getTenantId());
+ update.setAssigneeOuId(assignee.getOuId());
+ update.setAssigneeName(assignee.getAssignerName());
+ extAxProcessLogMapper.update(update, buildQueryWrapper(queryLog));
+ }
+
+ LambdaQueryWrapper buildQueryWrapper(ExtAxProcessLog log) {
+ return new LambdaQueryWrapper()
+ .eq(Objects.nonNull(log.getId()), ExtAxProcessLog::getId, log.getId())
+ .eq(StringUtils.hasText(log.getProcessInstanceId()), ExtAxProcessLog::getProcessInstanceId, log.getProcessInstanceId())
+ .eq(StringUtils.hasText(log.getActivityId()), ExtAxProcessLog::getActivityId, log.getActivityId())
+ .eq(StringUtils.hasText(log.getActivityName()), ExtAxProcessLog::getActivityName, log.getActivityName())
+ .eq(StringUtils.hasText(log.getTaskId()), ExtAxProcessLog::getTaskId, log.getTaskId())
+ .eq(StringUtils.hasText(log.getTenantId()), ExtAxProcessLog::getTenantId, log.getTenantId());
+ }
+}
diff --git a/workflow-engine-core/src/main/resources/sql/upgrade_to_1.4.2.sql b/workflow-engine-core/src/main/resources/sql/upgrade_to_1.4.2.sql
index 19f94326e..28639e798 100644
--- a/workflow-engine-core/src/main/resources/sql/upgrade_to_1.4.2.sql
+++ b/workflow-engine-core/src/main/resources/sql/upgrade_to_1.4.2.sql
@@ -2,22 +2,28 @@ create table `workflow-engine`.ext_ax_process_log
(
id bigint auto_increment comment '主键'
primary key,
- process_instance_id varchar(64) default '' not null comment '流程实例 ID',
- activity_id varchar(64) default '' not null comment '节点 ID',
- activity_name varchar(255) default '' not null comment '节点名称',
- approval_method varchar(32) default '' not null comment '审批方式:配置审批人/业务指定/业务触发(不含人)',
- node_type varchar(32) default '' not null comment '节点类型:审批节点/业务节点/评论节点/抄送节点',
- node_mode varchar(32) default '' not null comment '节点模式:会签/或签',
- task_id varchar(64) default '' not null comment '任务 ID',
- advice varchar(4000) default '' not null comment '操作建议',
- operation_desc varchar(4000) default '' not null comment '操作描述',
- assignee varchar(1024) default '' not null comment '审批人',
- start_time datetime(3) default CURRENT_TIMESTAMP(3) not null comment '任务开始时间',
- end_time datetime(3) null comment '任务结束时间',
- returned tinyint(1) default 0 not null comment '已回退',
- status varchar(16) default '' not null comment '任务状态:审批中/通过/驳回/转交/加签',
- create_at datetime default CURRENT_TIMESTAMP not null comment '创建时间',
- update_at datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
- is_delete bigint default 0 not null comment '是否删除'
+ process_instance_id varchar(64) default '' not null comment '流程实例 ID',
+ tenant_id bigint not null comment '实例归属租户',
+ activity_id varchar(64) default '' not null comment '节点 ID',
+ activity_name varchar(255) default '' not null comment '节点名称',
+ approval_method varchar(32) default '' not null comment '审批方式:配置审批人/业务指定/业务触发(不含人)',
+ node_type varchar(32) default '' not null comment '节点类型:审批节点/业务节点/评论节点/抄送节点',
+ node_mode varchar(32) default '' not null comment '节点模式:会签/或签',
+ task_id varchar(64) default '' not null comment '任务 ID',
+ advice varchar(4000) default '' not null comment '操作建议',
+ operation_desc varchar(4000) default '' not null comment '操作描述',
+ assignee_full json null comment '审批人(JSON)',
+ assignee_id bigint default 0 not null comment '审批人标识(axzo=personId)',
+ assignee_tenant_id varchar(255) default '' not null comment '审批人归属租户',
+ assignee_name varchar(255) default '' not null comment '审批人姓名',
+ assignee_ou_id bigint default 0 not null comment '审批人归属单位',
+ start_time datetime(3) default CURRENT_TIMESTAMP(3) not null comment '任务开始时间',
+ end_time datetime(3) null comment '任务结束时间',
+ returned tinyint(1) default 0 not null comment '已回退标志',
+ status varchar(16) default '' not null comment '任务状态:审批中/通过/驳回/转交/加签',
+ extra json null comment '扩展字段',
+ create_at datetime default CURRENT_TIMESTAMP not null comment '创建时间',
+ update_at datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
+ is_delete bigint default 0 not null comment '是否删除'
)
comment '审批日志持久化';
From ae173d789bf609db95c6e82dc1de219c9b88ea43 Mon Sep 17 00:00:00 2001
From: yangqicheng
Date: Tue, 3 Sep 2024 16:47:30 +0800
Subject: [PATCH 008/139] =?UTF-8?q?REQ-2924-=E5=A2=9E=E5=8A=A0=E5=9B=9E?=
=?UTF-8?q?=E9=80=80=E5=88=B0=E6=8C=87=E5=AE=9A=E8=8A=82=E7=82=B9=EF=BC=8C?=
=?UTF-8?q?=E5=9B=9E=E9=80=80=E8=8A=82=E7=82=B9=E9=80=89=E9=A1=B9=E6=8E=A5?=
=?UTF-8?q?=E5=8F=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../client/feign/bpmn/ProcessTaskApi.java | 17 +++-
.../bpmn/task/BpmnOptionalNodeDTO.java | 31 +++++++
.../bpmn/task/BpmnUserTaskNodeDTO.java | 36 ++++++++
.../service/BpmnProcessDefinitionService.java | 11 +++
.../core/service/BpmnProcessTaskService.java | 8 ++
.../BpmnProcessDefinitionServiceImpl.java | 50 +++++++++++
.../impl/BpmnProcessTaskServiceImpl.java | 88 ++++++++++++++++++-
.../web/bpmn/BpmnProcessTaskController.java | 24 ++++-
8 files changed, 259 insertions(+), 6 deletions(-)
create mode 100644 workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnOptionalNodeDTO.java
create mode 100644 workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnUserTaskNodeDTO.java
diff --git a/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/bpmn/ProcessTaskApi.java b/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/bpmn/ProcessTaskApi.java
index d173f1856..204a66d8e 100644
--- a/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/bpmn/ProcessTaskApi.java
+++ b/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/bpmn/ProcessTaskApi.java
@@ -1,8 +1,8 @@
package cn.axzo.workflow.client.feign.bpmn;
-import cn.axzo.workflow.client.config.CommonFeignConfiguration;
import cn.axzo.workflow.common.annotation.InvokeMode;
import cn.axzo.workflow.common.annotation.Manageable;
+import cn.axzo.workflow.common.model.request.bpmn.task.BpmnOptionalNodeDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCompleteDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCreateDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAttachmentDTO;
@@ -13,6 +13,7 @@ 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.request.bpmn.task.BpmnTaskRemindDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskTransferDTO;
+import cn.axzo.workflow.common.model.request.bpmn.task.BpmnUserTaskNodeDTO;
import cn.axzo.workflow.common.model.response.BpmPageResult;
import cn.axzo.workflow.common.model.response.bpmn.BatchOperationResultVO;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceGroupVO;
@@ -22,7 +23,6 @@ import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskInstanceVO;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskTodoPageItemVO;
import cn.azxo.framework.common.model.CommonResponse;
import io.swagger.v3.oas.annotations.Operation;
-import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@@ -72,7 +72,20 @@ public interface ProcessTaskApi {
@PostMapping("/api/process/task/batch/approve")
CommonResponse batchApproveTask(@Validated @RequestBody List dtos);
+ /**
+ * 获取当前节点可退回节点选项列表
+ * @param bpmnUserTaskNodeDTO 参数
+ * @return
+ */
+ @Operation(summary = "获取当前节点可退回节点选项列表")
+ @PostMapping("/api/process/task/back/optional/nodes")
+ CommonResponse> getApproveOptionalNodes(@Validated @RequestBody BpmnUserTaskNodeDTO bpmnUserTaskNodeDTO);
+ /**
+ * 回退到指定节点
+ * @param dto
+ * @return
+ */
@Operation(summary = "回退")
@PostMapping("/api/process/task/back")
CommonResponse backTask(@Validated @RequestBody BpmnTaskBackAuditDTO dto);
diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnOptionalNodeDTO.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnOptionalNodeDTO.java
new file mode 100644
index 000000000..665a5b19f
--- /dev/null
+++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnOptionalNodeDTO.java
@@ -0,0 +1,31 @@
+package cn.axzo.workflow.common.model.request.bpmn.task;
+
+import cn.axzo.workflow.common.enums.BpmnFlowNodeType;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 退回到指定节点,可选节点模型
+ */
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+@Builder
+public class BpmnOptionalNodeDTO {
+
+ private String processInstanceId;
+
+ private String processDefinitionId;
+
+ private String processNodeId;
+
+ private String processNodeName;
+
+ private String processNodeDesc;
+
+ private BpmnFlowNodeType nodeType;
+
+ private Integer ordinal;
+}
diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnUserTaskNodeDTO.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnUserTaskNodeDTO.java
new file mode 100644
index 000000000..9a1e89517
--- /dev/null
+++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnUserTaskNodeDTO.java
@@ -0,0 +1,36 @@
+package cn.axzo.workflow.common.model.request.bpmn.task;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotBlank;
+
+@ApiModel("节点信息模型")
+@Data
+@Accessors(chain = true)
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+public class BpmnUserTaskNodeDTO {
+
+ @ApiModelProperty(value = "租户id")
+ @NotBlank(message = "租户id不能为空")
+ private String tenantId;
+
+ @ApiModelProperty(value = "流程实例id")
+ @NotBlank(message = "流程实例id不能为空")
+ private String processInstanceId;
+
+ @ApiModelProperty(value = "审批任务id")
+ @NotBlank(message = "审批任务id不能为空")
+ private String taskId;
+
+ private String processNodeId;
+
+ private String processNodeName;
+}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessDefinitionService.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessDefinitionService.java
index 88e3a7648..e67398dcc 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessDefinitionService.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessDefinitionService.java
@@ -4,6 +4,9 @@ import cn.axzo.workflow.common.model.request.bpmn.definition.BpmnProcessDefiniti
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessDefinitionPageDTO;
import cn.axzo.workflow.common.model.response.BpmPageResult;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessDefinitionVO;
+import org.flowable.bpmn.model.EndEvent;
+import org.flowable.bpmn.model.FlowElement;
+import org.flowable.bpmn.model.FlowNode;
import org.flowable.common.engine.impl.db.SuspensionState;
import org.flowable.engine.repository.Model;
import org.flowable.engine.repository.ProcessDefinition;
@@ -82,4 +85,12 @@ public interface BpmnProcessDefinitionService {
List getProcessDefinitionListByDeploymentIds(Set deploymentIds);
void delete(String deploymentId, Boolean cascade);
+
+ List findEndFlowElement(String processDefinitionId);
+
+ List findFlowNodes(String processDefinitionId);
+
+ List findFlowElements(String processDefinitionId);
+
+ List findFlowElementsByIds(String processDefinitionId, List flowElementIds);
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessTaskService.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessTaskService.java
index 28482b76c..f78bff7bc 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessTaskService.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessTaskService.java
@@ -1,5 +1,6 @@
package cn.axzo.workflow.core.service;
+import cn.axzo.workflow.common.model.request.bpmn.task.BpmnOptionalNodeDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCompleteDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCreateDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAttachmentDTO;
@@ -53,6 +54,13 @@ public interface BpmnProcessTaskService {
*/
BatchOperationResultVO batchApproveTask(List taskAuditDTOS);
+ /**
+ * 退回到指定节点,可以退回节点选项
+ * @param processInstanceId 流程实例id
+ * @param taskId 任务id
+ */
+ List getApproveOptionalNodes(String processInstanceId, String taskId, String tenantId);
+
/**
* 驳回
*/
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessDefinitionServiceImpl.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessDefinitionServiceImpl.java
index 55956d45c..e2df82aa3 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessDefinitionServiceImpl.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessDefinitionServiceImpl.java
@@ -14,6 +14,9 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.BpmnModel;
+import org.flowable.bpmn.model.EndEvent;
+import org.flowable.bpmn.model.FlowElement;
+import org.flowable.bpmn.model.FlowNode;
import org.flowable.common.engine.impl.db.SuspensionState;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.repository.Deployment;
@@ -27,6 +30,7 @@ import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -282,4 +286,50 @@ public class BpmnProcessDefinitionServiceImpl implements BpmnProcessDefinitionSe
}
return repositoryService.createDeploymentQuery().deploymentId(id).singleResult();
}
+
+ @Override
+ public List findEndFlowElement(String processDefinitionId) {
+ return getNodesByType(processDefinitionId, EndEvent.class);
+ }
+
+ @Override
+ public List findFlowNodes(String processDefinitionId) {
+ return getNodesByType(processDefinitionId, FlowNode.class);
+ }
+
+ @Override
+ public List findFlowElements(String processDefinitionId) {
+ return getNodesByType(processDefinitionId, FlowElement.class);
+ }
+
+ @Override
+ public List findFlowElementsByIds(String processDefinitionId, List flowElementIds) {
+ if (CollectionUtils.isEmpty(flowElementIds)) {
+ return emptyList();
+ }
+ ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
+ .processDefinitionId(processDefinitionId)
+ .singleResult();
+ if (processDefinition == null) {
+ return emptyList();
+ }
+ BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId());
+ return flowElementIds.stream().map(bpmnModel::getFlowElement).collect(Collectors.toList());
+ }
+
+ private List getNodesByType(String processDefinitionId, Class clazz) {
+ ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
+ .processDefinitionId(processDefinitionId)
+ .singleResult();
+ if (processDefinition == null) {
+ return emptyList();
+ }
+ BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId());
+ Collection flowNodes = bpmnModel.getMainProcess().findFlowElementsOfType(clazz);
+ if (CollectionUtils.isEmpty(flowNodes)) {
+ return emptyList();
+ }
+ return new ArrayList<>(flowNodes);
+ }
+
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java
index 99b5b0c50..2e52fb165 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java
@@ -1,7 +1,9 @@
package cn.axzo.workflow.core.service.impl;
import cn.axzo.workflow.common.enums.BpmnCountersignTypeEnum;
+import cn.axzo.workflow.common.enums.BpmnFlowNodeType;
import cn.axzo.workflow.common.model.request.bpmn.BpmnNoticeConf;
+import cn.axzo.workflow.common.model.request.bpmn.task.BpmnOptionalNodeDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCompleteDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCreateDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAttachmentDTO;
@@ -40,6 +42,7 @@ import cn.axzo.workflow.core.engine.event.MessagePushEventBuilder;
import cn.axzo.workflow.core.engine.event.MessagePushEventImpl;
import cn.axzo.workflow.core.engine.event.MessagePushEventType;
import cn.axzo.workflow.core.repository.entity.ExtAxHiTaskInst;
+import cn.axzo.workflow.core.service.BpmnProcessDefinitionService;
import cn.axzo.workflow.core.service.BpmnProcessTaskService;
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
import cn.axzo.workflow.core.service.converter.BpmnHistoricAttachmentConverter;
@@ -50,7 +53,13 @@ import cn.axzo.workflow.core.service.converter.BpmnTaskTodoPageItemConverter;
import cn.hutool.core.collection.CollUtil;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
+import org.flowable.bpmn.model.BaseElement;
import org.flowable.bpmn.model.BpmnModel;
+import org.flowable.bpmn.model.FlowElement;
+import org.flowable.bpmn.model.SequenceFlow;
+import org.flowable.bpmn.model.ServiceTask;
+import org.flowable.bpmn.model.UserTask;
import org.flowable.common.engine.api.delegate.event.FlowableEventDispatcher;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.common.engine.impl.interceptor.CommandExecutor;
@@ -59,6 +68,7 @@ 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.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.history.HistoricProcessInstanceQuery;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
@@ -82,7 +92,6 @@ import org.flowable.variable.service.impl.persistence.entity.HistoricVariableIns
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
-import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
@@ -96,6 +105,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
@@ -108,7 +118,11 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELAT
import static cn.axzo.workflow.common.constant.BpmnConstants.NO_ASSIGNEE;
import static cn.axzo.workflow.common.constant.BpmnConstants.OLD_INTERNAL_TASK_RELATION_ASSIGNEE_INFO_SNAPSHOT;
import static cn.axzo.workflow.common.constant.BpmnConstants.WORKFLOW_ENGINE_VERSION;
+import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_BUSINESS;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_CARBON_COPY;
+import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_EMPTY;
+import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_STARTER;
+import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_TASK;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.APPROVED;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.PROCESSING;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.REJECTED;
@@ -153,6 +167,8 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
@Resource
@Lazy
private BpmnProcessTaskService bpmnProcessTaskService;
+ @Resource
+ private BpmnProcessDefinitionService bpmnProcessModelService;
@Override
public BpmPageResult getTodoTaskPage(BpmnTaskPageSearchDTO dto) {
@@ -323,6 +339,76 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
}
}
+ @Override
+ public List getApproveOptionalNodes(String processInstanceId, String taskId, String tenantId) {
+ Task task = processEngineConfiguration.getTaskService().createTaskQuery().taskId(taskId).singleResult();
+ if (task != null) {
+ //1.获取当前的流程实例
+ ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
+ if (processInstance == null) {
+ //流程为空,已经结束,返回空
+ return Collections.emptyList();
+ }
+ List hisList = historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).list();
+ List activeActivityIds = runtimeService.getActiveActivityIds(processInstanceId);
+ if (CollectionUtils.isEmpty(activeActivityIds)) {
+ return Collections.emptyList();
+ }
+ List flowElements = bpmnProcessModelService.findFlowElements(task.getProcessDefinitionId());
+ if (CollectionUtils.isEmpty(flowElements)) {
+ return Collections.emptyList();
+ }
+ //考虑会签
+ Map flowElementMap = flowElements.stream().collect(Collectors.toMap(BaseElement::getId, f -> f));
+ List executePath = new ArrayList<>();
+ for (HistoricActivityInstance his : hisList) {
+ FlowElement flowElement = flowElementMap.get(his.getActivityId());
+ if (flowElement != null) {
+ FlowElement previousNode = CollectionUtils.isEmpty(executePath) ? null : executePath.get(executePath.size() - 1);
+ //上一级直接连接,不是同一个节点,表示跳转过去的,
+ if (previousNode != null && !his.getActivityId().equals(previousNode.getId()) && (previousNode instanceof UserTask || previousNode instanceof ServiceTask) && !(flowElement instanceof SequenceFlow)) {
+ int i = executePath.size() - 1;
+ for (; i >= 0; i--) {
+ if (executePath.get(i).getId().equals(flowElement.getId())) {
+ break;
+ }
+ }
+ //去掉跳过的路径
+ executePath = executePath.subList(0, i);
+ }
+ if (previousNode == null || !previousNode.getId().equals(his.getActivityId())) {
+ executePath.add(flowElement);
+ }
+ }
+ }
+ AtomicInteger index = new AtomicInteger(0);
+ List resultList = executePath.stream()
+ .filter(flowElement -> !activeActivityIds.contains(flowElement.getId())) //排除当前节点
+ .filter(flowElement -> {
+ BpmnFlowNodeType currentNodeType = BpmnMetaParserHelper.getNodeType(flowElement).orElse(NODE_EMPTY);
+ return currentNodeType == NODE_TASK || currentNodeType == NODE_BUSINESS;
+ })
+ .filter(flowElement -> !NODE_STARTER.getType().equals(flowElement.getId()))
+ .map(flowElement -> BpmnOptionalNodeDTO
+ .builder()
+ .processInstanceId(task.getProcessInstanceId())
+ .processDefinitionId(task.getProcessDefinitionId())
+ .processNodeId(flowElement.getId())
+ .processNodeName(flowElement.getName())
+ .processNodeDesc(flowElement.getName())
+ .nodeType(BpmnMetaParserHelper.getNodeType(flowElement).orElse(NODE_EMPTY))
+ .ordinal(index.incrementAndGet())
+ .build())
+ .collect(Collectors.toList());
+ if (CollectionUtils.isNotEmpty(resultList)) {
+ BpmnOptionalNodeDTO bpmnOptionalNodeDTO = resultList.get(resultList.size() - 1);
+ bpmnOptionalNodeDTO.setProcessNodeDesc(bpmnOptionalNodeDTO.getProcessNodeId() + "(上一级)");
+ }
+ return resultList;
+ }
+ return Collections.emptyList();
+ }
+
@Override
public BatchOperationResultVO batchApproveTask(List dtos) {
return batchOperation(dtos, bpmnProcessTaskService::approveTask);
diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java
index 85b71c29a..f9468e6e1 100644
--- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java
+++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java
@@ -3,6 +3,7 @@ package cn.axzo.workflow.server.controller.web.bpmn;
import cn.axzo.workflow.client.feign.bpmn.ProcessTaskApi;
import cn.axzo.workflow.common.enums.AttachmentTypeEnum;
import cn.axzo.workflow.common.model.request.bpmn.task.AttachmentDTO;
+import cn.axzo.workflow.common.model.request.bpmn.task.BpmnOptionalNodeDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCompleteDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCreateDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAttachmentDTO;
@@ -13,6 +14,7 @@ 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.request.bpmn.task.BpmnTaskRemindDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskTransferDTO;
+import cn.axzo.workflow.common.model.request.bpmn.task.BpmnUserTaskNodeDTO;
import cn.axzo.workflow.common.model.response.BpmPageResult;
import cn.axzo.workflow.common.model.response.bpmn.BatchOperationResultVO;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceGroupVO;
@@ -119,6 +121,20 @@ public class BpmnProcessTaskController implements ProcessTaskApi {
return success(bpmnProcessTaskService.batchApproveTask(dtos));
}
+ /**
+ * 获取当前节点可退回节点选项列表
+ * @param dto 参数
+ * @return
+ */
+ @Operation(summary = "获取当前节点可退回节点选项列表")
+ @PostMapping("/api/process/task/back/optional/nodes")
+ @Override
+ @RepeatSubmit
+ public CommonResponse> getApproveOptionalNodes(@RequestBody @Validated BpmnUserTaskNodeDTO dto) {
+ List approveOptionalNodes = bpmnProcessTaskService.getApproveOptionalNodes(dto.getProcessInstanceId(), dto.getTaskId(), dto.getTenantId());
+ return success(approveOptionalNodes);
+ }
+
/**
* 回退
*/
@@ -132,10 +148,12 @@ public class BpmnProcessTaskController implements ProcessTaskApi {
}
/**
- * 驳回
+ * 回退到指定节点
+ * @param dto
+ * @return
*/
- @Operation(summary = "驳回任务")
- @PostMapping("/reject")
+ @Operation(summary = "回退")
+ @PostMapping("/api/process/task/back")
@Override
@RepeatSubmit
public CommonResponse rejectTask(@Validated @RequestBody BpmnTaskAuditDTO dto) {
From 19e75f3a65ff1cfa470a0edd29f0a33440d5191b Mon Sep 17 00:00:00 2001
From: yangqicheng
Date: Tue, 3 Sep 2024 17:17:20 +0800
Subject: [PATCH 009/139] =?UTF-8?q?REQ-2924-=E8=B0=83=E6=95=B4=E5=9B=9E?=
=?UTF-8?q?=E9=80=80=E4=BB=A3=E7=A0=81=E9=80=BB=E8=BE=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../bpmn/task/BpmnUserTaskNodeDTO.java | 4 -
.../common/code/BpmnInstanceRespCode.java | 1 +
.../impl/BpmnProcessTaskServiceImpl.java | 122 +++++++++---------
.../web/bpmn/BpmnProcessTaskController.java | 4 +-
4 files changed, 65 insertions(+), 66 deletions(-)
diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnUserTaskNodeDTO.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnUserTaskNodeDTO.java
index 9a1e89517..c1a228742 100644
--- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnUserTaskNodeDTO.java
+++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnUserTaskNodeDTO.java
@@ -29,8 +29,4 @@ public class BpmnUserTaskNodeDTO {
@ApiModelProperty(value = "审批任务id")
@NotBlank(message = "审批任务id不能为空")
private String taskId;
-
- private String processNodeId;
-
- private String processNodeName;
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/BpmnInstanceRespCode.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/BpmnInstanceRespCode.java
index 281569769..e1e8d2bbe 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/BpmnInstanceRespCode.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/BpmnInstanceRespCode.java
@@ -27,6 +27,7 @@ public enum BpmnInstanceRespCode implements IModuleRespCode {
TASK_CANT_COMMENT_INSTANCE_NOT_EXISTS("012", "流程实例【{}】不存在, 不能评论"),
RUNNING_INSTANCE_ONLY_FORECAST("013", "仅运行中的实例可以推测"),
ENGINE_EXEC_EXCEPTION("014", "引擎内部异常"),
+ PROCESS_TASK_NOT_EXISTS("015", "流程任务不存在或已处理"),
;
private final String code;
private final String message;
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java
index 2e52fb165..425f04fb8 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java
@@ -128,6 +128,8 @@ import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.PROCES
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.code.BpmnInstanceRespCode.PROCESS_INSTANCE_ID_NOT_EXISTS;
+import static cn.axzo.workflow.core.common.code.BpmnInstanceRespCode.PROCESS_INSTANCE_NOT_EXISTS;
+import static cn.axzo.workflow.core.common.code.BpmnInstanceRespCode.PROCESS_TASK_NOT_EXISTS;
import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.FIND_TASK_BY_PERSON_ID_ERROR;
import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.TASK_REMIND_ERROR_NOT_EXISTS;
import static cn.axzo.workflow.core.common.utils.BpmnCollectionUtils.convertSet;
@@ -342,71 +344,71 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
@Override
public List getApproveOptionalNodes(String processInstanceId, String taskId, String tenantId) {
Task task = processEngineConfiguration.getTaskService().createTaskQuery().taskId(taskId).singleResult();
- if (task != null) {
- //1.获取当前的流程实例
- ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
- if (processInstance == null) {
- //流程为空,已经结束,返回空
- return Collections.emptyList();
- }
- List hisList = historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).list();
- List activeActivityIds = runtimeService.getActiveActivityIds(processInstanceId);
- if (CollectionUtils.isEmpty(activeActivityIds)) {
- return Collections.emptyList();
- }
- List flowElements = bpmnProcessModelService.findFlowElements(task.getProcessDefinitionId());
- if (CollectionUtils.isEmpty(flowElements)) {
- return Collections.emptyList();
- }
- //考虑会签
- Map flowElementMap = flowElements.stream().collect(Collectors.toMap(BaseElement::getId, f -> f));
- List executePath = new ArrayList<>();
- for (HistoricActivityInstance his : hisList) {
- FlowElement flowElement = flowElementMap.get(his.getActivityId());
- if (flowElement != null) {
- FlowElement previousNode = CollectionUtils.isEmpty(executePath) ? null : executePath.get(executePath.size() - 1);
- //上一级直接连接,不是同一个节点,表示跳转过去的,
- if (previousNode != null && !his.getActivityId().equals(previousNode.getId()) && (previousNode instanceof UserTask || previousNode instanceof ServiceTask) && !(flowElement instanceof SequenceFlow)) {
- int i = executePath.size() - 1;
- for (; i >= 0; i--) {
- if (executePath.get(i).getId().equals(flowElement.getId())) {
- break;
- }
+ if (task == null) {
+ throw new WorkflowEngineException(PROCESS_TASK_NOT_EXISTS);
+ }
+ //1.获取当前的流程实例
+ ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
+ if (processInstance == null) {
+ //流程为空,已经结束,返回空
+ throw new WorkflowEngineException(PROCESS_INSTANCE_NOT_EXISTS);
+ }
+ List hisList = historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).list();
+ List activeActivityIds = runtimeService.getActiveActivityIds(processInstanceId);
+ if (CollectionUtils.isEmpty(activeActivityIds)) {
+ return Collections.emptyList();
+ }
+ List flowElements = bpmnProcessModelService.findFlowElements(task.getProcessDefinitionId());
+ if (CollectionUtils.isEmpty(flowElements)) {
+ return Collections.emptyList();
+ }
+ //考虑会签
+ Map flowElementMap = flowElements.stream().collect(Collectors.toMap(BaseElement::getId, f -> f));
+ List executePath = new ArrayList<>();
+ for (HistoricActivityInstance his : hisList) {
+ FlowElement flowElement = flowElementMap.get(his.getActivityId());
+ if (flowElement != null) {
+ FlowElement previousNode = CollectionUtils.isEmpty(executePath) ? null : executePath.get(executePath.size() - 1);
+ //上一级直接连接,不是同一个节点,表示跳转过去的,
+ if (previousNode != null && !his.getActivityId().equals(previousNode.getId()) && (previousNode instanceof UserTask || previousNode instanceof ServiceTask) && !(flowElement instanceof SequenceFlow)) {
+ int i = executePath.size() - 1;
+ for (; i >= 0; i--) {
+ if (executePath.get(i).getId().equals(flowElement.getId())) {
+ break;
}
- //去掉跳过的路径
- executePath = executePath.subList(0, i);
- }
- if (previousNode == null || !previousNode.getId().equals(his.getActivityId())) {
- executePath.add(flowElement);
}
+ //去掉跳过的路径
+ executePath = executePath.subList(0, i);
+ }
+ if (previousNode == null || !previousNode.getId().equals(his.getActivityId())) {
+ executePath.add(flowElement);
}
}
- AtomicInteger index = new AtomicInteger(0);
- List resultList = executePath.stream()
- .filter(flowElement -> !activeActivityIds.contains(flowElement.getId())) //排除当前节点
- .filter(flowElement -> {
- BpmnFlowNodeType currentNodeType = BpmnMetaParserHelper.getNodeType(flowElement).orElse(NODE_EMPTY);
- return currentNodeType == NODE_TASK || currentNodeType == NODE_BUSINESS;
- })
- .filter(flowElement -> !NODE_STARTER.getType().equals(flowElement.getId()))
- .map(flowElement -> BpmnOptionalNodeDTO
- .builder()
- .processInstanceId(task.getProcessInstanceId())
- .processDefinitionId(task.getProcessDefinitionId())
- .processNodeId(flowElement.getId())
- .processNodeName(flowElement.getName())
- .processNodeDesc(flowElement.getName())
- .nodeType(BpmnMetaParserHelper.getNodeType(flowElement).orElse(NODE_EMPTY))
- .ordinal(index.incrementAndGet())
- .build())
- .collect(Collectors.toList());
- if (CollectionUtils.isNotEmpty(resultList)) {
- BpmnOptionalNodeDTO bpmnOptionalNodeDTO = resultList.get(resultList.size() - 1);
- bpmnOptionalNodeDTO.setProcessNodeDesc(bpmnOptionalNodeDTO.getProcessNodeId() + "(上一级)");
- }
- return resultList;
}
- return Collections.emptyList();
+ AtomicInteger index = new AtomicInteger(0);
+ List resultList = executePath.stream()
+ .filter(flowElement -> !activeActivityIds.contains(flowElement.getId())) //排除当前节点
+ .filter(flowElement -> {
+ BpmnFlowNodeType currentNodeType = BpmnMetaParserHelper.getNodeType(flowElement).orElse(NODE_EMPTY);
+ return currentNodeType == NODE_TASK || currentNodeType == NODE_BUSINESS;
+ })
+ .filter(flowElement -> !NODE_STARTER.getType().equals(flowElement.getId()))
+ .map(flowElement -> BpmnOptionalNodeDTO
+ .builder()
+ .processInstanceId(task.getProcessInstanceId())
+ .processDefinitionId(task.getProcessDefinitionId())
+ .processNodeId(flowElement.getId())
+ .processNodeName(flowElement.getName())
+ .processNodeDesc(flowElement.getName())
+ .nodeType(BpmnMetaParserHelper.getNodeType(flowElement).orElse(NODE_EMPTY))
+ .ordinal(index.incrementAndGet())
+ .build())
+ .collect(Collectors.toList());
+ if (CollectionUtils.isNotEmpty(resultList)) {
+ BpmnOptionalNodeDTO bpmnOptionalNodeDTO = resultList.get(resultList.size() - 1);
+ bpmnOptionalNodeDTO.setProcessNodeDesc(bpmnOptionalNodeDTO.getProcessNodeId() + "(上一级)");
+ }
+ return resultList;
}
@Override
diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java
index f9468e6e1..6c68abdae 100644
--- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java
+++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java
@@ -124,10 +124,10 @@ public class BpmnProcessTaskController implements ProcessTaskApi {
/**
* 获取当前节点可退回节点选项列表
* @param dto 参数
- * @return
+ * @return 可选退回节点列表
*/
@Operation(summary = "获取当前节点可退回节点选项列表")
- @PostMapping("/api/process/task/back/optional/nodes")
+ @PostMapping("/back/optional/nodes")
@Override
@RepeatSubmit
public CommonResponse> getApproveOptionalNodes(@RequestBody @Validated BpmnUserTaskNodeDTO dto) {
From 4a48c9a5e22f314ef23480466b0121d7c6caa589 Mon Sep 17 00:00:00 2001
From: yangqicheng
Date: Tue, 3 Sep 2024 18:53:26 +0800
Subject: [PATCH 010/139] =?UTF-8?q?REQ-2924-=E5=9B=9E=E9=80=80=E5=8A=9F?=
=?UTF-8?q?=E8=83=BD=E6=94=AF=E6=8C=81=E5=BC=82=E6=AD=A5=E6=9C=BA=E5=88=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../enums/BpmnProcessInstanceResultEnum.java | 1 +
.../bpmn/task/BpmnTaskBackAuditDTO.java | 6 +-
.../engine/cmd/CustomApproveTaskAsyncCmd.java | 2 +
.../engine/cmd/CustomBackTaskAsyncCmd.java | 83 +++++++++++++++++++
.../core/engine/cmd/CustomBackTaskCmd.java | 28 +++----
.../engine/job/AsyncBackTaskJobHandler.java | 50 +++++++++++
.../impl/BpmnProcessTaskServiceImpl.java | 7 +-
7 files changed, 154 insertions(+), 23 deletions(-)
create mode 100644 workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskAsyncCmd.java
create mode 100644 workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AsyncBackTaskJobHandler.java
diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/enums/BpmnProcessInstanceResultEnum.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/enums/BpmnProcessInstanceResultEnum.java
index 81ba92e01..150ecbc35 100644
--- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/enums/BpmnProcessInstanceResultEnum.java
+++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/enums/BpmnProcessInstanceResultEnum.java
@@ -6,6 +6,7 @@ public enum BpmnProcessInstanceResultEnum {
PROCESSING("PROCESSING", "审批中"),
APPROVED("APPROVED", "已通过"),
REJECTED("REJECTED", "已驳回"),
+ BACKED("BACKED", "已回退"),
CANCELLED("CANCELLED", "已撤回"),
ABORTED("ABORTED", "已中止"),
TRANSFER("TRANSFER", "已转交"),
diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnTaskBackAuditDTO.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnTaskBackAuditDTO.java
index a7a9611f9..f618fcd4f 100644
--- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnTaskBackAuditDTO.java
+++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnTaskBackAuditDTO.java
@@ -3,7 +3,6 @@ package cn.axzo.workflow.common.model.request.bpmn.task;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
-import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@@ -11,6 +10,7 @@ import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
+import java.io.Serializable;
@EqualsAndHashCode(callSuper = true)
@ApiModel("回退到指定节点入参模型")
@@ -18,7 +18,9 @@ import javax.validation.constraints.NotEmpty;
@Validated
@AllArgsConstructor
@NoArgsConstructor
-public class BpmnTaskBackAuditDTO extends BpmnTaskAuditDTO {
+public class BpmnTaskBackAuditDTO extends BpmnTaskAuditDTO implements Serializable {
+
+ private static final long serialVersionUID = 2226704888158991717L;
@ApiModelProperty(value = "当前流程节点id", required = true)
@NotBlank(message = "当前流程节点id不能为空")
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomApproveTaskAsyncCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomApproveTaskAsyncCmd.java
index f7bccb3ab..c89d20c74 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomApproveTaskAsyncCmd.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomApproveTaskAsyncCmd.java
@@ -29,8 +29,10 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask
* @since 2024/1/4 15:50
*/
public class CustomApproveTaskAsyncCmd extends AbstractCommand implements Serializable {
+ private static final long serialVersionUID = -4706627700694867170L;
private static final Logger log = LoggerFactory.getLogger(CustomApproveTaskAsyncCmd.class);
+
private final BpmnTaskAuditDTO dto;
public CustomApproveTaskAsyncCmd(BpmnTaskAuditDTO dto) {
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskAsyncCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskAsyncCmd.java
new file mode 100644
index 000000000..0dbfda785
--- /dev/null
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskAsyncCmd.java
@@ -0,0 +1,83 @@
+package cn.axzo.workflow.core.engine.cmd;
+
+import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskBackAuditDTO;
+import cn.axzo.workflow.core.engine.job.AsyncApproveTaskJobHandler;
+import cn.axzo.workflow.core.engine.job.AsyncBackTaskJobHandler;
+import cn.hutool.json.JSONUtil;
+import com.alibaba.fastjson.JSON;
+import org.flowable.common.engine.impl.interceptor.CommandContext;
+import org.flowable.engine.TaskService;
+import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
+import org.flowable.engine.impl.util.CommandContextUtil;
+import org.flowable.job.service.JobService;
+import org.flowable.job.service.impl.persistence.entity.JobEntity;
+import org.flowable.task.api.Task;
+import org.flowable.task.api.history.HistoricTaskInstance;
+import org.flowable.task.api.history.HistoricTaskInstanceQuery;
+import org.flowable.task.service.impl.persistence.entity.TaskEntity;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask;
+
+public class CustomBackTaskAsyncCmd extends AbstractCommand implements Serializable {
+
+ private static final long serialVersionUID = 1773108485033787095L;
+
+ private static final Logger log = LoggerFactory.getLogger(CustomBackTaskAsyncCmd.class);
+
+ private final BpmnTaskBackAuditDTO dto;
+
+ public CustomBackTaskAsyncCmd(BpmnTaskBackAuditDTO dto) {
+ this.dto = dto;
+ }
+
+ @Override
+ public String executeInternal(CommandContext commandContext) {
+ ProcessEngineConfigurationImpl processEngineConfiguration =
+ CommandContextUtil.getProcessEngineConfiguration(commandContext);
+ HistoricTaskInstanceQuery taskQuery =
+ processEngineConfiguration.getHistoryService().createHistoricTaskInstanceQuery();
+ TaskService taskService = processEngineConfiguration.getTaskService();
+
+ HistoricTaskInstance historicTaskInstance = taskQuery.taskId(dto.getTaskId()).singleResult();
+
+ Task task = taskService.createTaskQuery().taskId(dto.getTaskId()).singleResult();
+ if (Objects.isNull(task)) {
+ log.info("任务不存在: {}", dto.getTaskId());
+ }
+ validTask(historicTaskInstance, (TaskEntity) task, dto.getApprover(), null);
+
+ return startAsync(processEngineConfiguration, task);
+ }
+
+ private String startAsync(ProcessEngineConfigurationImpl processEngineConfiguration, Task task) {
+ JobService jobService = processEngineConfiguration.getJobServiceConfiguration().getJobService();
+
+ JobEntity job = jobService.createJob();
+ // 这里的 executionId 可为 null
+ job.setExecutionId(task.getExecutionId());
+ job.setProcessInstanceId(task.getProcessInstanceId());
+ job.setProcessDefinitionId(task.getProcessDefinitionId());
+ job.setElementId(task.getTaskDefinitionKey());
+ job.setElementName(task.getName());
+ job.setJobHandlerType(AsyncBackTaskJobHandler.TYPE);
+ job.setTenantId(task.getTenantId());
+
+ // 携带自定义的数据
+ job.setCustomValues(JSONUtil.toJsonStr(dto));
+
+ // 创建异步任务并调度
+ jobService.createAsyncJob(job, false);
+ jobService.scheduleAsyncJob(job);
+ return job.getId();
+ }
+
+ @Override
+ public String paramToJsonString() {
+ return JSON.toJSONString(dto);
+ }
+}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java
index b3db09fcd..4613b9177 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java
@@ -28,9 +28,8 @@ import java.util.Objects;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC;
-import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_SPECIFY_NEXT_APPROVER;
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_COMPLETE_OPERATION_TYPE;
-import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.APPROVED;
+import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.BACKED;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.addComment;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.batchAddAttachment;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask;
@@ -39,7 +38,10 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask
* 回退命令
*/
public class CustomBackTaskCmd extends AbstractCommand implements Serializable {
+ private static final long serialVersionUID = -1241290344311892346L;
+
private static final Logger log = LoggerFactory.getLogger(CustomBackTaskCmd.class);
+
private final String taskId;
/**
* advice 统一均为审批节点的审批意见,一般为用户在同意、驳回时填写的内容
@@ -57,19 +59,15 @@ public class CustomBackTaskCmd extends AbstractCommand implements Serializ
*/
private final List attachmentList;
private final BpmnTaskDelegateAssigner approver;
- /**
- * 下级节点的审批,可为空
- */
- private final BpmnTaskDelegateAssigner nextApprover;
/**
* 指定节点类型
*/
- private List nodeTypes;
+ private final List nodeTypes;
- private String currentActivityId;
+ private final String currentActivityId;
- private String toActivityId;
+ private final String toActivityId;
@Override
public String paramToJsonString() {
@@ -79,7 +77,6 @@ public class CustomBackTaskCmd extends AbstractCommand implements Serializ
params.put("operationDesc", operationDesc);
params.put("attachmentList", JSON.toJSONString(attachmentList));
params.put("approver", JSON.toJSONString(approver));
- params.put("nextApprover", JSON.toJSONString(nextApprover));
params.put("nodeTypes", JSON.toJSONString(nodeTypes));
return JSON.toJSONString(params);
}
@@ -96,7 +93,6 @@ public class CustomBackTaskCmd extends AbstractCommand implements Serializ
this.advice = dto.getAdvice();
this.attachmentList = dto.getAttachmentList();
this.approver = dto.getApprover();
- this.nextApprover = dto.getNextApprover();
this.nodeTypes = dto.getNodeTypes();
// 这里的不能直接使用字符串的比较,因为外部可能传入空字符串,比如发起人的通过时,就是传入的空字符串
if (Objects.nonNull(operationDesc)) {
@@ -133,16 +129,12 @@ public class CustomBackTaskCmd extends AbstractCommand implements Serializ
Authentication.setAuthenticatedUserId(null);
RuntimeService runtimeService = processEngineConfiguration.getRuntimeService();
- if (Objects.nonNull(nextApprover)) {
- // 主动设置下级审批人
- runtimeService.setVariable(task.getProcessInstanceId(), INTERNAL_SPECIFY_NEXT_APPROVER,
- nextApprover);
- }
- ((TaskEntity) task).setTransientVariable(TASK_COMPLETE_OPERATION_TYPE + taskId, APPROVED.getStatus());
+ ((TaskEntity) task).setTransientVariable(TASK_COMPLETE_OPERATION_TYPE + taskId, BACKED.getStatus());
runtimeService.createChangeActivityStateBuilder()
.processInstanceId(task.getProcessInstanceId())
- .moveActivityIdsToSingleActivityId(Collections.singletonList(currentActivityId),toActivityId).changeState();
+ .moveActivityIdsToSingleActivityId(Collections.singletonList(currentActivityId), toActivityId)
+ .changeState();
return null;
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AsyncBackTaskJobHandler.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AsyncBackTaskJobHandler.java
new file mode 100644
index 000000000..bfec5ab1a
--- /dev/null
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AsyncBackTaskJobHandler.java
@@ -0,0 +1,50 @@
+package cn.axzo.workflow.core.engine.job;
+
+import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskBackAuditDTO;
+import cn.axzo.workflow.core.engine.cmd.CustomBackTaskCmd;
+import cn.hutool.json.JSONUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.flowable.common.engine.impl.interceptor.CommandContext;
+import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
+import org.flowable.engine.impl.util.CommandContextUtil;
+import org.flowable.job.service.JobHandler;
+import org.flowable.job.service.impl.persistence.entity.JobEntity;
+import org.flowable.task.api.Task;
+import org.flowable.variable.api.delegate.VariableScope;
+
+import java.util.Objects;
+
+import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_STARTER;
+
+@Slf4j
+public class AsyncBackTaskJobHandler extends AbstractExecuteWithLockJobHandler implements JobHandler {
+
+ public static final String TYPE = "async-back-task";
+
+ @Override
+ public String getType() {
+ return TYPE;
+ }
+
+ @Override
+ public void executeInternal(JobEntity job, String configuration, VariableScope variableScope, CommandContext commandContext) {
+ log.info("AsyncBackTaskJobHandler executing...");
+ log(job);
+ ProcessEngineConfigurationImpl processEngineConfiguration =
+ CommandContextUtil.getProcessEngineConfiguration(commandContext);
+ BpmnTaskBackAuditDTO dto = JSONUtil.toBean(job.getCustomValues(), BpmnTaskBackAuditDTO.class);
+ Task task = processEngineConfiguration.getTaskService().createTaskQuery().taskId(dto.getTaskId()).singleResult();
+ if (Objects.isNull(task)) {
+ return;
+ }
+ CustomBackTaskCmd command;
+ if (Objects.equals(task.getTaskDefinitionKey(), NODE_STARTER.getType())) {
+ // 这里的 operationDesc 设置为“” 是为了在日志中不显示(已通过)
+ command = new CustomBackTaskCmd(dto, "");
+ } else {
+ command = new CustomBackTaskCmd(dto);
+ }
+ processEngineConfiguration.getCommandExecutor().execute(command);
+ }
+
+}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java
index 425f04fb8..283cdce74 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java
@@ -28,6 +28,7 @@ import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper;
import cn.axzo.workflow.core.engine.cmd.CustomApproveTaskAsyncCmd;
import cn.axzo.workflow.core.engine.cmd.CustomApproveTaskCmd;
+import cn.axzo.workflow.core.engine.cmd.CustomBackTaskAsyncCmd;
import cn.axzo.workflow.core.engine.cmd.CustomBackTaskCmd;
import cn.axzo.workflow.core.engine.cmd.CustomCommentTaskCmd;
import cn.axzo.workflow.core.engine.cmd.CustomCompleteDummyTaskCmd;
@@ -323,7 +324,7 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
@Transactional(rollbackFor = Exception.class)
public void approveTask(BpmnTaskAuditDTO dto) {
CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutor();
- if (dto.getAsync()) {
+ if (Boolean.TRUE.equals(dto.getAsync())) {
commandExecutor.execute(new CustomApproveTaskAsyncCmd(dto));
} else {
commandExecutor.execute(new CustomApproveTaskCmd(dto));
@@ -334,8 +335,8 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
@Transactional(rollbackFor = Exception.class)
public void backTask(BpmnTaskBackAuditDTO dto) {
CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutor();
- if (dto.getAsync()) {
- commandExecutor.execute(new CustomApproveTaskAsyncCmd(dto));
+ if (Boolean.TRUE.equals(dto.getAsync())) {
+ commandExecutor.execute(new CustomBackTaskAsyncCmd(dto));
} else {
commandExecutor.execute(new CustomBackTaskCmd(dto));
}
From 10701800b53e548165260b0fc1455e6b836ea516 Mon Sep 17 00:00:00 2001
From: wangli <274027703@qq.com>
Date: Wed, 4 Sep 2024 12:52:03 +0800
Subject: [PATCH 011/139] =?UTF-8?q?feat(REQ-2924)=20-=20=E7=A7=BB=E9=99=A4?=
=?UTF-8?q?=E5=BC=95=E6=93=8E=E8=BF=87=E6=97=B6=E4=BB=A3=E7=A0=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
...ernalExtAxTaskInstEvent_lo_1_Listener.java | 93 -------------------
1 file changed, 93 deletions(-)
delete mode 100644 workflow-engine-core/src/main/java/cn/axzo/workflow/core/listener/impl/InternalExtAxTaskInstEvent_lo_1_Listener.java
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/listener/impl/InternalExtAxTaskInstEvent_lo_1_Listener.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/listener/impl/InternalExtAxTaskInstEvent_lo_1_Listener.java
deleted file mode 100644
index 602ba4841..000000000
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/listener/impl/InternalExtAxTaskInstEvent_lo_1_Listener.java
+++ /dev/null
@@ -1,93 +0,0 @@
-package cn.axzo.workflow.core.listener.impl;
-
-import cn.axzo.workflow.common.enums.BpmnFlowNodeMode;
-import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
-import cn.axzo.workflow.core.common.context.TaskOperationContext;
-import cn.axzo.workflow.core.listener.AbstractBpmnEventListener;
-import cn.axzo.workflow.core.listener.BpmnTaskEventListener;
-import cn.axzo.workflow.core.service.ExtAxProcessLogService;
-import lombok.AllArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.flowable.bpmn.model.BpmnModel;
-import org.flowable.bpmn.model.FlowElement;
-import org.flowable.bpmn.model.UserTask;
-import org.flowable.engine.RepositoryService;
-import org.flowable.engine.RuntimeService;
-import org.flowable.engine.impl.bpmn.behavior.MultiInstanceActivityBehavior;
-import org.flowable.task.service.delegate.DelegateTask;
-
-import java.util.Objects;
-
-import static cn.axzo.workflow.common.constant.BpmnConstants.AND_SIGN_EXPRESSION;
-import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_INITIATOR;
-import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_INFO;
-import static cn.axzo.workflow.common.constant.BpmnConstants.OLD_INTERNAL_INITIATOR;
-import static cn.axzo.workflow.common.enums.BpmnFlowNodeMode.AND;
-import static cn.axzo.workflow.common.enums.BpmnFlowNodeMode.GENERAL;
-import static cn.axzo.workflow.common.enums.BpmnFlowNodeMode.OR;
-import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_STARTER;
-
-/**
- * Core 包内置的,可共用与 Jar 包集成和微服务集成
- *
- * 该类主要处理新版的日志表
- *
- * @author wangli
- * @since 2023/12/9 22:56
- */
-@Slf4j
-//@Component
-//@Scope("prototype")
-@AllArgsConstructor
-public class InternalExtAxTaskInstEvent_lo_1_Listener extends AbstractBpmnEventListener implements BpmnTaskEventListener {
- private final RuntimeService runtimeService;
- private final RepositoryService repositoryService;
- private final ExtAxProcessLogService processLogService;
-
- @Override
- public int getOrder() {
- return Integer.MIN_VALUE + 1;
- }
-
- /**
- * Assigned 事件先于 Create 事件,所以在此事件中, 只要任务逻辑上应该有人,那么这里的数据就有人, 仅创建日志的初始状态
- *
- * @param delegateTask
- */
- @Override
- public void onCreated(DelegateTask delegateTask) {
- BpmnTaskDelegateAssigner assignee;
- // 记录发起人
- boolean isNodeStarter = Objects.equals(delegateTask.getTaskDefinitionKey(), NODE_STARTER.getType());
- if (isNodeStarter) {
- assignee = getContext().getInitiator(() ->
- BpmnTaskDelegateAssigner.toObjectCompatible(runtimeService.getVariable(delegateTask.getProcessInstanceId(),
- INTERNAL_INITIATOR)));
- if (Objects.isNull(assignee)) {
- // 兼容历史数据
- assignee = getContext().getInitiator(() ->
- BpmnTaskDelegateAssigner.toObjectCompatible(runtimeService.getVariable(delegateTask.getProcessInstanceId(), OLD_INTERNAL_INITIATOR)));
- }
- } else {
- assignee = BpmnTaskDelegateAssigner.toObjectCompatible(runtimeService.getVariable(delegateTask.getProcessInstanceId(), INTERNAL_TASK_RELATION_ASSIGNEE_INFO + delegateTask.getId()));
- }
-
- BpmnModel bpmnModel = repositoryService.getBpmnModel(delegateTask.getProcessDefinitionId());
- FlowElement flowElement = bpmnModel.getFlowElement(delegateTask.getTaskDefinitionKey());
-
- }
-
-
- private BpmnFlowNodeMode getNodeMode(FlowElement flowElement) {
- BpmnFlowNodeMode node = GENERAL;
- if (flowElement instanceof UserTask) {
- UserTask userTask = (UserTask) flowElement;
- if (userTask.getBehavior() instanceof MultiInstanceActivityBehavior) {
- MultiInstanceActivityBehavior behavior =
- (MultiInstanceActivityBehavior) userTask.getBehavior();
- node = Objects.equals(AND_SIGN_EXPRESSION, behavior.getCompletionCondition()) ? AND : OR;
- }
- }
- return node;
- }
-}
From 8ec054f6be58a930c07e75a5d5248545bd94380c Mon Sep 17 00:00:00 2001
From: wangli <274027703@qq.com>
Date: Wed, 4 Sep 2024 16:02:39 +0800
Subject: [PATCH 012/139] =?UTF-8?q?feat(REQ-2924)=20-=20=E6=B7=BB=E5=8A=A0?=
=?UTF-8?q?=E4=B8=80=E4=BA=9B=E6=96=B0=E7=9A=84=E6=97=A5=E5=BF=97=E5=A4=84?=
=?UTF-8?q?=E7=90=86=E9=80=BB=E8=BE=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../listener/EngineEntityEventListener.java | 28 +++++++++++++------
.../core/service/ExtAxProcessLogService.java | 15 ++++++++++
.../impl/ExtAxProcessLogServiceImpl.java | 9 ++++++
3 files changed, 44 insertions(+), 8 deletions(-)
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/EngineEntityEventListener.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/EngineEntityEventListener.java
index 8326140b1..f76131e69 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/EngineEntityEventListener.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/EngineEntityEventListener.java
@@ -17,6 +17,7 @@ import org.flowable.common.engine.api.delegate.event.AbstractFlowableEventListen
import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType;
import org.flowable.common.engine.api.delegate.event.FlowableEntityEvent;
import org.flowable.common.engine.api.delegate.event.FlowableEvent;
+import org.flowable.engine.HistoryService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.impl.bpmn.behavior.MultiInstanceActivityBehavior;
@@ -31,15 +32,16 @@ import java.util.Set;
import static cn.axzo.workflow.common.constant.BpmnConstants.AND_SIGN_EXPRESSION;
import static cn.axzo.workflow.common.constant.BpmnConstants.HIDDEN_ASSIGNEE_ID;
+import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_INITIATOR;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_INFO;
import static cn.axzo.workflow.common.constant.BpmnConstants.OLD_INTERNAL_INITIATOR;
-import static cn.axzo.workflow.common.enums.ApprovalMethodEnum.bizSpecify;
import static cn.axzo.workflow.common.enums.ApprovalMethodEnum.nobody;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeMode.AND;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeMode.GENERAL;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeMode.OR;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_STARTER;
+import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.APPROVED;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.PROCESSING;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApprovalMethod;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getNodeType;
@@ -108,6 +110,18 @@ public class EngineEntityEventListener extends AbstractFlowableEventListener {
private void onDeleted(TaskEntity taskEntity) {
log.error("onDeleted");
+ ExtAxProcessLog queryLog = new ExtAxProcessLog();
+ queryLog.setProcessInstanceId(taskEntity.getProcessInstanceId());
+ queryLog.setTaskId(taskEntity.getId());
+ ExtAxProcessLog update = new ExtAxProcessLog();
+ if (Objects.equals(taskEntity.getTaskDefinitionKey(), NODE_STARTER.getType())) {
+ update.setStatus(APPROVED.getStatus());
+ } else {
+ ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
+ HistoryService historyService = processEngineConfiguration.getHistoryService();
+
+ }
+ processLogService.update(queryLog, update);
}
private void onUpdated(TaskEntity taskEntity) {
@@ -120,7 +134,8 @@ public class EngineEntityEventListener extends AbstractFlowableEventListener {
} else {
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
RuntimeService runtimeService = processEngineConfiguration.getRuntimeService();
- List assigneeList = runtimeService.getVariable(taskEntity.getProcessInstanceId(), "[_ACTIVITY_INFO_SNAPSHOT_]" + taskEntity.getTaskDefinitionKey(), List.class);
+ List assigneeList = runtimeService.getVariable(taskEntity.getProcessInstanceId(),
+ INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + taskEntity.getTaskDefinitionKey(), List.class);
ListUtils.emptyIfNull(assigneeList).stream().filter(e -> Objects.equals(e.buildAssigneeId(), taskEntity.getAssignee())).findAny()
.ifPresent(assignee -> {
log.error("审批人: {}", JSON.toJSONString(assignee));
@@ -165,16 +180,11 @@ public class EngineEntityEventListener extends AbstractFlowableEventListener {
log.setActivityId(taskEntity.getTaskDefinitionKey());
log.setActivityName(taskEntity.getName());
log.setApprovalMethod((isNodeStarter ? nobody : getApprovalMethod(flowElement).orElse(nobody)).getType());
- if (Objects.equals(log.getApprovalMethod(), nobody.getType()) || Objects.equals(log.getApprovalMethod(), bizSpecify.getType())) {
- log.setOperationDesc("待处理");
- }
log.setNodeType((getNodeType(flowElement).orElse(BpmnFlowNodeType.NODE_EMPTY)).getType());
log.setNodeMode((isNodeStarter ? BpmnFlowNodeMode.GENERAL : getNodeMode(flowElement)).getType());
log.setTaskId(taskEntity.getId());
+ log.setOperationDesc("待处理");
if (Objects.nonNull(assignee)) {
- // FIXME 应该还有逻辑来拼接
- log.setOperationDesc(isNodeStarter ? assignee.getAssignerName() : null);
-
log.setAssigneeFull(assignee);
log.setAssigneeId(Long.valueOf(assignee.getPersonId()));
log.setAssigneeTenantId(assignee.getTenantId());
@@ -183,6 +193,7 @@ public class EngineEntityEventListener extends AbstractFlowableEventListener {
}
log.setStartTime(taskEntity.getCreateTime());
log.setStatus(PROCESSING.getStatus());
+
processLogService.insert(log);
}
@@ -199,6 +210,7 @@ public class EngineEntityEventListener extends AbstractFlowableEventListener {
return node;
}
+
@Override
public boolean isFailOnException() {
return true;
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/ExtAxProcessLogService.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/ExtAxProcessLogService.java
index 7cee90d03..99b9ef4e8 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/ExtAxProcessLogService.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/ExtAxProcessLogService.java
@@ -25,6 +25,21 @@ public interface ExtAxProcessLogService {
*/
void delete(ExtAxProcessLog deleteLog);
+ /**
+ * 根据有 ID 的实体直接更新
+ *
+ * @param updateLog
+ */
+ void updateById(ExtAxProcessLog updateLog);
+
+ /**
+ * 根据条件更新指定对象的列
+ *
+ * @param query
+ * @param update
+ */
+ void update(ExtAxProcessLog query, ExtAxProcessLog update);
+
/**
* 更新指定任务的审批人
*
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/ExtAxProcessLogServiceImpl.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/ExtAxProcessLogServiceImpl.java
index 5f491349a..67c30f0e7 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/ExtAxProcessLogServiceImpl.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/ExtAxProcessLogServiceImpl.java
@@ -42,9 +42,18 @@ public class ExtAxProcessLogServiceImpl implements ExtAxProcessLogService {
extAxProcessLogMapper.delete(buildQueryWrapper(deleteLog));
}
+ public void updateById(ExtAxProcessLog updateLog) {
+ extAxProcessLogMapper.updateById(updateLog);
+ }
+
+ public void update(ExtAxProcessLog query, ExtAxProcessLog update) {
+ extAxProcessLogMapper.update(update, buildQueryWrapper(query));
+ }
+
@Override
public void updateAssignee(ExtAxProcessLog queryLog, BpmnTaskDelegateAssigner assignee) {
updateAssignee(queryLog, assignee, assignee.getAssignerName());
+
}
@Override
From ebc6bf0441cba5ec5693d45ce748b547a3b0dbbe Mon Sep 17 00:00:00 2001
From: wangli <274027703@qq.com>
Date: Wed, 4 Sep 2024 20:25:06 +0800
Subject: [PATCH 013/139] =?UTF-8?q?feat(REQ-2924)=20-=20=E5=AE=8C=E6=88=90?=
=?UTF-8?q?=E4=B8=9A=E5=8A=A1=E8=8A=82=E7=82=B9=E6=97=A0=E4=BA=BA=E7=9A=84?=
=?UTF-8?q?=E8=A7=A6=E5=8F=91=E9=80=BB=E8=BE=91=E6=97=A5=E5=BF=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../enums/BpmnProcessInstanceResultEnum.java | 2 +-
.../enums/BpmnProcessTaskResultEnum.java | 6 +++---
.../CustomReceiveTaskActivityBehavior.java | 12 ++++++++----
.../listener/EngineEntityEventListener.java | 19 ++++++++++++++++---
4 files changed, 28 insertions(+), 11 deletions(-)
diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/enums/BpmnProcessInstanceResultEnum.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/enums/BpmnProcessInstanceResultEnum.java
index 150ecbc35..a69939c39 100644
--- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/enums/BpmnProcessInstanceResultEnum.java
+++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/enums/BpmnProcessInstanceResultEnum.java
@@ -6,7 +6,7 @@ public enum BpmnProcessInstanceResultEnum {
PROCESSING("PROCESSING", "审批中"),
APPROVED("APPROVED", "已通过"),
REJECTED("REJECTED", "已驳回"),
- BACKED("BACKED", "已回退"),
+ BACKED("BACKED", "已退回"),
CANCELLED("CANCELLED", "已撤回"),
ABORTED("ABORTED", "已中止"),
TRANSFER("TRANSFER", "已转交"),
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/enums/BpmnProcessTaskResultEnum.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/enums/BpmnProcessTaskResultEnum.java
index 3b6532d74..23eadcd0f 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/enums/BpmnProcessTaskResultEnum.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/enums/BpmnProcessTaskResultEnum.java
@@ -9,7 +9,8 @@ import java.util.Arrays;
* @since 2023/9/18 17:11
*/
public enum BpmnProcessTaskResultEnum {
-
+ PENDING("PENDING", "待处理"),
+ PROCESSED("PROCESSED", "已处理"),
AUTO_SKIP("AUTO_SKIP", "任务自动跳过"),
// 引擎默认的标识,不允许修改
MI_END("MI_END", "多实例任务运行结束"),
@@ -17,8 +18,7 @@ public enum BpmnProcessTaskResultEnum {
DELETE_MI_EXECUTION("Delete MI execution", "多实例任务被删除"),
INITIATOR_REVOCATION("INITIATOR_REVOCATION", "发起者主动撤回"),
REJECTION_AUTO_COMPLETED("REJECTION_AUTO_COMPLETED", "审批驳回自动结束"),
- BACKED("BACKED", "退回");
-
+ ;
private final String status;
/**
* 描述
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/behavior/CustomReceiveTaskActivityBehavior.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/behavior/CustomReceiveTaskActivityBehavior.java
index 7661176b9..5c0db9d78 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/behavior/CustomReceiveTaskActivityBehavior.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/behavior/CustomReceiveTaskActivityBehavior.java
@@ -7,18 +7,17 @@ import org.flowable.bpmn.model.ReceiveTask;
import org.flowable.common.engine.api.delegate.event.FlowableEventDispatcher;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.delegate.DelegateExecution;
-import org.flowable.engine.delegate.TaskListener;
import org.flowable.engine.impl.bpmn.behavior.ReceiveTaskActivityBehavior;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.engine.impl.util.TaskHelper;
-import org.flowable.task.api.Task;
import org.flowable.task.service.TaskService;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import java.util.Objects;
+import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_COMPLETE_OPERATION_TYPE;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.APPROVED;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.PROCESSING;
@@ -51,7 +50,6 @@ public class CustomReceiveTaskActivityBehavior extends ReceiveTaskActivityBehavi
task.setName(receiveTask.getName());
TaskHelper.insertTask(task, (ExecutionEntity) execution, true, false);
- processEngineConfiguration.getListenerNotificationHelper().executeTaskListeners(task, TaskListener.EVENTNAME_CREATE);
// 添加 taskInst 扩展表数据
FlowableEventDispatcher eventDispatcher = processEngineConfiguration.getEventDispatcher();
@@ -68,12 +66,18 @@ public class CustomReceiveTaskActivityBehavior extends ReceiveTaskActivityBehavi
FlowableEventDispatcher eventDispatcher = processEngineConfiguration.getEventDispatcher();
org.flowable.engine.TaskService taskService = processEngineConfiguration.getTaskService();
- Task task = taskService.createTaskQuery().executionId(execution.getId())
+ TaskEntity task = (TaskEntity) taskService.createTaskQuery().executionId(execution.getId())
.taskDefinitionKey(execution.getCurrentActivityId()).singleResult();
if (Objects.nonNull(task)) {
+ // 用于新版日志
+ task.setTransientVariable(TASK_COMPLETE_OPERATION_TYPE + task.getId(), APPROVED.getStatus());
+
eventDispatcher.dispatchEvent(new ExtTaskInstUpdateEvent(execution.getProcessInstanceId(),
receiveTask.getId(), task.getId(), APPROVED),
processEngineConfiguration.getEngineCfgKey());
+// // 新版日志使用
+// eventDispatcher.dispatchEvent(FlowableEventBuilder.createEntityEvent(FlowableEngineEventType.ENTITY_DELETED, task),
+// processEngineConfiguration.getEngineCfgKey());
} else {
log.warn("task is null, executionId: {}, activityId: {}", execution.getId(),
execution.getCurrentActivityId());
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/EngineEntityEventListener.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/EngineEntityEventListener.java
index f76131e69..44673e646 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/EngineEntityEventListener.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/EngineEntityEventListener.java
@@ -3,6 +3,7 @@ package cn.axzo.workflow.core.engine.listener;
import cn.axzo.framework.jackson.utility.JSON;
import cn.axzo.workflow.common.enums.BpmnFlowNodeMode;
import cn.axzo.workflow.common.enums.BpmnFlowNodeType;
+import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.core.repository.entity.ExtAxProcessLog;
import cn.axzo.workflow.core.service.ExtAxProcessLogService;
@@ -17,25 +18,29 @@ import org.flowable.common.engine.api.delegate.event.AbstractFlowableEventListen
import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType;
import org.flowable.common.engine.api.delegate.event.FlowableEntityEvent;
import org.flowable.common.engine.api.delegate.event.FlowableEvent;
-import org.flowable.engine.HistoryService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.impl.bpmn.behavior.MultiInstanceActivityBehavior;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
+import org.flowable.engine.impl.cmd.GetTaskCommentsByTypeCmd;
import org.flowable.engine.impl.util.CommandContextUtil;
+import org.flowable.engine.task.Comment;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.springframework.stereotype.Component;
+import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import static cn.axzo.workflow.common.constant.BpmnConstants.AND_SIGN_EXPRESSION;
+import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC;
import static cn.axzo.workflow.common.constant.BpmnConstants.HIDDEN_ASSIGNEE_ID;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_INITIATOR;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_INFO;
import static cn.axzo.workflow.common.constant.BpmnConstants.OLD_INTERNAL_INITIATOR;
+import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_COMPLETE_OPERATION_TYPE;
import static cn.axzo.workflow.common.enums.ApprovalMethodEnum.nobody;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeMode.AND;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeMode.GENERAL;
@@ -43,6 +48,7 @@ import static cn.axzo.workflow.common.enums.BpmnFlowNodeMode.OR;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_STARTER;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.APPROVED;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.PROCESSING;
+import static cn.axzo.workflow.core.common.enums.BpmnProcessTaskResultEnum.PENDING;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApprovalMethod;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getNodeType;
import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ENTITY_ACTIVATED;
@@ -118,8 +124,15 @@ public class EngineEntityEventListener extends AbstractFlowableEventListener {
update.setStatus(APPROVED.getStatus());
} else {
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
- HistoryService historyService = processEngineConfiguration.getHistoryService();
+ List comments = processEngineConfiguration.getCommandExecutor()
+ .execute(new GetTaskCommentsByTypeCmd(taskEntity.getId(), COMMENT_TYPE_OPERATION_DESC));
+ comments.stream().max(Comparator.comparing(Comment::getTime)).ifPresent(e -> update.setOperationDesc(e.getFullMessage()));
+ String completionType = taskEntity.getVariable(TASK_COMPLETE_OPERATION_TYPE + taskEntity.getId(), String.class);
+ log.info("TASK_COMPLETE_OPERATION_TYPE: {}", completionType);
+ update.setStatus(completionType);
+ queryLog.setOperationDesc(PENDING.getDesc());
+ update.setOperationDesc(BpmnProcessInstanceResultEnum.valueOfStatus(completionType).getDesc());
}
processLogService.update(queryLog, update);
}
@@ -183,7 +196,7 @@ public class EngineEntityEventListener extends AbstractFlowableEventListener {
log.setNodeType((getNodeType(flowElement).orElse(BpmnFlowNodeType.NODE_EMPTY)).getType());
log.setNodeMode((isNodeStarter ? BpmnFlowNodeMode.GENERAL : getNodeMode(flowElement)).getType());
log.setTaskId(taskEntity.getId());
- log.setOperationDesc("待处理");
+ log.setOperationDesc(PENDING.getDesc());
if (Objects.nonNull(assignee)) {
log.setAssigneeFull(assignee);
log.setAssigneeId(Long.valueOf(assignee.getPersonId()));
From 1dfa3642826c89a296c26e2ed8c21317c77e066d Mon Sep 17 00:00:00 2001
From: yangqicheng
Date: Thu, 5 Sep 2024 11:53:59 +0800
Subject: [PATCH 014/139] =?UTF-8?q?REQ-2924-=E8=B0=83=E6=95=B4=E5=9B=9E?=
=?UTF-8?q?=E9=80=80=E5=88=B0=E6=8C=87=E5=AE=9A=E8=8A=82=E7=82=B9=E9=80=BB?=
=?UTF-8?q?=E8=BE=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../client/feign/bpmn/ProcessTaskApi.java | 2 +-
.../bpmn/task/BpmnTaskBackAuditDTO.java | 9 +-
.../core/engine/cmd/CustomBackTaskCmd.java | 78 +++++------------
.../web/bpmn/BpmnProcessTaskController.java | 4 +-
.../starter/api/WorkflowCoreService.java | 86 +++++++++----------
5 files changed, 68 insertions(+), 111 deletions(-)
diff --git a/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/bpmn/ProcessTaskApi.java b/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/bpmn/ProcessTaskApi.java
index 204a66d8e..214ab75a8 100644
--- a/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/bpmn/ProcessTaskApi.java
+++ b/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/bpmn/ProcessTaskApi.java
@@ -79,7 +79,7 @@ public interface ProcessTaskApi {
*/
@Operation(summary = "获取当前节点可退回节点选项列表")
@PostMapping("/api/process/task/back/optional/nodes")
- CommonResponse> getApproveOptionalNodes(@Validated @RequestBody BpmnUserTaskNodeDTO bpmnUserTaskNodeDTO);
+ CommonResponse> getBackOptionalNodes(@Validated @RequestBody BpmnUserTaskNodeDTO bpmnUserTaskNodeDTO);
/**
* 回退到指定节点
diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnTaskBackAuditDTO.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnTaskBackAuditDTO.java
index f618fcd4f..b4a2aed67 100644
--- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnTaskBackAuditDTO.java
+++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnTaskBackAuditDTO.java
@@ -9,7 +9,6 @@ import lombok.NoArgsConstructor;
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.NotBlank;
-import javax.validation.constraints.NotEmpty;
import java.io.Serializable;
@EqualsAndHashCode(callSuper = true)
@@ -20,13 +19,9 @@ import java.io.Serializable;
@NoArgsConstructor
public class BpmnTaskBackAuditDTO extends BpmnTaskAuditDTO implements Serializable {
- private static final long serialVersionUID = 2226704888158991717L;
-
- @ApiModelProperty(value = "当前流程节点id", required = true)
- @NotBlank(message = "当前流程节点id不能为空")
- private String currentActivityId;
+ private static final long serialVersionUID = -4160538355403179298L;
@ApiModelProperty(value = "目标流程节点id", required = true)
- @NotEmpty(message = "目标流程节点id不能为空")
+ @NotBlank(message = "目标流程节点id不能为空")
private String toActivityId;
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java
index 4613b9177..83e9f806d 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java
@@ -1,10 +1,8 @@
package cn.axzo.workflow.core.engine.cmd;
-import cn.axzo.workflow.common.enums.BpmnFlowNodeType;
-import cn.axzo.workflow.common.model.request.bpmn.task.AttachmentDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskBackAuditDTO;
-import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import com.alibaba.fastjson.JSON;
+import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.RuntimeService;
@@ -15,14 +13,11 @@ import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.api.history.HistoricTaskInstanceQuery;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -37,71 +32,38 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask
/**
* 回退命令
*/
+@Slf4j
public class CustomBackTaskCmd extends AbstractCommand implements Serializable {
private static final long serialVersionUID = -1241290344311892346L;
- private static final Logger log = LoggerFactory.getLogger(CustomBackTaskCmd.class);
+ private final BpmnTaskBackAuditDTO dto;
- private final String taskId;
- /**
- * advice 统一均为审批节点的审批意见,一般为用户在同意、驳回时填写的内容
- * 有值时,在日志中一般出现在 operationDesc 的下方
- */
- private final String advice;
- /**
- * operationDesc 统一为审批节点的动作描述,例如:某某转交、加签某某等
- * 在日志中一般出现在节点名称的下方
- * 不传,默认"已通过"
- */
- private String operationDesc;
- /**
- * 附件, 可为空
- */
- private final List attachmentList;
- private final BpmnTaskDelegateAssigner approver;
-
- /**
- * 指定节点类型
- */
- private final List nodeTypes;
-
- private final String currentActivityId;
-
- private final String toActivityId;
+ private final String operationDesc;
@Override
public String paramToJsonString() {
Map params = new HashMap<>();
- params.put("taskId", taskId);
- params.put("advice", advice);
+ params.put("taskId", dto.getTaskId());
+ params.put("advice", dto.getAdvice());
params.put("operationDesc", operationDesc);
- params.put("attachmentList", JSON.toJSONString(attachmentList));
- params.put("approver", JSON.toJSONString(approver));
- params.put("nodeTypes", JSON.toJSONString(nodeTypes));
+ params.put("attachmentList", JSON.toJSONString(dto.getAttachmentList()));
+ params.put("approver", JSON.toJSONString(dto.getApprover()));
+ params.put("nodeTypes", JSON.toJSONString(dto.getNodeTypes()));
return JSON.toJSONString(params);
}
public CustomBackTaskCmd(BpmnTaskBackAuditDTO dto) {
this(dto, null);
- if (Objects.nonNull(dto.getOperationDesc())) {
- this.operationDesc = dto.getOperationDesc();
- }
}
public CustomBackTaskCmd(BpmnTaskBackAuditDTO dto, String operationDesc) {
- this.taskId = dto.getTaskId();
- this.advice = dto.getAdvice();
- this.attachmentList = dto.getAttachmentList();
- this.approver = dto.getApprover();
- this.nodeTypes = dto.getNodeTypes();
+ this.dto = dto;
// 这里的不能直接使用字符串的比较,因为外部可能传入空字符串,比如发起人的通过时,就是传入的空字符串
if (Objects.nonNull(operationDesc)) {
this.operationDesc = operationDesc;
} else {
this.operationDesc = "已回退";
}
- this.currentActivityId = dto.getCurrentActivityId();
- this.toActivityId = dto.getToActivityId();
}
@Override
@@ -112,28 +74,28 @@ public class CustomBackTaskCmd extends AbstractCommand implements Serializ
processEngineConfiguration.getHistoryService().createHistoricTaskInstanceQuery();
TaskService taskService = processEngineConfiguration.getTaskService();
- HistoricTaskInstance historicTaskInstance = taskQuery.taskId(taskId).singleResult();
+ HistoricTaskInstance historicTaskInstance = taskQuery.taskId(dto.getTaskId()).singleResult();
- Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
- validTask(historicTaskInstance, (TaskEntity) task, approver, nodeTypes);
- if (StringUtils.hasLength(advice)) {
- Authentication.setAuthenticatedUserId(approver.buildAssigneeId());
- addComment(commandContext, task, COMMENT_TYPE_ADVICE, advice);
+ Task task = taskService.createTaskQuery().taskId(dto.getTaskId()).singleResult();
+ validTask(historicTaskInstance, (TaskEntity) task, dto.getApprover(), dto.getNodeTypes());
+ if (StringUtils.hasLength(dto.getAdvice())) {
+ Authentication.setAuthenticatedUserId(dto.getApprover().buildAssigneeId());
+ addComment(commandContext, task, COMMENT_TYPE_ADVICE, dto.getAdvice());
Authentication.setAuthenticatedUserId(null);
}
- batchAddAttachment(commandContext, task.getProcessInstanceId(), taskId, attachmentList, approver);
+ batchAddAttachment(commandContext, task.getProcessInstanceId(), dto.getTaskId(), dto.getAttachmentList(), dto.getApprover());
- Authentication.setAuthenticatedUserId(Objects.nonNull(approver) ? approver.buildAssigneeId() : null);
+ Authentication.setAuthenticatedUserId(Objects.nonNull(dto.getApprover()) ? dto.getApprover().buildAssigneeId() : null);
addComment(commandContext, task, COMMENT_TYPE_OPERATION_DESC, operationDesc);
Authentication.setAuthenticatedUserId(null);
RuntimeService runtimeService = processEngineConfiguration.getRuntimeService();
- ((TaskEntity) task).setTransientVariable(TASK_COMPLETE_OPERATION_TYPE + taskId, BACKED.getStatus());
+ ((TaskEntity) task).setTransientVariable(TASK_COMPLETE_OPERATION_TYPE + dto.getTaskId(), BACKED.getStatus());
runtimeService.createChangeActivityStateBuilder()
.processInstanceId(task.getProcessInstanceId())
- .moveActivityIdsToSingleActivityId(Collections.singletonList(currentActivityId), toActivityId)
+ .moveActivityIdsToSingleActivityId(Collections.singletonList(task.getTaskDefinitionKey()), dto.getToActivityId())
.changeState();
return null;
}
diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java
index 6c68abdae..bcf08eaaf 100644
--- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java
+++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java
@@ -130,7 +130,7 @@ public class BpmnProcessTaskController implements ProcessTaskApi {
@PostMapping("/back/optional/nodes")
@Override
@RepeatSubmit
- public CommonResponse> getApproveOptionalNodes(@RequestBody @Validated BpmnUserTaskNodeDTO dto) {
+ public CommonResponse> getBackOptionalNodes(@RequestBody @Validated BpmnUserTaskNodeDTO dto) {
List approveOptionalNodes = bpmnProcessTaskService.getApproveOptionalNodes(dto.getProcessInstanceId(), dto.getTaskId(), dto.getTenantId());
return success(approveOptionalNodes);
}
@@ -144,7 +144,7 @@ public class BpmnProcessTaskController implements ProcessTaskApi {
@Override
public CommonResponse backTask(@Validated @RequestBody BpmnTaskBackAuditDTO dto) {
bpmnProcessTaskService.backTask(dto);
- return success();
+ return success(true);
}
/**
diff --git a/workflow-engine-spring-boot-starter/src/main/java/cn/axzo/workflow/starter/api/WorkflowCoreService.java b/workflow-engine-spring-boot-starter/src/main/java/cn/axzo/workflow/starter/api/WorkflowCoreService.java
index f7d7aefdf..fd86467fc 100644
--- a/workflow-engine-spring-boot-starter/src/main/java/cn/axzo/workflow/starter/api/WorkflowCoreService.java
+++ b/workflow-engine-spring-boot-starter/src/main/java/cn/axzo/workflow/starter/api/WorkflowCoreService.java
@@ -1,59 +1,41 @@
package cn.axzo.workflow.starter.api;
-import cn.axzo.workflow.starter.feign.ext.WorkflowEngineStarterFeignConfiguration;
-import cn.axzo.workflow.common.util.ThreadUtil;
-import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.ASYNC;
-import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.SYNC;
-import cn.axzo.workflow.client.config.CommonFeignConfiguration;
+import cn.axzo.workflow.common.annotation.InvokeMode;
+import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAbortDTO;
+import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCancelDTO;
+import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCarbonCopyDTO;
+import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCreateDTO;
+import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceQueryDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnActivitySetAssigneeDTO;
-import cn.azxo.framework.common.model.CommonResponse;
+import cn.axzo.workflow.common.model.request.bpmn.task.BpmnOptionalNodeDTO;
+import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCompleteDTO;
+import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCreateDTO;
+import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO;
+import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskBackAuditDTO;
+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.BpmnTaskTransferDTO;
+import cn.axzo.workflow.common.model.request.bpmn.task.BpmnUserTaskNodeDTO;
+import cn.axzo.workflow.common.model.response.bpmn.BatchOperationResultVO;
+import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceVO;
+import cn.axzo.workflow.common.util.ThreadUtil;
+import cn.axzo.workflow.starter.feign.ext.WorkflowEngineStarterFeignConfiguration;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
-import javax.validation.constraints.NotBlank;
-import cn.axzo.workflow.common.annotation.InvokeMode;
-import cn.axzo.workflow.common.annotation.Manageable;
-import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAbortDTO;
-import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAdminPageReqVO;
-import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCancelDTO;
-import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCarbonCopyDTO;
-import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCheckApproverDTO;
-import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCreateDTO;
-import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCreateWithFormDTO;
-import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceMyPageReqVO;
-import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceQueryDTO;
-import cn.axzo.workflow.common.model.response.BpmPageResult;
-import cn.axzo.workflow.common.model.response.bpmn.BatchOperationResultVO;
-import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceAdminPageItemVO;
-import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstancePageItemVO;
-import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceVO;
-import cn.axzo.workflow.common.model.response.bpmn.process.ProcessNodeDetailVO;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.PutMapping;
+
import javax.annotation.Nullable;
-import javax.validation.constraints.NotNull;
+import javax.validation.constraints.NotBlank;
import java.util.List;
import java.util.Map;
-import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCompleteDTO;
-import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCreateDTO;
-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.request.bpmn.task.BpmnTaskRemindDTO;
-import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskTransferDTO;
-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 javax.validation.constraints.NotEmpty;
+
+import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.ASYNC;
+import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.SYNC;
/**
* Workflow Engine Starter Core Service
该类是根据 API 动态生成,不同版本可能会开放新的接口,或回收一些旧接口
@@ -194,6 +176,24 @@ public interface WorkflowCoreService {
@PostMapping("/api/process/task/batch/approve")
BatchOperationResultVO batchApproveTask(@Validated @RequestBody List dtos);
+ /**
+ * 获取当前节点可退回节点选项列表
+ * @param bpmnUserTaskNodeDTO 参数
+ * @return
+ */
+ @Operation(summary = "获取当前节点可退回节点选项列表")
+ @PostMapping("/api/process/task/back/optional/nodes")
+ List getBackOptionalNodes(@Validated @RequestBody BpmnUserTaskNodeDTO bpmnUserTaskNodeDTO);
+
+ /**
+ * 回退到指定节点
+ * @param dto
+ * @return
+ */
+ @Operation(summary = "回退")
+ @PostMapping("/api/process/task/back")
+ Boolean backTask(@Validated @RequestBody BpmnTaskBackAuditDTO dto);
+
/**
* 驳回
*
From 465cbd2791f3513ea8d7b8c8074d2fbce8ab2c80 Mon Sep 17 00:00:00 2001
From: wangli <274027703@qq.com>
Date: Thu, 5 Sep 2024 18:47:03 +0800
Subject: [PATCH 015/139] =?UTF-8?q?feat(REQ-2924)=20-=20=E8=B0=83=E6=95=B4?=
=?UTF-8?q?=E5=B7=A5=E5=85=B7=E7=B1=BB=E6=B7=BB=E5=8A=A0=20comment=20?=
=?UTF-8?q?=E6=97=B6=EF=BC=8C=E4=B8=8D=E8=BF=94=E5=9B=9E=E5=AE=9E=E4=BD=93?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../core/engine/cmd/helper/CustomTaskHelper.java | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java
index b9a134431..d6c8fcd09 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java
@@ -27,7 +27,6 @@ import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.engine.impl.util.ProcessDefinitionUtil;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.task.Attachment;
-import org.flowable.engine.task.Comment;
import org.flowable.engine.task.Event;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
@@ -239,15 +238,18 @@ public class CustomTaskHelper {
Authentication.setAuthenticatedUserId(null);
}
- public static Comment addComment(CommandContext commandContext, String taskId, String processInstanceId,
+ public static void addComment(CommandContext commandContext, String taskId, String processInstanceId,
String type, String message) {
TaskEntity task = new TaskEntityImpl();
task.setId(taskId);
task.setProcessInstanceId(processInstanceId);
- return addComment(commandContext, task, type, message);
+ addComment(commandContext, task, type, message);
}
- public static Comment addComment(CommandContext commandContext, Task task, String type, String message) {
+ public static void addComment(CommandContext commandContext, Task task, String type, String message) {
+ if (!StringUtils.hasText(message)) {
+ return;
+ }
ProcessEngineConfigurationImpl processEngineConfiguration =
CommandContextUtil.getProcessEngineConfiguration(commandContext);
@@ -270,7 +272,6 @@ public class CustomTaskHelper {
processEngineConfiguration.getCommentEntityManager().insert(comment);
- return comment;
}
public static Attachment addAttachment(CommandContext commandContext, Task task, AttachmentDTO attachmentDto) {
From 53a17ed10019c3c00d4e6e4860cdbeb2ee2c9c94 Mon Sep 17 00:00:00 2001
From: wangli
Date: Fri, 6 Sep 2024 00:36:47 +0800
Subject: [PATCH 016/139] =?UTF-8?q?feat(REQ-2924)=20-=20=E6=B5=8B=E8=AF=95?=
=?UTF-8?q?=E8=BD=AC=E4=BA=A4=E6=97=A5=E5=BF=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../cmd/CustomAbortProcessInstanceCmd.java | 9 +-
.../cmd/CustomCancelProcessInstanceCmd.java | 8 +-
.../cmd/CustomCountersignUserTaskCmd.java | 8 +-
.../engine/cmd/CustomRejectionTaskCmd.java | 11 +-
.../engine/cmd/helper/CustomTaskHelper.java | 22 ++-
.../entity/EngineEntityEventListener.java | 115 +++++++++++++++
.../listener/entity/EntityEventHandle.java | 27 ++++
.../entity/type/CommentEntityEventHandle.java | 82 +++++++++++
.../type/TaskEntityEventHandle.java} | 138 +++++++-----------
.../core/engine/model/AddComment.java | 40 +++++
...ProcessInstanceAdminPageItemConverter.java | 14 +-
.../starter/api/WorkflowManageService.java | 88 +++++------
12 files changed, 398 insertions(+), 164 deletions(-)
create mode 100644 workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/EngineEntityEventListener.java
create mode 100644 workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/EntityEventHandle.java
create mode 100644 workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/type/CommentEntityEventHandle.java
rename workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/{EngineEntityEventListener.java => entity/type/TaskEntityEventHandle.java} (63%)
create mode 100644 workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/model/AddComment.java
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomAbortProcessInstanceCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomAbortProcessInstanceCmd.java
index cb5836728..69faa460c 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomAbortProcessInstanceCmd.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomAbortProcessInstanceCmd.java
@@ -2,6 +2,7 @@ package cn.axzo.workflow.core.engine.cmd;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
+import cn.axzo.workflow.core.engine.model.AddComment;
import cn.axzo.workflow.core.engine.operation.DeleteProcessInstanceOperation;
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
import com.alibaba.fastjson.JSON;
@@ -20,7 +21,6 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
-import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC;
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;
@@ -35,7 +35,7 @@ import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.CANCEL
import static cn.axzo.workflow.core.common.code.BpmnInstanceRespCode.PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS;
import static cn.axzo.workflow.core.common.code.BpmnInstanceRespCode.PROCESS_INSTANCE_CANT_ABORT;
import static cn.axzo.workflow.core.common.code.BpmnInstanceRespCode.PROCESS_INSTANCE_NOT_EXISTS;
-import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.addComment;
+import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.completeVirtualTask;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.createVirtualTask;
/**
@@ -106,9 +106,10 @@ public class CustomAbortProcessInstanceCmd extends AbstractCommand impleme
// 添加自定义的节点,用于展示最后的操作
Task task = createVirtualTask(commandContext, extAxHiTaskInstService, processInstanceId,
"系统中止", NODE_ABORT.getType(), null, BpmnTaskDelegateAssigner.buildDummyAssigner("system",
- TASK_ASSIGNEE_SKIP_FLAT, "系统"), ABORTED.getStatus());
- addComment(commandContext, task, COMMENT_TYPE_OPERATION_DESC, reason);
+ TASK_ASSIGNEE_SKIP_FLAT, "系统"), ABORTED.getStatus(), new AddComment(reason));
runtimeService.setVariable(task.getProcessInstanceId(), TASK_COMPLETE_OPERATION_TYPE + task.getId(), ABORTED);
+
+ completeVirtualTask(commandContext, task);
return null;
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCancelProcessInstanceCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCancelProcessInstanceCmd.java
index e235d8fdd..cb1996e3a 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCancelProcessInstanceCmd.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCancelProcessInstanceCmd.java
@@ -2,6 +2,7 @@ package cn.axzo.workflow.core.engine.cmd;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
+import cn.axzo.workflow.core.engine.model.AddComment;
import cn.axzo.workflow.core.engine.operation.DeleteProcessInstanceOperation;
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
import com.alibaba.fastjson.JSON;
@@ -18,7 +19,6 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
-import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC;
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;
@@ -32,7 +32,7 @@ import static cn.axzo.workflow.core.common.code.BpmnInstanceRespCode.PROCESS_INS
import static cn.axzo.workflow.core.common.code.BpmnInstanceRespCode.PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF;
import static cn.axzo.workflow.core.common.code.BpmnInstanceRespCode.PROCESS_INSTANCE_CANT_CANCEL;
import static cn.axzo.workflow.core.common.code.BpmnInstanceRespCode.PROCESS_INSTANCE_NOT_EXISTS;
-import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.addComment;
+import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.completeVirtualTask;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.createVirtualTask;
/**
@@ -108,8 +108,8 @@ public class CustomCancelProcessInstanceCmd extends AbstractCommand implem
// 添加自定义的节点,用于展示最后的操作
Task task = createVirtualTask(commandContext, extAxHiTaskInstService, processInstanceId,
- "发起人撤回", NODE_CANCEL.getType(), reason, initiator, CANCELLED.getStatus());
- addComment(commandContext, task, COMMENT_TYPE_OPERATION_DESC, "已撤回");
+ "发起人撤回", NODE_CANCEL.getType(), reason, initiator, CANCELLED.getStatus(), new AddComment(CANCELLED.getDesc()));
+ completeVirtualTask(commandContext, task);
return null;
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCountersignUserTaskCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCountersignUserTaskCmd.java
index 7d5f7c2bb..7f190bc6b 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCountersignUserTaskCmd.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCountersignUserTaskCmd.java
@@ -4,6 +4,7 @@ import cn.axzo.workflow.common.enums.BpmnCountersignTypeEnum;
import cn.axzo.workflow.common.model.request.bpmn.task.AttachmentDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper;
+import cn.axzo.workflow.core.engine.model.AddComment;
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
@@ -23,12 +24,11 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC;
import static cn.axzo.workflow.common.constant.BpmnConstants.COUNTERSIGN_ASSIGNER_SHOW_NUMBER;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.COUNTERSIGN;
-import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.addComment;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.batchAddAttachment;
+import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.completeVirtualTask;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.createVirtualTask;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTaskAssignerCount;
@@ -155,9 +155,9 @@ public class CustomCountersignUserTaskCmd extends AbstractCommand implemen
}
message.append("等").append(targetTaskAssigneeList.size()).append("人进行审批");
Task virtualTask = createVirtualTask(commandContext, extAxHiTaskInstService, task.getProcessInstanceId(), task.getName(),
- task.getTaskDefinitionKey(), advice, originTaskAssignee, COUNTERSIGN.getStatus());
- addComment(commandContext, virtualTask, COMMENT_TYPE_OPERATION_DESC, message.toString());
+ task.getTaskDefinitionKey(), advice, originTaskAssignee, COUNTERSIGN.getStatus(), new AddComment(message.toString()));
batchAddAttachment(commandContext, task.getProcessInstanceId(), task.getId(), attachmentList, originTaskAssignee);
+ completeVirtualTask(commandContext, virtualTask);
}
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomRejectionTaskCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomRejectionTaskCmd.java
index 259d69036..02fc23b46 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomRejectionTaskCmd.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomRejectionTaskCmd.java
@@ -4,6 +4,7 @@ import cn.axzo.workflow.common.enums.BpmnFlowNodeType;
import cn.axzo.workflow.common.model.request.bpmn.task.AttachmentDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
+import cn.axzo.workflow.core.engine.model.AddComment;
import cn.axzo.workflow.core.engine.operation.DeleteProcessInstanceOperation;
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
import com.alibaba.fastjson.JSON;
@@ -23,7 +24,6 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
-import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC;
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;
@@ -32,8 +32,8 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_PROCESS_DE
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_PROCESS_TYPE_REJECT;
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_COMPLETE_OPERATION_TYPE;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.REJECTED;
-import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.addComment;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.batchAddAttachment;
+import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.completeVirtualTask;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.createVirtualTask;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask;
@@ -103,11 +103,12 @@ public class CustomRejectionTaskCmd extends AbstractCommand implements Ser
((TaskEntity) task).setTransientVariable(TASK_COMPLETE_OPERATION_TYPE + task.getId(), REJECTED.getStatus());
Task virtualTask = createVirtualTask(commandContext, extAxHiTaskInstService, task.getProcessInstanceId(), task.getName(),
- task.getTaskDefinitionKey(), advice, Objects.equals(operationDesc, "自动驳回") ? null : approver, REJECTED.getStatus());
-
- addComment(commandContext, virtualTask, COMMENT_TYPE_OPERATION_DESC, operationDesc);
+ task.getTaskDefinitionKey(), advice,
+ Objects.equals(operationDesc, "自动驳回") ? null : approver, REJECTED.getStatus(),
+ new AddComment(operationDesc));
batchAddAttachment(commandContext, task.getProcessInstanceId(), virtualTask.getId(), attachmentList, approver);
+ completeVirtualTask(commandContext, virtualTask);
RuntimeService runtimeService = processEngineConfiguration.getRuntimeService();
finishProcessInstance(commandContext, runtimeService, task, advice);
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java
index d6c8fcd09..2c607957c 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java
@@ -6,6 +6,7 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceVO;
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper;
+import cn.axzo.workflow.core.engine.model.AddComment;
import cn.axzo.workflow.core.repository.entity.ExtAxHiTaskInst;
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
import cn.axzo.workflow.core.service.converter.BpmnHistoricTaskInstanceConverter;
@@ -246,8 +247,11 @@ public class CustomTaskHelper {
addComment(commandContext, task, type, message);
}
+ public static void addComment(CommandContext commandContext, Task task, AddComment addComment) {
+ addComment(commandContext, task, addComment.getCommentType(), addComment.getContent());
+ }
public static void addComment(CommandContext commandContext, Task task, String type, String message) {
- if (!StringUtils.hasText(message)) {
+ if (!StringUtils.hasText(type) || !StringUtils.hasText(message)) {
return;
}
ProcessEngineConfigurationImpl processEngineConfiguration =
@@ -317,7 +321,7 @@ public class CustomTaskHelper {
public static Task createVirtualTask(CommandContext commandContext, ExtAxHiTaskInstService extAxHiTaskInstService
, String processInstanceId, String nodeName, String taskDefinitionKey, String advice,
BpmnTaskDelegateAssigner assigner,
- String extTaskInstStatus) {
+ String extTaskInstStatus, AddComment addComment) {
ProcessEngineConfigurationImpl processEngineConfiguration =
CommandContextUtil.getProcessEngineConfiguration(commandContext);
HistoryService historyService = processEngineConfiguration.getHistoryService();
@@ -352,6 +356,8 @@ public class CustomTaskHelper {
// 添加审批意见
addAdvice(commandContext, task, advice, Objects.nonNull(assigner) ? assigner.buildAssigneeId() : null);
+ // 添加操作描述
+ addComment(commandContext, task, addComment);
CustomTaskHelper.createExtTaskInst(extAxHiTaskInstService, task.getProcessInstanceId(), task.getId(),
task.getTaskDefinitionKey(), assigner, extTaskInstStatus);
@@ -362,12 +368,20 @@ public class CustomTaskHelper {
task.setVariable(INTERNAL_TASK_RELATION_ASSIGNEE_INFO + task.getId(), assigner.toJson());
}
- // 完成临时节点
- taskService.complete(task.getId());
+ // 完成临时节点, 1.4.2虚拟节点创建方法不再默认完成,需主动调用 completeVirtualTask 完成
+ // taskService.complete(task.getId());
return task;
}
+ public static Task completeVirtualTask(CommandContext commandContext, Task task) {
+ ProcessEngineConfigurationImpl processEngineConfiguration =
+ CommandContextUtil.getProcessEngineConfiguration(commandContext);
+ TaskService taskService = processEngineConfiguration.getTaskService();
+ taskService.complete(task.getId());
+ return task;
+ }
+
private static void addAdvice(CommandContext commandContext, Task task, String comment, String userId) {
if (StringUtils.hasLength(comment)) {
Authentication.setAuthenticatedUserId(userId);
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/EngineEntityEventListener.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/EngineEntityEventListener.java
new file mode 100644
index 000000000..7dd04b9e3
--- /dev/null
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/EngineEntityEventListener.java
@@ -0,0 +1,115 @@
+package cn.axzo.workflow.core.engine.listener.entity;
+
+import com.google.common.collect.ImmutableSet;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.flowable.common.engine.api.delegate.event.AbstractFlowableEventListener;
+import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType;
+import org.flowable.common.engine.api.delegate.event.FlowableEntityEvent;
+import org.flowable.common.engine.api.delegate.event.FlowableEvent;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ENTITY_ACTIVATED;
+import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ENTITY_CREATED;
+import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ENTITY_DELETED;
+import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ENTITY_INITIALIZED;
+import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ENTITY_SUSPENDED;
+import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ENTITY_UPDATED;
+
+/**
+ * TODO
+ *
+ * @author wangli
+ * @since 2024-09-02 15:34
+ */
+@Component
+@Slf4j
+@AllArgsConstructor
+public class EngineEntityEventListener extends AbstractFlowableEventListener {
+
+ private final List handles;
+ public static final Set SUPPORTED =
+ ImmutableSet.builder()
+ .add(ENTITY_CREATED)
+ .add(ENTITY_INITIALIZED)
+ .add(ENTITY_UPDATED)
+ .add(ENTITY_DELETED)
+ .add(ENTITY_SUSPENDED)
+ .add(ENTITY_ACTIVATED)
+ .build();
+
+ @Override
+ public void onEvent(FlowableEvent event) {
+ if (event instanceof FlowableEntityEvent && SUPPORTED.contains(event.getType())) {
+ FlowableEntityEvent entityEvent = (FlowableEntityEvent) event;
+// log.warn("entity event type: {}, class: {}",entityEvent.getType(), entityEvent.getEntity().getClass());
+ handles.forEach(handle -> {
+ Object entity = entityEvent.getEntity();
+ if (handle.support(entity)) {
+ Object convert = handle.convert(entity);
+ if (Objects.equals(event.getType(), ENTITY_CREATED)) {
+ handle.onCreate(convert);
+ } else if (Objects.equals(event.getType(), ENTITY_INITIALIZED)) {
+ handle.onInitialized(convert);
+ } else if (Objects.equals(event.getType(), ENTITY_UPDATED)) {
+ handle.onUpdated(convert);
+ } else if (Objects.equals(event.getType(), ENTITY_DELETED)) {
+ handle.onDeleted(convert);
+ } else if (Objects.equals(event.getType(), ENTITY_SUSPENDED)) {
+ handle.onSuspended(convert);
+ } else if (Objects.equals(event.getType(), ENTITY_ACTIVATED)) {
+ handle.onActivated(convert);
+ }
+ }
+ });
+// if (entityEvent.getEntity() instanceof TaskEntity) {
+// TaskEntity taskEntity = (TaskEntity) entityEvent.getEntity();
+// log.error("event taskId :{}, taskDefKey: {}", taskEntity.getId(), taskEntity.getTaskDefinitionKey());
+//
+// if (Objects.equals(event.getType(), ENTITY_CREATED)) {
+// onCreate(taskEntity);
+// } else if (Objects.equals(event.getType(), ENTITY_INITIALIZED)) {
+// onInitialized(taskEntity);
+// } else if (Objects.equals(event.getType(), ENTITY_UPDATED)) {
+// onUpdated(taskEntity);
+// } else if (Objects.equals(event.getType(), ENTITY_DELETED)) {
+// onDeleted(taskEntity);
+// } else if (Objects.equals(event.getType(), ENTITY_SUSPENDED)) {
+// onSuspended(taskEntity);
+// } else if (Objects.equals(event.getType(), ENTITY_ACTIVATED)) {
+// onActivated(taskEntity);
+// }
+// } else if(entityEvent.getEntity() instanceof CommentEntity) {
+// CommentEntity commentEntity = (CommentEntity) entityEvent.getEntity();
+// log.error("event taskId :{}", commentEntity.getId());
+//
+// if (Objects.equals(event.getType(), ENTITY_CREATED)) {
+// onCreate(commentEntity);
+// } else if (Objects.equals(event.getType(), ENTITY_INITIALIZED)) {
+// onInitialized(commentEntity);
+// } else if (Objects.equals(event.getType(), ENTITY_UPDATED)) {
+// onUpdated(commentEntity);
+// } else if (Objects.equals(event.getType(), ENTITY_DELETED)) {
+// onDeleted(commentEntity);
+// } else if (Objects.equals(event.getType(), ENTITY_SUSPENDED)) {
+// onSuspended(commentEntity);
+// } else if (Objects.equals(event.getType(), ENTITY_ACTIVATED)) {
+// onActivated(commentEntity);
+// }
+// }
+
+ }
+ }
+
+
+
+
+ @Override
+ public boolean isFailOnException() {
+ return true;
+ }
+}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/EntityEventHandle.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/EntityEventHandle.java
new file mode 100644
index 000000000..e3ae053ff
--- /dev/null
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/EntityEventHandle.java
@@ -0,0 +1,27 @@
+package cn.axzo.workflow.core.engine.listener.entity;
+
+/**
+ * TODO
+ *
+ * @author wangli
+ * @since 2024-09-06 00:03
+ */
+public interface EntityEventHandle {
+
+ boolean support(Object entity);
+
+ T convert(Object entity);
+
+ void onCreate(T entity);
+
+ void onInitialized(T entity);
+
+ void onUpdated(T entity);
+
+ void onDeleted(T entity);
+
+ void onSuspended(T entity);
+
+ void onActivated(T entity);
+
+}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/type/CommentEntityEventHandle.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/type/CommentEntityEventHandle.java
new file mode 100644
index 000000000..d3f416f6a
--- /dev/null
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/type/CommentEntityEventHandle.java
@@ -0,0 +1,82 @@
+package cn.axzo.workflow.core.engine.listener.entity.type;
+
+import cn.axzo.workflow.core.engine.listener.entity.EntityEventHandle;
+import cn.axzo.workflow.core.repository.entity.ExtAxProcessLog;
+import cn.axzo.workflow.core.service.ExtAxProcessLogService;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.flowable.engine.impl.persistence.entity.CommentEntity;
+import org.springframework.stereotype.Component;
+
+import java.util.Objects;
+
+import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE;
+import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC;
+
+/**
+ * TODO
+ *
+ * @author wangli
+ * @since 2024-09-06 00:14
+ */
+@Slf4j
+@Component
+@AllArgsConstructor
+public class CommentEntityEventHandle implements EntityEventHandle {
+ private final ExtAxProcessLogService processLogService;
+
+ @Override
+ public boolean support(Object entity) {
+ return entity instanceof CommentEntity;
+ }
+
+ @Override
+ public CommentEntity convert(Object entity) {
+ return (CommentEntity) entity;
+ }
+
+ @Override
+ public void onCreate(CommentEntity entity) {
+ log.info("comment event onCreate: {}", entity.getId());
+ ExtAxProcessLog queryLog = new ExtAxProcessLog();
+ queryLog.setProcessInstanceId(entity.getProcessInstanceId());
+ queryLog.setTaskId(entity.getId());
+ ExtAxProcessLog update = new ExtAxProcessLog();
+ if (Objects.equals(COMMENT_TYPE_ADVICE, entity.getType())) {
+ update.setAdvice(entity.getFullMessage());
+ } else if (Objects.equals(COMMENT_TYPE_OPERATION_DESC, entity.getType())) {
+ update.setOperationDesc(entity.getFullMessage());
+ }
+ processLogService.update(queryLog, update);
+ }
+
+ @Override
+ public void onInitialized(CommentEntity entity) {
+ log.info("comment event onInitialized: {}", entity.getId());
+
+ }
+
+ @Override
+ public void onUpdated(CommentEntity entity) {
+ log.info("comment event onUpdated: {}", entity.getId());
+
+ }
+
+ @Override
+ public void onDeleted(CommentEntity entity) {
+ log.info("comment event onDeleted: {}", entity.getId());
+
+ }
+
+ @Override
+ public void onSuspended(CommentEntity entity) {
+ log.info("comment event onSuspended: {}", entity.getId());
+
+ }
+
+ @Override
+ public void onActivated(CommentEntity entity) {
+ log.info("comment event onSuspended: {}", entity.getId());
+
+ }
+}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/EngineEntityEventListener.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/type/TaskEntityEventHandle.java
similarity index 63%
rename from workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/EngineEntityEventListener.java
rename to workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/type/TaskEntityEventHandle.java
index 44673e646..3514e6614 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/EngineEntityEventListener.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/type/TaskEntityEventHandle.java
@@ -1,23 +1,19 @@
-package cn.axzo.workflow.core.engine.listener;
+package cn.axzo.workflow.core.engine.listener.entity.type;
import cn.axzo.framework.jackson.utility.JSON;
import cn.axzo.workflow.common.enums.BpmnFlowNodeMode;
import cn.axzo.workflow.common.enums.BpmnFlowNodeType;
import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
+import cn.axzo.workflow.core.engine.listener.entity.EntityEventHandle;
import cn.axzo.workflow.core.repository.entity.ExtAxProcessLog;
import cn.axzo.workflow.core.service.ExtAxProcessLogService;
-import com.google.common.collect.ImmutableSet;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.ListUtils;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.UserTask;
-import org.flowable.common.engine.api.delegate.event.AbstractFlowableEventListener;
-import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType;
-import org.flowable.common.engine.api.delegate.event.FlowableEntityEvent;
-import org.flowable.common.engine.api.delegate.event.FlowableEvent;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.impl.bpmn.behavior.MultiInstanceActivityBehavior;
@@ -31,15 +27,12 @@ import org.springframework.stereotype.Component;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
-import java.util.Set;
import static cn.axzo.workflow.common.constant.BpmnConstants.AND_SIGN_EXPRESSION;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC;
import static cn.axzo.workflow.common.constant.BpmnConstants.HIDDEN_ASSIGNEE_ID;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT;
-import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_INITIATOR;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_INFO;
-import static cn.axzo.workflow.common.constant.BpmnConstants.OLD_INTERNAL_INITIATOR;
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_COMPLETE_OPERATION_TYPE;
import static cn.axzo.workflow.common.enums.ApprovalMethodEnum.nobody;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeMode.AND;
@@ -51,79 +44,60 @@ import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.PROCES
import static cn.axzo.workflow.core.common.enums.BpmnProcessTaskResultEnum.PENDING;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApprovalMethod;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getNodeType;
-import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ENTITY_ACTIVATED;
-import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ENTITY_CREATED;
-import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ENTITY_DELETED;
-import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ENTITY_INITIALIZED;
-import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ENTITY_SUSPENDED;
-import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ENTITY_UPDATED;
/**
* TODO
*
* @author wangli
- * @since 2024-09-02 15:34
+ * @since 2024-09-06 00:02
*/
-@Component
@Slf4j
+@Component
@AllArgsConstructor
-public class EngineEntityEventListener extends AbstractFlowableEventListener {
-
+public class TaskEntityEventHandle implements EntityEventHandle {
private final ExtAxProcessLogService processLogService;
- public static final Set SUPPORTED =
- ImmutableSet.builder()
- .add(ENTITY_CREATED)
- .add(ENTITY_INITIALIZED)
- .add(ENTITY_UPDATED)
- .add(ENTITY_DELETED)
- .add(ENTITY_SUSPENDED)
- .add(ENTITY_ACTIVATED)
- .build();
-
@Override
- public void onEvent(FlowableEvent event) {
- if (event instanceof FlowableEntityEvent) {
- FlowableEntityEvent entityEvent = (FlowableEntityEvent) event;
-// log.warn("entity event type: {}, class: {}",entityEvent.getType(), entityEvent.getEntity().getClass());
- if (entityEvent.getEntity() instanceof TaskEntity) {
- TaskEntity taskEntity = (TaskEntity) entityEvent.getEntity();
- log.error("event taskId :{}, taskDefKey: {}", taskEntity.getId(), taskEntity.getTaskDefinitionKey());
- if (Objects.equals(event.getType(), ENTITY_CREATED)) {
- onCreate(taskEntity);
- } else if (Objects.equals(event.getType(), ENTITY_INITIALIZED)) {
- onInitialized(taskEntity);
- } else if (Objects.equals(event.getType(), ENTITY_UPDATED)) {
- onUpdated(taskEntity);
- } else if (Objects.equals(event.getType(), ENTITY_DELETED)) {
- onDeleted(taskEntity);
- } else if (Objects.equals(event.getType(), ENTITY_SUSPENDED)) {
- onSuspended(taskEntity);
- } else if (Objects.equals(event.getType(), ENTITY_ACTIVATED)) {
- onActivated(taskEntity);
- }
- }
- }
+ public boolean support(Object entity) {
+ return entity instanceof TaskEntity;
}
- private void onActivated(TaskEntity taskEntity) {
+ @Override
+ public TaskEntity convert(Object entity) {
+ return (TaskEntity) entity;
+ }
+
+ @Override
+ public void onActivated(TaskEntity taskEntity) {
log.error("onActivated");
}
- private void onSuspended(TaskEntity taskEntity) {
+ public void onSuspended(TaskEntity taskEntity) {
log.error("onSuspended");
}
- private void onDeleted(TaskEntity taskEntity) {
+ public void onDeleted(TaskEntity taskEntity) {
log.error("onDeleted");
ExtAxProcessLog queryLog = new ExtAxProcessLog();
queryLog.setProcessInstanceId(taskEntity.getProcessInstanceId());
queryLog.setTaskId(taskEntity.getId());
ExtAxProcessLog update = new ExtAxProcessLog();
+
+ ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
+ RuntimeService runtimeService = processEngineConfiguration.getRuntimeService();
+// BpmnTaskDelegateAssigner assignee = BpmnTaskDelegateAssigner.toObjectCompatible(runtimeService.getVariable(taskEntity.getProcessInstanceId(), INTERNAL_TASK_RELATION_ASSIGNEE_INFO + taskEntity.getId()));
+ BpmnTaskDelegateAssigner assignee = BpmnTaskDelegateAssigner.toObjectCompatible(taskEntity.getVariable(INTERNAL_TASK_RELATION_ASSIGNEE_INFO + taskEntity.getId()));
+ if (Objects.nonNull(assignee)) {
+ update.setAssigneeFull(assignee);
+ update.setAssigneeId(Long.valueOf(assignee.getPersonId()));
+ update.setAssigneeTenantId(assignee.getTenantId());
+ update.setAssigneeName(assignee.getAssignerName());
+ update.setAssigneeOuId(assignee.getOuId());
+ }
+
if (Objects.equals(taskEntity.getTaskDefinitionKey(), NODE_STARTER.getType())) {
update.setStatus(APPROVED.getStatus());
} else {
- ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
List comments = processEngineConfiguration.getCommandExecutor()
.execute(new GetTaskCommentsByTypeCmd(taskEntity.getId(), COMMENT_TYPE_OPERATION_DESC));
comments.stream().max(Comparator.comparing(Comment::getTime)).ifPresent(e -> update.setOperationDesc(e.getFullMessage()));
@@ -137,7 +111,7 @@ public class EngineEntityEventListener extends AbstractFlowableEventListener {
processLogService.update(queryLog, update);
}
- private void onUpdated(TaskEntity taskEntity) {
+ public void onUpdated(TaskEntity taskEntity) {
log.error("onUpdated");
if (Objects.equals(HIDDEN_ASSIGNEE_ID, taskEntity.getAssignee())) {
ExtAxProcessLog queryLog = new ExtAxProcessLog();
@@ -160,28 +134,28 @@ public class EngineEntityEventListener extends AbstractFlowableEventListener {
}
}
- private void onInitialized(TaskEntity taskEntity) {
+ public void onInitialized(TaskEntity taskEntity) {
log.error("onInitialized");
}
- private void onCreate(TaskEntity taskEntity) {
+ public void onCreate(TaskEntity taskEntity) {
log.error("onCreate");
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
- RuntimeService runtimeService = processEngineConfiguration.getRuntimeService();
- BpmnTaskDelegateAssigner assignee;
-
- // 记录发起人
+// RuntimeService runtimeService = processEngineConfiguration.getRuntimeService();
+// BpmnTaskDelegateAssigner assignee;
+//
+// // 记录发起人
boolean isNodeStarter = Objects.equals(taskEntity.getTaskDefinitionKey(), NODE_STARTER.getType());
- if (isNodeStarter) {
- assignee = BpmnTaskDelegateAssigner.toObjectCompatible(runtimeService.getVariable(taskEntity.getProcessInstanceId(),
- INTERNAL_INITIATOR));
- if (Objects.isNull(assignee)) {
- // 兼容历史数据
- assignee = BpmnTaskDelegateAssigner.toObjectCompatible(runtimeService.getVariable(taskEntity.getProcessInstanceId(), OLD_INTERNAL_INITIATOR));
- }
- } else {
- assignee = BpmnTaskDelegateAssigner.toObjectCompatible(runtimeService.getVariable(taskEntity.getProcessInstanceId(), INTERNAL_TASK_RELATION_ASSIGNEE_INFO + taskEntity.getId()));
- }
+// if (isNodeStarter) {
+// assignee = BpmnTaskDelegateAssigner.toObjectCompatible(runtimeService.getVariable(taskEntity.getProcessInstanceId(),
+// INTERNAL_INITIATOR));
+// if (Objects.isNull(assignee)) {
+// // 兼容历史数据
+// assignee = BpmnTaskDelegateAssigner.toObjectCompatible(runtimeService.getVariable(taskEntity.getProcessInstanceId(), OLD_INTERNAL_INITIATOR));
+// }
+// } else {
+// assignee = BpmnTaskDelegateAssigner.toObjectCompatible(runtimeService.getVariable(taskEntity.getProcessInstanceId(), INTERNAL_TASK_RELATION_ASSIGNEE_INFO + taskEntity.getId()));
+// }
RepositoryService repositoryService = processEngineConfiguration.getRepositoryService();
BpmnModel bpmnModel = repositoryService.getBpmnModel(taskEntity.getProcessDefinitionId());
@@ -197,13 +171,13 @@ public class EngineEntityEventListener extends AbstractFlowableEventListener {
log.setNodeMode((isNodeStarter ? BpmnFlowNodeMode.GENERAL : getNodeMode(flowElement)).getType());
log.setTaskId(taskEntity.getId());
log.setOperationDesc(PENDING.getDesc());
- if (Objects.nonNull(assignee)) {
- log.setAssigneeFull(assignee);
- log.setAssigneeId(Long.valueOf(assignee.getPersonId()));
- log.setAssigneeTenantId(assignee.getTenantId());
- log.setAssigneeName(assignee.getAssignerName());
- log.setAssigneeOuId(assignee.getOuId());
- }
+// if (Objects.nonNull(assignee)) {
+// log.setAssigneeFull(assignee);
+// log.setAssigneeId(Long.valueOf(assignee.getPersonId()));
+// log.setAssigneeTenantId(assignee.getTenantId());
+// log.setAssigneeName(assignee.getAssignerName());
+// log.setAssigneeOuId(assignee.getOuId());
+// }
log.setStartTime(taskEntity.getCreateTime());
log.setStatus(PROCESSING.getStatus());
@@ -222,10 +196,4 @@ public class EngineEntityEventListener extends AbstractFlowableEventListener {
}
return node;
}
-
-
- @Override
- public boolean isFailOnException() {
- return true;
- }
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/model/AddComment.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/model/AddComment.java
new file mode 100644
index 000000000..acbce8564
--- /dev/null
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/model/AddComment.java
@@ -0,0 +1,40 @@
+package cn.axzo.workflow.core.engine.model;
+
+import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC;
+
+/**
+ * 评论模型
+ *
+ * @author wangli
+ * @since 2024-09-05 23:18
+ */
+public class AddComment {
+ private String commentType;
+ private String content;
+
+ public AddComment(String commentType, String content) {
+ this.commentType = commentType;
+ this.content = content;
+ }
+
+ public AddComment(String content) {
+ this.commentType = COMMENT_TYPE_OPERATION_DESC;
+ this.content = content;
+ }
+
+ public String getCommentType() {
+ return commentType;
+ }
+
+ public void setCommentType(String commentType) {
+ this.commentType = commentType;
+ }
+
+ public String getContent() {
+ return content;
+ }
+
+ public void setContent(String content) {
+ this.content = content;
+ }
+}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/converter/BpmnProcessInstanceAdminPageItemConverter.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/converter/BpmnProcessInstanceAdminPageItemConverter.java
index 42ff1140f..a4a51262e 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/converter/BpmnProcessInstanceAdminPageItemConverter.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/converter/BpmnProcessInstanceAdminPageItemConverter.java
@@ -30,12 +30,12 @@ import static org.mapstruct.NullValueCheckStrategy.ALWAYS;
* @since 2024/1/25 16:31
*/
@Mapper(
- componentModel = "spring",
- nullValueCheckStrategy = ALWAYS,
- imports = Arrays.class
+ componentModel = "spring",
+ nullValueCheckStrategy = ALWAYS,
+ imports = Arrays.class
)
public interface BpmnProcessInstanceAdminPageItemConverter extends EntityConverter {
+ HistoricProcessInstance> {
@Mapping(target = "processInstanceId", source = "id")
@Mapping(target = "processInstanceName", source = "name")
@@ -58,8 +58,8 @@ public interface BpmnProcessInstanceAdminPageItemConverter extends EntityConvert
if (Objects.equals(PROCESSING.getStatus(), i.getBusinessStatus())) {
List flowElements = instanceFlowElementMap.get(i.getId()).stream()
- .filter(j -> j instanceof UserTask || j instanceof ReceiveTask || j instanceof ServiceTask)
- .collect(Collectors.toList());
+ .filter(j -> j instanceof UserTask || j instanceof ReceiveTask || j instanceof ServiceTask)
+ .collect(Collectors.toList());
vo.setTotalNodeCount(flowElements.size());
// 进行中的节点
@@ -85,7 +85,7 @@ public interface BpmnProcessInstanceAdminPageItemConverter extends EntityConvert
vo.setCategoryDesc(category.getLabel());
vo.setWorkspaceTypeCode(category.getWorkspaceTypeCode());
vo.setBusinessStatusDesc(BpmnProcessInstanceResultEnum.valueOfStatus(vo.getBusinessStatus()).getDesc());
- vo.setWorkspaceType(WorkspaceType.getType(Integer.valueOf(vo.getWorkspaceTypeCode())));
+ vo.setWorkspaceType(WorkspaceType.getType(Integer.valueOf(Objects.nonNull(vo.getWorkspaceTypeCode()) ? vo.getWorkspaceTypeCode() : "0")));
result.add(vo);
});
return result;
diff --git a/workflow-engine-spring-boot-starter/src/main/java/cn/axzo/workflow/starter/api/WorkflowManageService.java b/workflow-engine-spring-boot-starter/src/main/java/cn/axzo/workflow/starter/api/WorkflowManageService.java
index 78809f2da..be5f34628 100644
--- a/workflow-engine-spring-boot-starter/src/main/java/cn/axzo/workflow/starter/api/WorkflowManageService.java
+++ b/workflow-engine-spring-boot-starter/src/main/java/cn/axzo/workflow/starter/api/WorkflowManageService.java
@@ -1,77 +1,63 @@
package cn.axzo.workflow.starter.api;
-import cn.axzo.workflow.starter.feign.ext.WorkflowEngineStarterFeignConfiguration;
-import cn.axzo.workflow.common.util.ThreadUtil;
-import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.ASYNC;
-import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.SYNC;
-import cn.axzo.workflow.client.config.CommonFeignConfiguration;
import cn.axzo.workflow.common.annotation.InvokeMode;
import cn.axzo.workflow.common.annotation.Manageable;
import cn.axzo.workflow.common.model.request.bpmn.BpmnButtonMetaInfo;
-import cn.azxo.framework.common.model.CommonResponse;
-import org.springframework.cloud.openfeign.FeignClient;
-import org.springframework.web.bind.annotation.GetMapping;
-import java.util.List;
+import cn.axzo.workflow.common.model.request.bpmn.RestBpmnProcessVariable;
+import cn.axzo.workflow.common.model.request.bpmn.definition.BpmnProcessDefinitionUpdateDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.BpmnModelCreateDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.BpmnModelSearchDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.BpmnModelUpdateDTO;
-import cn.axzo.workflow.common.model.response.BpmPageResult;
-import cn.axzo.workflow.common.model.response.bpmn.model.BpmnModelDetailVO;
-import cn.axzo.workflow.common.model.response.bpmn.model.BpmnModelExtVO;
-import io.swagger.v3.oas.annotations.Operation;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestParam;
-import javax.validation.constraints.NotBlank;
-import javax.validation.constraints.NotNull;
-import cn.axzo.workflow.common.model.request.bpmn.task.BpmnActivitySetAssigneeDTO;
-import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAbortDTO;
+import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessDefinitionPageDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAdminPageReqVO;
-import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCancelDTO;
-import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCarbonCopyDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCheckApproverDTO;
-import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCreateDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCreateWithFormDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceMyPageReqVO;
-import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceQueryDTO;
-import cn.axzo.workflow.common.model.response.bpmn.BatchOperationResultVO;
-import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceAdminPageItemVO;
-import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstancePageItemVO;
-import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceVO;
-import cn.axzo.workflow.common.model.response.bpmn.process.ProcessNodeDetailVO;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import javax.annotation.Nullable;
-import java.util.Map;
+import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAttachmentDTO;
+import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskPageSearchDTO;
+import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskRemindDTO;
import cn.axzo.workflow.common.model.request.category.CategoryConfigCreateDTO;
import cn.axzo.workflow.common.model.request.category.CategoryConfigSearchDTO;
import cn.axzo.workflow.common.model.request.category.CategoryCreateDTO;
import cn.axzo.workflow.common.model.request.category.CategorySearchDTO;
import cn.axzo.workflow.common.model.request.category.CategoryUpdateDTO;
-import cn.axzo.workflow.common.model.response.category.CategoryConfigItemVO;
-import cn.axzo.workflow.common.model.response.category.CategoryItemVO;
-import org.springframework.web.bind.annotation.PathVariable;
-import cn.axzo.workflow.common.model.request.bpmn.RestBpmnProcessVariable;
-import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCompleteDTO;
-import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCreateDTO;
-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.request.bpmn.task.BpmnTaskRemindDTO;
-import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskTransferDTO;
+import cn.axzo.workflow.common.model.response.BpmPageResult;
+import cn.axzo.workflow.common.model.response.bpmn.model.BpmnModelDetailVO;
+import cn.axzo.workflow.common.model.response.bpmn.model.BpmnModelExtVO;
+import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessDefinitionVO;
+import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceAdminPageItemVO;
+import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstancePageItemVO;
+import cn.axzo.workflow.common.model.response.bpmn.process.ProcessNodeDetailVO;
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.common.model.response.category.CategoryConfigItemVO;
+import cn.axzo.workflow.common.model.response.category.CategoryItemVO;
+import cn.axzo.workflow.common.util.ThreadUtil;
+import cn.axzo.workflow.starter.feign.ext.WorkflowEngineStarterFeignConfiguration;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import io.swagger.v3.oas.annotations.Operation;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import javax.annotation.Nullable;
+import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
-import cn.axzo.workflow.common.model.request.bpmn.definition.BpmnProcessDefinitionUpdateDTO;
-import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessDefinitionPageDTO;
-import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessDefinitionVO;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.Map;
+
+import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.ASYNC;
+import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.SYNC;
/**
* Workflow Engine Starter Management Service
该类是根据 API 动态生成,不同版本可能会开放新的接口,或回收一些旧接口
From 9e63eb6a0615783c96eaccee6fd6e4faaaf794a5 Mon Sep 17 00:00:00 2001
From: wangli <274027703@qq.com>
Date: Fri, 6 Sep 2024 10:30:33 +0800
Subject: [PATCH 017/139] =?UTF-8?q?feat(REQ-2924)=20-=20=E8=B0=83=E6=95=B4?=
=?UTF-8?q?=20Task=20=E4=B8=BA=20TaskEntity?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../core/engine/cmd/CustomApproveTaskCmd.java | 4 ++--
.../workflow/core/engine/cmd/CustomBackTaskCmd.java | 7 +++----
.../core/engine/cmd/CustomCompleteDummyTaskCmd.java | 4 ++--
.../core/engine/cmd/CustomTransferUserTaskCmd.java | 9 ++++-----
.../core/engine/cmd/helper/CustomTaskHelper.java | 12 +++++++-----
.../listener/entity/type/TaskEntityEventHandle.java | 12 ++++++------
6 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomApproveTaskCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomApproveTaskCmd.java
index e6e961069..4e4720113 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomApproveTaskCmd.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomApproveTaskCmd.java
@@ -115,8 +115,8 @@ public class CustomApproveTaskCmd extends AbstractCommand implements Seria
HistoricTaskInstance historicTaskInstance = taskQuery.taskId(taskId).singleResult();
- Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
- validTask(historicTaskInstance, (TaskEntity) task, approver, nodeTypes);
+ TaskEntity task = (TaskEntity) taskService.createTaskQuery().taskId(taskId).singleResult();
+ validTask(historicTaskInstance, task, approver, nodeTypes);
// TODO 所有的跟 Task 相关的动作都可以在这里进行扩展,用于扩展八大按钮标准动作以外的一些逻辑,但这里需要结合 Spring 能力,需设计好扩展点,否则无法进行扩展
// 其他动态也应该在类似的地方预留扩展点
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java
index 83e9f806d..2535978b0 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java
@@ -9,7 +9,6 @@ import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.util.CommandContextUtil;
-import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.api.history.HistoricTaskInstanceQuery;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
@@ -76,8 +75,8 @@ public class CustomBackTaskCmd extends AbstractCommand implements Serializ
HistoricTaskInstance historicTaskInstance = taskQuery.taskId(dto.getTaskId()).singleResult();
- Task task = taskService.createTaskQuery().taskId(dto.getTaskId()).singleResult();
- validTask(historicTaskInstance, (TaskEntity) task, dto.getApprover(), dto.getNodeTypes());
+ TaskEntity task = (TaskEntity) taskService.createTaskQuery().taskId(dto.getTaskId()).singleResult();
+ validTask(historicTaskInstance, task, dto.getApprover(), dto.getNodeTypes());
if (StringUtils.hasLength(dto.getAdvice())) {
Authentication.setAuthenticatedUserId(dto.getApprover().buildAssigneeId());
addComment(commandContext, task, COMMENT_TYPE_ADVICE, dto.getAdvice());
@@ -91,7 +90,7 @@ public class CustomBackTaskCmd extends AbstractCommand implements Serializ
Authentication.setAuthenticatedUserId(null);
RuntimeService runtimeService = processEngineConfiguration.getRuntimeService();
- ((TaskEntity) task).setTransientVariable(TASK_COMPLETE_OPERATION_TYPE + dto.getTaskId(), BACKED.getStatus());
+ task.setTransientVariable(TASK_COMPLETE_OPERATION_TYPE + dto.getTaskId(), BACKED.getStatus());
runtimeService.createChangeActivityStateBuilder()
.processInstanceId(task.getProcessInstanceId())
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCompleteDummyTaskCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCompleteDummyTaskCmd.java
index a00361cbf..d193f80cb 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCompleteDummyTaskCmd.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCompleteDummyTaskCmd.java
@@ -7,12 +7,12 @@ import cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper;
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
import com.alibaba.fastjson.JSON;
import org.flowable.common.engine.impl.identity.Authentication;
-import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.TaskService;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.task.api.Task;
+import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
@@ -65,7 +65,7 @@ public class CustomCompleteDummyTaskCmd extends AbstractCommand implements
CommandContextUtil.getProcessEngineConfiguration(commandContext);
TaskService taskService = processEngineConfiguration.getTaskService();
- Task task = taskService.createTaskQuery().processInstanceId(processInstanceId)
+ TaskEntity task = (TaskEntity) taskService.createTaskQuery().processInstanceId(processInstanceId)
.taskId(taskId).singleResult();
if (Objects.isNull(task)) {
throw new WorkflowEngineException(DUMMY_TASK_NOT_EXISTS, processInstanceId, taskId);
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomTransferUserTaskCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomTransferUserTaskCmd.java
index 5cf121307..bc51f1f04 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomTransferUserTaskCmd.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomTransferUserTaskCmd.java
@@ -6,7 +6,6 @@ import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import org.flowable.common.engine.impl.identity.Authentication;
-import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
@@ -83,11 +82,11 @@ public class CustomTransferUserTaskCmd extends AbstractCommand implements
HistoricTaskInstance historicTaskInstance = taskQuery.taskId(originTaskId).singleResult();
TaskService taskService = processEngineConfiguration.getTaskService();
- Task task = taskService.createTaskQuery().taskId(originTaskId).singleResult();
+ TaskEntity task = (TaskEntity) taskService.createTaskQuery().taskId(originTaskId).singleResult();
- validTask(historicTaskInstance, (TaskEntity) task, originTaskAssignee, null);
+ validTask(historicTaskInstance, task, originTaskAssignee, null);
- validTaskAssignerDuplicated(commandContext, (TaskEntity) task, Lists.newArrayList(targetTaskAssignee));
+ validTaskAssignerDuplicated(commandContext, task, Lists.newArrayList(targetTaskAssignee));
processAssignee(processEngineConfiguration, task);
@@ -103,7 +102,7 @@ public class CustomTransferUserTaskCmd extends AbstractCommand implements
return null;
}
- private void resolveOriginTask(CommandContext commandContext, TaskService taskService, Task task) {
+ private void resolveOriginTask(CommandContext commandContext, TaskService taskService, TaskEntity task) {
BpmnTaskDelegateAssigner assigner = buildDummyAssigner("transfer", TASK_ASSIGNEE_SKIP_FLAT, "dummyApprover");
task.setAssignee(assigner.buildAssigneeId());
((TaskEntity) task).setScopeType("TRANSFER");
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java
index 2c607957c..5fd11f522 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java
@@ -247,10 +247,11 @@ public class CustomTaskHelper {
addComment(commandContext, task, type, message);
}
- public static void addComment(CommandContext commandContext, Task task, AddComment addComment) {
+ public static void addComment(CommandContext commandContext, TaskEntity task, AddComment addComment) {
addComment(commandContext, task, addComment.getCommentType(), addComment.getContent());
}
- public static void addComment(CommandContext commandContext, Task task, String type, String message) {
+
+ public static void addComment(CommandContext commandContext, TaskEntity task, String type, String message) {
if (!StringUtils.hasText(type) || !StringUtils.hasText(message)) {
return;
}
@@ -276,6 +277,7 @@ public class CustomTaskHelper {
processEngineConfiguration.getCommentEntityManager().insert(comment);
+ task.setTransientVariable(type, message);
}
public static Attachment addAttachment(CommandContext commandContext, Task task, AttachmentDTO attachmentDto) {
@@ -341,8 +343,7 @@ public class CustomTaskHelper {
task.setTaskDefinitionKey(taskDefinitionKey);
task.setPriority(DEFAULT_PRIORITY);
task.setCreateTime(new Date());
- // 创建临时节点
- taskService.saveTask(task);
+
if (Objects.nonNull(assigner)) {
CommandContextUtil.getEntityCache().findInCache(TaskEntity.class).stream()
@@ -382,10 +383,11 @@ public class CustomTaskHelper {
return task;
}
- private static void addAdvice(CommandContext commandContext, Task task, String comment, String userId) {
+ private static void addAdvice(CommandContext commandContext, TaskEntity task, String comment, String userId) {
if (StringUtils.hasLength(comment)) {
Authentication.setAuthenticatedUserId(userId);
addComment(commandContext, task, COMMENT_TYPE_ADVICE, comment);
+ task.setTransientVariable(COMMENT_TYPE_ADVICE + task.getId(), comment);
Authentication.setAuthenticatedUserId(null);
}
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/type/TaskEntityEventHandle.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/type/TaskEntityEventHandle.java
index 3514e6614..6c7e61a96 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/type/TaskEntityEventHandle.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/type/TaskEntityEventHandle.java
@@ -18,17 +18,15 @@ import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.impl.bpmn.behavior.MultiInstanceActivityBehavior;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
-import org.flowable.engine.impl.cmd.GetTaskCommentsByTypeCmd;
import org.flowable.engine.impl.util.CommandContextUtil;
-import org.flowable.engine.task.Comment;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.springframework.stereotype.Component;
-import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import static cn.axzo.workflow.common.constant.BpmnConstants.AND_SIGN_EXPRESSION;
+import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC;
import static cn.axzo.workflow.common.constant.BpmnConstants.HIDDEN_ASSIGNEE_ID;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT;
@@ -98,11 +96,13 @@ public class TaskEntityEventHandle implements EntityEventHandle {
if (Objects.equals(taskEntity.getTaskDefinitionKey(), NODE_STARTER.getType())) {
update.setStatus(APPROVED.getStatus());
} else {
- List comments = processEngineConfiguration.getCommandExecutor()
- .execute(new GetTaskCommentsByTypeCmd(taskEntity.getId(), COMMENT_TYPE_OPERATION_DESC));
- comments.stream().max(Comparator.comparing(Comment::getTime)).ifPresent(e -> update.setOperationDesc(e.getFullMessage()));
String completionType = taskEntity.getVariable(TASK_COMPLETE_OPERATION_TYPE + taskEntity.getId(), String.class);
log.info("TASK_COMPLETE_OPERATION_TYPE: {}", completionType);
+ Object advice = taskEntity.getTransientVariable(COMMENT_TYPE_ADVICE);
+ log.info("COMMENT_TYPE_ADVICE: {}", advice);
+ Object operationDesc = taskEntity.getTransientVariable(COMMENT_TYPE_OPERATION_DESC);
+ log.info("COMMENT_TYPE_OPERATION_DESC: {}", operationDesc);
+
update.setStatus(completionType);
queryLog.setOperationDesc(PENDING.getDesc());
From 879e1a8cafb4f23ff86dba1146a84f6e98877919 Mon Sep 17 00:00:00 2001
From: yangqicheng
Date: Fri, 6 Sep 2024 12:08:06 +0800
Subject: [PATCH 018/139] =?UTF-8?q?REQ-2924-=E5=A4=84=E7=90=86=E4=BF=AE?=
=?UTF-8?q?=E6=94=B9=E9=94=99=E8=AF=AF=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../bpmn/task/BpmnOptionalNodeDTO.java | 21 +++++++++++++++++++
.../web/bpmn/BpmnProcessTaskController.java | 12 +++++------
2 files changed, 26 insertions(+), 7 deletions(-)
diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnOptionalNodeDTO.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnOptionalNodeDTO.java
index 665a5b19f..b5581813b 100644
--- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnOptionalNodeDTO.java
+++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnOptionalNodeDTO.java
@@ -15,17 +15,38 @@ import lombok.NoArgsConstructor;
@Builder
public class BpmnOptionalNodeDTO {
+ /**
+ * 对应流程实例id
+ */
private String processInstanceId;
+ /**
+ * 对应流程定义id
+ */
private String processDefinitionId;
+ /**
+ * 节点id
+ */
private String processNodeId;
+ /**
+ * 节点名称
+ */
private String processNodeName;
+ /**
+ * 节点描述,用于页面展示
+ */
private String processNodeDesc;
+ /**
+ * 节点类型
+ */
private BpmnFlowNodeType nodeType;
+ /**
+ * 序号,越小越靠近发起节点
+ */
private Integer ordinal;
}
diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java
index bcf08eaaf..f2c638b06 100644
--- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java
+++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java
@@ -136,9 +136,9 @@ public class BpmnProcessTaskController implements ProcessTaskApi {
}
/**
- * 回退
+ * 回退到指定节点
*/
- @Operation(summary = "回退任务")
+ @Operation(summary = "回退任务到指定节点")
@PostMapping("/back")
@RepeatSubmit
@Override
@@ -148,12 +148,10 @@ public class BpmnProcessTaskController implements ProcessTaskApi {
}
/**
- * 回退到指定节点
- * @param dto
- * @return
+ * 驳回
*/
- @Operation(summary = "回退")
- @PostMapping("/api/process/task/back")
+ @Operation(summary = "驳回任务")
+ @PostMapping("/reject")
@Override
@RepeatSubmit
public CommonResponse rejectTask(@Validated @RequestBody BpmnTaskAuditDTO dto) {
From b6ab7db0ed2f1c3f4c8401a7d6e3a237a8254598 Mon Sep 17 00:00:00 2001
From: yangqicheng
Date: Fri, 6 Sep 2024 14:10:04 +0800
Subject: [PATCH 019/139] =?UTF-8?q?REQ-2924-=E8=B0=83=E6=95=B4=E8=8E=B7?=
=?UTF-8?q?=E5=8F=96=E9=80=80=E5=9B=9E=E8=8A=82=E7=82=B9=E5=88=97=E8=A1=A8?=
=?UTF-8?q?=E6=8E=A5=E5=8F=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../client/feign/bpmn/ProcessTaskApi.java | 9 +++---
.../bpmn/task/BpmnUserTaskNodeDTO.java | 32 -------------------
.../core/service/BpmnProcessTaskService.java | 3 +-
.../impl/BpmnProcessTaskServiceImpl.java | 3 +-
.../web/bpmn/BpmnProcessTaskController.java | 9 +++---
.../starter/api/WorkflowCoreService.java | 9 +++---
6 files changed, 15 insertions(+), 50 deletions(-)
delete mode 100644 workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnUserTaskNodeDTO.java
diff --git a/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/bpmn/ProcessTaskApi.java b/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/bpmn/ProcessTaskApi.java
index 214ab75a8..0d9828443 100644
--- a/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/bpmn/ProcessTaskApi.java
+++ b/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/bpmn/ProcessTaskApi.java
@@ -13,7 +13,6 @@ 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.request.bpmn.task.BpmnTaskRemindDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskTransferDTO;
-import cn.axzo.workflow.common.model.request.bpmn.task.BpmnUserTaskNodeDTO;
import cn.axzo.workflow.common.model.response.BpmPageResult;
import cn.axzo.workflow.common.model.response.bpmn.BatchOperationResultVO;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceGroupVO;
@@ -74,12 +73,12 @@ public interface ProcessTaskApi {
/**
* 获取当前节点可退回节点选项列表
- * @param bpmnUserTaskNodeDTO 参数
- * @return
+ * @param taskId 当前任务id
+ * @return 可以退回节点列表
*/
@Operation(summary = "获取当前节点可退回节点选项列表")
- @PostMapping("/api/process/task/back/optional/nodes")
- CommonResponse> getBackOptionalNodes(@Validated @RequestBody BpmnUserTaskNodeDTO bpmnUserTaskNodeDTO);
+ @GetMapping("/api/process/task/back/optional/nodes")
+ CommonResponse> getBackOptionalNodes(@RequestParam @NotBlank(message = "任务id不能为空") String taskId);
/**
* 回退到指定节点
diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnUserTaskNodeDTO.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnUserTaskNodeDTO.java
deleted file mode 100644
index c1a228742..000000000
--- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnUserTaskNodeDTO.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package cn.axzo.workflow.common.model.request.bpmn.task;
-
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import lombok.experimental.Accessors;
-
-import javax.validation.constraints.NotBlank;
-
-@ApiModel("节点信息模型")
-@Data
-@Accessors(chain = true)
-@AllArgsConstructor
-@NoArgsConstructor
-@Builder
-public class BpmnUserTaskNodeDTO {
-
- @ApiModelProperty(value = "租户id")
- @NotBlank(message = "租户id不能为空")
- private String tenantId;
-
- @ApiModelProperty(value = "流程实例id")
- @NotBlank(message = "流程实例id不能为空")
- private String processInstanceId;
-
- @ApiModelProperty(value = "审批任务id")
- @NotBlank(message = "审批任务id不能为空")
- private String taskId;
-}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessTaskService.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessTaskService.java
index f78bff7bc..346b2fd31 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessTaskService.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessTaskService.java
@@ -56,10 +56,9 @@ public interface BpmnProcessTaskService {
/**
* 退回到指定节点,可以退回节点选项
- * @param processInstanceId 流程实例id
* @param taskId 任务id
*/
- List getApproveOptionalNodes(String processInstanceId, String taskId, String tenantId);
+ List getBackOptionalNodes(String taskId);
/**
* 驳回
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java
index 283cdce74..77d7a6646 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java
@@ -343,11 +343,12 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
}
@Override
- public List getApproveOptionalNodes(String processInstanceId, String taskId, String tenantId) {
+ public List getBackOptionalNodes(String taskId) {
Task task = processEngineConfiguration.getTaskService().createTaskQuery().taskId(taskId).singleResult();
if (task == null) {
throw new WorkflowEngineException(PROCESS_TASK_NOT_EXISTS);
}
+ String processInstanceId = task.getProcessInstanceId();
//1.获取当前的流程实例
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
if (processInstance == null) {
diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java
index f2c638b06..096805280 100644
--- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java
+++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java
@@ -14,7 +14,6 @@ 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.request.bpmn.task.BpmnTaskRemindDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskTransferDTO;
-import cn.axzo.workflow.common.model.request.bpmn.task.BpmnUserTaskNodeDTO;
import cn.axzo.workflow.common.model.response.BpmPageResult;
import cn.axzo.workflow.common.model.response.bpmn.BatchOperationResultVO;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceGroupVO;
@@ -123,15 +122,15 @@ public class BpmnProcessTaskController implements ProcessTaskApi {
/**
* 获取当前节点可退回节点选项列表
- * @param dto 参数
+ * @param taskId 当前任务id
* @return 可选退回节点列表
*/
@Operation(summary = "获取当前节点可退回节点选项列表")
- @PostMapping("/back/optional/nodes")
+ @GetMapping("/back/optional/nodes")
@Override
@RepeatSubmit
- public CommonResponse> getBackOptionalNodes(@RequestBody @Validated BpmnUserTaskNodeDTO dto) {
- List approveOptionalNodes = bpmnProcessTaskService.getApproveOptionalNodes(dto.getProcessInstanceId(), dto.getTaskId(), dto.getTenantId());
+ public CommonResponse> getBackOptionalNodes(@RequestParam @NotBlank(message = "任务id不能为空") String taskId) {
+ List approveOptionalNodes = bpmnProcessTaskService.getBackOptionalNodes(taskId);
return success(approveOptionalNodes);
}
diff --git a/workflow-engine-spring-boot-starter/src/main/java/cn/axzo/workflow/starter/api/WorkflowCoreService.java b/workflow-engine-spring-boot-starter/src/main/java/cn/axzo/workflow/starter/api/WorkflowCoreService.java
index fd86467fc..b9074162b 100644
--- a/workflow-engine-spring-boot-starter/src/main/java/cn/axzo/workflow/starter/api/WorkflowCoreService.java
+++ b/workflow-engine-spring-boot-starter/src/main/java/cn/axzo/workflow/starter/api/WorkflowCoreService.java
@@ -15,7 +15,6 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskBackAuditDTO;
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.BpmnTaskTransferDTO;
-import cn.axzo.workflow.common.model.request.bpmn.task.BpmnUserTaskNodeDTO;
import cn.axzo.workflow.common.model.response.bpmn.BatchOperationResultVO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceVO;
import cn.axzo.workflow.common.util.ThreadUtil;
@@ -178,12 +177,12 @@ public interface WorkflowCoreService {
/**
* 获取当前节点可退回节点选项列表
- * @param bpmnUserTaskNodeDTO 参数
- * @return
+ * @param taskId 当前任务id
+ * @return 可以退回节点列表
*/
@Operation(summary = "获取当前节点可退回节点选项列表")
- @PostMapping("/api/process/task/back/optional/nodes")
- List getBackOptionalNodes(@Validated @RequestBody BpmnUserTaskNodeDTO bpmnUserTaskNodeDTO);
+ @GetMapping("/api/process/task/back/optional/nodes")
+ List getBackOptionalNodes(@RequestParam @NotBlank(message = "任务id不能为空") String taskId);
/**
* 回退到指定节点
From f610bc9a97f79aec4b36f797ae9f04f1353531e7 Mon Sep 17 00:00:00 2001
From: wangli <274027703@qq.com>
Date: Fri, 6 Sep 2024 14:49:16 +0800
Subject: [PATCH 020/139] =?UTF-8?q?feat(REQ-2924)=20-=20=E5=AE=8C=E5=96=84?=
=?UTF-8?q?=E8=AF=84=E8=AE=BA=E5=8A=9F=E8=83=BD=E7=9A=84=E6=97=A5=E5=BF=97?=
=?UTF-8?q?=E9=80=BB=E8=BE=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../core/engine/cmd/CustomCommentTaskCmd.java | 48 ++++++++++---------
.../engine/cmd/helper/CustomTaskHelper.java | 4 +-
.../entity/type/TaskEntityEventHandle.java | 29 +++++++----
3 files changed, 49 insertions(+), 32 deletions(-)
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCommentTaskCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCommentTaskCmd.java
index 0faf9d4ee..c712829b0 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCommentTaskCmd.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCommentTaskCmd.java
@@ -4,13 +4,11 @@ import cn.axzo.workflow.common.model.request.bpmn.task.AttachmentDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCommentExtDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
-import cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper;
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import org.flowable.common.engine.impl.cfg.IdGenerator;
import org.flowable.common.engine.impl.identity.Authentication;
-import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.HistoryService;
import org.flowable.engine.TaskService;
@@ -22,7 +20,6 @@ import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.flowable.variable.service.HistoricVariableService;
import org.flowable.variable.service.impl.persistence.entity.HistoricVariableInstanceEntity;
import org.flowable.variable.service.impl.types.StringType;
-import org.springframework.util.StringUtils;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
@@ -36,9 +33,13 @@ import java.util.Objects;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_COMMENT_EXT;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_INFO;
+import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_COMPLETE_OPERATION_TYPE;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_COMMENT;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.COMMENTED;
import static cn.axzo.workflow.core.common.code.BpmnInstanceRespCode.TASK_CANT_COMMENT_INSTANCE_NOT_EXISTS;
+import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.addComment;
+import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.batchAddAttachment;
+import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.createExtTaskInst;
import static org.flowable.task.api.Task.DEFAULT_PRIORITY;
/**
@@ -80,11 +81,11 @@ public class CustomCommentTaskCmd extends AbstractCommand implements Seria
@Override
public Void execute(CommandContext commandContext) {
ProcessEngineConfigurationImpl processEngineConfiguration =
- CommandContextUtil.getProcessEngineConfiguration(commandContext);
+ CommandContextUtil.getProcessEngineConfiguration(commandContext);
HistoryService historyService = processEngineConfiguration.getHistoryService();
HistoricProcessInstance processInstance =
- historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
+ historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
if (Objects.isNull(processInstance)) {
throw new WorkflowEngineException(TASK_CANT_COMMENT_INSTANCE_NOT_EXISTS, processInstanceId);
}
@@ -103,32 +104,35 @@ public class CustomCommentTaskCmd extends AbstractCommand implements Seria
task.setTaskDefinitionKey(NODE_COMMENT.getType());
task.setPriority(DEFAULT_PRIORITY);
task.setCreateTime(new Date());
- // 创建临时节点
- taskService.saveTask(task);
+
// 处理该评论节点的评论人
buildAndInsertHistoryVariable(task, processInstance, processEngineConfiguration);
CommandContextUtil.getEntityCache().findInCache(HistoricTaskInstanceEntity.class).stream()
- .filter(i -> Objects.equals(i.getId(), task.getId())).findAny()
- .ifPresent(i -> i.setAssignee(operator.buildAssigneeId()));
- // 完成临时节点
- taskService.complete(task.getId());
+ .filter(i -> Objects.equals(i.getId(), task.getId())).findAny()
+ .ifPresent(i -> i.setAssignee(operator.buildAssigneeId()));
// 新增评论
Authentication.setAuthenticatedUserId(operator.buildAssigneeId());
- if (StringUtils.hasText(comment)) {
- CustomTaskHelper.addComment(commandContext, task, COMMENT_TYPE_ADVICE, comment);
- }
- if (Objects.nonNull(commentExt)) {
- CustomTaskHelper.addComment(commandContext, task, COMMENT_TYPE_COMMENT_EXT, JSONUtil.toJsonStr(commentExt));
- }
+ addComment(commandContext, task, COMMENT_TYPE_ADVICE, comment);
+ addComment(commandContext, task, COMMENT_TYPE_COMMENT_EXT, JSONUtil.toJsonStr(commentExt));
Authentication.setAuthenticatedUserId(null);
// 处理附件
- CustomTaskHelper.batchAddAttachment(commandContext, processInstanceId, task.getId(), attachmentList, operator);
+ batchAddAttachment(commandContext, processInstanceId, task.getId(), attachmentList, operator);
- CustomTaskHelper.createExtTaskInst(extAxHiTaskInstService, processInstanceId,
- task.getId(), task.getTaskDefinitionKey(), operator, COMMENTED.getStatus());
+ createExtTaskInst(extAxHiTaskInstService, processInstanceId,
+ task.getId(), task.getTaskDefinitionKey(), operator, COMMENTED.getStatus());
+ task.setTransientVariable(TASK_COMPLETE_OPERATION_TYPE + task.getId(), COMMENTED.getStatus());
+
+ // 保存临时节点
+ taskService.saveTask(task);
+
+ // 设置快照信息
+ task.setVariable(INTERNAL_TASK_RELATION_ASSIGNEE_INFO + task.getId(), operator.toJson());
+
+ // 完成临时节点
+ taskService.complete(task.getId());
return null;
}
@@ -136,9 +140,9 @@ public class CustomCommentTaskCmd extends AbstractCommand implements Seria
HistoricProcessInstance processInstance,
ProcessEngineConfigurationImpl processEngineConfiguration) {
HistoricVariableService historicVariableService =
- processEngineConfiguration.getVariableServiceConfiguration().getHistoricVariableService();
+ processEngineConfiguration.getVariableServiceConfiguration().getHistoricVariableService();
HistoricVariableInstanceEntity historicVariableInstance =
- historicVariableService.createHistoricVariableInstance();
+ historicVariableService.createHistoricVariableInstance();
historicVariableInstance.setTaskId(task.getId());
historicVariableInstance.setExecutionId(task.getExecutionId());
historicVariableInstance.setProcessInstanceId(processInstance.getId());
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java
index 5fd11f522..c506a981d 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java
@@ -344,7 +344,6 @@ public class CustomTaskHelper {
task.setPriority(DEFAULT_PRIORITY);
task.setCreateTime(new Date());
-
if (Objects.nonNull(assigner)) {
CommandContextUtil.getEntityCache().findInCache(TaskEntity.class).stream()
.filter(i -> Objects.equals(i.getId(), task.getId())).findAny()
@@ -364,6 +363,9 @@ public class CustomTaskHelper {
task.getTaskDefinitionKey(), assigner, extTaskInstStatus);
task.setTransientVariable(TASK_COMPLETE_OPERATION_TYPE + task.getId(), extTaskInstStatus);
+ // 保存任务
+ taskService.saveTask(task);
+
if (Objects.nonNull(assigner)) {
// 设置快照信息
task.setVariable(INTERNAL_TASK_RELATION_ASSIGNEE_INFO + task.getId(), assigner.toJson());
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/type/TaskEntityEventHandle.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/type/TaskEntityEventHandle.java
index 6c7e61a96..7df816d11 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/type/TaskEntityEventHandle.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/type/TaskEntityEventHandle.java
@@ -3,7 +3,6 @@ package cn.axzo.workflow.core.engine.listener.entity.type;
import cn.axzo.framework.jackson.utility.JSON;
import cn.axzo.workflow.common.enums.BpmnFlowNodeMode;
import cn.axzo.workflow.common.enums.BpmnFlowNodeType;
-import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.core.engine.listener.entity.EntityEventHandle;
import cn.axzo.workflow.core.repository.entity.ExtAxProcessLog;
@@ -21,7 +20,9 @@ import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+import java.util.Date;
import java.util.List;
import java.util.Objects;
@@ -79,6 +80,7 @@ public class TaskEntityEventHandle implements EntityEventHandle {
ExtAxProcessLog queryLog = new ExtAxProcessLog();
queryLog.setProcessInstanceId(taskEntity.getProcessInstanceId());
queryLog.setTaskId(taskEntity.getId());
+ queryLog.setOperationDesc(PENDING.getDesc());
ExtAxProcessLog update = new ExtAxProcessLog();
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
@@ -97,17 +99,26 @@ public class TaskEntityEventHandle implements EntityEventHandle {
update.setStatus(APPROVED.getStatus());
} else {
String completionType = taskEntity.getVariable(TASK_COMPLETE_OPERATION_TYPE + taskEntity.getId(), String.class);
- log.info("TASK_COMPLETE_OPERATION_TYPE: {}", completionType);
+ if (StringUtils.hasText(completionType)) {
+ log.info("TASK_COMPLETE_OPERATION_TYPE: {}", completionType);
+ update.setStatus(completionType);
+ }
Object advice = taskEntity.getTransientVariable(COMMENT_TYPE_ADVICE);
- log.info("COMMENT_TYPE_ADVICE: {}", advice);
+ if (Objects.nonNull(advice) && StringUtils.hasText(advice.toString())) {
+ log.info("COMMENT_TYPE_ADVICE: {}", advice);
+ update.setAdvice(advice.toString());
+ }
Object operationDesc = taskEntity.getTransientVariable(COMMENT_TYPE_OPERATION_DESC);
- log.info("COMMENT_TYPE_OPERATION_DESC: {}", operationDesc);
-
- update.setStatus(completionType);
-
- queryLog.setOperationDesc(PENDING.getDesc());
- update.setOperationDesc(BpmnProcessInstanceResultEnum.valueOfStatus(completionType).getDesc());
+ if (Objects.nonNull(operationDesc) && StringUtils.hasText(operationDesc.toString())) {
+ log.info("COMMENT_TYPE_OPERATION_DESC: {}", operationDesc);
+ update.setOperationDesc(Objects.nonNull(assignee) ? assignee.getAssignerName() + operationDesc : operationDesc.toString());
+ } else {
+ update.setOperationDesc(Objects.nonNull(assignee) ? assignee.getAssignerName() : "");
+ // 评论节点会给 operationDesc 赋 COMMENTED 的值,所以注释
+// update.setOperationDesc(BpmnProcessInstanceResultEnum.valueOfStatus(completionType).getDesc());
+ }
}
+ update.setEndTime(new Date());
processLogService.update(queryLog, update);
}
From 155537c130050d943f25852ce37abff939d689da Mon Sep 17 00:00:00 2001
From: wangli <274027703@qq.com>
Date: Fri, 6 Sep 2024 18:31:31 +0800
Subject: [PATCH 021/139] =?UTF-8?q?feat(REQ-2924)=20-=20=E5=AE=8C=E5=96=84?=
=?UTF-8?q?=E8=BD=AC=E4=BA=A4=E5=8A=9F=E8=83=BD=E7=9A=84=E6=97=A5=E5=BF=97?=
=?UTF-8?q?=E9=80=BB=E8=BE=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../engine/cmd/CustomTransferUserTaskCmd.java | 35 ++++++++++---------
.../entity/type/TaskEntityEventHandle.java | 2 +-
2 files changed, 19 insertions(+), 18 deletions(-)
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomTransferUserTaskCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomTransferUserTaskCmd.java
index bc51f1f04..51778165d 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomTransferUserTaskCmd.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomTransferUserTaskCmd.java
@@ -15,7 +15,6 @@ import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.api.history.HistoricTaskInstanceQuery;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
-import org.springframework.util.StringUtils;
import java.io.Serializable;
import java.util.HashMap;
@@ -76,9 +75,9 @@ public class CustomTransferUserTaskCmd extends AbstractCommand implements
@Override
public Void execute(CommandContext commandContext) {
ProcessEngineConfigurationImpl processEngineConfiguration =
- CommandContextUtil.getProcessEngineConfiguration(commandContext);
+ CommandContextUtil.getProcessEngineConfiguration(commandContext);
HistoricTaskInstanceQuery taskQuery =
- processEngineConfiguration.getHistoryService().createHistoricTaskInstanceQuery();
+ processEngineConfiguration.getHistoryService().createHistoricTaskInstanceQuery();
HistoricTaskInstance historicTaskInstance = taskQuery.taskId(originTaskId).singleResult();
TaskService taskService = processEngineConfiguration.getTaskService();
@@ -88,16 +87,19 @@ public class CustomTransferUserTaskCmd extends AbstractCommand implements
validTaskAssignerDuplicated(commandContext, task, Lists.newArrayList(targetTaskAssignee));
+ // 修改节点对应的审批人集合快照信息
processAssignee(processEngineConfiguration, task);
+ // 对被转交的任务进行建议和附件的处理
resolveOriginTask(commandContext, taskService, task);
-
batchAddAttachment(commandContext, task.getProcessInstanceId(), task.getId(), attachmentList,
- originTaskAssignee);
+ originTaskAssignee);
- addMultiTask(commandContext, (TaskEntity) task, targetTaskAssignee);
- ((TaskEntity) task).setTransientVariable(TASK_COMPLETE_OPERATION_TYPE + task.getId(), TRANSFER.getStatus());
- deleteMultiTask(commandContext, (TaskEntity) task);
+ // 生成转交任务
+ addMultiTask(commandContext, task, targetTaskAssignee);
+ task.setTransientVariable(TASK_COMPLETE_OPERATION_TYPE + task.getId(), TRANSFER.getStatus());
+ // 结束被转交任务
+ deleteMultiTask(commandContext, task);
return null;
}
@@ -105,23 +107,22 @@ public class CustomTransferUserTaskCmd extends AbstractCommand implements
private void resolveOriginTask(CommandContext commandContext, TaskService taskService, TaskEntity task) {
BpmnTaskDelegateAssigner assigner = buildDummyAssigner("transfer", TASK_ASSIGNEE_SKIP_FLAT, "dummyApprover");
task.setAssignee(assigner.buildAssigneeId());
- ((TaskEntity) task).setScopeType("TRANSFER");
- taskService.saveTask(task);
+ task.setScopeType("TRANSFER");
Authentication.setAuthenticatedUserId(originTaskAssignee.buildAssigneeId());
addComment(commandContext, task, COMMENT_TYPE_OPERATION_DESC, "转交给" + targetTaskAssignee.getAssignerName());
- if (StringUtils.hasLength(advice)) {
- addComment(commandContext, task, COMMENT_TYPE_ADVICE, advice);
- }
+ addComment(commandContext, task, COMMENT_TYPE_ADVICE, advice);
Authentication.setAuthenticatedUserId(null);
+
+ taskService.saveTask(task);
}
public void processAssignee(ProcessEngineConfigurationImpl processEngineConfiguration, Task task) {
RuntimeService runtimeService = processEngineConfiguration.getRuntimeService();
List originAssingeeList = runtimeService.getVariable(task.getProcessInstanceId(),
- INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + task.getTaskDefinitionKey(), List.class);
+ INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + task.getTaskDefinitionKey(), List.class);
Optional exists = originAssingeeList.stream()
- .filter(i -> Objects.equals(i.buildAssigneeId(), targetTaskAssignee.buildAssigneeId())).findAny();
+ .filter(i -> Objects.equals(i.buildAssigneeId(), targetTaskAssignee.buildAssigneeId())).findAny();
if (exists.isPresent()) {
throw new WorkflowEngineException(ASSIGNEE_HAS_BEEN_EXISTS);
}
@@ -134,8 +135,8 @@ public class CustomTransferUserTaskCmd extends AbstractCommand implements
}
originAssingeeList.add(targetTaskAssignee);
runtimeService.setVariable(task.getProcessInstanceId(),
- INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + task.getTaskDefinitionKey(),
- originAssingeeList);
+ INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + task.getTaskDefinitionKey(),
+ originAssingeeList);
}
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/type/TaskEntityEventHandle.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/type/TaskEntityEventHandle.java
index 7df816d11..a852e0786 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/type/TaskEntityEventHandle.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/type/TaskEntityEventHandle.java
@@ -45,7 +45,7 @@ import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApprova
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getNodeType;
/**
- * TODO
+ * 评论、加签、转交
*
* @author wangli
* @since 2024-09-06 00:02
From ddc4bd64da37ead46cf41047f2387658749dde29 Mon Sep 17 00:00:00 2001
From: wangli <274027703@qq.com>
Date: Fri, 6 Sep 2024 18:31:48 +0800
Subject: [PATCH 022/139] =?UTF-8?q?feat(REQ-2924)=20-=20=E6=B5=8B=E8=AF=95?=
=?UTF-8?q?=E5=9B=9E=E9=80=80=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../core/engine/cmd/CustomBackTaskCmd.java | 19 +++++++------------
1 file changed, 7 insertions(+), 12 deletions(-)
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java
index 2535978b0..6acc44fa0 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java
@@ -12,7 +12,6 @@ import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.api.history.HistoricTaskInstanceQuery;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
-import org.springframework.util.StringUtils;
import java.io.Serializable;
import java.util.Collections;
@@ -68,24 +67,20 @@ public class CustomBackTaskCmd extends AbstractCommand implements Serializ
@Override
public Void execute(CommandContext commandContext) {
ProcessEngineConfigurationImpl processEngineConfiguration =
- CommandContextUtil.getProcessEngineConfiguration(commandContext);
+ CommandContextUtil.getProcessEngineConfiguration(commandContext);
HistoricTaskInstanceQuery taskQuery =
- processEngineConfiguration.getHistoryService().createHistoricTaskInstanceQuery();
+ processEngineConfiguration.getHistoryService().createHistoricTaskInstanceQuery();
TaskService taskService = processEngineConfiguration.getTaskService();
HistoricTaskInstance historicTaskInstance = taskQuery.taskId(dto.getTaskId()).singleResult();
TaskEntity task = (TaskEntity) taskService.createTaskQuery().taskId(dto.getTaskId()).singleResult();
validTask(historicTaskInstance, task, dto.getApprover(), dto.getNodeTypes());
- if (StringUtils.hasLength(dto.getAdvice())) {
- Authentication.setAuthenticatedUserId(dto.getApprover().buildAssigneeId());
- addComment(commandContext, task, COMMENT_TYPE_ADVICE, dto.getAdvice());
- Authentication.setAuthenticatedUserId(null);
- }
batchAddAttachment(commandContext, task.getProcessInstanceId(), dto.getTaskId(), dto.getAttachmentList(), dto.getApprover());
- Authentication.setAuthenticatedUserId(Objects.nonNull(dto.getApprover()) ? dto.getApprover().buildAssigneeId() : null);
+ Authentication.setAuthenticatedUserId(dto.getApprover().buildAssigneeId());
+ addComment(commandContext, task, COMMENT_TYPE_ADVICE, dto.getAdvice());
addComment(commandContext, task, COMMENT_TYPE_OPERATION_DESC, operationDesc);
Authentication.setAuthenticatedUserId(null);
@@ -93,9 +88,9 @@ public class CustomBackTaskCmd extends AbstractCommand implements Serializ
task.setTransientVariable(TASK_COMPLETE_OPERATION_TYPE + dto.getTaskId(), BACKED.getStatus());
runtimeService.createChangeActivityStateBuilder()
- .processInstanceId(task.getProcessInstanceId())
- .moveActivityIdsToSingleActivityId(Collections.singletonList(task.getTaskDefinitionKey()), dto.getToActivityId())
- .changeState();
+ .processInstanceId(task.getProcessInstanceId())
+ .moveActivityIdsToSingleActivityId(Collections.singletonList(task.getTaskDefinitionKey()), dto.getToActivityId())
+ .changeState();
return null;
}
From 5e5d27a5eefea0aee40618ac6805b81e1203b597 Mon Sep 17 00:00:00 2001
From: wangli
Date: Fri, 6 Sep 2024 20:57:43 +0800
Subject: [PATCH 023/139] =?UTF-8?q?feat(REQ-2924)=20-=20=E7=A7=BB=E9=99=A4?=
=?UTF-8?q?=E4=B8=80=E4=BA=9B=E6=97=A0=E7=94=A8=E6=89=93=E5=8D=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../core/engine/interceptor/CustomRetryInterceptor.java | 3 ---
1 file changed, 3 deletions(-)
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomRetryInterceptor.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomRetryInterceptor.java
index 04671e6f4..c4a634bad 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomRetryInterceptor.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomRetryInterceptor.java
@@ -38,9 +38,6 @@ public class CustomRetryInterceptor extends AbstractCommandInterceptor {
try {
// try to execute the command
- if (log.isDebugEnabled()) {
- log.debug("assignableFrom result: {}", AbstractCommand.class.isAssignableFrom(command.getClass()));
- }
if (AbstractCommand.class.isAssignableFrom(command.getClass())) {
// 如果在以后,重试三次也不能解决的话, 可以利用这里的拿到的参数,重新自动构造CMD,并执行.
log.info("Executing command params: {} traceId:{} ", TraceUtil.traceId(),
From 105a9229ac287749d79a3d2d929ffdd7f944c689 Mon Sep 17 00:00:00 2001
From: wangli
Date: Fri, 6 Sep 2024 23:54:56 +0800
Subject: [PATCH 024/139] =?UTF-8?q?feat(REQ-2924)=20-=20=E6=B5=8B=E8=AF=95?=
=?UTF-8?q?=E9=A9=B3=E5=9B=9E=E3=80=81=E6=92=A4=E5=9B=9E=E3=80=81=E4=B8=AD?=
=?UTF-8?q?=E6=AD=A2=E3=80=81=E6=8A=84=E9=80=81=E5=8A=9F=E8=83=BD=E7=9A=84?=
=?UTF-8?q?=E6=96=B0=E5=AE=A1=E6=89=B9=E6=97=A5=E5=BF=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../common/constant/BpmnConstants.java | 2 +
.../process/BpmnProcessInstanceCancelDTO.java | 1 +
.../CustomReceiveTaskActivityBehavior.java | 5 +-
...askDelegateExpressionActivityBehavior.java | 26 +++++++--
.../cmd/CustomAbortProcessInstanceCmd.java | 2 +-
.../cmd/CustomCancelProcessInstanceCmd.java | 2 +-
.../engine/cmd/CustomRejectionTaskCmd.java | 8 +--
.../entity/type/CommentEntityEventHandle.java | 3 +-
.../entity/type/TaskEntityEventHandle.java | 55 ++++++++++++++++---
.../DeleteProcessInstanceOperation.java | 11 +++-
.../repository/entity/ExtAxProcessLog.java | 3 +-
.../core/service/ExtAxProcessLogService.java | 6 +-
.../impl/ExtAxProcessLogServiceImpl.java | 10 +++-
13 files changed, 103 insertions(+), 31 deletions(-)
diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/constant/BpmnConstants.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/constant/BpmnConstants.java
index 6c132c786..91f4ab550 100644
--- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/constant/BpmnConstants.java
+++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/constant/BpmnConstants.java
@@ -108,6 +108,7 @@ public interface BpmnConstants {
String BPM_MODEL_CATEGORY = "bpm_model_category";
String BPM_ALLOW_SKIP_USER_TASK = "_INTERNAL_SKIP_USER_TASK_";
String AUTO_APPROVAL_TYPE = "autoApprovalType";
+ String PROCESS_CLOSING_TYPE = "[_PROCESS_CLOSING_TYPE]";
/**
* 用于国内审批节点填写审批建议
*
@@ -120,6 +121,7 @@ public interface BpmnConstants {
String NUMBER_OF_INSTANCES = "nrOfInstances";
String MULTI_INSTANCE_LOOP_COUNTER = "loopCounter";
String TASK_COMPLETE_OPERATION_TYPE = "_TASK_COMPLETE_TYPE";
+
/**
* 会签表达式
*/
diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/process/BpmnProcessInstanceCancelDTO.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/process/BpmnProcessInstanceCancelDTO.java
index 5b44b327c..4bf8718b5 100644
--- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/process/BpmnProcessInstanceCancelDTO.java
+++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/process/BpmnProcessInstanceCancelDTO.java
@@ -36,6 +36,7 @@ public class BpmnProcessInstanceCancelDTO {
* 工作台 ID
*/
@ApiModelProperty(value = "工作台 ID")
+ @NotBlank(message = "工作台不能为空")
private String tenantId;
/**
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/behavior/CustomReceiveTaskActivityBehavior.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/behavior/CustomReceiveTaskActivityBehavior.java
index 5c0db9d78..1837174b1 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/behavior/CustomReceiveTaskActivityBehavior.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/behavior/CustomReceiveTaskActivityBehavior.java
@@ -75,11 +75,8 @@ public class CustomReceiveTaskActivityBehavior extends ReceiveTaskActivityBehavi
eventDispatcher.dispatchEvent(new ExtTaskInstUpdateEvent(execution.getProcessInstanceId(),
receiveTask.getId(), task.getId(), APPROVED),
processEngineConfiguration.getEngineCfgKey());
-// // 新版日志使用
-// eventDispatcher.dispatchEvent(FlowableEventBuilder.createEntityEvent(FlowableEngineEventType.ENTITY_DELETED, task),
-// processEngineConfiguration.getEngineCfgKey());
} else {
- log.warn("task is null, executionId: {}, activityId: {}", execution.getId(),
+ log.warn("ReceiveTask is null, executionId: {}, activityId: {}", execution.getId(),
execution.getCurrentActivityId());
}
super.leave(execution);
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/behavior/CustomServiceTaskDelegateExpressionActivityBehavior.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/behavior/CustomServiceTaskDelegateExpressionActivityBehavior.java
index 378fa8998..108939712 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/behavior/CustomServiceTaskDelegateExpressionActivityBehavior.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/behavior/CustomServiceTaskDelegateExpressionActivityBehavior.java
@@ -2,6 +2,7 @@ package cn.axzo.workflow.core.engine.behavior;
import cn.axzo.workflow.core.engine.event.ExtTaskInstCreateEvent;
import cn.axzo.workflow.core.engine.event.ExtTaskInstUpdateEvent;
+import cn.axzo.workflow.core.engine.listener.EngineCarbonCopyEventListener;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.MapExceptionEntry;
import org.flowable.bpmn.model.ServiceTask;
@@ -19,14 +20,16 @@ import org.flowable.task.service.TaskService;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import java.util.List;
+import java.util.Objects;
+import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_COMPLETE_OPERATION_TYPE;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.APPROVED;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.PROCESSING;
/**
* 自定义的服务任务活动行为处理器
*
- * 主要用来创建审批日志
+ * 主要用来创建抄送节点审批日志,真实计算抄送人的集合是由 {@link EngineCarbonCopyEventListener} 来完成的
*
* @author wangli
* @since 13/03/2024 14:17
@@ -35,6 +38,7 @@ import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.PROCES
public class CustomServiceTaskDelegateExpressionActivityBehavior extends ServiceTaskDelegateExpressionActivityBehavior {
protected final ServiceTask serviceTask;
+ // thread safe
private TaskEntity task;
public CustomServiceTaskDelegateExpressionActivityBehavior(String serviceTaskId, Expression expression,
@@ -57,7 +61,7 @@ public class CustomServiceTaskDelegateExpressionActivityBehavior extends Service
task.setTaskDefinitionKey(serviceTask.getId());
task.setPropagatedStageInstanceId(execution.getPropagatedStageInstanceId());
task.setName(serviceTask.getName());
- TaskHelper.insertTask(task, (ExecutionEntity) execution, false, false);
+ TaskHelper.insertTask(task, (ExecutionEntity) execution, true, false);
// 添加 taskInst 扩展表数据
FlowableEventDispatcher eventDispatcher = processEngineConfiguration.getEventDispatcher();
@@ -72,11 +76,23 @@ public class CustomServiceTaskDelegateExpressionActivityBehavior extends Service
CommandContext commandContext = CommandContextUtil.getCommandContext();
ProcessEngineConfigurationImpl processEngineConfiguration =
CommandContextUtil.getProcessEngineConfiguration(commandContext);
-
FlowableEventDispatcher eventDispatcher = processEngineConfiguration.getEventDispatcher();
- eventDispatcher.dispatchEvent(new ExtTaskInstUpdateEvent(execution.getProcessInstanceId(),
- execution.getCurrentActivityId(), task.getId(), APPROVED),
+
+ org.flowable.engine.TaskService taskService = processEngineConfiguration.getTaskService();
+ TaskEntity serviceTask = (TaskEntity) taskService.createTaskQuery().taskId(task.getId())
+ .taskDefinitionKey(execution.getCurrentActivityId()).singleResult();
+ if (Objects.nonNull(serviceTask)) {
+ // 用于新版日志
+ serviceTask.setTransientVariable(TASK_COMPLETE_OPERATION_TYPE + serviceTask.getId(), APPROVED.getStatus());
+
+ eventDispatcher.dispatchEvent(new ExtTaskInstUpdateEvent(execution.getProcessInstanceId(),
+ execution.getCurrentActivityId(), serviceTask.getId(), APPROVED),
processEngineConfiguration.getEngineCfgKey());
+ } else {
+ log.warn("ServiceTask is null, executionId: {}, activityId: {}", execution.getId(),
+ execution.getCurrentActivityId());
+ }
+
super.leave(execution);
}
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomAbortProcessInstanceCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomAbortProcessInstanceCmd.java
index 69faa460c..2ccd617a4 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomAbortProcessInstanceCmd.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomAbortProcessInstanceCmd.java
@@ -101,7 +101,7 @@ public class CustomAbortProcessInstanceCmd extends AbstractCommand impleme
runtimeService.setVariables(instance.getId(), variables);
CommandContextUtil.getAgenda(commandContext).planOperation(new DeleteProcessInstanceOperation(commandContext,
- processInstanceId, extAxHiTaskInstService));
+ processInstanceId, extAxHiTaskInstService, ABORTED));
// 添加自定义的节点,用于展示最后的操作
Task task = createVirtualTask(commandContext, extAxHiTaskInstService, processInstanceId,
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCancelProcessInstanceCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCancelProcessInstanceCmd.java
index cb1996e3a..f32129f5c 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCancelProcessInstanceCmd.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCancelProcessInstanceCmd.java
@@ -104,7 +104,7 @@ public class CustomCancelProcessInstanceCmd extends AbstractCommand implem
runtimeService.setVariables(instance.getId(), variables);
CommandContextUtil.getAgenda(commandContext).planOperation(new DeleteProcessInstanceOperation(commandContext,
- processInstanceId, extAxHiTaskInstService));
+ processInstanceId, extAxHiTaskInstService, CANCELLED));
// 添加自定义的节点,用于展示最后的操作
Task task = createVirtualTask(commandContext, extAxHiTaskInstService, processInstanceId,
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomRejectionTaskCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomRejectionTaskCmd.java
index 02fc23b46..2ee944c96 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomRejectionTaskCmd.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomRejectionTaskCmd.java
@@ -97,11 +97,11 @@ public class CustomRejectionTaskCmd extends AbstractCommand implements Ser
HistoricTaskInstance historicTaskInstance = taskQuery.taskId(taskId).singleResult();
TaskService taskService = processEngineConfiguration.getTaskService();
- Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
+ TaskEntity task = (TaskEntity) taskService.createTaskQuery().taskId(taskId).singleResult();
- validTask(historicTaskInstance, (TaskEntity) task, approver, nodeTypes);
+ validTask(historicTaskInstance, task, approver, nodeTypes);
- ((TaskEntity) task).setTransientVariable(TASK_COMPLETE_OPERATION_TYPE + task.getId(), REJECTED.getStatus());
+ task.setTransientVariable(TASK_COMPLETE_OPERATION_TYPE + task.getId(), REJECTED.getStatus());
Task virtualTask = createVirtualTask(commandContext, extAxHiTaskInstService, task.getProcessInstanceId(), task.getName(),
task.getTaskDefinitionKey(), advice,
Objects.equals(operationDesc, "自动驳回") ? null : approver, REJECTED.getStatus(),
@@ -126,7 +126,7 @@ public class CustomRejectionTaskCmd extends AbstractCommand implements Ser
runtimeService.setVariables(task.getProcessInstanceId(), variables);
CommandContextUtil.getAgenda(commandContext)
.planOperation(new DeleteProcessInstanceOperation(commandContext, task.getProcessInstanceId(),
- extAxHiTaskInstService));
+ extAxHiTaskInstService, REJECTED));
}
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/type/CommentEntityEventHandle.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/type/CommentEntityEventHandle.java
index d3f416f6a..c7e03e86d 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/type/CommentEntityEventHandle.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/type/CommentEntityEventHandle.java
@@ -6,7 +6,6 @@ import cn.axzo.workflow.core.service.ExtAxProcessLogService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.impl.persistence.entity.CommentEntity;
-import org.springframework.stereotype.Component;
import java.util.Objects;
@@ -20,7 +19,7 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERAT
* @since 2024-09-06 00:14
*/
@Slf4j
-@Component
+//@Component
@AllArgsConstructor
public class CommentEntityEventHandle implements EntityEventHandle {
private final ExtAxProcessLogService processLogService;
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/type/TaskEntityEventHandle.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/type/TaskEntityEventHandle.java
index a852e0786..a221541a8 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/type/TaskEntityEventHandle.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/type/TaskEntityEventHandle.java
@@ -7,6 +7,7 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.core.engine.listener.entity.EntityEventHandle;
import cn.axzo.workflow.core.repository.entity.ExtAxProcessLog;
import cn.axzo.workflow.core.service.ExtAxProcessLogService;
+import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.ListUtils;
@@ -20,6 +21,7 @@ import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.Date;
@@ -32,6 +34,7 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERAT
import static cn.axzo.workflow.common.constant.BpmnConstants.HIDDEN_ASSIGNEE_ID;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_INFO;
+import static cn.axzo.workflow.common.constant.BpmnConstants.NO_ASSIGNEE;
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_COMPLETE_OPERATION_TYPE;
import static cn.axzo.workflow.common.enums.ApprovalMethodEnum.nobody;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeMode.AND;
@@ -39,13 +42,16 @@ import static cn.axzo.workflow.common.enums.BpmnFlowNodeMode.GENERAL;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeMode.OR;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_STARTER;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.APPROVED;
+import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.DELETED;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.PROCESSING;
import static cn.axzo.workflow.core.common.enums.BpmnProcessTaskResultEnum.PENDING;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApprovalMethod;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getNodeType;
/**
- * 评论、加签、转交
+ * 同意、评论、加签、转交、驳回、撤回、中止、抄送
+ *
+ * 退回
*
* @author wangli
* @since 2024-09-06 00:02
@@ -87,22 +93,19 @@ public class TaskEntityEventHandle implements EntityEventHandle {
RuntimeService runtimeService = processEngineConfiguration.getRuntimeService();
// BpmnTaskDelegateAssigner assignee = BpmnTaskDelegateAssigner.toObjectCompatible(runtimeService.getVariable(taskEntity.getProcessInstanceId(), INTERNAL_TASK_RELATION_ASSIGNEE_INFO + taskEntity.getId()));
BpmnTaskDelegateAssigner assignee = BpmnTaskDelegateAssigner.toObjectCompatible(taskEntity.getVariable(INTERNAL_TASK_RELATION_ASSIGNEE_INFO + taskEntity.getId()));
- if (Objects.nonNull(assignee)) {
- update.setAssigneeFull(assignee);
+ if (Objects.nonNull(assignee) && !Objects.equals(NO_ASSIGNEE, assignee.buildAssigneeId())) {
+ update.setAssigneeFull(Lists.newArrayList(assignee));
update.setAssigneeId(Long.valueOf(assignee.getPersonId()));
update.setAssigneeTenantId(assignee.getTenantId());
update.setAssigneeName(assignee.getAssignerName());
update.setAssigneeOuId(assignee.getOuId());
}
+ boolean needDelete = false;
if (Objects.equals(taskEntity.getTaskDefinitionKey(), NODE_STARTER.getType())) {
update.setStatus(APPROVED.getStatus());
} else {
- String completionType = taskEntity.getVariable(TASK_COMPLETE_OPERATION_TYPE + taskEntity.getId(), String.class);
- if (StringUtils.hasText(completionType)) {
- log.info("TASK_COMPLETE_OPERATION_TYPE: {}", completionType);
- update.setStatus(completionType);
- }
+
Object advice = taskEntity.getTransientVariable(COMMENT_TYPE_ADVICE);
if (Objects.nonNull(advice) && StringUtils.hasText(advice.toString())) {
log.info("COMMENT_TYPE_ADVICE: {}", advice);
@@ -117,9 +120,45 @@ public class TaskEntityEventHandle implements EntityEventHandle {
// 评论节点会给 operationDesc 赋 COMMENTED 的值,所以注释
// update.setOperationDesc(BpmnProcessInstanceResultEnum.valueOfStatus(completionType).getDesc());
}
+
+
+ String completionType = taskEntity.getVariable(TASK_COMPLETE_OPERATION_TYPE + taskEntity.getId(), String.class);
+ if (StringUtils.hasText(completionType)) {
+ log.info("TASK_COMPLETE_OPERATION_TYPE: {}", completionType);
+ update.setStatus(completionType);
+ } else {
+ // 多实例除操作人以外的任务,直接删除日志, 例如一个节点有两个人或签,A 人驳回了,那么 B 人不再需要操作,任务自动删除。而会签也同理
+ update.setStatus(DELETED.getStatus());// delete标志着是多实例删除
+ needDelete = true;
+ }
}
update.setEndTime(new Date());
+
+ // 判断是否抄送节点,如果是的话,需要将抄送人集合放入对应字段
+ if (isCarbonCopyNode(queryLog)) {
+ // 抄送人集合
+ List carbonCopies = runtimeService.getVariable(taskEntity.getProcessInstanceId(), INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + taskEntity.getTaskDefinitionKey(), List.class);
+ update.setAssigneeFull(carbonCopies);
+ update.setOperationDesc("抄送" + carbonCopies.size() + "人");
+ }
+
processLogService.update(queryLog, update);
+
+ if (needDelete) {
+ // 再逻辑删除该记录
+ ExtAxProcessLog deleteLog = new ExtAxProcessLog();
+ deleteLog.setProcessInstanceId(taskEntity.getProcessInstanceId());
+ deleteLog.setTaskId(taskEntity.getId());
+ processLogService.delete(deleteLog);
+ }
+ }
+
+ private boolean isCarbonCopyNode(ExtAxProcessLog queryLog) {
+ List logs = processLogService.genericQuery(queryLog);
+ if (CollectionUtils.isEmpty(logs) || logs.size() != 1) {
+ return false;
+ }
+ return Objects.equals(logs.get(0).getNodeType(), BpmnFlowNodeType.NODE_CARBON_COPY.getType());
}
public void onUpdated(TaskEntity taskEntity) {
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/operation/DeleteProcessInstanceOperation.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/operation/DeleteProcessInstanceOperation.java
index df7346997..d1e14ba0b 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/operation/DeleteProcessInstanceOperation.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/operation/DeleteProcessInstanceOperation.java
@@ -1,5 +1,6 @@
package cn.axzo.workflow.core.engine.operation;
+import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.HistoryService;
@@ -16,6 +17,7 @@ import java.util.List;
import java.util.Objects;
import static cn.axzo.workflow.common.constant.BpmnConstants.HIDDEN_ASSIGNEE_ID;
+import static cn.axzo.workflow.common.constant.BpmnConstants.PROCESS_CLOSING_TYPE;
/**
* 通用的在 Command 内执行删除流程实例时的额外操作
@@ -27,21 +29,25 @@ public class DeleteProcessInstanceOperation extends AbstractOperation {
private final String processInstanceId;
private final ExtAxHiTaskInstService extAxHiTaskInstService;
private String customDeleteReason;
+ private final BpmnProcessInstanceResultEnum closingType;
public DeleteProcessInstanceOperation(CommandContext commandContext, String processInstanceId,
- ExtAxHiTaskInstService extAxHiTaskInstService) {
+ ExtAxHiTaskInstService extAxHiTaskInstService,
+ BpmnProcessInstanceResultEnum closingType) {
super(commandContext, null);
this.processInstanceId = processInstanceId;
this.extAxHiTaskInstService = extAxHiTaskInstService;
+ this.closingType = closingType;
}
public DeleteProcessInstanceOperation(CommandContext commandContext, String processInstanceId,
ExtAxHiTaskInstService extAxHiTaskInstService,
- String customDeleteReason) {
+ String customDeleteReason, BpmnProcessInstanceResultEnum closingType) {
super(commandContext, null);
this.processInstanceId = processInstanceId;
this.extAxHiTaskInstService = extAxHiTaskInstService;
this.customDeleteReason = customDeleteReason;
+ this.closingType = closingType;
}
@Override
@@ -65,6 +71,7 @@ public class DeleteProcessInstanceOperation extends AbstractOperation {
}
RuntimeService runtimeService = processEngineConfiguration.getRuntimeService();
+ runtimeService.setVariableLocal(processInstanceId, PROCESS_CLOSING_TYPE, closingType);
runtimeService.deleteProcessInstance(processInstanceId, StringUtils.hasText(customDeleteReason) ? customDeleteReason : HIDDEN_ASSIGNEE_ID);
// 将结束流程实例的原因记录下来
// runtimeService.deleteProcessInstance(processInstanceId, reason);
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/repository/entity/ExtAxProcessLog.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/repository/entity/ExtAxProcessLog.java
index 179b8d732..569569c39 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/repository/entity/ExtAxProcessLog.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/repository/entity/ExtAxProcessLog.java
@@ -11,6 +11,7 @@ import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.Date;
+import java.util.List;
/**
* 审批日志
@@ -68,7 +69,7 @@ public class ExtAxProcessLog extends BaseEntity {
* 审批人对象信息
*/
@TableField(typeHandler = JacksonTypeHandler.class)
- private BpmnTaskDelegateAssigner assigneeFull;
+ private List assigneeFull;
/**
* 审批人标识
*/
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/ExtAxProcessLogService.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/ExtAxProcessLogService.java
index 99b9ef4e8..ef2791f63 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/ExtAxProcessLogService.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/ExtAxProcessLogService.java
@@ -3,6 +3,8 @@ package cn.axzo.workflow.core.service;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.core.repository.entity.ExtAxProcessLog;
+import java.util.List;
+
/**
* Api Log 表操作服务
*
@@ -21,7 +23,7 @@ public interface ExtAxProcessLogService {
/**
* 根据参数删除指定任务
*
- * @param deleteLog
+ * @param deleteLog 查询条件
*/
void delete(ExtAxProcessLog deleteLog);
@@ -49,4 +51,6 @@ public interface ExtAxProcessLogService {
void updateAssignee(ExtAxProcessLog updateLog, BpmnTaskDelegateAssigner assignee);
void updateAssignee(ExtAxProcessLog updateLog, BpmnTaskDelegateAssigner assignee, String operationDesc);
+
+ List genericQuery(ExtAxProcessLog query);
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/ExtAxProcessLogServiceImpl.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/ExtAxProcessLogServiceImpl.java
index 67c30f0e7..c9c1e8005 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/ExtAxProcessLogServiceImpl.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/ExtAxProcessLogServiceImpl.java
@@ -65,7 +65,7 @@ public class ExtAxProcessLogServiceImpl implements ExtAxProcessLogService {
}
ExtAxProcessLog update = new ExtAxProcessLog();
update.setOperationDesc(StringUtils.hasText(operationDesc) ? operationDesc : assignee.getAssignerName());
- update.setAssigneeFull(assignee);
+ update.setAssigneeFull(Lists.newArrayList(assignee));
update.setAssigneeId(Long.valueOf(assignee.getPersonId()));
update.setAssigneeTenantId(assignee.getTenantId());
update.setAssigneeOuId(assignee.getOuId());
@@ -73,6 +73,11 @@ public class ExtAxProcessLogServiceImpl implements ExtAxProcessLogService {
extAxProcessLogMapper.update(update, buildQueryWrapper(queryLog));
}
+ @Override
+ public List genericQuery(ExtAxProcessLog query) {
+ return extAxProcessLogMapper.selectList(buildQueryWrapper(query));
+ }
+
LambdaQueryWrapper buildQueryWrapper(ExtAxProcessLog log) {
return new LambdaQueryWrapper()
.eq(Objects.nonNull(log.getId()), ExtAxProcessLog::getId, log.getId())
@@ -80,6 +85,7 @@ public class ExtAxProcessLogServiceImpl implements ExtAxProcessLogService {
.eq(StringUtils.hasText(log.getActivityId()), ExtAxProcessLog::getActivityId, log.getActivityId())
.eq(StringUtils.hasText(log.getActivityName()), ExtAxProcessLog::getActivityName, log.getActivityName())
.eq(StringUtils.hasText(log.getTaskId()), ExtAxProcessLog::getTaskId, log.getTaskId())
- .eq(StringUtils.hasText(log.getTenantId()), ExtAxProcessLog::getTenantId, log.getTenantId());
+ .eq(StringUtils.hasText(log.getTenantId()), ExtAxProcessLog::getTenantId, log.getTenantId())
+ .eq(ExtAxProcessLog::getIsDelete, 0);
}
}
From f30d891f82a6f09e2d62a208a95baeeb79c8a54b Mon Sep 17 00:00:00 2001
From: wangli
Date: Sat, 7 Sep 2024 23:00:07 +0800
Subject: [PATCH 025/139] =?UTF-8?q?feat(REQ-2924)=20-=20=E6=96=B0=E5=A2=9E?=
=?UTF-8?q?=E6=96=B0=E7=89=88=E6=97=A5=E5=BF=97=E6=9F=A5=E8=AF=A2=E9=80=BB?=
=?UTF-8?q?=E8=BE=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../client/feign/bpmn/ProcessInstanceApi.java | 15 +-
.../common/enums/ApprovalMethodEnum.java | 10 +
.../workflow/common/enums/BpmnButtonEnum.java | 2 +-
.../common/enums/BpmnFlowNodeMode.java | 10 +
.../common/model/request/BpmnApproveConf.java | 9 +-
.../model/request/bpmn/BpmnButtonConf.java | 9 +-
.../BpmnProcessInstanceLogQueryDTO.java | 54 +++
.../request/bpmn/task/AttachmentDTO.java | 6 +
.../bpmn/task/BpmnOptionalNodeDTO.java | 4 +-
.../process/BpmnProcessInstanceLogVO.java | 143 ++++++
.../bpmn/task/BpmnTaskInstanceLogVO.java | 123 ++++++
.../core/common/code/BpmnTaskRespCode.java | 1 +
.../conf/handler/ButtonConfTypeHandler.java | 57 +++
.../conf/handler/ListAssigneeTypeHandler.java | 57 +++
.../core/engine/cmd/CustomBackTaskCmd.java | 24 +-
.../engine/job/AsyncBackTaskJobHandler.java | 11 +-
.../entity/type/TaskEntityEventHandle.java | 35 +-
.../repository/entity/ExtAxProcessLog.java | 10 +-
.../service/BpmnProcessInstanceService.java | 24 +-
.../impl/BpmnProcessInstanceServiceImpl.java | 414 +++++++++++++-----
.../impl/BpmnProcessTaskServiceImpl.java | 6 +-
.../support/FlowNodeForecastService.java | 56 ++-
.../main/resources/sql/upgrade_to_1.4.2.sql | 5 +-
.../AbstractBpmnTaskAssigneeSelector.java | 143 ++++--
.../BasedIdentityTaskAssigneeSelector.java | 5 -
.../TransferToAdminTaskAssigneeSelector.java | 5 -
.../server/controller/web/TestController.java | 11 +-
.../bpmn/BpmnProcessInstanceController.java | 36 +-
.../web/bpmn/BpmnProcessTaskController.java | 35 +-
29 files changed, 1081 insertions(+), 239 deletions(-)
create mode 100644 workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/process/BpmnProcessInstanceLogQueryDTO.java
create mode 100644 workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/response/bpmn/process/BpmnProcessInstanceLogVO.java
create mode 100644 workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/response/bpmn/task/BpmnTaskInstanceLogVO.java
create mode 100644 workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/handler/ButtonConfTypeHandler.java
create mode 100644 workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/handler/ListAssigneeTypeHandler.java
diff --git a/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/bpmn/ProcessInstanceApi.java b/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/bpmn/ProcessInstanceApi.java
index e2368600f..465d79c4f 100644
--- a/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/bpmn/ProcessInstanceApi.java
+++ b/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/bpmn/ProcessInstanceApi.java
@@ -1,6 +1,5 @@
package cn.axzo.workflow.client.feign.bpmn;
-import cn.axzo.workflow.client.config.CommonFeignConfiguration;
import cn.axzo.workflow.common.annotation.InvokeMode;
import cn.axzo.workflow.common.annotation.Manageable;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAbortDTO;
@@ -10,18 +9,19 @@ import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCar
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCheckApproverDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCreateDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCreateWithFormDTO;
+import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceLogQueryDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceMyPageReqVO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceQueryDTO;
import cn.axzo.workflow.common.model.response.BpmPageResult;
import cn.axzo.workflow.common.model.response.bpmn.BatchOperationResultVO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceAdminPageItemVO;
+import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceLogVO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstancePageItemVO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceVO;
import cn.axzo.workflow.common.model.response.bpmn.process.ProcessNodeDetailVO;
import cn.azxo.framework.common.model.CommonResponse;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.swagger.v3.oas.annotations.Operation;
-import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
@@ -241,4 +241,15 @@ public interface ProcessInstanceApi {
@Manageable
@InvokeMode(SYNC)
CommonResponse checkInstanceApprover(@Validated @RequestBody BpmnProcessInstanceCheckApproverDTO dto);
+
+ /**
+ * 获取指定流程的日志
+ *
+ * @param dto
+ * @return
+ */
+ @Operation(summary = "获取指定流程的日志")
+ @PostMapping("/api/process/instance/log")
+ @InvokeMode(SYNC)
+ CommonResponse getProcessInstanceLog(@Validated @RequestBody BpmnProcessInstanceLogQueryDTO dto);
}
diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/enums/ApprovalMethodEnum.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/enums/ApprovalMethodEnum.java
index 81f213001..2d6451b8e 100644
--- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/enums/ApprovalMethodEnum.java
+++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/enums/ApprovalMethodEnum.java
@@ -1,5 +1,8 @@
package cn.axzo.workflow.common.enums;
+import java.util.Arrays;
+import java.util.Objects;
+
/**
* 审批方式枚举
*
@@ -48,4 +51,11 @@ public enum ApprovalMethodEnum {
public void setRemark(String remark) {
this.remark = remark;
}
+
+ public static ApprovalMethodEnum valueOfType(String type) {
+ return Arrays.stream(ApprovalMethodEnum.values())
+ .filter(i -> Objects.equals(i.getType(), type))
+ .findAny()
+ .orElse(null);
+ }
}
diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/enums/BpmnButtonEnum.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/enums/BpmnButtonEnum.java
index d9cc769c1..e7c72e8fd 100644
--- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/enums/BpmnButtonEnum.java
+++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/enums/BpmnButtonEnum.java
@@ -33,7 +33,7 @@ public enum BpmnButtonEnum {
*/
BPMN_COMMENT(6, "BPMN_COMMENT", "评论"),
/**
- * 回退按钮
+ * 退回按钮
*/
BPMN_ROLLBACK(7, "BPMN_ROLLBACK", "退回"),
/**
diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/enums/BpmnFlowNodeMode.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/enums/BpmnFlowNodeMode.java
index e812d2986..00bad8570 100644
--- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/enums/BpmnFlowNodeMode.java
+++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/enums/BpmnFlowNodeMode.java
@@ -1,6 +1,9 @@
package cn.axzo.workflow.common.enums;
+import java.util.Arrays;
+import java.util.Objects;
+
public enum BpmnFlowNodeMode {
GENERAL("GENERAL", "普通节点"),
OR("OR", "或签节点"),
@@ -35,4 +38,11 @@ public enum BpmnFlowNodeMode {
public void setDesc(String desc) {
this.desc = desc;
}
+
+ public static BpmnFlowNodeMode valueOfType(String type) {
+ return Arrays.stream(BpmnFlowNodeMode.values())
+ .filter(i -> Objects.equals(i.getType(), type))
+ .findAny()
+ .orElse(null);
+ }
}
diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/BpmnApproveConf.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/BpmnApproveConf.java
index abc5fe45e..ed9af9805 100644
--- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/BpmnApproveConf.java
+++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/BpmnApproveConf.java
@@ -3,18 +3,23 @@ package cn.axzo.workflow.common.model.request;
import cn.axzo.workflow.common.enums.AutoApprovalTypeEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
import lombok.Data;
-import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import javax.validation.Valid;
@ApiModel("JSON 版本的 BPMN 协议模型中流程配置管理")
@Data
-@NoArgsConstructor
+@AllArgsConstructor
@Accessors(chain = true)
public class BpmnApproveConf {
+ public BpmnApproveConf() {
+ this.supportBatchOperation = false;
+ this.userAgreeSignature = false;
+ }
+
/**
* 是否支持批量审批
*/
diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/BpmnButtonConf.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/BpmnButtonConf.java
index cf78a06ed..61f052ac0 100644
--- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/BpmnButtonConf.java
+++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/BpmnButtonConf.java
@@ -7,6 +7,7 @@ import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
+import java.util.ArrayList;
import java.util.List;
/**
@@ -25,25 +26,25 @@ public class BpmnButtonConf implements Serializable {
* 发起人的按钮配置信息, 需要给全量按钮的配置
*/
@ApiModelProperty(value = "发起人的按钮配置信息")
- private List initiator;
+ private List initiator = new ArrayList<>();
/**
* 当前审批人的按钮配置信息, JSON 格式
*/
@ApiModelProperty(value = "当前审批人的按钮配置信息")
- private List current;
+ private List current = new ArrayList<>();
/**
* 历史审批人的按钮配置信息, JSON 格式
*/
@ApiModelProperty(value = "历史审批人的按钮配置信息")
- private List history;
+ private List history = new ArrayList<>();
/**
* 抄送人的按钮配置信息, JSON 格式
*/
@ApiModelProperty(value = "抄送人的按钮配置信息")
- private List carbonCopy;
+ private List carbonCopy = new ArrayList<>();
public List getInitiator() {
return initiator;
diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/process/BpmnProcessInstanceLogQueryDTO.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/process/BpmnProcessInstanceLogQueryDTO.java
new file mode 100644
index 000000000..17e7ad583
--- /dev/null
+++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/process/BpmnProcessInstanceLogQueryDTO.java
@@ -0,0 +1,54 @@
+package cn.axzo.workflow.common.model.request.bpmn.process;
+
+import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * 查询流程实例日志
+ *
+ * @author wangli
+ * @since 2024-09-07 17:32
+ */
+@ApiModel("查询流程实例日志")
+@Data
+@Accessors(chain = true)
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+public class BpmnProcessInstanceLogQueryDTO {
+
+ /**
+ * 流程实例 ID
+ */
+ @ApiModelProperty(value = "流程实例 ID")
+ @NotBlank(message = "流程实例 ID 不能为空")
+ private String processInstanceId;
+
+ /**
+ * 谁来访问该实例日志,如果为空,则始终不就返回按钮信息
+ *
+ * 注意,为了确保历史审批数据的查询,需要将除 avatar 外的其他所有属性补全
+ */
+ @ApiModelProperty(value = "访问者信息", notes = "如果为空,则始终不就返回按钮信息")
+ private BpmnTaskDelegateAssigner visitor;
+
+ /**
+ * 返回结果中是否包含按钮
+ */
+ @ApiModelProperty(value = "返回结果中是否包含按钮", notes = "如果访问者为空,该属性为 true 时,同样也不会返回按钮")
+ private Boolean hasButton = false;
+
+ /**
+ * 是否需要加密(同一个实例的日志,在不同端[cms/oms]下,审批人的信息需要按一定规则进行隐藏控制)
+ */
+ @ApiModelProperty(value = "是否需要加密", notes = "同一个实例的日志,在不同端[cms/oms]下,审批人的信息需要按一定规则进行隐藏控制")
+ private Boolean encrypt;
+}
diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/AttachmentDTO.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/AttachmentDTO.java
index 0ce3b76f0..b71352af2 100644
--- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/AttachmentDTO.java
+++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/AttachmentDTO.java
@@ -3,7 +3,10 @@ package cn.axzo.workflow.common.model.request.bpmn.task;
import cn.axzo.workflow.common.enums.AttachmentTypeEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
import lombok.Data;
+import lombok.NoArgsConstructor;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@@ -16,6 +19,9 @@ import javax.validation.constraints.NotNull;
*/
@ApiModel("附件模型")
@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
public class AttachmentDTO {
/**
diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnOptionalNodeDTO.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnOptionalNodeDTO.java
index b5581813b..459bfb13e 100644
--- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnOptionalNodeDTO.java
+++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnOptionalNodeDTO.java
@@ -28,12 +28,12 @@ public class BpmnOptionalNodeDTO {
/**
* 节点id
*/
- private String processNodeId;
+ private String processActivityId;
/**
* 节点名称
*/
- private String processNodeName;
+ private String processActivityName;
/**
* 节点描述,用于页面展示
diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/response/bpmn/process/BpmnProcessInstanceLogVO.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/response/bpmn/process/BpmnProcessInstanceLogVO.java
new file mode 100644
index 000000000..4d2ad7731
--- /dev/null
+++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/response/bpmn/process/BpmnProcessInstanceLogVO.java
@@ -0,0 +1,143 @@
+package cn.axzo.workflow.common.model.response.bpmn.process;
+
+import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
+import cn.axzo.workflow.common.enums.WorkspaceType;
+import cn.axzo.workflow.common.model.request.bpmn.BpmnButtonConf;
+import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
+import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskInstanceLogVO;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 流程实例日志模型
+ *
+ * @author wangli
+ * @since 2024-09-07 17:07
+ */
+@ApiModel("流程实例日志模型")
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class BpmnProcessInstanceLogVO {
+ /**
+ * 流程实例的编号
+ */
+ @ApiModelProperty(value = "流程实例的编号", example = "1024")
+ private String id;
+
+ /**
+ * 流程名称
+ */
+ @ApiModelProperty(value = "流程名称", example = "权限点申请")
+ private String name;
+
+ /**
+ * 流程分类
+ */
+ @ApiModelProperty(value = "流程分类", notes = "关联的业务分类", example = "1")
+ private String category;
+
+ /**
+ * 审核状态
+ */
+ @ApiModelProperty(value = "审核状态(PROCESSING:审核中,APPROVED:已通过,REJECTED:已拒绝,CANCELLED:已取消)", example = "APPROVED")
+ private BpmnProcessInstanceResultEnum result;
+
+ /**
+ * 发起时间
+ */
+ @ApiModelProperty("发起时间")
+ private Date startTime;
+
+ /**
+ * 结束时间
+ */
+ @ApiModelProperty("结束时间")
+ private Date endTime;
+
+ /**
+ * 流程定义 KEY
+ */
+ @ApiModelProperty("流程定义 KEY")
+ private String processDefinitionKey;
+
+ /**
+ * 流程定义 ID
+ */
+ @ApiModelProperty("流程定义 ID")
+ private String processDefinitionId;
+
+ /**
+ * 业务的唯一标识
+ */
+ @ApiModelProperty(value = "业务的唯一标识", example = "1", notes = "例如说,请假申请的编号")
+ private String businessKey;
+
+ /**
+ * 流程最终状态
+ */
+ @ApiModelProperty("流程最终状态")
+ private String businessStatus;
+
+ /**
+ * 发起人
+ */
+ @ApiModelProperty("发起人")
+ private BpmnTaskDelegateAssigner initiator;
+
+ /**
+ * 当前流程发起租户
+ */
+ @ApiModelProperty("当前流程发起租户")
+ private String tenantId;
+
+ /**
+ * 是代运营的流程
+ */
+ @ApiModelProperty("是代运营的流程")
+ private Boolean agented;
+
+ /**
+ * 任务信息集合
+ */
+ @ApiModelProperty("任务信息集合")
+ private List tasks;
+
+ /**
+ * 当前实例对应模型的全局兜底按钮配置
+ */
+ @ApiModelProperty(value = "当前实例对应模型的全局兜底按钮配置")
+ private BpmnButtonConf defaultButtonConf;
+
+ /**
+ * 是否支持批量审批
+ */
+ @ApiModelProperty(value = "是否支持批量审批")
+ private Boolean supportBatchOperation;
+
+ /**
+ * 审批同意录入手写签名
+ */
+ @ApiModelProperty(value = "审批同意录入手写签名")
+ private Boolean userAgreeSignature;
+
+ /**
+ * 数据产生版本
+ */
+ @ApiModelProperty(value = "数据产生版本")
+ private String workflowEngineVersion;
+
+ /**
+ * 当前流程对应工作台类型
+ */
+ @ApiModelProperty(value = "工作台类型")
+ private WorkspaceType workspaceType;
+}
diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/response/bpmn/task/BpmnTaskInstanceLogVO.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/response/bpmn/task/BpmnTaskInstanceLogVO.java
new file mode 100644
index 000000000..32172360a
--- /dev/null
+++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/response/bpmn/task/BpmnTaskInstanceLogVO.java
@@ -0,0 +1,123 @@
+package cn.axzo.workflow.common.model.response.bpmn.task;
+
+import cn.axzo.workflow.common.enums.ApprovalMethodEnum;
+import cn.axzo.workflow.common.enums.BpmnFlowNodeMode;
+import cn.axzo.workflow.common.enums.BpmnFlowNodeType;
+import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
+import cn.axzo.workflow.common.model.request.bpmn.task.AttachmentDTO;
+import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 流程任务日志模型
+ *
+ * @author wangli
+ * @since 2024-09-07 17:08
+ */
+@ApiModel("流程任务日志模型")
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class BpmnTaskInstanceLogVO {
+
+ /**
+ * 审批任务 ID
+ */
+ @ApiModelProperty(value = "审批任务 ID")
+ private String taskId;
+ /**
+ * 审批任务节点定义KEY
+ */
+ @ApiModelProperty(value = "审批任务节点定义KEY")
+ private String taskDefinitionKey;
+ /**
+ * 审批任务节点名称
+ */
+ @ApiModelProperty(value = "审批任务节点名称")
+ private String name;
+ /**
+ * 任务创建时间
+ */
+ @ApiModelProperty(value = "任务创建时间")
+ private Date createTime;
+ /**
+ * 任务结束时间
+ */
+ @ApiModelProperty(value = "任务结束时间")
+ private Date endTime;
+ /**
+ * 审批方式
+ */
+ @ApiModelProperty(value = "审批方式")
+ private ApprovalMethodEnum approvalMethod;
+ /**
+ * 节点类型
+ */
+ @ApiModelProperty(value = "节点类型")
+ private BpmnFlowNodeType nodeType;
+ /**
+ * 审批任务节点的类型
+ */
+ @ApiModelProperty(value = "审批任务节点的类型")
+ private BpmnFlowNodeMode nodeMode;
+ /**
+ * 任务状态
+ */
+ @ApiModelProperty(value = "任务状态")
+ private BpmnProcessInstanceResultEnum result;
+
+ /**
+ * 操作描述
+ */
+ @ApiModelProperty(value = "操作描述")
+ private String operationDesc;
+ /**
+ * 审批建议
+ */
+ @ApiModelProperty(value = "审批建议")
+ private String advice;
+ /**
+ * 一些扩展信息
+ */
+ @ApiModelProperty(value = "一些扩展信息")
+ private String commentExt;
+ /**
+ * 图片列表
+ */
+ @ApiModelProperty(value = "图片列表")
+ private List imageList;
+ /**
+ * 附件列表
+ */
+ @ApiModelProperty(value = "附件列表")
+ private List fileList;
+ /**
+ * 手写签名地址
+ */
+ @ApiModelProperty(value = "手写签名地址")
+ private String signatureUrl;
+ /**
+ * 审批人快照信息
+ */
+ @ApiModelProperty(value = "审批人快照信息")
+ private BpmnTaskDelegateAssigner assigneeSnapshot;
+ /**
+ * 未完成节点多实例模式的审批人信息
+ */
+ @ApiModelProperty(value = "未完成节点多实例模式的审批人信息")
+ private List forecastAssignees;
+
+ public boolean isVirtual() {
+ return StringUtils.isBlank(this.taskId);
+ }
+}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/BpmnTaskRespCode.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/BpmnTaskRespCode.java
index 3fdbeea92..663f31544 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/BpmnTaskRespCode.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/BpmnTaskRespCode.java
@@ -37,6 +37,7 @@ public enum BpmnTaskRespCode implements IModuleRespCode {
TASK_TYPE_MISMATCH("020", "节点类型不匹配,当前节点类型:【{}】,指定节点类型:【{}】!"),
PROCESS_CANT_SET_ASSIGNEE("021", "当前审批状态不允许设置审批人"),
ASSIGNER_NUMBER_EXCEEDS_NUMBER_LIMIT("022", String.format("人员数量超过限制,节点审批人限制数量为: %d!", APPROVAL_ASSIGNER_LIMIT_NUMBER)),
+ BACK_TARGET_ACTIVITY_NOT_EXISTS("023", "回退到指定节点【{}】失败!"),
;
private final String code;
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/handler/ButtonConfTypeHandler.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/handler/ButtonConfTypeHandler.java
new file mode 100644
index 000000000..c235e42c9
--- /dev/null
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/handler/ButtonConfTypeHandler.java
@@ -0,0 +1,57 @@
+package cn.axzo.workflow.core.conf.handler;
+
+import cn.axzo.workflow.common.model.request.bpmn.BpmnButtonConf;
+import com.baomidou.mybatisplus.core.toolkit.Assert;
+import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.MappedJdbcTypes;
+import org.apache.ibatis.type.MappedTypes;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * BpmnButtonConf 数据映射转换
+ *
+ * @author wangli
+ * @since 2024-09-07 22:40
+ */
+@Slf4j
+@MappedTypes({List.class})
+@MappedJdbcTypes({JdbcType.VARCHAR})
+public class ButtonConfTypeHandler extends AbstractJsonTypeHandler {
+ private static ObjectMapper objectMapper = new ObjectMapper();
+
+ public ButtonConfTypeHandler(Class> type) {
+ if (log.isTraceEnabled()) {
+ log.trace("JacksonTypeHandler(" + type + ")");
+ }
+ Assert.notNull(type, "Type argument cannot be null", new Object[0]);
+ }
+
+ protected BpmnButtonConf parse(String json) {
+ try {
+ // 这里进行了json解析,同样在这里也可以进行字段查询后的处理,如对象内部的手机号字段的加密展示等
+ return objectMapper.readValue(json, new TypeReference() {
+ });
+ } catch (IOException var3) {
+ throw new RuntimeException(var3);
+ }
+ }
+
+ protected String toJson(BpmnButtonConf obj) {
+ try {
+ return objectMapper.writeValueAsString(obj);
+ } catch (JsonProcessingException var3) {
+ throw new RuntimeException(var3);
+ }
+ }
+
+ public static void setObjectMapper(ObjectMapper om) {
+ objectMapper = om;
+ }
+}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/handler/ListAssigneeTypeHandler.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/handler/ListAssigneeTypeHandler.java
new file mode 100644
index 000000000..cd54a7f40
--- /dev/null
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/handler/ListAssigneeTypeHandler.java
@@ -0,0 +1,57 @@
+package cn.axzo.workflow.core.conf.handler;
+
+import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
+import com.baomidou.mybatisplus.core.toolkit.Assert;
+import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.MappedJdbcTypes;
+import org.apache.ibatis.type.MappedTypes;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * BpmnTaskDelegateAssigner 数据映射转换
+ *
+ * @author wangli
+ * @since 2024-09-07 22:40
+ */
+@Slf4j
+@MappedTypes({List.class})
+@MappedJdbcTypes({JdbcType.VARCHAR})
+public class ListAssigneeTypeHandler extends AbstractJsonTypeHandler> {
+ private static ObjectMapper objectMapper = new ObjectMapper();
+
+ public ListAssigneeTypeHandler(Class> type) {
+ if (log.isTraceEnabled()) {
+ log.trace("JacksonTypeHandler(" + type + ")");
+ }
+ Assert.notNull(type, "Type argument cannot be null", new Object[0]);
+ }
+
+ protected List parse(String json) {
+ try {
+ // 这里进行了json解析,同样在这里也可以进行字段查询后的处理,如对象内部的手机号字段的加密展示等
+ return objectMapper.readValue(json, new TypeReference>() {
+ });
+ } catch (IOException var3) {
+ throw new RuntimeException(var3);
+ }
+ }
+
+ protected String toJson(List obj) {
+ try {
+ return objectMapper.writeValueAsString(obj);
+ } catch (JsonProcessingException var3) {
+ throw new RuntimeException(var3);
+ }
+ }
+
+ public static void setObjectMapper(ObjectMapper om) {
+ objectMapper = om;
+ }
+}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java
index 6acc44fa0..706c8af42 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java
@@ -1,8 +1,11 @@
package cn.axzo.workflow.core.engine.cmd;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskBackAuditDTO;
+import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
+import org.flowable.bpmn.model.BpmnModel;
+import org.flowable.bpmn.model.FlowElement;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.RuntimeService;
@@ -23,6 +26,7 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC;
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_COMPLETE_OPERATION_TYPE;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.BACKED;
+import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.BACK_TARGET_ACTIVITY_NOT_EXISTS;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.addComment;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.batchAddAttachment;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask;
@@ -36,7 +40,7 @@ public class CustomBackTaskCmd extends AbstractCommand implements Serializ
private final BpmnTaskBackAuditDTO dto;
- private final String operationDesc;
+ private static String operationDesc = "已回退";
@Override
public String paramToJsonString() {
@@ -51,17 +55,7 @@ public class CustomBackTaskCmd extends AbstractCommand implements Serializ
}
public CustomBackTaskCmd(BpmnTaskBackAuditDTO dto) {
- this(dto, null);
- }
-
- public CustomBackTaskCmd(BpmnTaskBackAuditDTO dto, String operationDesc) {
this.dto = dto;
- // 这里的不能直接使用字符串的比较,因为外部可能传入空字符串,比如发起人的通过时,就是传入的空字符串
- if (Objects.nonNull(operationDesc)) {
- this.operationDesc = operationDesc;
- } else {
- this.operationDesc = "已回退";
- }
}
@Override
@@ -77,11 +71,17 @@ public class CustomBackTaskCmd extends AbstractCommand implements Serializ
TaskEntity task = (TaskEntity) taskService.createTaskQuery().taskId(dto.getTaskId()).singleResult();
validTask(historicTaskInstance, task, dto.getApprover(), dto.getNodeTypes());
+ BpmnModel bpmnModel = processEngineConfiguration.getRepositoryService().getBpmnModel(historicTaskInstance.getProcessDefinitionId());
+ FlowElement flowElement = bpmnModel.getFlowElement(dto.getToActivityId());
+ if (Objects.isNull(flowElement)) {
+ throw new WorkflowEngineException(BACK_TARGET_ACTIVITY_NOT_EXISTS, dto.getToActivityId());
+ }
+
batchAddAttachment(commandContext, task.getProcessInstanceId(), dto.getTaskId(), dto.getAttachmentList(), dto.getApprover());
Authentication.setAuthenticatedUserId(dto.getApprover().buildAssigneeId());
addComment(commandContext, task, COMMENT_TYPE_ADVICE, dto.getAdvice());
- addComment(commandContext, task, COMMENT_TYPE_OPERATION_DESC, operationDesc);
+ addComment(commandContext, task, COMMENT_TYPE_OPERATION_DESC, operationDesc + flowElement.getName());
Authentication.setAuthenticatedUserId(null);
RuntimeService runtimeService = processEngineConfiguration.getRuntimeService();
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AsyncBackTaskJobHandler.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AsyncBackTaskJobHandler.java
index bfec5ab1a..ec466959c 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AsyncBackTaskJobHandler.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AsyncBackTaskJobHandler.java
@@ -14,8 +14,6 @@ import org.flowable.variable.api.delegate.VariableScope;
import java.util.Objects;
-import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_STARTER;
-
@Slf4j
public class AsyncBackTaskJobHandler extends AbstractExecuteWithLockJobHandler implements JobHandler {
@@ -37,14 +35,7 @@ public class AsyncBackTaskJobHandler extends AbstractExecuteWithLockJobHandler i
if (Objects.isNull(task)) {
return;
}
- CustomBackTaskCmd command;
- if (Objects.equals(task.getTaskDefinitionKey(), NODE_STARTER.getType())) {
- // 这里的 operationDesc 设置为“” 是为了在日志中不显示(已通过)
- command = new CustomBackTaskCmd(dto, "");
- } else {
- command = new CustomBackTaskCmd(dto);
- }
- processEngineConfiguration.getCommandExecutor().execute(command);
+ processEngineConfiguration.getCommandExecutor().execute(new CustomBackTaskCmd(dto));
}
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/type/TaskEntityEventHandle.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/type/TaskEntityEventHandle.java
index a221541a8..65597e5eb 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/type/TaskEntityEventHandle.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/entity/type/TaskEntityEventHandle.java
@@ -4,6 +4,7 @@ import cn.axzo.framework.jackson.utility.JSON;
import cn.axzo.workflow.common.enums.BpmnFlowNodeMode;
import cn.axzo.workflow.common.enums.BpmnFlowNodeType;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
+import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper;
import cn.axzo.workflow.core.engine.listener.entity.EntityEventHandle;
import cn.axzo.workflow.core.repository.entity.ExtAxProcessLog;
import cn.axzo.workflow.core.service.ExtAxProcessLogService;
@@ -19,6 +20,7 @@ import org.flowable.engine.RuntimeService;
import org.flowable.engine.impl.bpmn.behavior.MultiInstanceActivityBehavior;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.util.CommandContextUtil;
+import org.flowable.engine.impl.util.ProcessDefinitionUtil;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
@@ -186,26 +188,23 @@ public class TaskEntityEventHandle implements EntityEventHandle {
public void onInitialized(TaskEntity taskEntity) {
log.error("onInitialized");
+ BpmnMetaParserHelper.getButtonConfig(ProcessDefinitionUtil.getProcess(taskEntity.getProcessDefinitionId()), taskEntity.getTaskDefinitionKey())
+ .ifPresent(buttons -> {
+ ExtAxProcessLog queryLog = new ExtAxProcessLog();
+ queryLog.setProcessInstanceId(taskEntity.getProcessInstanceId());
+ queryLog.setTaskId(taskEntity.getId());
+
+ ExtAxProcessLog updateLog = new ExtAxProcessLog();
+ updateLog.setButtonConf(buttons);
+ processLogService.update(queryLog, updateLog);
+ });
}
public void onCreate(TaskEntity taskEntity) {
log.error("onCreate");
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
-// RuntimeService runtimeService = processEngineConfiguration.getRuntimeService();
-// BpmnTaskDelegateAssigner assignee;
-//
-// // 记录发起人
+ // 记录发起人
boolean isNodeStarter = Objects.equals(taskEntity.getTaskDefinitionKey(), NODE_STARTER.getType());
-// if (isNodeStarter) {
-// assignee = BpmnTaskDelegateAssigner.toObjectCompatible(runtimeService.getVariable(taskEntity.getProcessInstanceId(),
-// INTERNAL_INITIATOR));
-// if (Objects.isNull(assignee)) {
-// // 兼容历史数据
-// assignee = BpmnTaskDelegateAssigner.toObjectCompatible(runtimeService.getVariable(taskEntity.getProcessInstanceId(), OLD_INTERNAL_INITIATOR));
-// }
-// } else {
-// assignee = BpmnTaskDelegateAssigner.toObjectCompatible(runtimeService.getVariable(taskEntity.getProcessInstanceId(), INTERNAL_TASK_RELATION_ASSIGNEE_INFO + taskEntity.getId()));
-// }
RepositoryService repositoryService = processEngineConfiguration.getRepositoryService();
BpmnModel bpmnModel = repositoryService.getBpmnModel(taskEntity.getProcessDefinitionId());
@@ -221,13 +220,6 @@ public class TaskEntityEventHandle implements EntityEventHandle {
log.setNodeMode((isNodeStarter ? BpmnFlowNodeMode.GENERAL : getNodeMode(flowElement)).getType());
log.setTaskId(taskEntity.getId());
log.setOperationDesc(PENDING.getDesc());
-// if (Objects.nonNull(assignee)) {
-// log.setAssigneeFull(assignee);
-// log.setAssigneeId(Long.valueOf(assignee.getPersonId()));
-// log.setAssigneeTenantId(assignee.getTenantId());
-// log.setAssigneeName(assignee.getAssignerName());
-// log.setAssigneeOuId(assignee.getOuId());
-// }
log.setStartTime(taskEntity.getCreateTime());
log.setStatus(PROCESSING.getStatus());
@@ -246,4 +238,5 @@ public class TaskEntityEventHandle implements EntityEventHandle {
}
return node;
}
+
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/repository/entity/ExtAxProcessLog.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/repository/entity/ExtAxProcessLog.java
index 569569c39..c78bdfe7e 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/repository/entity/ExtAxProcessLog.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/repository/entity/ExtAxProcessLog.java
@@ -1,7 +1,10 @@
package cn.axzo.workflow.core.repository.entity;
import cn.axzo.framework.data.mybatisplus.model.BaseEntity;
+import cn.axzo.workflow.common.model.request.bpmn.BpmnButtonConf;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
+import cn.axzo.workflow.core.conf.handler.ButtonConfTypeHandler;
+import cn.axzo.workflow.core.conf.handler.ListAssigneeTypeHandler;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
@@ -68,7 +71,7 @@ public class ExtAxProcessLog extends BaseEntity {
/**
* 审批人对象信息
*/
- @TableField(typeHandler = JacksonTypeHandler.class)
+ @TableField(typeHandler = ListAssigneeTypeHandler.class)
private List assigneeFull;
/**
* 审批人标识
@@ -95,9 +98,10 @@ public class ExtAxProcessLog extends BaseEntity {
*/
private Date endTime;
/**
- * 已回退标志
+ * 节点按钮的全量配置
*/
- private Boolean returned;
+ @TableField(typeHandler = ButtonConfTypeHandler.class)
+ private BpmnButtonConf buttonConf;
/**
* 任务状态:审批中/通过/驳回/转交/加签/退回
*/
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessInstanceService.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessInstanceService.java
index 82e629a77..4de469d2a 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessInstanceService.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessInstanceService.java
@@ -7,18 +7,21 @@ import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCar
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCheckApproverDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCreateDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCreateWithFormDTO;
+import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceLogQueryDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceMyPageReqVO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceQueryDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.HistoricProcessInstanceSearchDTO;
import cn.axzo.workflow.common.model.response.BpmPageResult;
import cn.axzo.workflow.common.model.response.bpmn.BatchOperationResultVO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceAdminPageItemVO;
+import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceLogVO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstancePageItemVO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceVO;
import cn.axzo.workflow.common.model.response.bpmn.process.HistoricProcessInstanceVO;
import cn.axzo.workflow.common.model.response.bpmn.process.ProcessNodeDetailVO;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.flowable.engine.history.HistoricProcessInstance;
+import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.form.api.FormInfo;
import javax.annotation.Nullable;
@@ -107,7 +110,7 @@ public interface BpmnProcessInstanceService {
* 获得流程实例
*
* @param processDefinitionId 流程实例的编号
- * @param status 状态
+ * @param status 状态
* @link SuspensionState.ACTIVE.getStateCode()
*/
Boolean updateProcessStatus(String processDefinitionId, Integer status);
@@ -143,9 +146,28 @@ public interface BpmnProcessInstanceService {
*/
List getProcessInstanceNodeForecast(String processInstanceId, String tenantId);
+ /**
+ * 对指定流程的指定节点开始推送未来的结点,并结合变量计算正确的分支
+ *
+ * @param processInstanceId 实例编号
+ * @param startNodeDefinitionKey 从该节点开始推断后续的节点
+ * @param containSelf 是否包含起始节点
+ * @param checkAliveThrowException 如果给的实例编号已到终态,不会执行推测,用该参数为 true 时,抛出实例完结的异常信息,如果为 false时,直接返回空集合
+ * @return
+ */
+ List getProcessInstanceNodeForecastWithSpecifyTaskDefinitionKey(String processInstanceId, ProcessInstance instance, String startNodeDefinitionKey, Boolean containSelf, Boolean checkAliveThrowException);
+
List getProcessInstanceNodeFilterForecast(String processInstanceId, String tenantId, List nodeDefinitionKeys);
List getTenantIds();
Boolean checkInstanceApprover(BpmnProcessInstanceCheckApproverDTO dto);
+
+ /**
+ * 获取指定流程实例的日志
+ *
+ * @param dto
+ * @return
+ */
+ BpmnProcessInstanceLogVO getProcessInstanceLog(BpmnProcessInstanceLogQueryDTO dto);
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessInstanceServiceImpl.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessInstanceServiceImpl.java
index 50ef58cf9..46fa043d0 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessInstanceServiceImpl.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessInstanceServiceImpl.java
@@ -1,8 +1,14 @@
package cn.axzo.workflow.core.service.impl;
import cn.axzo.workflow.common.constant.BpmnConstants;
+import cn.axzo.workflow.common.enums.ApprovalMethodEnum;
+import cn.axzo.workflow.common.enums.AttachmentTypeEnum;
import cn.axzo.workflow.common.enums.BpmnFlowNodeMode;
+import cn.axzo.workflow.common.enums.BpmnFlowNodeType;
+import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
import cn.axzo.workflow.common.enums.WorkspaceType;
+import cn.axzo.workflow.common.model.request.BpmnApproveConf;
+import cn.axzo.workflow.common.model.request.bpmn.BpmnButtonConf;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAbortDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAdminPageReqVO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCancelDTO;
@@ -10,9 +16,11 @@ import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCar
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCheckApproverDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCreateDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCreateWithFormDTO;
+import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceLogQueryDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceMyPageReqVO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceQueryDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.HistoricProcessInstanceSearchDTO;
+import cn.axzo.workflow.common.model.request.bpmn.task.AttachmentDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.common.model.request.category.CategorySearchDTO;
import cn.axzo.workflow.common.model.response.BpmPageResult;
@@ -20,10 +28,12 @@ import cn.axzo.workflow.common.model.response.bpmn.BatchOperationItemResultVO;
import cn.axzo.workflow.common.model.response.bpmn.BatchOperationResultVO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessDefinitionVO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceAdminPageItemVO;
+import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceLogVO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstancePageItemVO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceVO;
import cn.axzo.workflow.common.model.response.bpmn.process.HistoricProcessInstanceVO;
import cn.axzo.workflow.common.model.response.bpmn.process.ProcessNodeDetailVO;
+import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskInstanceLogVO;
import cn.axzo.workflow.common.model.response.category.CategoryItemVO;
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
import cn.axzo.workflow.core.common.utils.BpmnCollectionUtils;
@@ -34,10 +44,12 @@ import cn.axzo.workflow.core.engine.cmd.CustomCancelProcessInstanceCmd;
import cn.axzo.workflow.core.engine.cmd.CustomCarbonCopyUserSelectorCmd;
import cn.axzo.workflow.core.engine.cmd.CustomForecastUserTaskAssigneeCmd;
import cn.axzo.workflow.core.engine.listener.EngineExecutionStartListener;
+import cn.axzo.workflow.core.repository.entity.ExtAxProcessLog;
import cn.axzo.workflow.core.service.BpmnProcessDefinitionService;
import cn.axzo.workflow.core.service.BpmnProcessInstanceService;
import cn.axzo.workflow.core.service.CategoryService;
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
+import cn.axzo.workflow.core.service.ExtAxProcessLogService;
import cn.axzo.workflow.core.service.converter.BpmnHistoricProcessInstanceConverter;
import cn.axzo.workflow.core.service.converter.BpmnHistoricTaskInstanceConverter;
import cn.axzo.workflow.core.service.converter.BpmnProcessInstanceAdminPageItemConverter;
@@ -77,6 +89,7 @@ import org.flowable.engine.runtime.NativeActivityInstanceQuery;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.engine.runtime.ProcessInstanceBuilder;
import org.flowable.engine.runtime.ProcessInstanceQuery;
+import org.flowable.engine.task.Attachment;
import org.flowable.form.api.FormInfo;
import org.flowable.spring.SpringProcessEngineConfiguration;
import org.flowable.task.api.Task;
@@ -95,6 +108,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -187,12 +201,14 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
@Resource
@Lazy
private BpmnProcessInstanceService bpmnProcessInstanceService;
+ @Resource
+ private ExtAxProcessLogService processLogService;
@Override
public HistoricProcessInstance getProcessInstanceByBusinessKey(String businessKey, @Nullable String tenantId,
@Nullable Boolean hasVariable) {
HistoricProcessInstanceQuery query =
- historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(businessKey);
+ historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(businessKey);
if (Boolean.TRUE.equals(hasVariable)) {
query.includeProcessVariables();
}
@@ -205,7 +221,7 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
@Override
public BpmPageResult getMyProcessInstancePage(@Valid BpmnProcessInstanceMyPageReqVO dto) {
HistoricProcessInstanceQuery query =
- historyService.createHistoricProcessInstanceQuery().processInstanceTenantId(dto.getTenantId());
+ historyService.createHistoricProcessInstanceQuery().processInstanceTenantId(dto.getTenantId());
if (StringUtils.isNotBlank(dto.getName())) {
query.processInstanceName(dto.getName());
}
@@ -234,7 +250,7 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
query.processInstanceTenantId(dto.getTenantId());
}
List instances = query.orderByProcessInstanceStartTime().desc()
- .listPage((dto.getPageNo() - 1) * dto.getPageSize(), dto.getPageSize());
+ .listPage((dto.getPageNo() - 1) * dto.getPageSize(), dto.getPageSize());
if (CollectionUtils.isEmpty(instances)) {
return BpmPageResult.empty();
@@ -343,11 +359,11 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
// 设置流程名字
ProcessInstanceBuilder instanceBuilder = runtimeService.createProcessInstanceBuilder()
- .processDefinitionId(definition.getId())
- .businessKey(dto.getBusinessKey())
- .variables(dto.getVariables())
- .name(name)
- .overrideProcessDefinitionTenantId(dto.getTenantId());
+ .processDefinitionId(definition.getId())
+ .businessKey(dto.getBusinessKey())
+ .variables(dto.getVariables())
+ .name(name)
+ .overrideProcessDefinitionTenantId(dto.getTenantId());
ProcessInstance instance;
if (dto.getAsync()) {
// 异步开始
@@ -363,8 +379,8 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
@Override
public String createProcessInstanceWithForm(BpmnProcessInstanceCreateWithFormDTO dto) {
BpmnProcessDefinitionVO definition =
- processDefinitionService.getActiveProcessDefinitionByKey(dto.getProcessDefinitionKey(),
- dto.getInitiator().getTenantId());
+ processDefinitionService.getActiveProcessDefinitionByKey(dto.getProcessDefinitionKey(),
+ dto.getInitiator().getTenantId());
// 校验流程定义
if (definition == null) {
throw new WorkflowEngineException(PROCESS_DEFINITION_KEY_NOT_EXISTS, dto.getProcessDefinitionKey());
@@ -378,11 +394,11 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
// 设置流程实例的开始人,参考https://wenku.baidu.com/view/5538062e7a563c1ec5da50e2524de518964bd3f9.html
Authentication.setAuthenticatedUserId(dto.getInitiator().buildAssigneeId());
String name = StringUtils.isNotBlank(dto.getCustomProcessInstanceName()) ?
- dto.getCustomProcessInstanceName()
- : definition.getName();
+ dto.getCustomProcessInstanceName()
+ : definition.getName();
ProcessInstance instance = runtimeService.startProcessInstanceWithForm(definition.getId(),
- dto.getOutcome(), dto.getVariables(), name);
+ dto.getOutcome(), dto.getVariables(), name);
Authentication.setAuthenticatedUserId(null);
return instance.getProcessInstanceId();
}
@@ -399,7 +415,7 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
commandExecutor.execute(new CustomCancelProcessInstanceAsyncCmd(dto));
} else {
commandExecutor.execute(new CustomCancelProcessInstanceCmd(dto.getProcessInstanceId(), dto.getTenantId(),
- dto.getReason(), dto.getInitiator(), extAxHiTaskInstService));
+ dto.getReason(), dto.getInitiator(), extAxHiTaskInstService));
}
return true;
}
@@ -412,7 +428,7 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
commandExecutor.execute(new CustomAbortProcessInstanceAsyncCmd(dto));
} else {
commandExecutor.execute(new CustomAbortProcessInstanceCmd(dto.getProcessInstanceId(), dto.getTenantId(),
- dto.getReason(), extAxHiTaskInstService));
+ dto.getReason(), extAxHiTaskInstService));
}
return true;
}
@@ -461,13 +477,13 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
NativeHistoricProcessInstanceQuery query = historyService.createNativeHistoricProcessInstanceQuery();
String tableName = managementService.getTableName(HistoricProcessInstance.class);
StringBuilder baseQuerySql = new StringBuilder("SELECT RES.*, ")
- .append("DEF.KEY_ as PROC_DEF_KEY_,")
- .append("DEF.NAME_ as PROC_DEF_NAME_,")
- .append("DEF.VERSION_ as PROC_DEF_VERSION_,")
- .append("DEF.DEPLOYMENT_ID_ as DEPLOYMENT_ID_")
- .append(" FROM ").append(tableName)
- .append(" RES LEFT OUTER JOIN ACT_RE_PROCDEF DEF ON RES.PROC_DEF_ID_ = DEF.ID_")
- .append(" WHERE 1 = 1");
+ .append("DEF.KEY_ as PROC_DEF_KEY_,")
+ .append("DEF.NAME_ as PROC_DEF_NAME_,")
+ .append("DEF.VERSION_ as PROC_DEF_VERSION_,")
+ .append("DEF.DEPLOYMENT_ID_ as DEPLOYMENT_ID_")
+ .append(" FROM ").append(tableName)
+ .append(" RES LEFT OUTER JOIN ACT_RE_PROCDEF DEF ON RES.PROC_DEF_ID_ = DEF.ID_")
+ .append(" WHERE 1 = 1");
if (StringUtils.isNotBlank(dto.getProcessInstanceId())) {
List ids = Lists.newArrayList(dto.getProcessInstanceId().replaceAll(" ", "").split(","));
baseQuerySql.append(" AND RES.PROC_INST_ID_ IN (");
@@ -519,8 +535,8 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
baseQuerySql.append(" ORDER BY RES.START_TIME_ DESC ");
List instances = query.sql(baseQuerySql.toString())
- .listPage((dto.getPageNo() - 1) * dto.getPageSize(),
- dto.getPageSize());
+ .listPage((dto.getPageNo() - 1) * dto.getPageSize(),
+ dto.getPageSize());
baseQuerySql.replace(7, 163, "count(1)");
NativeHistoricProcessInstanceQuery countSqlQuery = query.sql(baseQuerySql.toString());
@@ -529,8 +545,8 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
}
List processingInstanceIds =
- instances.stream().filter(i -> Objects.equals(PROCESSING.getStatus(), i.getBusinessStatus()))
- .map(HistoricProcessInstance::getId).distinct().collect(Collectors.toList());
+ instances.stream().filter(i -> Objects.equals(PROCESSING.getStatus(), i.getBusinessStatus()))
+ .map(HistoricProcessInstance::getId).distinct().collect(Collectors.toList());
Map> instanceFlowElementMap = new HashMap<>();
processingInstanceIds.forEach(i -> {
// 查询每个流程推测出来的总节点数
@@ -543,13 +559,13 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
Map leastEndActivityMap = getInstanceLastActivity(processingInstanceIds);
List categories = instances.stream().map(HistoricProcessInstance::getProcessDefinitionKey)
- .distinct().collect(Collectors.toList());
+ .distinct().collect(Collectors.toList());
Map categoryLabelMap = categoryService.listByValue(BPM_MODEL_CATEGORY, categories)
- .stream().collect(Collectors.toMap(CategoryItemVO::getValue, Function.identity(), (s, t) -> s));
+ .stream().collect(Collectors.toMap(CategoryItemVO::getValue, Function.identity(), (s, t) -> s));
List vos = instanceAdminPageItemConverter.toVos(instances,
- instanceFlowElementMap, liveActivityMap, leastEndActivityMap,
- categoryLabelMap);
+ instanceFlowElementMap, liveActivityMap, leastEndActivityMap,
+ categoryLabelMap);
return new BpmPageResult<>(vos, countSqlQuery.count());
}
@@ -567,10 +583,10 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
String tableName = managementService.getTableName(ActivityInstanceEntity.class);
StringBuilder querySql = new StringBuilder();
querySql.append("SELECT * FROM (")
- .append("SELECT *, ROW_NUMBER() OVER (PARTITION BY PROC_INST_ID_ ORDER BY START_TIME_ DESC) AS rn ")
- .append(" FROM ")
- .append(tableName)
- .append(" WHERE PROC_INST_ID_ in (");
+ .append("SELECT *, ROW_NUMBER() OVER (PARTITION BY PROC_INST_ID_ ORDER BY START_TIME_ DESC) AS rn ")
+ .append(" FROM ")
+ .append(tableName)
+ .append(" WHERE PROC_INST_ID_ in (");
for (int i = 0; i < processInstanceIds.size(); i++) {
querySql.append("#{processInstanceId_").append(i).append("}");
if (i < processInstanceIds.size() - 1) {
@@ -584,8 +600,8 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
}
querySql.append(") as t WHERE rn = 1");
return nativeQuery.sql(querySql.toString()).list().stream()
- .collect(Collectors.toMap(ActivityInstance::getProcessInstanceId, Function.identity(),
- (s, t) -> s));
+ .collect(Collectors.toMap(ActivityInstance::getProcessInstanceId, Function.identity(),
+ (s, t) -> s));
}
@@ -601,7 +617,7 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
public HistoricProcessInstance getHistoricProcessInstanceByBusinessKey(String businessKey, String tenantId) {
HistoricProcessInstanceQuery query =
- historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(businessKey);
+ historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(businessKey);
if (StringUtils.isNotBlank(tenantId)) {
query.processInstanceTenantId(tenantId);
}
@@ -615,7 +631,7 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
processInstance = getProcessInstance(dto.getProcessInstanceId(), dto.getTenantId(), dto.getHasVariable());
} else if (StringUtils.isNotBlank(dto.getBusinessKey())) {
processInstance = getProcessInstanceByBusinessKey(dto.getBusinessKey(), dto.getTenantId(),
- dto.getHasVariable());
+ dto.getHasVariable());
}
// 获得流程实例
@@ -624,10 +640,10 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
}
// 获得流程定义
BpmnProcessDefinitionVO processDefinition = processDefinitionService
- .getProcessDefinition(processInstance.getProcessDefinitionId());
+ .getProcessDefinition(processInstance.getProcessDefinitionId());
if (Objects.isNull(processDefinition)) {
throw new WorkflowEngineException(PROCESS_DEFINITION_ID_NOT_EXISTS,
- processInstance.getProcessDefinitionId());
+ processInstance.getProcessDefinitionId());
}
Object tempAssigner = null;
@@ -641,10 +657,10 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
} else {
List variableInstances = historyService.createHistoricVariableInstanceQuery()
- .processInstanceId(processInstance.getId()).list();
+ .processInstanceId(processInstance.getId()).list();
for (HistoricVariableInstance i : variableInstances) {
if (Objects.equals(i.getVariableName(), INTERNAL_INITIATOR) || Objects.equals(i.getVariableName(),
- OLD_INTERNAL_INITIATOR)) {
+ OLD_INTERNAL_INITIATOR)) {
tempAssigner = i.getValue();
}
if (Objects.equals(i.getVariableName(), WORKFLOW_ENGINE_VERSION)) {
@@ -658,17 +674,17 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
}
List runningTasks = taskService.createTaskQuery().processInstanceId(processInstance.getId())
- .active()
- .orderByTaskCreateTime()
- .desc()
- .list();
+ .active()
+ .orderByTaskCreateTime()
+ .desc()
+ .list();
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId());
return instanceConverter.toVo(processInstance, processDefinition,
- getButtonConfig(bpmnModel.getMainProcess()),
- getProcessApproveConf(bpmnModel.getMainProcess()),
- BpmnTaskDelegateAssigner.toObjectCompatible(tempAssigner), version, categoryService.get(BPM_MODEL_CATEGORY,
- processInstance.getProcessDefinitionKey()), runningTasks);
+ getButtonConfig(bpmnModel.getMainProcess()),
+ getProcessApproveConf(bpmnModel.getMainProcess()),
+ BpmnTaskDelegateAssigner.toObjectCompatible(tempAssigner), version, categoryService.get(BPM_MODEL_CATEGORY,
+ processInstance.getProcessDefinitionKey()), runningTasks);
}
/**
@@ -679,7 +695,7 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
*/
public Map getProcessInstanceMap(Set ids) {
return BpmnCollectionUtils.convertMap(getProcessInstances(ids),
- ProcessInstance::getProcessInstanceId);
+ ProcessInstance::getProcessInstanceId);
}
@@ -691,19 +707,19 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
*/
public Map getHistoricProcessInstanceMap(Set ids) {
return BpmnCollectionUtils.convertMap(getHistoricProcessInstances(ids),
- HistoricProcessInstance::getId);
+ HistoricProcessInstance::getId);
}
public List getHistoricProcessInstances(Set ids) {
HistoricProcessInstanceQuery historicProcessInstanceQuery =
- historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids);
+ historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids);
return historicProcessInstanceQuery.list();
}
@Override
public ObjectNode getProcessInstanceGraphical(String processInstanceId, @Nullable String tenantId) {
HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery()
- .processInstanceId(processInstanceId);
+ .processInstanceId(processInstanceId);
if (StringUtils.isNotBlank(tenantId)) {
query.processInstanceTenantId(tenantId);
}
@@ -714,7 +730,7 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
List activityInstances =
- historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).list();
+ historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).list();
Set completedActivityInstances = new HashSet<>();
Set currentElements = new HashSet<>();
@@ -729,13 +745,13 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
}
// Gather completed flows
List completedFlows = graphicService.gatherCompletedFlows(completedActivityInstances, currentElements
- , bpmnModel);
+ , bpmnModel);
Set completedElements = new HashSet<>(completedActivityInstances);
completedElements.addAll(completedFlows);
ObjectNode displayNode = graphicService.processProcessElements(bpmnModel, completedElements, currentElements,
- new ArrayList<>(), processInstanceId);
+ new ArrayList<>(), processInstanceId);
if (!CollectionUtils.isEmpty(completedActivityInstances)) {
ArrayNode completedActivities = displayNode.putArray("completedActivities");
for (String completed : completedActivityInstances) {
@@ -766,30 +782,30 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
StringBuilder baseQuerySql = new StringBuilder("SELECT a.* FROM ").append(tableName).append(" a");
if (StringUtils.isNotBlank(dto.getCategory())) {
baseQuerySql.append(" LEFT JOIN ACT_RE_PROCDEF b ON a.PROC_DEF_ID_ = b.ID_ ")
- .append(sqlConnectors(baseQuerySql))
- .append(" b.CATEGORY_ = #{category}");
+ .append(sqlConnectors(baseQuerySql))
+ .append(" b.CATEGORY_ = #{category}");
query.parameter("category", dto.getCategory());
}
if (StringUtils.isNotBlank(dto.getSearchKey())) {
baseQuerySql.append(sqlConnectors(baseQuerySql))
- .append(" (a.BUSINESS_KEY_ LIKE #{searchKey}")
- .append(" or")
- .append(" a.NAME_ LIKE #{searchKey})");
+ .append(" (a.BUSINESS_KEY_ LIKE #{searchKey}")
+ .append(" or")
+ .append(" a.NAME_ LIKE #{searchKey})");
query.parameter("searchKey", "%" + dto.getSearchKey() + "%");
}
if (StringUtils.isNotBlank(dto.getResult())) {
baseQuerySql.append(sqlConnectors(baseQuerySql))
- .append(" a.BUSINESS_STATUS_ = #{result}");
+ .append(" a.BUSINESS_STATUS_ = #{result}");
query.parameter("result", dto.getResult());
}
if (Objects.nonNull(dto.getTenantId())) {
baseQuerySql.append(sqlConnectors(baseQuerySql))
- .append(" a.TENANT_ID_ = #{tenantId}");
+ .append(" a.TENANT_ID_ = #{tenantId}");
query.parameter("tenantId", dto.getTenantId());
}
if (!CollectionUtils.isEmpty(dto.getUserIds())) {
baseQuerySql.append(sqlConnectors(baseQuerySql))
- .append(" a.START_USER_ID_ in (");
+ .append(" a.START_USER_ID_ in (");
for (int i = 0; i < dto.getUserIds().size(); i++) {
baseQuerySql.append("#{userId").append(i).append("}");
if (i < dto.getUserIds().size() - 1) {
@@ -801,20 +817,20 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
}
if (Objects.nonNull(dto.getStartBeginTime()) && Objects.nonNull(dto.getStartEndTime())) {
baseQuerySql.append(sqlConnectors(baseQuerySql))
- .append(" a.START_TIME_ between #{startBeginTime} and #{startEndTime}");
+ .append(" a.START_TIME_ between #{startBeginTime} and #{startEndTime}");
query.parameter("startBeginTime", dto.getStartBeginTime());
query.parameter("startEndTime", dto.getStartEndTime());
}
if (Objects.nonNull(dto.getFinishedBeginTime()) && Objects.nonNull(dto.getFinishedEndTime())) {
baseQuerySql.append(sqlConnectors(baseQuerySql))
- .append(" a.END_TIME_ between #{finishedBeginTime} and #{finishedEndTime}");
+ .append(" a.END_TIME_ between #{finishedBeginTime} and #{finishedEndTime}");
query.parameter("finishedBeginTime", dto.getFinishedBeginTime());
query.parameter("finishedEndTime", dto.getFinishedEndTime());
}
baseQuerySql.append(" ORDER BY a.START_TIME_ DESC");
NativeHistoricProcessInstanceQuery dataSqlQuery = query.sql(baseQuerySql.toString());
List instances = dataSqlQuery
- .listPage((dto.getPageNo() - 1) * dto.getPageSize(), dto.getPageSize());
+ .listPage((dto.getPageNo() - 1) * dto.getPageSize(), dto.getPageSize());
if (CollectionUtils.isEmpty(instances)) {
return BpmPageResult.empty();
}
@@ -822,17 +838,17 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
NativeHistoricProcessInstanceQuery countSqlQuery = query.sql(countSql(baseQuerySql));
if (StringUtils.isNotBlank(dto.getCategory())) {
return new BpmPageResult(historicProcessInstanceConverter.toVos(instances, dto.getCategory()),
- countSqlQuery.count());
+ countSqlQuery.count());
} else {
Set procDefIds = new HashSet<>();
instances.forEach(i -> procDefIds.add(i.getProcessDefinitionId()));
Map defCategoryMap =
- repositoryService.createProcessDefinitionQuery().processDefinitionIds(procDefIds).list()
- .stream().collect(Collectors.toMap(ProcessDefinition::getId,
- ProcessDefinition::getCategory, (s, t) -> s));
+ repositoryService.createProcessDefinitionQuery().processDefinitionIds(procDefIds).list()
+ .stream().collect(Collectors.toMap(ProcessDefinition::getId,
+ ProcessDefinition::getCategory, (s, t) -> s));
List vos = new ArrayList<>();
instances.forEach(i -> vos.add(historicProcessInstanceConverter.toVo(i,
- defCategoryMap.getOrDefault(i.getProcessDefinitionId(), ""))));
+ defCategoryMap.getOrDefault(i.getProcessDefinitionId(), ""))));
return new BpmPageResult(vos, countSqlQuery.count());
}
}
@@ -844,10 +860,34 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
return getProcessInstanceNodeFilterForecast(processInstanceId, tenantId, Collections.emptyList());
}
+ @Override
+ public List getProcessInstanceNodeForecastWithSpecifyTaskDefinitionKey(String processInstanceId,
+ ProcessInstance instance,
+ String startNodeDefinitionKey,
+ Boolean containSelf,
+ Boolean checkAliveThrowException) {
+ if (Objects.isNull(instance)) {
+ instance = runtimeService.createProcessInstanceQuery()
+ .processInstanceId(processInstanceId).singleResult();
+ if (Objects.isNull(instance)) {
+ if (checkAliveThrowException) {
+ throw new WorkflowEngineException(RUNNING_INSTANCE_ONLY_FORECAST);
+ } else {
+ return Collections.emptyList();
+ }
+ }
+ }
+
+ List flowElements = forecastService.performProcessForecasting(instance.getProcessInstanceId(), instance, startNodeDefinitionKey, containSelf);
+
+ return buildNodeDetailVos(processInstanceId, Collections.emptyList(), instance, flowElements);
+ }
+
+
@Override
public List getProcessInstanceNodeFilterForecast(String processInstanceId, String tenantId, List nodeDefinitionKeys) {
ProcessInstanceQuery query = runtimeService.createProcessInstanceQuery()
- .processInstanceId(processInstanceId);
+ .processInstanceId(processInstanceId);
if (StringUtils.isNotBlank(tenantId)) {
query.processInstanceTenantId(tenantId);
}
@@ -857,31 +897,35 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
}
List flowElements = forecastService.performProcessForecasting(processInstanceId, instance);
+ return buildNodeDetailVos(processInstanceId, nodeDefinitionKeys, instance, flowElements);
+ }
+
+ private List buildNodeDetailVos(String processInstanceId, List nodeDefinitionKeys, ProcessInstance instance, List flowElements) {
BpmnModel bpmnModel = repositoryService.getBpmnModel(instance.getProcessDefinitionId());
List resultList = new ArrayList<>(flowElements.size());
// 发起人节点,也是一个 UserTask 节点, 所以这里默认就包含了发起人节点
flowElements.stream()
- .filter(i -> (i instanceof UserTask || i instanceof ReceiveTask || i instanceof ServiceTask))
- .forEach(i -> {
- ProcessNodeDetailVO node = new ProcessNodeDetailVO();
- node.setForecastAssigners(Collections.emptyList());
- // 每个节点设置的按钮配置
- getButtonConfig(bpmnModel.getMainProcess(), i.getId()).ifPresent(node::setButtonConf);
- // 设置审批方式
- getApprovalMethod(i).ifPresent(node::setApprovalMethod);
- getNodeType(i).ifPresent(node::setNodeType);
- if (Objects.equals(NODE_STARTER.getType(), i.getId())) {
- node.setNodeType(NODE_STARTER);
- }
- node.setNodeMode(GENERAL);
- node.setId(i.getId()).setName(i.getName());
- if (i instanceof UserTask) {
- parseUserTask(processInstanceId, (UserTask) i, node, nodeDefinitionKeys);
- } else if (i instanceof ServiceTask) {
- parseServiceTask(processInstanceId, (ServiceTask) i, node, nodeDefinitionKeys);
- }
- resultList.add(node);
- });
+ .filter(i -> (i instanceof UserTask || i instanceof ReceiveTask || i instanceof ServiceTask))
+ .forEach(i -> {
+ ProcessNodeDetailVO node = new ProcessNodeDetailVO();
+ node.setForecastAssigners(Collections.emptyList());
+ // 每个节点设置的按钮配置
+ getButtonConfig(bpmnModel.getMainProcess(), i.getId()).ifPresent(node::setButtonConf);
+ // 设置审批方式
+ getApprovalMethod(i).ifPresent(node::setApprovalMethod);
+ getNodeType(i).ifPresent(node::setNodeType);
+ if (Objects.equals(NODE_STARTER.getType(), i.getId())) {
+ node.setNodeType(NODE_STARTER);
+ }
+ node.setNodeMode(GENERAL);
+ node.setId(i.getId()).setName(i.getName());
+ if (i instanceof UserTask) {
+ parseUserTask(processInstanceId, (UserTask) i, node, nodeDefinitionKeys);
+ } else if (i instanceof ServiceTask) {
+ parseServiceTask(processInstanceId, (ServiceTask) i, node, nodeDefinitionKeys);
+ }
+ resultList.add(node);
+ });
return resultList;
}
@@ -892,10 +936,10 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
return;
}
getCarbonCopyConfigs(i).ifPresent(carbons ->
- node.setForecastAssigners(springProcessEngineConfiguration.getCommandExecutor()
- .execute(new CustomCarbonCopyUserSelectorCmd(processInstanceId, carbons,
- i, engineExecutionStartListener,
- historicTaskInstanceConverter, serviceVersion))));
+ node.setForecastAssigners(springProcessEngineConfiguration.getCommandExecutor()
+ .execute(new CustomCarbonCopyUserSelectorCmd(processInstanceId, carbons,
+ i, engineExecutionStartListener,
+ historicTaskInstanceConverter, serviceVersion))));
}
private void parseUserTask(String processInstanceId, UserTask i, ProcessNodeDetailVO node, List skipTaskDefinitionKeys) {
@@ -903,10 +947,10 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
// 设置审批模式,
if (i.getBehavior() instanceof MultiInstanceActivityBehavior) {
MultiInstanceActivityBehavior behavior =
- (MultiInstanceActivityBehavior) i.getBehavior();
+ (MultiInstanceActivityBehavior) i.getBehavior();
node.setNodeMode(Objects.equals(AND_SIGN_EXPRESSION,
- behavior.getCompletionCondition()) ?
- AND : OR);
+ behavior.getCompletionCondition()) ?
+ AND : OR);
} else {
node.setNodeMode(BpmnFlowNodeMode.GENERAL);
}
@@ -917,9 +961,9 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
if (Objects.equals(node.getApprovalMethod(), human)) {
// 推测当前节点的审批人,并且如果审批人为空,也会根据审批人为空的策略去找人
List forecastAssigners =
- springProcessEngineConfiguration.getCommandExecutor()
- .execute(new CustomForecastUserTaskAssigneeCmd(processInstanceId,
- i, engineExecutionStartListener));
+ springProcessEngineConfiguration.getCommandExecutor()
+ .execute(new CustomForecastUserTaskAssigneeCmd(processInstanceId,
+ i, engineExecutionStartListener));
node.setForecastAssigners(forecastAssigners);
if (CollectionUtils.isEmpty(forecastAssigners)) {
getApproverEmptyHandleType(i).ifPresent(emptyHandleType -> {
@@ -944,7 +988,7 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
NativeHistoricProcessInstanceQuery query = historyService.createNativeHistoricProcessInstanceQuery();
String tableName = managementService.getTableName(HistoricProcessInstance.class);
String baseQuerySql = "SELECT DISTINCT TENANT_ID_ FROM " + tableName +
- " WHERE TENANT_ID_ IS NOT NULL AND TENANT_ID_ != '' AND TENANT_ID_ != 0 AND TENANT_ID_ != 'NULL'";
+ " WHERE TENANT_ID_ IS NOT NULL AND TENANT_ID_ != '' AND TENANT_ID_ != 0 AND TENANT_ID_ != 'NULL'";
NativeHistoricProcessInstanceQuery dataSqlQuery = query.sql(baseQuerySql);
return ListUtils.emptyIfNull(dataSqlQuery.list()).stream().map(HistoricProcessInstance::getTenantId).distinct().collect(Collectors.toList());
}
@@ -955,10 +999,160 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
dto.getApprover().setOuId(null);
}
List list = taskService.createTaskQuery()
- .processInstanceId(dto.getProcessInstanceId())
- .taskAssigneeLikeIgnoreCase(dto.getApprover().buildAssigneeId())
- .active()
- .list();
+ .processInstanceId(dto.getProcessInstanceId())
+ .taskAssigneeLikeIgnoreCase(dto.getApprover().buildAssigneeId())
+ .active()
+ .list();
return !CollectionUtils.isEmpty(list);
}
+
+ @Override
+ public BpmnProcessInstanceLogVO getProcessInstanceLog(BpmnProcessInstanceLogQueryDTO dto) {
+ HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
+ .processInstanceId(dto.getProcessInstanceId())
+ .includeProcessVariables().singleResult();
+ if (Objects.isNull(historicProcessInstance)) {
+ throw new WorkflowEngineException(PROCESS_INSTANCE_ID_NOT_EXISTS, dto.getProcessInstanceId());
+ }
+
+ ExtAxProcessLog query = new ExtAxProcessLog();
+ query.setProcessInstanceId(dto.getProcessInstanceId());
+ List logs = processLogService.genericQuery(query).stream()
+ .sorted(Comparator.comparing(ExtAxProcessLog::getEndTime, Comparator.nullsLast(Comparator.naturalOrder())))
+ .collect(Collectors.toList());
+
+ List