From 700dd1941227bfb1ef07c0fdde6feb065585d7f5 Mon Sep 17 00:00:00 2001 From: wangli <274027703@qq.com> Date: Tue, 3 Sep 2024 15:12:23 +0800 Subject: [PATCH] =?UTF-8?q?feat(REQ-2924)=20-=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E5=AE=A1=E6=89=B9=E6=97=A5=E5=BF=97=E7=9A=84=E5=AE=9E=E4=BD=93?= =?UTF-8?q?,=E4=BB=A5=E5=8F=8A=E5=AE=8C=E5=96=84=E7=9B=B8=E5=85=B3=20mappe?= =?UTF-8?q?r/service?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../workflow/common/enums/BpmnButtonEnum.java | 2 +- .../CustomReceiveTaskActivityBehavior.java | 5 +- .../listener/EngineEntityEventListener.java | 206 ++++++++++++++++++ ...ernalExtAxTaskInstEvent_lo_1_Listener.java | 93 ++++++++ ...nternalExtAxTaskInstEvent_lo_Listener.java | 6 - .../repository/entity/ExtAxProcessLog.java | 99 ++++++++- .../mapper/ExtAxProcessLogMapper.java | 8 + .../core/service/ExtAxProcessLogService.java | 37 ++++ .../impl/ExtAxProcessLogServiceImpl.java | 76 +++++++ .../main/resources/sql/upgrade_to_1.4.2.sql | 40 ++-- 10 files changed, 546 insertions(+), 26 deletions(-) create mode 100644 workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/EngineEntityEventListener.java create mode 100644 workflow-engine-core/src/main/java/cn/axzo/workflow/core/listener/impl/InternalExtAxTaskInstEvent_lo_1_Listener.java create mode 100644 workflow-engine-core/src/main/java/cn/axzo/workflow/core/repository/mapper/ExtAxProcessLogMapper.java create mode 100644 workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/ExtAxProcessLogService.java create mode 100644 workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/ExtAxProcessLogServiceImpl.java 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 2daf65036..d9cc769c1 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 @@ -35,7 +35,7 @@ public enum BpmnButtonEnum { /** * 回退按钮 */ - BPMN_ROLLBACK(7, "BPMN_ROLLBACK", "回退"), + BPMN_ROLLBACK(7, "BPMN_ROLLBACK", "退回"), /** * 抄送按钮 */ 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 3004da535..7661176b9 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,6 +7,7 @@ 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; @@ -48,7 +49,9 @@ public class CustomReceiveTaskActivityBehavior extends ReceiveTaskActivityBehavi task.setTaskDefinitionKey(receiveTask.getId()); task.setPropagatedStageInstanceId(execution.getPropagatedStageInstanceId()); task.setName(receiveTask.getName()); - TaskHelper.insertTask(task, (ExecutionEntity) execution, false, false); + TaskHelper.insertTask(task, (ExecutionEntity) execution, true, false); + + processEngineConfiguration.getListenerNotificationHelper().executeTaskListeners(task, TaskListener.EVENTNAME_CREATE); // 添加 taskInst 扩展表数据 FlowableEventDispatcher eventDispatcher = processEngineConfiguration.getEventDispatcher(); 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 new file mode 100644 index 000000000..8326140b1 --- /dev/null +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/EngineEntityEventListener.java @@ -0,0 +1,206 @@ +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.model.request.bpmn.task.BpmnTaskDelegateAssigner; +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; +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 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.HIDDEN_ASSIGNEE_ID; +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.PROCESSING; +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 + */ +@Component +@Slf4j +@AllArgsConstructor +public class EngineEntityEventListener extends AbstractFlowableEventListener { + + 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); + } + } + } + } + + private void onActivated(TaskEntity taskEntity) { + log.error("onActivated"); + } + + private void onSuspended(TaskEntity taskEntity) { + log.error("onSuspended"); + } + + private void onDeleted(TaskEntity taskEntity) { + log.error("onDeleted"); + } + + private void onUpdated(TaskEntity taskEntity) { + log.error("onUpdated"); + if (Objects.equals(HIDDEN_ASSIGNEE_ID, taskEntity.getAssignee())) { + ExtAxProcessLog queryLog = new ExtAxProcessLog(); + queryLog.setProcessInstanceId(taskEntity.getProcessInstanceId()); + queryLog.setTaskId(taskEntity.getId()); + processLogService.delete(queryLog); + } else { + ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(); + RuntimeService runtimeService = processEngineConfiguration.getRuntimeService(); + List 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 '审批日志持久化';