This commit is contained in:
ranke
2026-01-29 18:07:49 +08:00
parent ee4645dce3
commit c8cc9a9cb4
50 changed files with 318 additions and 157 deletions

View File

@@ -11,9 +11,12 @@ import com.alibaba.druid.support.logging.Log;
import com.alibaba.druid.support.logging.LogFactory;
import com.alibaba.druid.util.JdbcUtils;
import com.alibaba.druid.util.MySqlUtils;
import java.net.SocketTimeoutException;
import java.sql.*;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

View File

@@ -1,30 +0,0 @@
package com.zt.plat.module.bpm;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 项目的启动类
*
* 如果你碰到启动的问题,请认真阅读 http://172.16.46.63:30888/quick-start/ 文章
* 如果你碰到启动的问题,请认真阅读 http://172.16.46.63:30888/quick-start/ 文章
* 如果你碰到启动的问题,请认真阅读 http://172.16.46.63:30888/quick-start/ 文章
*
* @author ZT
*/
@SpringBootApplication
public class BpmServerApplication {
public static void main(String[] args) {
// 如果你碰到启动的问题,请认真阅读 http://172.16.46.63:30888/quick-start/ 文章
// 如果你碰到启动的问题,请认真阅读 http://172.16.46.63:30888/quick-start/ 文章
// 如果你碰到启动的问题,请认真阅读 http://172.16.46.63:30888/quick-start/ 文章
SpringApplication.run(BpmServerApplication.class, args);
// 如果你碰到启动的问题,请认真阅读 http://172.16.46.63:30888/quick-start/ 文章
// 如果你碰到启动的问题,请认真阅读 http://172.16.46.63:30888/quick-start/ 文章
// 如果你碰到启动的问题,请认真阅读 http://172.16.46.63:30888/quick-start/ 文章
}
}

View File

@@ -24,7 +24,6 @@ import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.repository.ProcessDefinition;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@@ -41,7 +40,7 @@ import static com.zt.plat.framework.web.core.util.WebFrameworkUtils.getLoginUser
* @author jason
*/
@RestController
@Validated
@Valid
public class BpmProcessInstanceApiImpl implements BpmProcessInstanceApi {
@Resource

View File

@@ -1,11 +1,11 @@
package com.zt.plat.module.bpm.controller.admin.definition.vo.model.simple;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.zt.plat.framework.common.core.KeyValue;
import com.zt.plat.framework.common.validation.InEnum;
import com.zt.plat.module.bpm.enums.definition.*;
import com.zt.plat.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotEmpty;

View File

@@ -26,11 +26,17 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.annotation.security.PermitAll;
import jakarta.validation.Valid;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.list.SetUniqueList;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.migration.ProcessInstanceMigrationBuilder;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ActivityInstance;
import org.flowable.task.api.Task;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
@@ -41,6 +47,7 @@ import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import static com.zt.plat.framework.common.pojo.CommonResult.success;
import static com.zt.plat.framework.common.util.collection.CollectionUtils.*;
@@ -234,4 +241,39 @@ public class BpmProcessInstanceController {
return success(processInstanceService.getProcessInstanceBpmnModelView(id));
}
@Resource
private RuntimeService runtimeService;
@Resource
private TaskService taskService2;
@GetMapping("/klwtest")
@Operation(summary = "klw测试")
@PermitAll
public CommonResult<String> klwtest(@RequestParam String processInstanceId, @RequestParam String nodeId) {
List<ActivityInstance> currentActivities = runtimeService
.createActivityInstanceQuery()
.processInstanceId(processInstanceId)
.unfinished()
.list();
// taskService2.addComment(null, processInstanceId,
// "测试 comment");
if (CollectionUtils.isNotEmpty(currentActivities)) {
runtimeService.createChangeActivityStateBuilder()
.processInstanceId(processInstanceId)
.moveActivityIdsToSingleActivityId(
currentActivities.stream()
.map(ActivityInstance::getActivityId)
.collect(Collectors.toList()),
nodeId
)
.changeState();
}
return success("klw测试");
}
}

View File

@@ -1,9 +1,9 @@
package com.zt.plat.module.bpm.controller.admin.task.vo.instance;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.zt.plat.module.bpm.controller.admin.base.user.UserSimpleBaseVO;
import com.zt.plat.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
import com.zt.plat.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

View File

@@ -1,9 +1,9 @@
package com.zt.plat.module.bpm.controller.admin.task.vo.instance;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.zt.plat.framework.common.core.KeyValue;
import com.zt.plat.module.bpm.controller.admin.base.user.UserSimpleBaseVO;
import com.zt.plat.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

View File

@@ -1,8 +1,8 @@
package com.zt.plat.module.bpm.controller.admin.task.vo.task;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.zt.plat.framework.common.core.KeyValue;
import com.zt.plat.module.bpm.controller.admin.base.user.UserSimpleBaseVO;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

View File

@@ -1,10 +1,10 @@
package com.zt.plat.module.bpm.dal.dataobject.definition;
import com.zt.plat.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.zt.plat.framework.mybatis.core.dataobject.BaseDO;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;

View File

@@ -1,8 +1,8 @@
package com.zt.plat.module.bpm.dal.dataobject.definition;
import com.zt.plat.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import com.zt.plat.framework.mybatis.core.dataobject.BaseDO;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;

View File

@@ -1,7 +1,5 @@
package com.zt.plat.module.bpm.dal.dataobject.definition;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import com.zt.plat.framework.mybatis.core.dataobject.BaseDO;
import com.zt.plat.framework.mybatis.core.type.LongListTypeHandler;
import com.zt.plat.module.bpm.controller.admin.definition.vo.model.BpmModelMetaInfoVO;
@@ -9,6 +7,8 @@ import com.zt.plat.module.bpm.enums.definition.BpmAutoApproveTypeEnum;
import com.zt.plat.module.bpm.enums.definition.BpmModelFormTypeEnum;
import com.zt.plat.module.bpm.enums.definition.BpmModelTypeEnum;
import com.zt.plat.module.system.api.user.dto.AdminUserRespDTO;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;

View File

@@ -1,10 +1,10 @@
package com.zt.plat.module.bpm.dal.dataobject.definition;
import com.zt.plat.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.zt.plat.framework.mybatis.core.dataobject.BaseDO;
import lombok.*;
/**

View File

@@ -1,11 +1,11 @@
package com.zt.plat.module.bpm.dal.dataobject.definition;
import com.zt.plat.framework.mybatis.core.dataobject.BaseDO;
import com.zt.plat.module.bpm.enums.definition.BpmProcessListenerTypeEnum;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.zt.plat.framework.mybatis.core.dataobject.BaseDO;
import com.zt.plat.module.bpm.enums.definition.BpmProcessListenerTypeEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;

View File

@@ -1,9 +1,9 @@
package com.zt.plat.module.bpm.dal.dataobject.definition;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import com.zt.plat.framework.common.enums.CommonStatusEnum;
import com.zt.plat.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;

View File

@@ -1,11 +1,11 @@
package com.zt.plat.module.bpm.dal.dataobject.oa;
import com.zt.plat.framework.mybatis.core.dataobject.BaseDO;
import com.zt.plat.module.bpm.enums.task.BpmTaskStatusEnum;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.zt.plat.framework.mybatis.core.dataobject.BaseDO;
import com.zt.plat.module.bpm.enums.task.BpmTaskStatusEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;

View File

@@ -1,10 +1,10 @@
package com.zt.plat.module.bpm.dal.dataobject.task;
import com.zt.plat.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.zt.plat.framework.mybatis.core.dataobject.BaseDO;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;

View File

@@ -10,8 +10,7 @@ import org.springframework.stereotype.Repository;
import java.time.Duration;
import java.time.LocalDateTime;
import static cn.hutool.core.date.DatePattern.PURE_DATETIME_PATTERN;
import static cn.hutool.core.date.DatePattern.PURE_DATE_PATTERN;
import static cn.hutool.core.date.DatePattern.*;
/**
* BPM 流程 Id 编码的 Redis DAO

View File

@@ -5,7 +5,6 @@ import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.google.common.annotations.VisibleForTesting;
import com.zt.plat.framework.common.enums.CommonStatusEnum;
import com.zt.plat.framework.common.util.object.ObjectUtils;
import com.zt.plat.framework.datapermission.core.annotation.DataPermission;
@@ -17,6 +16,7 @@ import com.zt.plat.module.bpm.framework.flowable.core.util.FlowableUtils;
import com.zt.plat.module.bpm.service.task.BpmProcessInstanceService;
import com.zt.plat.module.system.api.user.AdminUserApi;
import com.zt.plat.module.system.api.user.dto.AdminUserRespDTO;
import com.google.common.annotations.VisibleForTesting;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.CallActivity;

View File

@@ -2,11 +2,11 @@ package com.zt.plat.module.bpm.framework.flowable.core.candidate.strategy.dept;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import com.google.common.collect.Sets;
import com.zt.plat.module.bpm.framework.flowable.core.candidate.strategy.user.BpmTaskCandidateUserStrategy;
import com.zt.plat.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
import com.zt.plat.module.bpm.framework.flowable.core.util.FlowableUtils;
import com.zt.plat.module.bpm.service.task.BpmProcessInstanceService;
import com.google.common.collect.Sets;
import jakarta.annotation.Resource;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.engine.delegate.DelegateExecution;

View File

@@ -2,11 +2,11 @@ package com.zt.plat.module.bpm.framework.flowable.core.candidate.strategy.dept;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import com.google.common.collect.Sets;
import com.zt.plat.module.bpm.framework.flowable.core.candidate.strategy.user.BpmTaskCandidateUserStrategy;
import com.zt.plat.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
import com.zt.plat.module.bpm.framework.flowable.core.util.FlowableUtils;
import com.zt.plat.module.bpm.service.task.BpmProcessInstanceService;
import com.google.common.collect.Sets;
import jakarta.annotation.Resource;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.engine.delegate.DelegateExecution;

View File

@@ -1,10 +1,10 @@
package com.zt.plat.module.bpm.framework.flowable.core.candidate.strategy.other;
import com.google.common.collect.Sets;
import com.zt.plat.framework.common.util.collection.CollectionUtils;
import com.zt.plat.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
import com.zt.plat.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
import com.zt.plat.module.bpm.framework.flowable.core.util.FlowableUtils;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.common.engine.api.FlowableException;

View File

@@ -1,7 +1,7 @@
package com.zt.plat.module.bpm.framework.flowable.core.listener;
import com.google.common.collect.ImmutableSet;
import com.zt.plat.module.bpm.service.task.BpmProcessInstanceService;
import com.google.common.collect.ImmutableSet;
import jakarta.annotation.Resource;
import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType;

View File

@@ -3,13 +3,13 @@ package com.zt.plat.module.bpm.framework.flowable.core.listener;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.ImmutableSet;
import com.zt.plat.framework.common.util.number.NumberUtils;
import com.zt.plat.module.bpm.enums.definition.BpmBoundaryEventTypeEnum;
import com.zt.plat.module.bpm.framework.flowable.core.enums.BpmnModelConstants;
import com.zt.plat.module.bpm.framework.flowable.core.util.BpmnModelUtils;
import com.zt.plat.module.bpm.service.definition.BpmModelService;
import com.zt.plat.module.bpm.service.task.BpmTaskService;
import com.google.common.collect.ImmutableSet;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.BoundaryEvent;
@@ -83,7 +83,7 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener {
if (StrUtil.isEmpty(activity.getTaskId())) {
return;
}
taskService.processTaskCanceled(activity.getTaskId());
taskService.processTaskCanceled(activity.getTaskId(), null);
});
}

View File

@@ -2,7 +2,6 @@ package com.zt.plat.module.bpm.framework.flowable.core.util;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.zt.plat.framework.common.core.KeyValue;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.framework.common.util.json.JsonUtils;
@@ -10,6 +9,7 @@ import com.zt.plat.framework.common.util.spring.SpringUtils;
import com.zt.plat.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;
import com.zt.plat.module.bpm.enums.definition.BpmHttpRequestParamTypeEnum;
import com.zt.plat.module.bpm.service.task.BpmProcessInstanceService;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.http.HttpEntity;

View File

@@ -7,7 +7,6 @@ import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Maps;
import com.zt.plat.framework.common.util.collection.CollectionUtils;
import com.zt.plat.framework.common.util.json.JsonUtils;
import com.zt.plat.framework.common.util.number.NumberUtils;
@@ -16,10 +15,11 @@ import com.zt.plat.module.bpm.controller.admin.definition.vo.model.simple.BpmSim
import com.zt.plat.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
import com.zt.plat.module.bpm.enums.definition.*;
import com.zt.plat.module.bpm.framework.flowable.core.enums.BpmnModelConstants;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.converter.BpmnXMLConverter;
import org.flowable.bpmn.model.*;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.*;
import org.flowable.common.engine.api.FlowableException;
import org.flowable.common.engine.impl.util.io.BytesStreamSource;
import org.flowable.engine.impl.el.FixedValue;

View File

@@ -17,8 +17,8 @@ import com.zt.plat.module.bpm.service.task.listener.BpmCallActivityListener;
import com.zt.plat.module.bpm.service.task.listener.BpmUserTaskListener;
import org.flowable.bpmn.BpmnAutoLayout;
import org.flowable.bpmn.constants.BpmnXMLConstants;
import org.flowable.bpmn.model.*;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.*;
import org.flowable.engine.delegate.ExecutionListener;
import org.flowable.engine.delegate.TaskListener;

View File

@@ -1,6 +1,5 @@
package com.zt.plat.module.bpm.framework.rpc.config;
import com.zt.plat.module.capital.api.AmountCreditApplyApi;
import com.zt.plat.module.system.api.dept.DeptApi;
import com.zt.plat.module.system.api.dept.PostApi;
import com.zt.plat.module.system.api.dict.DictDataApi;
@@ -13,6 +12,6 @@ import org.springframework.context.annotation.Configuration;
@Configuration(value = "bpmRpcConfiguration", proxyBeanMethods = false)
@EnableFeignClients(clients = {RoleApi.class, DeptApi.class, PostApi.class, AdminUserApi.class, SmsSendApi.class, DictDataApi.class,
PermissionApi.class, AmountCreditApplyApi.class})
PermissionApi.class})
public class RpcConfiguration {
}

View File

@@ -1,7 +1,9 @@
package com.zt.plat.module.bpm.framework.web.config;
import com.zt.plat.framework.common.enums.WebFilterOrderEnum;
import com.zt.plat.framework.swagger.config.ZtSwaggerAutoConfiguration;
import com.zt.plat.module.bpm.framework.web.core.FlowableWebFilter;
import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

View File

@@ -24,9 +24,7 @@ import com.zt.plat.module.bpm.service.task.BpmProcessInstanceCopyService;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.StartEvent;
import org.flowable.bpmn.model.UserTask;
import org.flowable.bpmn.model.*;
import org.flowable.common.engine.impl.db.SuspensionState;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RepositoryService;
@@ -42,9 +40,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.*;
import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.zt.plat.framework.common.util.collection.CollectionUtils.convertMap;

View File

@@ -1,42 +0,0 @@
package com.zt.plat.module.bpm.service.supply.capital.listener;
import com.zt.plat.module.bpm.api.event.BpmProcessInstanceStatusEvent;
import com.zt.plat.module.bpm.api.event.BpmProcessInstanceStatusEventListener;
import com.zt.plat.module.bpm.enums.task.BpmProcessInstanceStatusEnum;
import com.zt.plat.module.capital.api.AmountCreditApplyApi;
import com.zt.plat.module.capital.enums.AmountCreditApplyApiStatusEnum;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* credit_letter_approval_process - 授信单的状态的监听器实现类
*
* @author qianshijiang
*/
@Component
public class BpmCreditLetterApprovalStatusListener extends BpmProcessInstanceStatusEventListener {
@Resource
private AmountCreditApplyApi amountCreditApplyApi;
@Override
protected List<String> getProcessDefinitionKey() {
return List.of(amountCreditApplyApi.PROCESS_KEY);
}
@Override
protected void onEvent(BpmProcessInstanceStatusEvent event) {
// 将流程中的状态转换为业务的状态
Integer status = event.getStatus();
String approvalStatus = null;
if (BpmProcessInstanceStatusEnum.APPROVE.getStatus() == status) {
approvalStatus = AmountCreditApplyApiStatusEnum.ACAS_PASS.getCode();
} else if (BpmProcessInstanceStatusEnum.REJECT.getStatus() == status) {
approvalStatus = AmountCreditApplyApiStatusEnum.ACAS_REJECT.getCode();
}
amountCreditApplyApi.updateAmountCreditApplyStatus(Long.parseLong(event.getBusinessKey()),approvalStatus);
}
}

View File

@@ -235,7 +235,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
@Override
public List<ActivityNode> getNextApprovalNodes(Long loginUserId, BpmApprovalDetailReqVO reqVO) {
// 1.1 校验任务存在,且是当前用户的
Task task = taskService.validateTask(loginUserId, reqVO.getTaskId());
Task task = taskService.validateTask(loginUserId, reqVO.getTaskId(), false);
// 1.2 校验流程实例存在
ProcessInstance instance = getProcessInstance(task.getProcessInstanceId());
if (instance == null) {

View File

@@ -98,7 +98,7 @@ public interface BpmTaskService {
* @param userId 用户 id
* @param taskId task id
*/
Task validateTask(Long userId, String taskId);
Task validateTask(Long userId, String taskId, boolean isCheckSuperAdmin);
/**
* 获取任务
@@ -269,7 +269,7 @@ public interface BpmTaskService {
*
* @param taskId 任务的编号
*/
void processTaskCanceled(String taskId);
void processTaskCanceled(String taskId, String reason);
/**
* 处理 Task 设置审批人事件,目前是发送审批消息

View File

@@ -6,12 +6,14 @@ import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.*;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONUtil;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.framework.common.util.date.DateUtils;
import com.zt.plat.framework.common.util.number.NumberUtils;
import com.zt.plat.framework.common.util.object.ObjectUtils;
import com.zt.plat.framework.common.util.object.PageUtils;
import com.zt.plat.framework.datapermission.core.annotation.DataPermission;
import com.zt.plat.framework.security.core.util.SecurityFrameworkUtils;
import com.zt.plat.framework.web.core.util.WebFrameworkUtils;
import com.zt.plat.module.bpm.controller.admin.definition.vo.model.BpmModelMetaInfoVO;
import com.zt.plat.module.bpm.controller.admin.task.vo.task.*;
@@ -35,11 +37,13 @@ import com.zt.plat.module.bpm.service.message.BpmMessageService;
import com.zt.plat.module.bpm.service.message.dto.BpmMessageSendWhenTaskTimeoutReqDTO;
import com.zt.plat.module.system.api.dept.DeptApi;
import com.zt.plat.module.system.api.dept.dto.DeptRespDTO;
import com.zt.plat.module.system.api.permission.PermissionApi;
import com.zt.plat.module.system.api.user.AdminUserApi;
import com.zt.plat.module.system.api.user.dto.AdminUserRespDTO;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.model.*;
import org.flowable.engine.HistoryService;
import org.flowable.engine.ManagementService;
@@ -107,6 +111,10 @@ public class BpmTaskServiceImpl implements BpmTaskService {
@Resource
private AdminUserApi adminUserApi;
@Resource
private PermissionApi permissionApi;
@Resource
private DeptApi deptApi;
@@ -142,12 +150,17 @@ public class BpmTaskServiceImpl implements BpmTaskService {
@Override
public BpmTaskRespVO getTodoTask(Long userId, String taskId, String processInstanceId) {
boolean isSelfTask = true;
// 1.1 获取指定的用户待办任务
Task todoTask = getMyTodoTask(userId, taskId);
// 1.2 获取不到,则获取该流程实例下,第一个用户的待办任务
if (todoTask == null) {
todoTask = getMyFirstTodoTask(userId, processInstanceId);
}
if (todoTask == null && isSuperAdmin(userId)) {
isSelfTask = false;
todoTask = getMyFirstTodoTaskForAdmin(processInstanceId);
}
if (todoTask == null) {
return null;
}
@@ -159,6 +172,19 @@ public class BpmTaskServiceImpl implements BpmTaskService {
BpmnModel bpmnModel = bpmProcessDefinitionService.getProcessDefinitionBpmnModel(todoTask.getProcessDefinitionId());
Map<Integer, BpmTaskRespVO.OperationButtonSetting> buttonsSetting = BpmnModelUtils.parseButtonsSetting(
bpmnModel, todoTask.getTaskDefinitionKey());
// 如果当前登录人是管理员,并且当前任务不属于管理员,则只显示退回,取消和转办按钮
if (!isSelfTask && buttonsSetting != null) {
Optional.ofNullable(buttonsSetting.get(1))
.ifPresent(button -> button.setEnable(false));
Optional.ofNullable(buttonsSetting.get(2))
.ifPresent(button -> button.setEnable(false));
Optional.ofNullable(buttonsSetting.get(4))
.ifPresent(button -> button.setEnable(false));
Optional.ofNullable(buttonsSetting.get(5))
.ifPresent(button -> button.setEnable(false));
Optional.ofNullable(buttonsSetting.get(7))
.ifPresent(button -> button.setEnable(false));
}
Boolean signEnable = parseSignEnable(bpmnModel, todoTask.getTaskDefinitionKey());
Boolean reasonRequire = parseReasonRequire(bpmnModel, todoTask.getTaskDefinitionKey());
Integer nodeType = parseNodeType(BpmnModelUtils.getFlowElementById(bpmnModel, todoTask.getTaskDefinitionKey()));
@@ -203,7 +229,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
/**
* 获得用户指定 processInstanceId 流程编号下的首个“待办”(未审批、且可审核)的任务
*
* @param userId 用户编号
* @param userId 用户编号
* @param processInstanceId 流程编号
* @return 任务
*/
@@ -221,12 +247,47 @@ public class BpmTaskServiceImpl implements BpmTaskService {
.list();
// 2. 查询我的首个任务
SecurityFrameworkUtils.getLoginUser();
return CollUtil.findOne(tasks, task -> {
return isAssignUserTask(userId, task) // 当前用户为审批人
|| isAddSignUserTask(userId, task); // 当前用户为加签人(为了减签)
});
}
/**
* 获得指定 processInstanceId 流程编号下的首个“待办”(未审批、且可审核)的任务(超级管理员用)
*
* @param processInstanceId 流程编号
* @return 任务
*/
private Task getMyFirstTodoTaskForAdmin(String processInstanceId) {
if (processInstanceId == null) {
return null;
}
// 1. 查询所有任务
List<Task> tasks = taskService.createTaskQuery()
.active()
.processInstanceId(processInstanceId)
.includeTaskLocalVariables()
.includeProcessVariables()
.orderByTaskCreateTime().asc() // 按创建时间升序
.list();
// 2. 查询首个任务
SecurityFrameworkUtils.getLoginUser();
return CollUtil.findOne(tasks, task -> {
return true; // 当前用户为超级管理员
});
}
private boolean isSuperAdmin(Long userId) {
CommonResult<Boolean> result = permissionApi.isSuperAdmin(userId);
if (result != null) {
return result.getCheckedData();
}
return false;
}
@Override
public PageResult<HistoricTaskInstance> getTaskDonePage(Long userId, BpmTaskPageReqVO pageVO) {
HistoricTaskInstanceQuery taskQuery = historyService.createHistoricTaskInstanceQuery()
@@ -301,10 +362,13 @@ public class BpmTaskServiceImpl implements BpmTaskService {
}
@Override
public Task validateTask(Long userId, String taskId) {
public Task validateTask(Long userId, String taskId, boolean isCheckSuperAdmin) {
Task task = validateTaskExist(taskId);
// 为什么判断 assignee 非空的情况下?
// 例如说:在审批人为空时,我们会有“自动审批通过”的策略,此时 userId 为 null允许通过
if (isCheckSuperAdmin && isSuperAdmin(userId)) {
return task;
}
if (StrUtil.isNotBlank(task.getAssignee())
&& ObjectUtil.notEqual(userId, NumberUtils.parseLong(task.getAssignee()))) {
throw exception(TASK_OPERATE_FAIL_ASSIGN_NOT_SELF);
@@ -528,7 +592,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
@Transactional(rollbackFor = Exception.class)
public void approveTask(Long userId, @Valid BpmTaskApproveReqVO reqVO) {
// 1.1 校验任务存在
Task task = validateTask(userId, reqVO.getId());
Task task = validateTask(userId, reqVO.getId(), false);
// 1.2 校验流程实例存在
ProcessInstance instance = processInstanceService.getProcessInstance(task.getProcessInstanceId());
if (instance == null) {
@@ -601,15 +665,15 @@ public class BpmTaskServiceImpl implements BpmTaskService {
/**
* 校验选择的下一个节点的审批人,是否合法
*
* <p>
* 1. 是否有漏选:没有选择审批人
* 2. 是否有多选:非下一个节点
*
* @param taskDefinitionKey 当前任务节点标识
* @param variables 流程变量
* @param bpmnModel 流程模型
* @param nextAssignees 下一个节点审批人集合(参数)
* @param processInstance 流程实例
* @param variables 流程变量
* @param bpmnModel 流程模型
* @param nextAssignees 下一个节点审批人集合(参数)
* @param processInstance 流程实例
*/
@SuppressWarnings("unchecked")
private Map<String, Object> validateAndSetNextAssignees(String taskDefinitionKey, Map<String, Object> variables, BpmnModel bpmnModel,
@@ -661,7 +725,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
approveUserSelectAssignees = new HashMap<>();
}
approveUserSelectAssignees.put(nextFlowNode.getId(), assignees);
Map<String,List<Long>> existingApproveUserSelectAssignees = (Map<String,List<Long>>) variables.get(
Map<String, List<Long>> existingApproveUserSelectAssignees = (Map<String, List<Long>>) variables.get(
BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_APPROVE_USER_SELECT_ASSIGNEES);
if (CollUtil.isNotEmpty(existingApproveUserSelectAssignees)) {
approveUserSelectAssignees.putAll(existingApproveUserSelectAssignees);
@@ -771,7 +835,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
@Transactional(rollbackFor = Exception.class)
public void rejectTask(Long userId, @Valid BpmTaskRejectReqVO reqVO) {
// 1.1 校验任务存在
Task task = validateTask(userId, reqVO.getId());
Task task = validateTask(userId, reqVO.getId(), false);
// 1.2 校验流程实例存在
ProcessInstance instance = processInstanceService.getProcessInstance(task.getProcessInstanceId());
if (instance == null) {
@@ -837,7 +901,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
@Transactional(rollbackFor = Exception.class)
public void returnTask(Long userId, BpmTaskReturnReqVO reqVO) {
// 1.1 当前任务 task
Task task = validateTask(userId, reqVO.getId());
Task task = validateTask(userId, reqVO.getId(), true);
if (task.isSuspended()) {
throw exception(TASK_IS_PENDING);
}
@@ -895,6 +959,8 @@ public class BpmTaskServiceImpl implements BpmTaskService {
List<String> runExecutionIds = new ArrayList<>();
// 2. 给当前要被退回的 task 数组,设置退回意见
boolean isSuperAdmin = isSuperAdmin(userId);
String reasonPrefix = isSuperAdmin ? "【管理员操作】" : "";
taskList.forEach(task -> {
// 需要排除掉,不需要设置退回意见的任务
if (!returnTaskKeyList.contains(task.getTaskDefinitionKey())) {
@@ -910,7 +976,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
// 2.1.2 更新 task 状态 + 原因
updateTaskStatusAndReason(task.getId(), BpmTaskStatusEnum.RETURN.getStatus(), reqVO.getReason());
} else { // 情况二:别人的任务,进行 CANCEL 标记
processTaskCanceled(task.getId());
processTaskCanceled(task.getId(), reasonPrefix + reqVO.getReason());
}
});
@@ -931,7 +997,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
public void delegateTask(Long userId, BpmTaskDelegateReqVO reqVO) {
String taskId = reqVO.getId();
// 1.1 校验任务
Task task = validateTask(userId, reqVO.getId());
Task task = validateTask(userId, reqVO.getId(), false);
if (task.getAssignee().equals(reqVO.getDelegateUserId().toString())) { // 校验当前审批人和被委派人不是同一人
throw exception(TASK_DELEGATE_FAIL_USER_REPEAT);
}
@@ -957,7 +1023,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
public void transferTask(Long userId, BpmTaskTransferReqVO reqVO) {
String taskId = reqVO.getId();
// 1.1 校验任务
Task task = validateTask(userId, reqVO.getId());
Task task = validateTask(userId, reqVO.getId(), true);
if (task.getAssignee().equals(reqVO.getAssigneeUserId().toString())) { // 校验当前审批人和被转派人不是同一人
throw exception(TASK_TRANSFER_FAIL_USER_REPEAT);
}
@@ -994,7 +1060,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
if (BpmTaskStatusEnum.isEndStatus(otherTaskStatus)) {
return;
}
processTaskCanceled(task.getId());
processTaskCanceled(task.getId(), null);
});
// 2. 终止流程
@@ -1066,7 +1132,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
* @return 当前任务
*/
private TaskEntityImpl validateTaskCanCreateSign(Long userId, BpmTaskSignCreateReqVO reqVO) {
TaskEntityImpl taskEntity = (TaskEntityImpl) validateTask(userId, reqVO.getId());
TaskEntityImpl taskEntity = (TaskEntityImpl) validateTask(userId, reqVO.getId(), false);
// 向前加签和向后加签不能同时存在
if (taskEntity.getScopeType() != null
&& ObjectUtil.notEqual(taskEntity.getScopeType(), reqVO.getType())) {
@@ -1217,7 +1283,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
}
// 2. 任务前置通知
if (ObjUtil.isNotNull(processDefinitionInfo.getTaskBeforeTriggerSetting())){
if (ObjUtil.isNotNull(processDefinitionInfo.getTaskBeforeTriggerSetting())) {
BpmModelMetaInfoVO.HttpRequestSetting setting = processDefinitionInfo.getTaskBeforeTriggerSetting();
BpmHttpRequestUtils.executeBpmHttpRequest(processInstance,
setting.getUrl(), setting.getHeader(), setting.getBody(), true, setting.getResponse());
@@ -1281,7 +1347,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
* 2. 审批不通过:在 {@link #rejectTask(Long, BpmTaskRejectReqVO)} 不通过时,对于加签的任务,不会被 Flowable 删除,此时需要通过该方法更新状态为已取消
*/
@Override
public void processTaskCanceled(String taskId) {
public void processTaskCanceled(String taskId, String reason) {
Task task = getTask(taskId);
// 1. 可能只是活动,不是任务,所以查询不到
if (task == null) {
@@ -1295,7 +1361,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
log.error("[updateTaskStatusWhenCanceled][taskId({}) 处于结果({}),无需进行更新]", taskId, status);
return;
}
updateTaskStatusAndReason(taskId, BpmTaskStatusEnum.CANCEL.getStatus(), BpmReasonEnum.CANCEL_BY_SYSTEM.getReason());
updateTaskStatusAndReason(taskId, BpmTaskStatusEnum.CANCEL.getStatus(), StringUtils.isNotBlank(reason) ? reason : BpmReasonEnum.CANCEL_BY_SYSTEM.getReason());
// 补充说明:由于 Task 被删除成 HistoricTask 后,无法通过 taskService.addComment 添加理由,所以无法存储具体的取消理由
}
@@ -1344,7 +1410,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
.taskVariableValueEquals(BpmnVariableConstants.TASK_VARIABLE_STATUS, BpmTaskStatusEnum.APPROVE.getStatus())
.finished();
if (BpmAutoApproveTypeEnum.APPROVE_ALL.getType().equals(processDefinitionInfo.getAutoApprovalType())
&& sameAssigneeQuery.count() > 0) {
&& sameAssigneeQuery.count() > 0) {
getSelf().approveTask(Long.valueOf(task.getAssignee()), new BpmTaskApproveReqVO().setId(task.getId())
.setReason(BpmAutoApproveTypeEnum.APPROVE_ALL.getName()));
return;
@@ -1356,7 +1422,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
return;
}
List<String> sourceTaskIds = convertList(BpmnModelUtils.getElementIncomingFlows( // 获取所有上一个节点
BpmnModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey())),
BpmnModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey())),
SequenceFlow::getSourceRef);
if (sameAssigneeQuery.taskDefinitionKeys(sourceTaskIds).count() > 0) {
getSelf().approveTask(Long.valueOf(task.getAssignee()), new BpmTaskApproveReqVO().setId(task.getId())
@@ -1451,7 +1517,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
}
// 任务后置通知
if (ObjUtil.isNotNull(processDefinitionInfo.getTaskAfterTriggerSetting())){
if (ObjUtil.isNotNull(processDefinitionInfo.getTaskAfterTriggerSetting())) {
BpmModelMetaInfoVO.HttpRequestSetting setting = processDefinitionInfo.getTaskAfterTriggerSetting();
BpmHttpRequestUtils.executeBpmHttpRequest(processInstance,
setting.getUrl(), setting.getHeader(), setting.getBody(), true, setting.getResponse());

View File

@@ -1,7 +1,6 @@
package com.zt.plat.module.bpm.service.task.trigger.form;
import cn.hutool.core.collection.CollUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.zt.plat.framework.common.util.json.JsonUtils;
import com.zt.plat.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;
import com.zt.plat.module.bpm.enums.definition.BpmTriggerTypeEnum;
@@ -9,6 +8,7 @@ import com.zt.plat.module.bpm.framework.flowable.core.util.BpmnModelUtils;
import com.zt.plat.module.bpm.framework.flowable.core.util.SimpleModelUtils;
import com.zt.plat.module.bpm.service.task.BpmProcessInstanceService;
import com.zt.plat.module.bpm.service.task.trigger.BpmTrigger;
import com.fasterxml.jackson.core.type.TypeReference;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

View File

@@ -1,7 +1,6 @@
package com.zt.plat.module.bpm.service.task.trigger.form;
import cn.hutool.core.collection.CollUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.zt.plat.framework.common.util.json.JsonUtils;
import com.zt.plat.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO.TriggerSetting.FormTriggerSetting;
import com.zt.plat.module.bpm.enums.definition.BpmTriggerTypeEnum;
@@ -9,6 +8,7 @@ import com.zt.plat.module.bpm.framework.flowable.core.util.BpmnModelUtils;
import com.zt.plat.module.bpm.framework.flowable.core.util.SimpleModelUtils;
import com.zt.plat.module.bpm.service.task.BpmProcessInstanceService;
import com.zt.plat.module.bpm.service.task.trigger.BpmTrigger;
import com.fasterxml.jackson.core.type.TypeReference;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

View File

@@ -10,6 +10,7 @@ import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
/**
* BPM HTTP 回调触发器

View File

@@ -9,6 +9,7 @@ import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
/**
* BPM 发送同步 HTTP 请求触发器

View File

@@ -11,6 +11,7 @@ import liquibase.statement.DatabaseFunction;
import liquibase.util.StringUtil;
import java.util.Locale;
import java.util.regex.Pattern;
@DataTypeInfo(name = "boolean", aliases = {"java.sql.Types.BOOLEAN", "java.lang.Boolean", "bit", "bool"}, minParameters = 0, maxParameters = 0, priority = LiquibaseDataType.PRIORITY_DEFAULT)
public class BooleanType extends LiquibaseDataType {

View File

@@ -12,8 +12,29 @@
*/
package org.flowable.common.engine.impl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.ServiceLoader;
import java.util.Set;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.builder.xml.XMLConfigBuilder;
import org.apache.ibatis.builder.xml.XMLMapperBuilder;
@@ -26,7 +47,27 @@ import org.apache.ibatis.session.defaults.DefaultSqlSessionFactory;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.apache.ibatis.transaction.managed.ManagedTransactionFactory;
import org.apache.ibatis.type.*;
import org.apache.ibatis.type.ArrayTypeHandler;
import org.apache.ibatis.type.BigDecimalTypeHandler;
import org.apache.ibatis.type.BlobInputStreamTypeHandler;
import org.apache.ibatis.type.BlobTypeHandler;
import org.apache.ibatis.type.BooleanTypeHandler;
import org.apache.ibatis.type.ByteTypeHandler;
import org.apache.ibatis.type.ClobTypeHandler;
import org.apache.ibatis.type.DateOnlyTypeHandler;
import org.apache.ibatis.type.DateTypeHandler;
import org.apache.ibatis.type.DoubleTypeHandler;
import org.apache.ibatis.type.FloatTypeHandler;
import org.apache.ibatis.type.IntegerTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.LongTypeHandler;
import org.apache.ibatis.type.NClobTypeHandler;
import org.apache.ibatis.type.NStringTypeHandler;
import org.apache.ibatis.type.ShortTypeHandler;
import org.apache.ibatis.type.SqlxmlTypeHandler;
import org.apache.ibatis.type.StringTypeHandler;
import org.apache.ibatis.type.TimeOnlyTypeHandler;
import org.apache.ibatis.type.TypeHandlerRegistry;
import org.flowable.common.engine.api.FlowableException;
import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType;
import org.flowable.common.engine.api.delegate.event.FlowableEventDispatcher;
@@ -38,10 +79,25 @@ import org.flowable.common.engine.impl.cfg.CommandExecutorImpl;
import org.flowable.common.engine.impl.cfg.IdGenerator;
import org.flowable.common.engine.impl.cfg.TransactionContextFactory;
import org.flowable.common.engine.impl.cfg.standalone.StandaloneMybatisTransactionContextFactory;
import org.flowable.common.engine.impl.db.*;
import org.flowable.common.engine.impl.db.CommonDbSchemaManager;
import org.flowable.common.engine.impl.db.DbSqlSessionFactory;
import org.flowable.common.engine.impl.db.LogSqlExecutionTimePlugin;
import org.flowable.common.engine.impl.db.MybatisTypeAliasConfigurator;
import org.flowable.common.engine.impl.db.MybatisTypeHandlerConfigurator;
import org.flowable.common.engine.impl.db.SchemaManager;
import org.flowable.common.engine.impl.event.EventDispatchAction;
import org.flowable.common.engine.impl.event.FlowableEventDispatcherImpl;
import org.flowable.common.engine.impl.interceptor.*;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandConfig;
import org.flowable.common.engine.impl.interceptor.CommandContextFactory;
import org.flowable.common.engine.impl.interceptor.CommandContextInterceptor;
import org.flowable.common.engine.impl.interceptor.CommandExecutor;
import org.flowable.common.engine.impl.interceptor.CommandInterceptor;
import org.flowable.common.engine.impl.interceptor.CrDbRetryInterceptor;
import org.flowable.common.engine.impl.interceptor.DefaultCommandInvoker;
import org.flowable.common.engine.impl.interceptor.LogInterceptor;
import org.flowable.common.engine.impl.interceptor.SessionFactory;
import org.flowable.common.engine.impl.interceptor.TransactionContextInterceptor;
import org.flowable.common.engine.impl.lock.LockManager;
import org.flowable.common.engine.impl.lock.LockManagerImpl;
import org.flowable.common.engine.impl.logging.LoggingListener;
@@ -51,7 +107,13 @@ import org.flowable.common.engine.impl.persistence.GenericManagerFactory;
import org.flowable.common.engine.impl.persistence.StrongUuidGenerator;
import org.flowable.common.engine.impl.persistence.cache.EntityCache;
import org.flowable.common.engine.impl.persistence.cache.EntityCacheImpl;
import org.flowable.common.engine.impl.persistence.entity.*;
import org.flowable.common.engine.impl.persistence.entity.ByteArrayEntityManager;
import org.flowable.common.engine.impl.persistence.entity.ByteArrayEntityManagerImpl;
import org.flowable.common.engine.impl.persistence.entity.Entity;
import org.flowable.common.engine.impl.persistence.entity.PropertyEntityManager;
import org.flowable.common.engine.impl.persistence.entity.PropertyEntityManagerImpl;
import org.flowable.common.engine.impl.persistence.entity.TableDataManager;
import org.flowable.common.engine.impl.persistence.entity.TableDataManagerImpl;
import org.flowable.common.engine.impl.persistence.entity.data.ByteArrayDataManager;
import org.flowable.common.engine.impl.persistence.entity.data.PropertyDataManager;
import org.flowable.common.engine.impl.persistence.entity.data.impl.MybatisByteArrayDataManager;
@@ -65,14 +127,8 @@ import org.flowable.eventregistry.api.EventRegistryEventConsumer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.sql.*;
import java.time.Duration;
import java.util.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
public abstract class AbstractEngineConfiguration {

View File

@@ -1,94 +0,0 @@
--- #################### 数据库相关配置 ####################
spring:
# 数据源配置项
autoconfigure:
exclude:
datasource:
druid: # Druid 【监控】相关的全局配置
web-stat-filter:
enabled: true
stat-view-servlet:
enabled: true
allow: # 设置白名单,不填则允许所有访问
url-pattern: /druid/*
login-username: # 控制台管理用户名和密码
login-password:
filter:
stat:
enabled: true
log-slow-sql: true # 慢 SQL 记录
slow-sql-millis: 100
merge-sql: true
wall:
config:
multi-statement-allow: true
dynamic: # 多数据源配置
druid: # Druid 【连接池】相关的全局配置
initial-size: 5 # 初始连接数
min-idle: 10 # 最小连接池数量
max-active: 20 # 最大连接池数量
max-wait: 600000 # 配置获取连接等待超时的时间,单位:毫秒
time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒
min-evictable-idle-time-millis: 300000 # 配置一个连接在池中最小生存的时间,单位:毫秒
max-evictable-idle-time-millis: 900000 # 配置一个连接在池中最大生存的时间,单位:毫秒
validation-query: SELECT 1 FROM DUAL # 配置检测连接是否有效
test-while-idle: true
test-on-borrow: false
test-on-return: false
primary: master
datasource:
master:
url: jdbc:mysql://172.16.46.247:4787/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true # MySQL Connector/J 8.X 连接的示例
username: jygk-test
password: Zgty@0527
slave: # 模拟从库,可根据自己需要修改 # 模拟从库,可根据自己需要修改
lazy: true # 开启懒加载,保证启动速度
url: jdbc:mysql://172.16.46.247:4787/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true # MySQL Connector/J 8.X 连接的示例
username: jygk-test
password: Zgty@0527
# Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
data:
redis:
host: 172.16.46.63 # 地址
port: 30379 # 端口
database: 1 # 数据库索引
# password: 123456 # 密码,建议生产环境开启
--- #################### MQ 消息队列相关配置 ####################
--- #################### 定时任务相关配置 ####################
xxl:
job:
admin:
addresses: http://172.16.46.63:30082/xxl-job-admin # 调度中心部署跟地址
--- #################### 服务保障相关配置 ####################
# Lock4j 配置项
lock4j:
acquire-timeout: 3000 # 获取分布式锁超时时间,默认为 3000 毫秒
expire: 30000 # 分布式锁的超时时间,默认为 30 毫秒
--- #################### 监控相关配置 ####################
# Actuator 监控端点的配置项
management:
endpoints:
web:
base-path: /actuator # Actuator 提供的 API 接口的根目录。默认为 /actuator
exposure:
include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。
# Spring Boot Admin 配置项
spring:
boot:
admin:
# Spring Boot Admin Client 客户端的相关配置
client:
instance:
service-host-type: IP # 注册实例时,优先使用 IP [IP, HOST_NAME, CANONICAL_HOST_NAME]
--- #################### ZT相关配置 ####################

View File

@@ -1,116 +0,0 @@
--- #################### 数据库相关配置 ####################
spring:
# 数据源配置项
autoconfigure:
exclude:
- de.codecentric.boot.admin.client.config.SpringBootAdminClientAutoConfiguration # 禁用 Spring Boot Admin 的 Client 的自动配置
datasource:
druid: # Druid 【监控】相关的全局配置
web-stat-filter:
enabled: true
stat-view-servlet:
enabled: true
allow: # 设置白名单,不填则允许所有访问
url-pattern: /druid/*
login-username: # 控制台管理用户名和密码
login-password:
filter:
stat:
enabled: true
log-slow-sql: true # 慢 SQL 记录
slow-sql-millis: 100
merge-sql: true
wall:
config:
multi-statement-allow: true
dynamic: # 多数据源配置
druid: # Druid 【连接池】相关的全局配置
initial-size: 1 # 初始连接数
min-idle: 1 # 最小连接池数量
max-active: 20 # 最大连接池数量
max-wait: 600000 # 配置获取连接等待超时的时间,单位:毫秒
time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒
min-evictable-idle-time-millis: 300000 # 配置一个连接在池中最小生存的时间,单位:毫秒
max-evictable-idle-time-millis: 900000 # 配置一个连接在池中最大生存的时间,单位:毫秒
validation-query: SELECT 1 FROM DUAL # 配置检测连接是否有效
test-while-idle: true
test-on-borrow: false
test-on-return: false
primary: master
datasource:
master:
url: jdbc:dm://172.16.46.247:1050?schema=BPM
username: SYSDBA
password: pgbsci6ddJ6Sqj@e
slave: # 模拟从库,可根据自己需要修改 # 模拟从库,可根据自己需要修改
lazy: true # 开启懒加载,保证启动速度
url: jdbc:dm://172.16.46.247:1050?schema=BPM
username: SYSDBA
password: pgbsci6ddJ6Sqj@e
# Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
data:
redis:
host: 172.16.46.64 # 地址
port: 30379 # 端口
database: 0 # 数据库索引
# password: 123456 # 密码,建议生产环境开启
# Flowable 在 DM 场景下需要识别为 Oracle 并自动升级表结构
flowable:
database-schema-update: true
database-type: oracle
--- #################### MQ 消息队列相关配置 ####################
--- #################### 定时任务相关配置 ####################
xxl:
job:
enabled: false # 是否开启调度中心,默认为 true 开启
admin:
addresses: http://172.16.46.63:30082/xxl-job-admin # 调度中心部署跟地址
--- #################### 服务保障相关配置 ####################
# Lock4j 配置项
lock4j:
acquire-timeout: 3000 # 获取分布式锁超时时间,默认为 3000 毫秒
expire: 30000 # 分布式锁的超时时间,默认为 30 毫秒
--- #################### 监控相关配置 ####################
# Actuator 监控端点的配置项
management:
endpoints:
web:
base-path: /actuator # Actuator 提供的 API 接口的根目录。默认为 /actuator
exposure:
include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。
# Spring Boot Admin 配置项
spring:
boot:
admin:
# Spring Boot Admin Client 客户端的相关配置
client:
instance:
service-host-type: IP # 注册实例时,优先使用 IP [IP, HOST_NAME, CANONICAL_HOST_NAME]
# 日志文件配置
logging:
level:
# 配置自己写的 MyBatis Mapper 打印日志
com.zt.plat.module.bpm.dal.mysql: debug
org.springframework.context.support.PostProcessorRegistrationDelegate: ERROR # TODO ZT先禁用Spring Boot 3.X 存在部分错误的 WARN 提示
--- #################### ZT相关配置 ####################
# ZT配置项设置当前项目所有自定义的配置
zt:
env: # 多环境的配置项
tag: ${HOSTNAME}
security:
mock-enable: true
access-log: # 访问日志的配置项
enable: false

View File

@@ -1,150 +0,0 @@
spring:
application:
name: bpm-server
profiles:
active: ${env.name}
#统一nacos配置使用 profile 管理
cloud:
nacos:
server-addr: ${config.server-addr} # Nacos 服务器地址
username: ${config.username} # Nacos 账号
password: ${config.password} # Nacos 密码
discovery: # 【配置中心】配置项
namespace: ${config.namespace} # 命名空间。这里使用 maven Profile 资源过滤进行动态替换
group: ${config.group} # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
metadata:
version: 1.0.0 # 服务实例的版本号,可用于灰度发布
config: # 【注册中心】配置项
namespace: ${config.namespace} # 命名空间。这里使用 maven Profile 资源过滤进行动态替换
group: ${config.group} # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
main:
allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。
allow-bean-definition-overriding: true # 允许 Bean 覆盖,例如说 Feign 等会存在重复定义的服务
config:
import:
- optional:classpath:application-${spring.profiles.active}.yaml # 加载【本地】配置
- optional:nacos:${spring.application.name}-${spring.profiles.active}.yaml # 加载【Nacos】的配置
# Servlet 配置
servlet:
# 文件上传相关配置项
multipart:
max-file-size: 16MB # 单个文件大小
max-request-size: 32MB # 设置总上传的文件大小
# Jackson 配置项
jackson:
serialization:
write-dates-as-timestamps: true # 设置 LocalDateTime 的格式,使用时间戳
write-date-timestamps-as-nanoseconds: false # 设置不使用 nanoseconds 的格式。例如说 1611460870.401,而是直接 1611460870401
write-durations-as-timestamps: true # 设置 Duration 的格式,使用时间戳
fail-on-empty-beans: false # 允许序列化无属性的 Bean
# Cache 配置项
cache:
type: REDIS
redis:
time-to-live: 1h # 设置过期时间为 1 小时
server:
port: 48083
logging:
file:
name: ${user.home}/logs/${spring.application.name}.log # 日志文件名,全路径
--- #################### 接口文档配置 ####################
springdoc:
api-docs:
enabled: true # 1. 是否开启 Swagger 接文档的元数据
path: /v3/api-docs
swagger-ui:
enabled: true # 2.1 是否开启 Swagger 文档的官方 UI 界面
path: /swagger-ui
default-flat-param-object: true # 参见 https://doc.xiaominfo.com/docs/faq/v4/knife4j-parameterobject-flat-param 文档
knife4j:
enable: false # TODO ZT需要关闭增强具体原因见https://github.com/xiaoymin/knife4j/issues/874
setting:
language: zh_cn
# 工作流 Flowable 配置
flowable:
# 1. false: 默认值Flowable 启动时,对比数据库表中保存的版本,如果不匹配。将抛出异常
# 2. true: 启动时会对数据库中所有表进行更新操作,如果表存在,不做处理,反之,自动创建表
# 3. create_drop: 启动时自动创建表,关闭时自动删除表
# 4. drop_create: 启动时,删除旧表,再创建新表
database-schema-update: false # 设置为 false可通过 https://github.com/flowable/flowable-sql 初始化
db-history-used: true # flowable6 默认 true 生成信息表,无需手动设置
check-process-definitions: false # 设置为 false禁用 /resources/processes 自动部署 BPMN XML 流程
history-level: audit # full保存历史数据的最高级别可保存全部流程相关细节包括流程流转各节点参数
# MyBatis Plus 的配置项
mybatis-plus:
configuration:
map-underscore-to-camel-case: true # 虽然默认为 true ,但是还是显示去指定下。
global-config:
db-config:
id-type: NONE # “智能”模式,基于 IdTypeEnvironmentPostProcessor + 数据源的类型,自动适配成 AUTO、INPUT 模式。
# id-type: AUTO # 自增 ID适合 MySQL 等直接自增的数据库
# id-type: INPUT # 用户输入 ID适合 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库
# id-type: ASSIGN_ID # 分配 ID默认使用雪花算法。注意Oracle、PostgreSQL、Kingbase、DB2、H2 数据库时,需要去除实体类上的 @KeySequence 注解
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
banner: false # 关闭控制台的 Banner 打印
type-aliases-package: ${zt.info.base-package}.dal.dataobject
encryptor:
password: XDV71a+xqStEA3WH # 加解密的秘钥,可使用 https://www.imaegoo.com/2020/aes-key-generator/ 网站生成
mybatis-plus-join:
banner: false # 关闭控制台的 Banner 打印
# Spring Data Redis 配置
spring:
data:
redis:
repositories:
enabled: false # 项目未使用到 Spring Data Redis 的 Repository所以直接禁用保证启动速度
# VO 转换(数据翻译)相关
easy-trans:
is-enable-global: true # 启用全局翻译(拦截所有 SpringMVC ResponseBody 进行自动翻译 )。如果对于性能要求很高可关闭此配置,或通过 @IgnoreTrans 忽略某个接口
--- #################### RPC 远程调用相关配置 ####################
--- #################### MQ 消息队列相关配置 ####################
--- #################### 定时任务相关配置 ####################
xxl:
job:
executor:
appname: ${spring.application.name} # 执行器 AppName
logpath: ${user.home}/logs/xxl-job/${spring.application.name} # 执行器运行日志文件存储磁盘路径
accessToken: default_token # 执行器通讯TOKEN
--- #################### ZT相关配置 ####################
zt:
info:
version: 1.0.0
base-package: com.zt.plat.module.bpm
web:
admin-ui:
url: http://dashboard.zt.iocoder.cn # Admin 管理后台 UI 的地址
xss:
enable: false
exclude-urls: # 如下 url仅仅是为了演示去掉配置也没关系
- ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求
swagger:
title: 流程模块
description: 提供流程模块功能
version: ${zt.info.version}
tenant: # 多租户相关配置项
enable: true
debug: false

View File

@@ -1,80 +0,0 @@
<configuration>
<!-- 引用 Spring Boot 的 logback 基础配置 -->
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<!-- 变量 zt.info.base-package基础业务包 -->
<springProperty scope="context" name="zt.info.base-package" source="zt.info.base-package"/>
<!-- 格式化输出:%d 表示日期,%X{tid} SkWalking 链路追踪编号,%thread 表示线程名,%-5level级别从左显示 5 个字符宽度,%msg日志消息%n是换行符 -->
<property name="PATTERN_DEFAULT" value="%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} | %highlight(${LOG_LEVEL_PATTERN:-%5p} ${PID:- }) | %boldYellow(%thread [%tid]) %boldGreen(%-40.40logger{39}) | %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
<!-- 控制台 Appender -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">     
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<pattern>${PATTERN_DEFAULT}</pattern>
</layout>
</encoder>
</appender>
<!-- 文件 Appender -->
<!-- 参考 Spring Boot 的 file-appender.xml 编写 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<pattern>${PATTERN_DEFAULT}</pattern>
</layout>
</encoder>
<!-- 日志文件名 -->
<file>${LOG_FILE}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 滚动后的日志文件名 -->
<fileNamePattern>${LOGBACK_ROLLINGPOLICY_FILE_NAME_PATTERN:-${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz}</fileNamePattern>
<!-- 启动服务时,是否清理历史日志,一般不建议清理 -->
<cleanHistoryOnStart>${LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START:-false}</cleanHistoryOnStart>
<!-- 日志文件,到达多少容量,进行滚动 -->
<maxFileSize>${LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE:-10MB}</maxFileSize>
<!-- 日志文件的总大小0 表示不限制 -->
<totalSizeCap>${LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP:-0}</totalSizeCap>
<!-- 日志文件的保留天数 -->
<maxHistory>${LOGBACK_ROLLINGPOLICY_MAX_HISTORY:-30}</maxHistory>
</rollingPolicy>
</appender>
<!-- 异步写入日志,提升性能 -->
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<!-- 不丢失日志。默认的,如果队列的 80% 已满,则会丢弃 TRACT、DEBUG、INFO 级别的日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能。默认值为 256 -->
<queueSize>256</queueSize>
<appender-ref ref="FILE"/>
</appender>
<!-- SkyWalking GRPC 日志收集实现日志中心。注意SkyWalking 8.4.0 版本开始支持 -->
<appender name="GRPC" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<pattern>${PATTERN_DEFAULT}</pattern>
</layout>
</encoder>
</appender>
<!-- 本地环境 -->
<springProfile name="local">
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="GRPC"/> <!-- 本地环境下,如果不想接入 SkyWalking 日志服务,可以注释掉本行 -->
<appender-ref ref="ASYNC"/> <!-- 本地环境下,如果不想打印日志,可以注释掉本行 -->
</root>
</springProfile>
<!-- 其它环境 -->
<springProfile name="dev,test,stage,prod,default">
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="ASYNC"/>
<appender-ref ref="GRPC"/>
</root>
</springProfile>
<logger name="com.zt.plat.module.bpm.dal" level="DEBUG" additivity="false">
<appender-ref ref="STDOUT"/>
</logger>
</configuration>

View File

@@ -4,15 +4,15 @@ import cn.hutool.core.util.RandomUtil;
import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.framework.common.util.json.JsonUtils;
import com.zt.plat.framework.test.core.ut.BaseDbUnitTest;
import com.zt.plat.module.bpm.controller.admin.definition.vo.form.BpmFormPageReqVO;
import com.zt.plat.module.bpm.controller.admin.definition.vo.form.BpmFormSaveReqVO;
import com.zt.plat.module.bpm.controller.admin.definition.vo.form.BpmFormPageReqVO;
import com.zt.plat.module.bpm.dal.dataobject.definition.BpmFormDO;
import com.zt.plat.module.bpm.dal.mysql.definition.BpmFormMapper;
import com.zt.plat.module.bpm.service.definition.dto.BpmFormFieldRespDTO;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.Import;
import jakarta.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

View File

@@ -5,15 +5,16 @@ import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.framework.test.core.ut.BaseDbUnitTest;
import com.zt.plat.framework.test.core.util.AssertUtils;
import com.zt.plat.framework.test.core.util.RandomUtils;
import com.zt.plat.module.bpm.controller.admin.definition.vo.group.BpmUserGroupPageReqVO;
import com.zt.plat.module.bpm.controller.admin.definition.vo.group.BpmUserGroupSaveReqVO;
import com.zt.plat.module.bpm.controller.admin.definition.vo.group.BpmUserGroupPageReqVO;
import com.zt.plat.module.bpm.dal.dataobject.definition.BpmUserGroupDO;
import com.zt.plat.module.bpm.dal.mysql.definition.BpmUserGroupMapper;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.Import;
import jakarta.annotation.Resource;
import java.time.LocalDateTime;
import static com.zt.plat.framework.common.util.date.LocalDateTimeUtils.buildTime;