Merge remote-tracking branch 'refs/remotes/origin/feature/starter' into feature/merge-all
This commit is contained in:
commit
5b2fa9e0ed
@ -1,5 +1,13 @@
|
||||
# Change logs
|
||||
|
||||
### 1.4.0-SNAPSHOT
|
||||
|
||||
> - 新增 workflow-engine-spring-boot-starter 组件,大幅简化业务方接入使用的难度。
|
||||
> - 在 Starter 中新增 MQ 监控功能,避免死信依赖运维。
|
||||
> - 优化发送待办时,提前判断是否有按钮,以及能否支持批量处理。
|
||||
> - 修复同一个实例下,多个人同时操作任务,可能导致数据库的 FK 异常等问题。
|
||||
> - 修复其他的一些小问题
|
||||
|
||||
### 1.3.3-SNAPSHOT
|
||||
|
||||
> - 支持“政务”类型的模型管理。
|
||||
|
||||
29
pom.xml
29
pom.xml
@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
@ -15,7 +16,7 @@
|
||||
<name>workflow-engine</name>
|
||||
|
||||
<properties>
|
||||
<revision>1.3.3-SNAPSHOT</revision>
|
||||
<revision>1.4.0-SNAPSHOT</revision>
|
||||
<axzo-bom.version>2.0.0-SNAPSHOT</axzo-bom.version>
|
||||
<axzo-dependencies.version>2.0.0-SNAPSHOT</axzo-dependencies.version>
|
||||
<feign-httpclient.version>11.8</feign-httpclient.version>
|
||||
@ -25,6 +26,7 @@
|
||||
<dingtalk.version>2.0.0</dingtalk.version>
|
||||
<arthas.version>3.7.1</arthas.version>
|
||||
<apache-maven.version>3.2.5</apache-maven.version>
|
||||
<javaparse.version>3.26.0</javaparse.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
@ -64,11 +66,21 @@
|
||||
<artifactId>workflow-engine-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<!--<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>workflow-auto-gen</artifactId>
|
||||
<version>1.3.3-SNAPSHOT</version>
|
||||
</dependency>-->
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>workflow-engine-server</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.axzo.workflow</groupId>
|
||||
<artifactId>workflow-engine-spring-boot-starter</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.axzo.maokai</groupId>
|
||||
<artifactId>maokai-api</artifactId>
|
||||
@ -99,6 +111,11 @@
|
||||
<artifactId>maven-artifact</artifactId>
|
||||
<version>${apache-maven.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.javaparser</groupId>
|
||||
<artifactId>javaparser-core</artifactId>
|
||||
<version>${javaparse.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
@ -120,6 +137,11 @@
|
||||
<artifactId>mapstruct-processor</artifactId>
|
||||
<version>${mapstruct.version}</version>
|
||||
</path>
|
||||
<path>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
@ -138,6 +160,7 @@
|
||||
<module>workflow-engine-common</module>
|
||||
<module>workflow-engine-core</module>
|
||||
<module>workflow-engine-server</module>
|
||||
|
||||
<module>workflow-engine-support</module>
|
||||
<module>workflow-engine-spring-boot-starter</module>
|
||||
</modules>
|
||||
</project>
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
|
||||
<artifactId>workflow-engine-api</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>workflow-engine-api</name>
|
||||
<name>Workflow Engine Api</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
|
||||
@ -32,7 +32,7 @@ import java.util.regex.Pattern;
|
||||
* @Date: 2022/9/17
|
||||
* @Description:
|
||||
*/
|
||||
@EnableFeignClients(basePackages = {"cn.axzo.workflow.client.feign"})
|
||||
//@EnableFeignClients(basePackages = {"cn.axzo.workflow.client.feign"})
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Slf4j
|
||||
public class WorkflowEngineClientAutoConfiguration {
|
||||
|
||||
@ -20,9 +20,9 @@ public class WorkflowRequestInterceptor implements RequestInterceptor {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
public static final String HEADER_HTTP_CLIENT = "http-client";
|
||||
public static final String HEADER_HTTP_CLIENT_VALUE = "workflowEngine-feign";
|
||||
public static final String HEADER_API_VERSION = "service-version";
|
||||
public static final String HEADER_HTTP_CLIENT = "Http-Client";
|
||||
public static final String HEADER_HTTP_CLIENT_VALUE = "WorkflowEngine-Feign";
|
||||
public static final String HEADER_API_VERSION = "Service-Version";
|
||||
public static final String HEADER_SERVER_NAME = "X-SERVER-NAME";
|
||||
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ package cn.axzo.workflow.client.feign.bpmn;
|
||||
import cn.axzo.workflow.client.config.CommonFeignConfiguration;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnActivitySetAssigneeDTO;
|
||||
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;
|
||||
@ -18,26 +19,29 @@ import javax.validation.constraints.NotBlank;
|
||||
* @author wangli
|
||||
* @since 2023/11/17 16:28
|
||||
*/
|
||||
@FeignClient(name = "workflow-engine", url = "${axzo.service.workflow-engine:http://workflow-engine:8080}", configuration = CommonFeignConfiguration.class)
|
||||
//@FeignClient(name = "workflow-engine", url = "${axzo.service.workflow-engine:http://workflow-engine:8080}", configuration = CommonFeignConfiguration.class)
|
||||
public interface ProcessActivityApi {
|
||||
|
||||
/**
|
||||
* 业务节点唤醒
|
||||
* <p>
|
||||
* 当模型中使用了“业务节点”,且设置了“不设置审批人”模式,则当业务监听到 PROCESS_ACTIVITY_START 事件时,可通过该接口推动流程继续运行
|
||||
*/
|
||||
@GetMapping("/api/process/activity/old/trigger")
|
||||
CommonResponse<Boolean> trigger(@NotBlank(message = "触发 ID 不能为空") @RequestParam String triggerId);
|
||||
|
||||
@GetMapping("/api/process/activity/trigger")
|
||||
CommonResponse<Boolean> trigger(@NotBlank(message = "触发 ID 不能为空") @RequestParam String triggerId,
|
||||
@RequestParam(required = false, defaultValue = "false") Boolean async);
|
||||
CommonResponse<Boolean> trigger(@NotBlank(message = "触发 ID 不能为空") @RequestParam String triggerId);
|
||||
|
||||
|
||||
/**
|
||||
* 业务节点设置审批人, 不支持重复设置
|
||||
* <p>
|
||||
* 当模型中使用了“业务节点”,且设置了“业务指定审批人”模式,则当业务监听到 PROCESS_ACTIVITY_WAIT_ASSIGNEE 事件时,可通过该接口设置动态设置审批人
|
||||
* <p>
|
||||
* <strong color=orange>注意:如果调用接口时,传入的审批人集合为空,流程引擎将对该审批流程实例自动中止。</strong>
|
||||
*
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/api/process/activity/assignee/set")
|
||||
@Operation(summary = "业务节点设置审批人,不支持重复调用设置审批人,需一次性传入所有审批人")
|
||||
CommonResponse<Boolean> setAssignee(@Validated @RequestBody BpmnActivitySetAssigneeDTO dto);
|
||||
}
|
||||
|
||||
@ -1,6 +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.definition.BpmnProcessDefinitionUpdateDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.model.BpmnModelUpdateDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessDefinitionPageDTO;
|
||||
@ -17,13 +19,16 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.SYNC;
|
||||
|
||||
/**
|
||||
* 流程定义 API
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2023/9/21 16:25
|
||||
*/
|
||||
@FeignClient(name = "workflow-engine", url = "${axzo.service.workflow-engine:http://workflow-engine:8080}", configuration = CommonFeignConfiguration.class)
|
||||
//@FeignClient(name = "workflow-engine", url = "${axzo.service.workflow-engine:http://workflow-engine:8080}", configuration = CommonFeignConfiguration.class)
|
||||
@Manageable
|
||||
public interface ProcessDefinitionApi {
|
||||
|
||||
|
||||
@ -31,6 +36,7 @@ public interface ProcessDefinitionApi {
|
||||
* 获取活跃的流程定义分页
|
||||
*/
|
||||
@GetMapping("/api/process/definition/page")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<BpmPageResult<BpmnProcessDefinitionVO>> getProcessDefinitionPage(@Validated @RequestBody BpmnProcessDefinitionPageDTO dto);
|
||||
|
||||
/**
|
||||
@ -40,6 +46,7 @@ public interface ProcessDefinitionApi {
|
||||
* @return
|
||||
*/
|
||||
@PutMapping("/api/process/definition/update")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<Boolean> updateProcessDefinition(@Validated @RequestBody BpmnProcessDefinitionUpdateDTO dto);
|
||||
|
||||
/**
|
||||
@ -49,6 +56,7 @@ public interface ProcessDefinitionApi {
|
||||
* @return 流程定义
|
||||
*/
|
||||
@GetMapping("/api/process/definition/get")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<BpmnProcessDefinitionVO> getProcessDefinition(@NotBlank(message = "流程定义 ID 不能为空") @RequestParam String processDefinitionId);
|
||||
|
||||
/**
|
||||
@ -58,6 +66,7 @@ public interface ProcessDefinitionApi {
|
||||
* @return 流程定义
|
||||
*/
|
||||
@GetMapping("/api/process/definition/getByDeploymentId")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<BpmnProcessDefinitionVO> getProcessDefinitionByDeploymentId(
|
||||
@NotBlank(message = "流程部署 ID 不能为空") @RequestParam String deploymentId);
|
||||
|
||||
@ -69,6 +78,7 @@ public interface ProcessDefinitionApi {
|
||||
* @return 流程定义
|
||||
*/
|
||||
@GetMapping("/api/process/definition/active/getByKey")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<BpmnProcessDefinitionVO> getActiveProcessDefinitionByKey(@NotBlank(message = "模型定义KEY不能为空") @RequestParam String key);
|
||||
|
||||
|
||||
@ -79,6 +89,7 @@ public interface ProcessDefinitionApi {
|
||||
* {@see SuspensionState}
|
||||
*/
|
||||
@PutMapping("/api/process/definition/state/update")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<Boolean> getActiveProcessDefinitionByKey(@NotBlank(message = "流程定义ID不能为空") @RequestParam String processDefinitionId,
|
||||
@NotNull(message = "状态不能为空") @RequestParam Integer state);
|
||||
|
||||
@ -88,6 +99,7 @@ public interface ProcessDefinitionApi {
|
||||
* @return 流程定义ID
|
||||
*/
|
||||
@GetMapping("/api/process/definition/active/getByCategory")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<String> getActiveProcessDefinitionId(@RequestParam(required = false) String tenantId,
|
||||
@NotBlank(message = "分类不能为空") @RequestParam(required = false) String category);
|
||||
|
||||
@ -97,6 +109,7 @@ public interface ProcessDefinitionApi {
|
||||
* @return 流程定义ID
|
||||
*/
|
||||
@GetMapping("/api/process/definition/active/json/model")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<BpmnModelUpdateDTO> getActiveProcessDefinitionJsonModel(@NotBlank(message = "模型 ID 不能为空") @RequestParam(required = false) String modelId,
|
||||
@NotBlank(message = "分类不能为空") @RequestParam(required = false) String category,
|
||||
@RequestParam(required = false) String tenantId);
|
||||
@ -109,6 +122,7 @@ public interface ProcessDefinitionApi {
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/api/process/definition/delete")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<Void> delete(@NotBlank(message = "流程定义部署 ID 不能为空") String deploymentId,
|
||||
@RequestParam(required = false) Boolean cascade);
|
||||
}
|
||||
|
||||
@ -1,6 +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.process.BpmnProcessInstanceAbortDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAdminPageReqVO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCancelDTO;
|
||||
@ -34,28 +36,16 @@ import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.SYNC;
|
||||
|
||||
/**
|
||||
* 流程实例 API
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2023/9/21 16:26
|
||||
*/
|
||||
@FeignClient(name = "workflow-engine", url = "${axzo.service.workflow-engine:http://workflow-engine:8080}", configuration = CommonFeignConfiguration.class)
|
||||
//@FeignClient(name = "workflow-engine", url = "${axzo.service.workflow-engine:http://workflow-engine:8080}", configuration = CommonFeignConfiguration.class)
|
||||
public interface ProcessInstanceApi {
|
||||
/**
|
||||
* 查询所有的审批流
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/api/process/instance/page/all")
|
||||
CommonResponse<BpmPageResult<BpmnProcessInstanceAdminPageItemVO>> getAllProcessInstancePage(@Validated @RequestBody BpmnProcessInstanceAdminPageReqVO dto);
|
||||
|
||||
/**
|
||||
* 我发起的审批列表
|
||||
*/
|
||||
@PostMapping("/api/process/instance/page/my")
|
||||
CommonResponse<BpmPageResult<BpmnProcessInstancePageItemVO>> getMyProcessInstancePage(@Validated @RequestBody BpmnProcessInstanceMyPageReqVO dto);
|
||||
|
||||
/**
|
||||
* 创建审批流程
|
||||
*
|
||||
@ -67,18 +57,11 @@ public interface ProcessInstanceApi {
|
||||
*
|
||||
* @param dto {@link BpmnProcessInstanceCreateDTO}
|
||||
*/
|
||||
@Operation(summary = "创建审批流程, MQ 触发规则:1. 当前流程实例会依次触发 process-instance-created 和 process-instance-started 事件,2. 第一个审批任务会依次触发 process-task-assigned 和 process-task-created 事件")
|
||||
@PostMapping("/api/process/instance/create")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<String> createProcessInstance(@Validated @RequestBody BpmnProcessInstanceCreateDTO dto);
|
||||
|
||||
/**
|
||||
* 创建审批流程并带上表单
|
||||
*
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/api/process/instance/form/create")
|
||||
CommonResponse<String> createProcessInstanceWith(@Validated @RequestBody BpmnProcessInstanceCreateWithFormDTO dto);
|
||||
|
||||
/**
|
||||
* 发起人主动撤回审核
|
||||
*
|
||||
@ -91,6 +74,7 @@ public interface ProcessInstanceApi {
|
||||
* @param dto {@link BpmnProcessInstanceCancelDTO}
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "发起人主动撤回审核,MQ 触发规则:1. 当前流程实例中现存的任务会依次触发 process-task-deleted 事件,2. 当前流程实例会触发 process-instance-cancelled 事件")
|
||||
@DeleteMapping("/api/process/instance/cancel")
|
||||
CommonResponse<Boolean> cancelProcessInstance(@Validated @RequestBody BpmnProcessInstanceCancelDTO dto);
|
||||
|
||||
@ -100,6 +84,7 @@ public interface ProcessInstanceApi {
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "中止流程实例")
|
||||
@DeleteMapping("/api/process/instance/abort")
|
||||
CommonResponse<Boolean> abortProcessInstance(@Validated @RequestBody BpmnProcessInstanceAbortDTO dto);
|
||||
|
||||
@ -109,16 +94,19 @@ public interface ProcessInstanceApi {
|
||||
* @param dtos
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "批量中止流程实例")
|
||||
@DeleteMapping("/api/process/instance/batch/abort")
|
||||
CommonResponse<BatchOperationResultVO> batchAbortProcessInstance(@Validated @RequestBody List<BpmnProcessInstanceAbortDTO> dtos);
|
||||
|
||||
/**
|
||||
* 抄送流程实例
|
||||
* 抄送流程实例(未实现)
|
||||
*
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "抄送流程实例")
|
||||
@PostMapping("/api/process/instance/carbon-copy")
|
||||
@Deprecated
|
||||
CommonResponse<Boolean> carbonCopyProcessInstance(@Validated @RequestBody BpmnProcessInstanceCarbonCopyDTO dto);
|
||||
|
||||
/**
|
||||
@ -127,9 +115,56 @@ public interface ProcessInstanceApi {
|
||||
* @param dto {@link BpmnProcessInstanceQueryDTO} 可根据 Id,BusinessKey进行查询
|
||||
* @return 流程实例, 租户Id不必传
|
||||
*/
|
||||
@Operation(summary = "获得流程实例")
|
||||
@GetMapping("/api/process/instance/get")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<BpmnProcessInstanceVO> getProcessInstanceVO(@Validated @RequestBody BpmnProcessInstanceQueryDTO dto);
|
||||
|
||||
/**
|
||||
* 获取指定流程实例的流程变量
|
||||
*
|
||||
* @param processInstanceId
|
||||
* @param tenantId
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "获取指定流程实例的流程变量")
|
||||
@GetMapping("/api/process/instance/cooperation-org")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<Map<String, Object>> getProcessVariables(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId,
|
||||
@Nullable @RequestParam(required = false) String tenantId);
|
||||
|
||||
/**
|
||||
* 创建审批流程并带上表单
|
||||
*
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "创建审批流程并带上表单")
|
||||
@PostMapping("/api/process/instance/form/create")
|
||||
@Manageable
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<String> createProcessInstanceWith(@Validated @RequestBody BpmnProcessInstanceCreateWithFormDTO dto);
|
||||
|
||||
/**
|
||||
* 查询所有的审批流
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "查询所有的审批流")
|
||||
@PostMapping("/api/process/instance/page/all")
|
||||
@Manageable
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<BpmPageResult<BpmnProcessInstanceAdminPageItemVO>> getAllProcessInstancePage(@Validated @RequestBody BpmnProcessInstanceAdminPageReqVO dto);
|
||||
|
||||
/**
|
||||
* 我发起的审批列表
|
||||
*/
|
||||
@Operation(summary = "我发起的审批列表")
|
||||
@PostMapping("/api/process/instance/page/my")
|
||||
@Manageable
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<BpmPageResult<BpmnProcessInstancePageItemVO>> getMyProcessInstancePage(@Validated @RequestBody BpmnProcessInstanceMyPageReqVO dto);
|
||||
|
||||
/**
|
||||
* 更新流程定义的状态
|
||||
*
|
||||
@ -138,6 +173,8 @@ public interface ProcessInstanceApi {
|
||||
*/
|
||||
@Operation(summary = "更新指定流程定义的版本的状态, 处于 suspended 状态的流程模型将不能再发起实例")
|
||||
@PutMapping("/api/process/instance/status/update")
|
||||
@Manageable
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<Boolean> updateProcessStatus(@NotBlank(message = "流程定义 ID 不能为空") @RequestParam String processDefinitionId,
|
||||
@NotNull(message = "状态不能为空") @RequestParam Integer status);
|
||||
|
||||
@ -148,7 +185,10 @@ public interface ProcessInstanceApi {
|
||||
* @param tenantId
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "获取审批流程实例的运行图")
|
||||
@GetMapping("/api/process/instance/graphical")
|
||||
@Manageable
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<ObjectNode> processInstanceGraphical(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId,
|
||||
@Nullable @RequestParam(required = false) String tenantId);
|
||||
|
||||
@ -157,7 +197,10 @@ public interface ProcessInstanceApi {
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "推断指定流程实例的所有节点执行顺序")
|
||||
@GetMapping("/api/process/instance/node/forecasting")
|
||||
@Manageable
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<List<ProcessNodeDetailVO>> processInstanceNodeForecast(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam(required = false) String processInstanceId,
|
||||
@Nullable @RequestParam(required = false) String tenantId);
|
||||
|
||||
@ -168,23 +211,15 @@ public interface ProcessInstanceApi {
|
||||
* 如果为假时,才结合 nodeDefinitionKeys 过滤掉传入的节点
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "推断指定流程实例的过滤掉部分节点执行顺序")
|
||||
@GetMapping("/api/process/instance/node/filter/forecasting")
|
||||
@Manageable
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<List<ProcessNodeDetailVO>> processInstanceFilterNodeForecast(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam(required = false) String processInstanceId,
|
||||
@Nullable @RequestParam(required = false) String tenantId,
|
||||
@RequestParam(required = false, defaultValue = "false") Boolean allNode,
|
||||
@Nullable @RequestParam(required = false) List<String> nodeDefinitionKeys);
|
||||
|
||||
/**
|
||||
* 获取指定流程实例的流程变量
|
||||
*
|
||||
* @param processInstanceId
|
||||
* @param tenantId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/api/process/instance/cooperation-org")
|
||||
CommonResponse<Map<String, Object>> getProcessVariables(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId,
|
||||
@Nullable @RequestParam(required = false) String tenantId);
|
||||
|
||||
/**
|
||||
* 查询实例的租户集合
|
||||
*
|
||||
@ -192,6 +227,8 @@ public interface ProcessInstanceApi {
|
||||
*/
|
||||
@Operation(summary = "查询实例的租户集合")
|
||||
@GetMapping("/api/process/instance/tenant/ids")
|
||||
@Manageable
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<List<String>> getTenantIds();
|
||||
|
||||
/**
|
||||
@ -201,5 +238,7 @@ public interface ProcessInstanceApi {
|
||||
*/
|
||||
@Operation(summary = "校验指定流程实例下,是否存在指定的审批人")
|
||||
@PostMapping("/api/process/instance/check/approver")
|
||||
@Manageable
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<Boolean> checkInstanceApprover(@Validated @RequestBody BpmnProcessInstanceCheckApproverDTO dto);
|
||||
}
|
||||
|
||||
@ -1,15 +1,30 @@
|
||||
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.azxo.framework.common.model.CommonResponse;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
@FeignClient(name = "workflow-engine", url = "${axzo.service.workflow-engine:http://workflow-engine:8080}", configuration = CommonFeignConfiguration.class)
|
||||
import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.SYNC;
|
||||
|
||||
//@FeignClient(name = "workflow-engine", url = "${axzo.service.workflow-engine:http://workflow-engine:8080}", configuration = CommonFeignConfiguration.class)
|
||||
public interface ProcessJobApi {
|
||||
|
||||
/**
|
||||
* 将死信队列中的任务转移到正常 JOB 队列中
|
||||
* <p>
|
||||
* 入参是二选一:当只有 jobId 时,仅将指定的 JOB 转移到正常的队列中;
|
||||
* 而传入的是具体的实例 ID,那么会将这个流程下的所有在死信队列中的任务都转移到正常的队列中
|
||||
*
|
||||
* @param jobId 具体的 JOB ID
|
||||
* @param procInstId 具体的实例 ID
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/api/process/job/dead-letter/resume")
|
||||
@Manageable
|
||||
CommonResponse<Void> executeDeadLetterJobAction(@RequestParam(required = false) String jobId,
|
||||
@RequestParam(required = false) String procInstId);
|
||||
}
|
||||
|
||||
@ -1,6 +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.model.BpmnModelCreateDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.model.BpmnModelSearchDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.model.BpmnModelUpdateDTO;
|
||||
@ -22,13 +24,16 @@ import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.SYNC;
|
||||
|
||||
/**
|
||||
* 流程模型 API
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2023/9/21 15:47
|
||||
*/
|
||||
@FeignClient(name = "workflow-engine", url = "${axzo.service.workflow-engine:http://workflow-engine:8080}", configuration = CommonFeignConfiguration.class)
|
||||
//@FeignClient(name = "workflow-engine", url = "${axzo.service.workflow-engine:http://workflow-engine:8080}", configuration = CommonFeignConfiguration.class)
|
||||
@Manageable
|
||||
public interface ProcessModelApi {
|
||||
|
||||
/**
|
||||
@ -39,6 +44,7 @@ public interface ProcessModelApi {
|
||||
*/
|
||||
@Operation(summary = "流程模型列表")
|
||||
@GetMapping("/api/process/model/page")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<BpmPageResult<BpmnModelDetailVO>> page(@Validated @RequestBody BpmnModelSearchDTO dto);
|
||||
|
||||
/**
|
||||
@ -47,6 +53,7 @@ public interface ProcessModelApi {
|
||||
*/
|
||||
@Operation(summary = "创建流程模型")
|
||||
@PostMapping("/api/process/model/create")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<String> create(@Validated @RequestBody BpmnModelCreateDTO dto);
|
||||
|
||||
/**
|
||||
@ -54,6 +61,7 @@ public interface ProcessModelApi {
|
||||
*/
|
||||
@Operation(summary = "通过模型ID查询指定流程模型")
|
||||
@GetMapping("/api/process/model/get")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<BpmnModelDetailVO> getById(@NotBlank(message = "流程模型 ID 不能为空") @RequestParam(required = false) String processModelId,
|
||||
@RequestParam(required = false) String tenantId);
|
||||
|
||||
@ -62,6 +70,7 @@ public interface ProcessModelApi {
|
||||
*/
|
||||
@Operation(summary = "通过模型KEY查询指定流程模型")
|
||||
@GetMapping("/api/process/model/getByKey")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<BpmnModelDetailVO> getByKey(@NotBlank(message = "流程模型 KEY 不能为空") @RequestParam(required = false) String processModelKey,
|
||||
@NotBlank(message = "租户不能为空") @RequestParam(required = false) String tenantId);
|
||||
|
||||
@ -74,6 +83,7 @@ public interface ProcessModelApi {
|
||||
*/
|
||||
@Operation(summary = "获取指定模型的扩展属性")
|
||||
@GetMapping("/api/process/model/ext")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<BpmnModelExtVO> getModelExt(@NotBlank(message = "模型 ID 不能为空") @RequestParam(required = false) String modelId);
|
||||
|
||||
/**
|
||||
@ -81,6 +91,7 @@ public interface ProcessModelApi {
|
||||
*/
|
||||
@Operation(summary = "更新流程模型")
|
||||
@PutMapping("/api/process/model/update")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<String> update(@RequestBody BpmnModelUpdateDTO dto);
|
||||
|
||||
|
||||
@ -91,6 +102,7 @@ public interface ProcessModelApi {
|
||||
*/
|
||||
@Operation(summary = "通过模型 ID 部署流程模型")
|
||||
@PostMapping("/api/process/model/deploy")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<String> deployById(@NotBlank(message = "流程模型 ID 不能为空") @RequestParam(required = false) String processModelId,
|
||||
@RequestParam(required = false, defaultValue = "") String modelTenantId,
|
||||
@RequestParam(required = false) String operator);
|
||||
@ -102,6 +114,7 @@ public interface ProcessModelApi {
|
||||
*/
|
||||
@Operation(summary = "通过模型 KEY 部署流程模型")
|
||||
@PostMapping("/api/process/model/deployByKey")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<String> deployByKey(@NotBlank(message = "流程模型 KEY 不能为空") @RequestParam(required = false) String processModelKey,
|
||||
@NotBlank(message = "租户不能为空") @RequestParam(required = false) String modelTenantId,
|
||||
@RequestParam(required = false) String operator);
|
||||
@ -116,6 +129,7 @@ public interface ProcessModelApi {
|
||||
*/
|
||||
@Operation(summary = "通过模型 ID 取消部署流程模型")
|
||||
@PostMapping("/api/process/model/undeploy")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<Void> unDeployById(@NotBlank(message = "流程模型 ID 不能为空") @RequestParam(required = false) String processModelId,
|
||||
@RequestParam(required = false, defaultValue = "") String tenantId,
|
||||
@RequestParam(required = false) String operator);
|
||||
@ -125,6 +139,7 @@ public interface ProcessModelApi {
|
||||
*/
|
||||
@Operation(summary = "删除指定模型 ID 的流程模型")
|
||||
@DeleteMapping("/api/process/model/delete")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<Void> deleteById(@NotBlank(message = "流程模型 ID 不能为空") @RequestParam String processModelId,
|
||||
@RequestParam(required = false, defaultValue = "") String tenantId);
|
||||
|
||||
@ -137,6 +152,7 @@ public interface ProcessModelApi {
|
||||
*/
|
||||
@Operation(summary = "删除指定模型 KEY 的流程模型")
|
||||
@DeleteMapping("/api/process/model/deleteByKey")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<Void> deleteByKey(@NotBlank(message = "流程模型 KEY 不能为空") @RequestParam String processModelKey,
|
||||
@RequestParam(required = false, defaultValue = "") String tenantId);
|
||||
|
||||
@ -150,6 +166,7 @@ public interface ProcessModelApi {
|
||||
*/
|
||||
@Operation(summary = "修改模型状态")
|
||||
@PostMapping("/api/process/model/changeStatus")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<Void> changeStatus(@NotBlank(message = "模型 ID 不能为空") @RequestParam String modelId,
|
||||
@NotNull(message = "状态不能为空") @RequestParam Integer status,
|
||||
@RequestParam(required = false) String operator);
|
||||
@ -161,6 +178,7 @@ public interface ProcessModelApi {
|
||||
*/
|
||||
@Operation(summary = "查询流程模型使用的分类列表")
|
||||
@GetMapping("/api/process/model/category/ids")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<List<String>> getModelCategoryList();
|
||||
|
||||
/**
|
||||
@ -170,5 +188,6 @@ public interface ProcessModelApi {
|
||||
*/
|
||||
@Operation(summary = "查询模型的租户集合")
|
||||
@GetMapping("/api/process/model/tenant/ids")
|
||||
CommonResponse<List<String>> getTenantIds();
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<List<String>> getModelTenantIds();
|
||||
}
|
||||
|
||||
@ -1,6 +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.BpmnRobotTaskCompleteDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCreateDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAttachmentDTO;
|
||||
@ -28,10 +30,12 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.SYNC;
|
||||
|
||||
|
||||
/**
|
||||
* 流程任务 API
|
||||
@ -39,46 +43,9 @@ import java.util.Map;
|
||||
* @author wangli
|
||||
* @since 2023/9/21 16:26
|
||||
*/
|
||||
@FeignClient(name = "workflow-engine", url = "${axzo.service.workflow-engine:http://workflow-engine:8080}", configuration = CommonFeignConfiguration.class)
|
||||
//@FeignClient(name = "workflow-engine", url = "${axzo.service.workflow-engine:http://workflow-engine:8080}", configuration = CommonFeignConfiguration.class)
|
||||
public interface ProcessTaskApi {
|
||||
|
||||
/**
|
||||
* 待审核列表
|
||||
*/
|
||||
@GetMapping("/api/process/task/page/todo")
|
||||
CommonResponse<BpmPageResult<BpmnTaskTodoPageItemVO>> getTodoTaskPage(@Validated @RequestBody BpmnTaskPageSearchDTO dto);
|
||||
|
||||
/**
|
||||
* 已完成的审批列表
|
||||
*/
|
||||
@GetMapping("/api/process/task/page/done")
|
||||
CommonResponse<BpmPageResult<BpmnTaskDonePageItemVO>> getDoneTaskPage(@Validated @RequestBody BpmnTaskPageSearchDTO dto);
|
||||
|
||||
/**
|
||||
* 获取指定流程实例的审批过程信息
|
||||
* <p>
|
||||
* 同一层级结构
|
||||
*/
|
||||
@GetMapping("/api/process/task/list/flat")
|
||||
CommonResponse<List<BpmnHistoricTaskInstanceVO>> getTaskListFlatByProcessInstanceId(@NotBlank(message = "流程实例 ID " +
|
||||
"不能为空") @RequestParam String processInstanceId, @Nullable @RequestParam(required = false) String tenantId);
|
||||
|
||||
/**
|
||||
* 获取指定流程实例的审批过程信息
|
||||
* <p>
|
||||
* 分组结构
|
||||
*/
|
||||
@GetMapping("/api/process/task/list/group")
|
||||
CommonResponse<List<BpmnHistoricTaskInstanceGroupVO>> getTaskListGroupByProcessInstanceId(@NotBlank(message =
|
||||
"流程实例 ID 不能为空") @RequestParam String processInstanceId, @Nullable @RequestParam(required = false) String tenantId);
|
||||
|
||||
/**
|
||||
* 获取实例正在审核的人列表
|
||||
*/
|
||||
@GetMapping("/api/process/task/active/list")
|
||||
CommonResponse<List<BpmnTaskInstanceVO>> getActiveTasksByProcessInstanceId(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId,
|
||||
@NotBlank(message = "租户不能为空") @RequestParam String tenantId);
|
||||
|
||||
/**
|
||||
* 同意
|
||||
*
|
||||
@ -90,6 +57,7 @@ public interface ProcessTaskApi {
|
||||
* 2.2. 流程实例正常结束会触发 process-instance-completed 事件
|
||||
* </pre>
|
||||
*/
|
||||
@Operation(summary = "同意,MQ 触发规则:1. 当前审批任务会依次触发 process-task-completed 和 process-task-deleted 事件(如果有下一级审批,则会触发第 2.1 点中的事件,如果当前审核任务最后一级审批,则会触发第 2.2 点中的事件),2.1. 下一级审批任务会依次触发 process-task-assigned 和 process-task-created 事件,2.2. 流程实例正常结束会触发 process-instance-completed 事件")
|
||||
@PostMapping("/api/process/task/approve")
|
||||
CommonResponse<Boolean> approveTask(@Validated @RequestBody BpmnTaskAuditDTO dto);
|
||||
|
||||
@ -99,6 +67,7 @@ public interface ProcessTaskApi {
|
||||
* @param dtos
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "批量同意")
|
||||
@PostMapping("/api/process/task/batch/approve")
|
||||
CommonResponse<BatchOperationResultVO> batchApproveTask(@Validated @RequestBody List<BpmnTaskAuditDTO> dtos);
|
||||
|
||||
@ -111,6 +80,7 @@ public interface ProcessTaskApi {
|
||||
* 2. 当前流程实例会触发 process-instance-rejected 事件
|
||||
* </pre>
|
||||
*/
|
||||
@Operation(summary = "驳回,MQ 触发规则:1. 当前审批任务会触发 process-task-deleted 事件, 2. 当前流程实例会触发 process-instance-rejected 事件")
|
||||
@PostMapping("/api/process/task/reject")
|
||||
CommonResponse<Boolean> rejectTask(@Validated @RequestBody BpmnTaskAuditDTO dto);
|
||||
|
||||
@ -153,16 +123,6 @@ public interface ProcessTaskApi {
|
||||
@PostMapping("/api/process/task/comment")
|
||||
CommonResponse<Boolean> commentTask(@Validated @RequestBody BpmnTaskCommentDTO dto);
|
||||
|
||||
/**
|
||||
* 添加附件
|
||||
*
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "添加附件")
|
||||
@PostMapping("/api/process/task/attachment")
|
||||
CommonResponse<Void> addAttachment(@Validated @RequestBody BpmnTaskAttachmentDTO dto);
|
||||
|
||||
/**
|
||||
* 加签
|
||||
*
|
||||
@ -181,6 +141,8 @@ public interface ProcessTaskApi {
|
||||
*/
|
||||
@Operation(summary = "审批流程催办")
|
||||
@PostMapping("/api/process/task/remind")
|
||||
@Manageable
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<Boolean> remindTask(@Validated @RequestBody BpmnTaskRemindDTO dto);
|
||||
|
||||
/**
|
||||
@ -203,6 +165,69 @@ public interface ProcessTaskApi {
|
||||
@PostMapping("/api/process/task/robot/complete")
|
||||
CommonResponse<Boolean> completeRobotTask(@Validated @RequestBody BpmnRobotTaskCompleteDTO dto);
|
||||
|
||||
/**
|
||||
* 添加附件
|
||||
*
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "添加附件")
|
||||
@PostMapping("/api/process/task/attachment")
|
||||
@Manageable
|
||||
CommonResponse<Void> addAttachment(@Validated @RequestBody BpmnTaskAttachmentDTO dto);
|
||||
|
||||
/**
|
||||
* 待审核列表
|
||||
*/
|
||||
@Operation(summary = "待审核列表")
|
||||
@GetMapping("/api/process/task/page/todo")
|
||||
@Manageable
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<BpmPageResult<BpmnTaskTodoPageItemVO>> getTodoTaskPage(@Validated @RequestBody BpmnTaskPageSearchDTO dto);
|
||||
|
||||
/**
|
||||
* 已完成的审批列表
|
||||
*/
|
||||
@Operation(summary = "已完成的审批列表")
|
||||
@GetMapping("/api/process/task/page/done")
|
||||
@Manageable
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<BpmPageResult<BpmnTaskDonePageItemVO>> getDoneTaskPage(@Validated @RequestBody BpmnTaskPageSearchDTO dto);
|
||||
|
||||
/**
|
||||
* 获取指定流程实例的审批过程信息
|
||||
* <p>
|
||||
* 同一层级结构
|
||||
*/
|
||||
@Operation(summary = "获取指定流程实例的审批过程信息")
|
||||
@GetMapping("/api/process/task/list/flat")
|
||||
@Manageable
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<List<BpmnHistoricTaskInstanceVO>> getTaskListFlatByProcessInstanceId(@NotBlank(message = "流程实例 ID " +
|
||||
"不能为空") @RequestParam String processInstanceId, @Nullable @RequestParam(required = false) String tenantId);
|
||||
|
||||
/**
|
||||
* 获取指定流程实例的审批过程信息
|
||||
* <p>
|
||||
* 分组结构
|
||||
*/
|
||||
@Operation(summary = "获取指定流程实例的审批过程信息")
|
||||
@GetMapping("/api/process/task/list/group")
|
||||
@Manageable
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<List<BpmnHistoricTaskInstanceGroupVO>> getTaskListGroupByProcessInstanceId(@NotBlank(message =
|
||||
"流程实例 ID 不能为空") @RequestParam String processInstanceId, @Nullable @RequestParam(required = false) String tenantId);
|
||||
|
||||
/**
|
||||
* 获取实例正在审核的人列表
|
||||
*/
|
||||
@Operation(summary = "获取实例正在审核的人列表")
|
||||
@GetMapping("/api/process/task/active/list")
|
||||
@Manageable
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<List<BpmnTaskInstanceVO>> getActiveTasksByProcessInstanceId(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId,
|
||||
@NotBlank(message = "租户不能为空") @RequestParam String tenantId);
|
||||
|
||||
/**
|
||||
* 根据实例 ID 和自然人 ID 查询对应待处理的任务 ID
|
||||
*
|
||||
@ -210,6 +235,8 @@ public interface ProcessTaskApi {
|
||||
*/
|
||||
@Operation(summary = "根据实例 ID 和自然人 ID 查询对应待处理的任务 ID")
|
||||
@GetMapping("/api/process/task/find")
|
||||
@Manageable
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<String> findTaskIdByInstanceIdAndPersonId(@RequestParam(required = false) @NotBlank(message = "流程实例 ID 不能为空") String processInstanceId,
|
||||
@RequestParam(required = false) @NotBlank(message = "自然人 ID 不能为空") String personId);
|
||||
|
||||
@ -220,6 +247,8 @@ public interface ProcessTaskApi {
|
||||
*/
|
||||
@Operation(summary = "根据实例 ID列表 和自然人 ID 查询对应待处理的任务 ID")
|
||||
@GetMapping("/api/process/task/batch/find")
|
||||
CommonResponse<Map<String, String>> findTaskIdByInstanceIdsAndPersonId(@RequestParam(required = false) @NotNull(message = "流程实例 ID列表 不能为空") List<String> processInstanceIds,
|
||||
@Manageable
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<Map<String, String>> findTaskIdByInstanceIdsAndPersonId(@RequestParam(required = false) @NotEmpty(message = "流程实例 ID列表 不能为空") List<String> processInstanceIds,
|
||||
@RequestParam(required = false) @NotBlank(message = "自然人 ID 不能为空") String personId);
|
||||
}
|
||||
|
||||
@ -1,6 +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.RestBpmnProcessVariable;
|
||||
import cn.azxo.framework.common.model.CommonResponse;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
@ -13,16 +15,20 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.SYNC;
|
||||
|
||||
/**
|
||||
* 流程变量api
|
||||
*/
|
||||
@FeignClient(name = "workflow-engine", url = "${axzo.service.workflow-engine:http://workflow-engine:8080}", configuration = CommonFeignConfiguration.class)
|
||||
//@FeignClient(name = "workflow-engine", url = "${axzo.service.workflow-engine:http://workflow-engine:8080}", configuration = CommonFeignConfiguration.class)
|
||||
@Manageable
|
||||
public interface ProcessVariableApi {
|
||||
|
||||
/**
|
||||
* 为指定流程新增变量
|
||||
*/
|
||||
@PostMapping("/api/process/variable/create/{executionId}")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<Void> createVariable(@PathVariable @NotBlank(message = "流程实例 ID 不能为空") String executionId,
|
||||
@RequestBody @Validated RestBpmnProcessVariable restVariable);
|
||||
|
||||
@ -34,6 +40,7 @@ public interface ProcessVariableApi {
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/api/process/variable/update/{executionId}")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<Void> updateVariable(@PathVariable @NotBlank(message = "流程实例 ID 不能为空") String executionId,
|
||||
@RequestBody @Validated RestBpmnProcessVariable restVariable);
|
||||
|
||||
@ -41,6 +48,7 @@ public interface ProcessVariableApi {
|
||||
* 批量删除流程变量
|
||||
*/
|
||||
@DeleteMapping("/api/process/variable/delete/{executionId}")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<Void> deleteVariables(@PathVariable("executionId") String executionId,
|
||||
@RequestParam String variableNames,
|
||||
@RequestParam(value = "scope", required = false) String scope);
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package cn.axzo.workflow.client.feign.manage;
|
||||
|
||||
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.category.CategoryConfigCreateDTO;
|
||||
import cn.axzo.workflow.common.model.request.category.CategoryConfigSearchDTO;
|
||||
import cn.axzo.workflow.common.model.request.category.CategoryCreateDTO;
|
||||
@ -22,6 +24,8 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.SYNC;
|
||||
|
||||
|
||||
/**
|
||||
* OMS流程业务管理API
|
||||
@ -31,7 +35,8 @@ import java.util.List;
|
||||
* @date 2023/11/6 16:01
|
||||
*/
|
||||
|
||||
@FeignClient(name = "workflow-engine", url = "${axzo.service.workflow-engine:http://workflow-engine:8080}", configuration = CommonFeignConfiguration.class)
|
||||
//@FeignClient(name = "workflow-engine", url = "${axzo.service.workflow-engine:http://workflow-engine:8080}", configuration = CommonFeignConfiguration.class)
|
||||
@Manageable
|
||||
public interface ProcessCategoryApi {
|
||||
|
||||
/**
|
||||
@ -40,6 +45,7 @@ public interface ProcessCategoryApi {
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/api/process/category/get")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<CategoryItemVO> get(@RequestParam Long id);
|
||||
|
||||
/**
|
||||
@ -49,6 +55,7 @@ public interface ProcessCategoryApi {
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/api/process/category/getByIds")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<List<CategoryItemVO>> getByIds(@RequestParam List<Long> ids);
|
||||
|
||||
/**
|
||||
@ -58,6 +65,7 @@ public interface ProcessCategoryApi {
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/api/process/category/getByValues")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<List<CategoryItemVO>> getByValues(@RequestParam List<String> values);
|
||||
|
||||
/**
|
||||
@ -66,6 +74,7 @@ public interface ProcessCategoryApi {
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/api/process/category/create")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<CategoryItemVO> create(@Validated @RequestBody CategoryCreateDTO req);
|
||||
|
||||
/**
|
||||
@ -74,6 +83,7 @@ public interface ProcessCategoryApi {
|
||||
* @return
|
||||
*/
|
||||
@PutMapping("/api/process/category/update")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<CategoryItemVO> update(@Validated @RequestBody CategoryUpdateDTO dto);
|
||||
|
||||
/**
|
||||
@ -83,6 +93,7 @@ public interface ProcessCategoryApi {
|
||||
* @return
|
||||
*/
|
||||
@DeleteMapping("/api/process/category/delete")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<Boolean> delete(@RequestParam Long id);
|
||||
|
||||
/**
|
||||
@ -93,6 +104,7 @@ public interface ProcessCategoryApi {
|
||||
* @return
|
||||
*/
|
||||
@PutMapping("/api/process/category/update/state")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<Boolean> updateState(@RequestParam Long id, @RequestParam Boolean state);
|
||||
|
||||
/**
|
||||
@ -101,6 +113,7 @@ public interface ProcessCategoryApi {
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/api/process/category/list")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<List<CategoryItemVO>> list(@RequestBody CategorySearchDTO dto);
|
||||
|
||||
/**
|
||||
@ -109,6 +122,7 @@ public interface ProcessCategoryApi {
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/api/process/category/page/search")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<BpmPageResult<CategoryItemVO>> search(@RequestBody CategorySearchDTO dto);
|
||||
|
||||
/**
|
||||
@ -118,6 +132,7 @@ public interface ProcessCategoryApi {
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/api/process/category/config/create")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<Boolean> createConfig(@RequestBody CategoryConfigCreateDTO dto);
|
||||
|
||||
/**
|
||||
@ -127,6 +142,7 @@ public interface ProcessCategoryApi {
|
||||
* @return
|
||||
*/
|
||||
@DeleteMapping("/api/process/category/config/delete/{id}")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<Boolean> deleteConfig(@PathVariable Long id);
|
||||
|
||||
/**
|
||||
@ -135,6 +151,7 @@ public interface ProcessCategoryApi {
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/api/process/category/config/page/search")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<BpmPageResult<CategoryConfigItemVO>> configSearch(@RequestBody CategoryConfigSearchDTO dto);
|
||||
|
||||
/**
|
||||
@ -145,6 +162,7 @@ public interface ProcessCategoryApi {
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/api/process/category/config/type/update")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<Boolean> updateCategoryConfigType(@RequestParam Long id, @RequestParam String configType);
|
||||
|
||||
/**
|
||||
@ -155,5 +173,6 @@ public interface ProcessCategoryApi {
|
||||
* @return true: 可以发起创建流程实例, false: 不可用
|
||||
*/
|
||||
@GetMapping("/api/process/category/check/status")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<Boolean> checkCategoryStatus(@RequestParam Long tenantId, @RequestParam String categoryCode);
|
||||
}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package cn.axzo.workflow.client.feign.manage;
|
||||
|
||||
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;
|
||||
@ -8,6 +10,8 @@ import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.SYNC;
|
||||
|
||||
|
||||
/**
|
||||
* OMS流程业务管理API
|
||||
@ -17,7 +21,8 @@ import java.util.List;
|
||||
* @date 2023/11/6 16:01
|
||||
*/
|
||||
|
||||
@FeignClient(name = "workflow-engine", url = "${axzo.service.workflow-engine:http://workflow-engine:8080}", configuration = CommonFeignConfiguration.class)
|
||||
//@FeignClient(name = "workflow-engine", url = "${axzo.service.workflow-engine:http://workflow-engine:8080}", configuration = CommonFeignConfiguration.class)
|
||||
@Manageable
|
||||
public interface ProcessConfigApi {
|
||||
|
||||
/**
|
||||
@ -26,6 +31,7 @@ public interface ProcessConfigApi {
|
||||
* @return 流程操作按钮列表
|
||||
*/
|
||||
@GetMapping("/api/process/config/button/list")
|
||||
@InvokeMode(SYNC)
|
||||
CommonResponse<List<BpmnButtonMetaInfo>> getDefaultButtons();
|
||||
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
|
||||
<artifactId>workflow-engine-common</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>workflow-engine-common</name>
|
||||
<name>workflow Engine Common</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
package cn.axzo.workflow.common.annotation;
|
||||
|
||||
import cn.axzo.workflow.common.enums.RpcInvokeModeEnum;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.ASYNC;
|
||||
|
||||
/**
|
||||
* 用于标记接口的方法调用模式
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024/6/1 19:01
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface InvokeMode {
|
||||
|
||||
/**
|
||||
* 调用模式, 默认异步
|
||||
*/
|
||||
RpcInvokeModeEnum value() default ASYNC;
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package cn.axzo.workflow.common.annotation;
|
||||
|
||||
/**
|
||||
* 控制接口是否调用受限,标记了注解的方法,表示受控,不允许暴露给客户端使用
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024/6/7 18:21
|
||||
*/
|
||||
public @interface Manageable {
|
||||
}
|
||||
@ -11,6 +11,7 @@ public interface BpmnConstants {
|
||||
*/
|
||||
String FLOWABLE_SKIP_EXPRESSION_ENABLE = "[_FLOWABLE_SKIP_EXPRESSION_ENABLED_]";
|
||||
String MQ_UNIQUE_ID = "[_MQ_UNIQUE_ID_]";
|
||||
String PROCESS_OWNERSHIP_APPLICATION = "[_PROCESS_OWNERSHIP_APPLICATION_]";
|
||||
String WORKFLOW_ENGINE_VERSION = "[_WORKFLOW_ENGINE_VERSION_]";
|
||||
String INTERNAL_INITIATOR = "[_INTERNAL_INITIATOR_]";
|
||||
@Deprecated
|
||||
@ -154,5 +155,6 @@ public interface BpmnConstants {
|
||||
/**
|
||||
* 用于 MQ 的 Header, 记录当前事件的归属应用
|
||||
*/
|
||||
String MQ_OWNERSHIP_APP = "MQ_OWNERSHIP_APPLICATION";
|
||||
String MQ_OWNERSHIP_APPLICATION = "MQ_OWNERSHIP_APPLICATION";
|
||||
String MQ_OWNERSHIP_PROCESS_DEFINITION_KEY = "MQ_OWNERSHIP_PROCESS_DEFINITION_KEY";
|
||||
}
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
package cn.axzo.workflow.common.constant;
|
||||
|
||||
/**
|
||||
* Starter 常量类
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024/5/29 11:13
|
||||
*/
|
||||
public interface StarterConstants {
|
||||
String STARTER_INVOKE_MODE = "WORKFLOW-ENGINE-STARTER-INVOKE-MODE";
|
||||
String DEBUGGING_MQ_SUFFIX = "_debugging";
|
||||
String K8S_POD_NAME_SPACE = "MY_POD_NAMESPACE";
|
||||
String NACOS_PROFILES_ACTIVE = "NACOS_PROFILES_ACTIVE";
|
||||
String MQ_GID_NAME_SEGMENT = "GID_SEGMENT";
|
||||
String ENABLE_MANAGEABLE = "ENABLE_MANAGEABLE";
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package cn.axzo.workflow.common.enums;
|
||||
|
||||
/**
|
||||
* PRC 调用模式枚举
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024/5/29 10:27
|
||||
*/
|
||||
public enum RpcInvokeModeEnum {
|
||||
SYNC,
|
||||
ASYNC,
|
||||
}
|
||||
@ -11,7 +11,7 @@ import cn.axzo.framework.rocketmq.Event;
|
||||
public enum WorkflowEngineEventEnum {
|
||||
|
||||
WORKFLOW_ENGINE_SERVER("workflow-engine", "workflow-engine-server", "引擎服务端事件"),
|
||||
WORKFLOW_ENGINE_CLIENT("workflow-engine", "workflow-engine-client-%s", "引擎客户端事件"),
|
||||
WORKFLOW_ENGINE_STARTER("workflow-engine", "workflow-engine-starter-%s", "引擎客户端事件"),
|
||||
;
|
||||
|
||||
private final String module;
|
||||
@ -34,4 +34,16 @@ public enum WorkflowEngineEventEnum {
|
||||
return eventCode;
|
||||
}
|
||||
|
||||
public String getModule() {
|
||||
return module;
|
||||
}
|
||||
|
||||
public String getTag() {
|
||||
return eventCode.getName();
|
||||
}
|
||||
|
||||
public String getDesc() {
|
||||
return desc;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@ import java.util.List;
|
||||
@Accessors(chain = true)
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public class CooperationOrgDTO implements Serializable {
|
||||
private static final long serialVersionUID = 4739924705980062997L;
|
||||
|
||||
|
||||
@ -22,9 +22,9 @@ public class BpmnProcessVariable {
|
||||
@NotBlank(message = "流程变量名称不能为空")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "流程变量类型")
|
||||
@NotBlank(message = "流程变量类型不能为空")
|
||||
private String type;
|
||||
// @ApiModelProperty(value = "流程变量类型")
|
||||
// @NotBlank(message = "流程变量类型不能为空")
|
||||
// private String type;
|
||||
|
||||
@ApiModelProperty(value = "流程变量值")
|
||||
@NotNull(message = "流程变量值不能为空")
|
||||
|
||||
@ -20,7 +20,7 @@ public class RestBpmnProcessVariable extends BpmnProcessVariable {
|
||||
/**
|
||||
* 变量作用域, 目前支持 LOCAL(局部变量) 和 GLOBAL(全局变量)
|
||||
*/
|
||||
private RestVariableScope scope;
|
||||
private RestVariableScope scope = RestVariableScope.GLOBAL;
|
||||
|
||||
public String getVariableScope() {
|
||||
String scope = null;
|
||||
|
||||
@ -2,7 +2,10 @@ package cn.axzo.workflow.common.model.request.bpmn.process;
|
||||
|
||||
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.annotation.Nullable;
|
||||
@ -17,6 +20,9 @@ import javax.validation.constraints.NotBlank;
|
||||
@ApiModel("最基础的流程实例查询入参模型")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class BpmnBasicProcessInstanceQueryDTO {
|
||||
/**
|
||||
* 流程实例 ID
|
||||
|
||||
@ -2,7 +2,10 @@ package cn.axzo.workflow.common.model.request.bpmn.process;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
@ -15,6 +18,9 @@ import javax.validation.constraints.NotBlank;
|
||||
*/
|
||||
@ApiModel("中止流程实例的入参模型")
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class BpmnProcessInstanceAbortDTO {
|
||||
|
||||
/**
|
||||
|
||||
@ -3,7 +3,10 @@ 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 javax.validation.Valid;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
@ -17,6 +20,9 @@ import javax.validation.constraints.NotNull;
|
||||
*/
|
||||
@ApiModel("取消流程实例的入参模型")
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class BpmnProcessInstanceCancelDTO {
|
||||
|
||||
/**
|
||||
|
||||
@ -4,7 +4,10 @@ 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 javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
@ -18,6 +21,9 @@ import java.util.List;
|
||||
*/
|
||||
@ApiModel("抄送流程实例的入参模型")
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class BpmnProcessInstanceCarbonCopyDTO {
|
||||
|
||||
/**
|
||||
|
||||
@ -4,7 +4,10 @@ import cn.axzo.workflow.common.model.dto.CooperationOrgDTO;
|
||||
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 javax.validation.Valid;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
@ -17,6 +20,9 @@ import java.util.Map;
|
||||
*/
|
||||
@ApiModel("创建流程实例的入参模型")
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class BpmnProcessInstanceCreateDTO {
|
||||
|
||||
/**
|
||||
@ -28,7 +34,7 @@ public class BpmnProcessInstanceCreateDTO {
|
||||
/**
|
||||
* 流程定义的标识
|
||||
* <p>
|
||||
* [对应业务分类的 businessId]
|
||||
* [对应 OMS 系统中审批业务的业务 ID]
|
||||
*/
|
||||
@NotEmpty(message = "流程定义的标识不能为空")
|
||||
private String processDefinitionKey;
|
||||
@ -56,6 +62,7 @@ public class BpmnProcessInstanceCreateDTO {
|
||||
* <p>
|
||||
* 用于流程引擎计算对应节点的审批人, 例如第一个审批节点配置的是劳务分包的岗位,第二个审批节点配置的专业分包的角色,
|
||||
* 那么, 组织关系就需要传入劳务分包的信息以及专业分包的信息,如果还有更多的审批节点配置,以此类推.
|
||||
* 同时,该属性还会用于计算抄送人,以及消息通知的目标接收人
|
||||
*/
|
||||
@ApiModelProperty(value = "组织关系")
|
||||
@NotNull(message = "组织关系不能为空")
|
||||
@ -81,17 +88,9 @@ public class BpmnProcessInstanceCreateDTO {
|
||||
private String customProcessInstanceName;
|
||||
|
||||
/**
|
||||
* 是否异步执行
|
||||
* 是否异步执行,该异步是引擎的一种运行模式
|
||||
*/
|
||||
@ApiModelProperty(value = "是否异步", notes = "异步时,只接收请求便返回数据")
|
||||
private Boolean async = true;
|
||||
|
||||
/**
|
||||
* 废弃
|
||||
* 下级审批人
|
||||
*/
|
||||
// @ApiModelProperty(value = "下级审批人", notes = "可为空,定义选择审批人,如果不为空,则覆盖下一级任务的审核人")
|
||||
// @Deprecated
|
||||
// private BpmnTaskDelegateAssigner nextApprover;
|
||||
|
||||
}
|
||||
|
||||
@ -2,8 +2,11 @@ package cn.axzo.workflow.common.model.request.bpmn.process;
|
||||
|
||||
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;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
|
||||
@ -2,7 +2,10 @@ 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 javax.validation.Valid;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
@ -16,6 +19,9 @@ import java.util.List;
|
||||
*/
|
||||
@ApiModel("业务节点设置审批人")
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class BpmnActivitySetAssigneeDTO {
|
||||
/**
|
||||
* PROCESS_ACTIVITY_WAIT_ASSIGNEE 事件中的触发 ID
|
||||
|
||||
@ -2,7 +2,10 @@ 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 javax.validation.Valid;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
@ -15,6 +18,9 @@ import javax.validation.constraints.NotBlank;
|
||||
*/
|
||||
@ApiModel("完成机器人节点的入参模型")
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class BpmnRobotTaskCompleteDTO {
|
||||
|
||||
/**
|
||||
|
||||
@ -2,7 +2,10 @@ 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 javax.validation.Valid;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
@ -16,6 +19,9 @@ import javax.validation.constraints.NotNull;
|
||||
*/
|
||||
@ApiModel("创建机器人节点的入参模型")
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class BpmnRobotTaskCreateDTO {
|
||||
/**
|
||||
* 流程实例 ID
|
||||
|
||||
@ -3,7 +3,10 @@ package cn.axzo.workflow.common.model.request.bpmn.task;
|
||||
import cn.axzo.workflow.common.enums.BpmnFlowNodeType;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.validation.Valid;
|
||||
@ -19,6 +22,9 @@ import java.util.List;
|
||||
@ApiModel("审批任务节点的入参模型")
|
||||
@Data
|
||||
@Validated
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class BpmnTaskAuditDTO {
|
||||
|
||||
@ApiModelProperty(value = "任务编号", required = true, example = "1024")
|
||||
|
||||
@ -2,7 +2,10 @@ 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 org.hibernate.validator.constraints.Length;
|
||||
|
||||
import javax.validation.Valid;
|
||||
@ -19,6 +22,9 @@ import java.util.List;
|
||||
*/
|
||||
@ApiModel("评论的入参模型")
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class BpmnTaskCommentDTO implements Serializable {
|
||||
|
||||
/**
|
||||
|
||||
@ -2,7 +2,10 @@ package cn.axzo.workflow.common.model.request.bpmn.task;
|
||||
|
||||
import cn.axzo.workflow.common.enums.BpmnCountersignTypeEnum;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.Valid;
|
||||
@ -21,6 +24,9 @@ import java.util.List;
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class BpmnTaskCountersignDTO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -8106887960942113552L;
|
||||
|
||||
@ -44,7 +44,7 @@ public class BpmnTaskDelegateAssigner implements Serializable {
|
||||
private static final long serialVersionUID = -8106887960942113552L;
|
||||
|
||||
/**
|
||||
* 审核人标识, 应该必传
|
||||
* 【废弃】审核人标识, 应该必传
|
||||
* <p>
|
||||
* 枢智:用户 ID
|
||||
* 安心筑:身份 ID
|
||||
@ -53,7 +53,7 @@ public class BpmnTaskDelegateAssigner implements Serializable {
|
||||
private String assignee;
|
||||
|
||||
/**
|
||||
* 审核人标识扩展信息
|
||||
* 【废弃】审核人标识扩展信息
|
||||
* <p>
|
||||
* 枢智:可不传
|
||||
* 安心筑:身份 Type 应该必传
|
||||
|
||||
@ -2,7 +2,10 @@ 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 javax.validation.Valid;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
@ -16,6 +19,9 @@ import java.util.List;
|
||||
*/
|
||||
@ApiModel("转交审批任务的入参模型")
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class BpmnTaskTransferDTO {
|
||||
|
||||
/**
|
||||
|
||||
@ -31,6 +31,11 @@ public class MessagePushDTO implements Serializable {
|
||||
*/
|
||||
private String processInstanceId;
|
||||
|
||||
/**
|
||||
* 业务 ID
|
||||
*/
|
||||
private String processDefinitionKey;
|
||||
|
||||
/**
|
||||
* 流程任务 ID
|
||||
*/
|
||||
|
||||
@ -28,8 +28,11 @@ public class ProcessTaskDTO implements Serializable {
|
||||
private ProcessTaskEventEnum type;
|
||||
|
||||
/**
|
||||
* 请使用 {@link ProcessTaskDTO#processDefinitionKey} 代替访问此属性,未来将逐步废弃
|
||||
* <p>
|
||||
* 流程实例所属业务分类,同时也等于流程模型对应的业务分类 ID
|
||||
*/
|
||||
@Deprecated
|
||||
private String category;
|
||||
|
||||
/**
|
||||
@ -41,6 +44,10 @@ public class ProcessTaskDTO implements Serializable {
|
||||
* 流程实例 ID
|
||||
*/
|
||||
private String processInstanceId;
|
||||
/**
|
||||
* 流程实例所属业务分类,同时也等于流程模型对应的业务分类 ID
|
||||
*/
|
||||
private String processDefinitionKey;
|
||||
|
||||
/**
|
||||
* 流程定义中当前任务节点 Key
|
||||
|
||||
@ -0,0 +1,44 @@
|
||||
package cn.axzo.workflow.common.model.response.mq;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Starter RPC 调用事件模型
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024/5/30 11:21
|
||||
*/
|
||||
public class WorkflowEngineStarterRpcInvokeDTO implements Serializable {
|
||||
private static final long serialVersionUID = -1L;
|
||||
|
||||
private String className;
|
||||
|
||||
private String methodName;
|
||||
|
||||
private List<String> parameters;
|
||||
|
||||
public String getClassName() {
|
||||
return className;
|
||||
}
|
||||
|
||||
public void setClassName(String className) {
|
||||
this.className = className;
|
||||
}
|
||||
|
||||
public String getMethodName() {
|
||||
return methodName;
|
||||
}
|
||||
|
||||
public void setMethodName(String methodName) {
|
||||
this.methodName = methodName;
|
||||
}
|
||||
|
||||
public List<String> getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
public void setParameters(List<String> parameters) {
|
||||
this.parameters = parameters;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package cn.axzo.workflow.common.util;
|
||||
|
||||
|
||||
import cn.axzo.workflow.common.enums.RpcInvokeModeEnum;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024/5/29 23:57
|
||||
*/
|
||||
public class ThreadUtil {
|
||||
|
||||
final static InheritableThreadLocal<RpcInvokeModeEnum> threadLocal = new InheritableThreadLocal<>();
|
||||
|
||||
public static void set(RpcInvokeModeEnum rpcInvokeMode) {
|
||||
threadLocal.set(rpcInvokeMode);
|
||||
}
|
||||
|
||||
public static RpcInvokeModeEnum get() {
|
||||
return threadLocal.get();
|
||||
}
|
||||
|
||||
public static void clear() {
|
||||
threadLocal.remove();
|
||||
}
|
||||
}
|
||||
@ -9,8 +9,7 @@
|
||||
<version>${revision}</version>
|
||||
<artifactId>workflow-engine-core</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>workflow-engine-core</name>
|
||||
<name>Workflow Engine Core</name>
|
||||
<properties>
|
||||
<flowable.version>6.7.2</flowable.version>
|
||||
<axzo-bom.version>2.0.0-SNAPSHOT</axzo-bom.version>
|
||||
@ -98,5 +97,9 @@
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-artifact</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.servlet</groupId>
|
||||
<artifactId>jakarta.servlet-api</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
@ -33,6 +33,7 @@ public enum BpmnTaskRespCode implements IModuleRespCode {
|
||||
FIND_TASK_BY_PERSON_ID_ERROR("018", "流程实例中:【{}】未查找指定自然人:【{}】的待处理的流程任务!"),
|
||||
PROCESS_INSTANCE_IS_NOT_EXIST("019", "Execution:{} 对应流程实例不存在,流程状态异常!"),
|
||||
TASK_TYPE_MISMATCH("020", "节点类型不匹配,当前节点类型:【{}】,指定节点类型:【{}】!"),
|
||||
PROCESS_CANT_SET_ASSIGNEE("021", "当前审批状态不允许设置审批人"),
|
||||
;
|
||||
|
||||
private String code;
|
||||
|
||||
@ -18,6 +18,8 @@ public enum FlowableEngineRespCode implements IModuleRespCode {
|
||||
ENGINE_USER_TASK_TYPE_NOT_SUPPORT("003", "审批指定方式暂不支持"),
|
||||
ENGINE_USER_TASK_PARAM_ERROR("004", "构建后的查询审批人入参为空. 任务节点【nodeId:{}】, 该节点选择的\"审批人所在范围\"是:【{}】,请检查 cooperationOrg 参数"),
|
||||
ENGINE_NOTICE_CUSTOM_FLOW_ELEMENT_ERROR("005", "查询通知目标用户前参数发生异常,未获取到 WorkspaceType"),
|
||||
ENGINE_ASYNC_COMMAND_EXECUTION_ERROR("006", "引擎出现 SQL 相关异常, 异常信息:【{}】"),
|
||||
ENGINE_ASYNC_COMMAND_EXECUTION_RETRY_GIVE_UP("007", "命令重试尝试【{}】次仍然失败,并出现异常, 将放弃"),
|
||||
;
|
||||
|
||||
private String code;
|
||||
|
||||
@ -0,0 +1,24 @@
|
||||
package cn.axzo.workflow.core.common.utils;
|
||||
|
||||
import org.slf4j.MDC;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import static cn.axzo.workflow.common.constant.LogFieldConstants.X_REQUEST_ID;
|
||||
import static cn.azxo.framework.common.constatns.Constants.CTX_LOG_ID_MDC;
|
||||
|
||||
/**
|
||||
* 获取 TraceId
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024/7/3 10:14
|
||||
*/
|
||||
public final class TraceUtil {
|
||||
|
||||
private TraceUtil() {
|
||||
}
|
||||
|
||||
public static String traceId() {
|
||||
String xRequestId = MDC.get(X_REQUEST_ID);
|
||||
return StringUtils.hasText(xRequestId) ? xRequestId : MDC.get(CTX_LOG_ID_MDC);
|
||||
}
|
||||
}
|
||||
@ -3,6 +3,7 @@ package cn.axzo.workflow.core.conf;
|
||||
import cn.axzo.workflow.core.engine.behavior.CustomActivityBehaviorFactory;
|
||||
import cn.axzo.workflow.core.engine.cmd.CustomCommandContextFactory;
|
||||
import cn.axzo.workflow.core.engine.id.BasedNacosSnowflakeIdGenerator;
|
||||
import cn.axzo.workflow.core.engine.interceptor.CustomRetryInterceptor;
|
||||
import cn.axzo.workflow.core.engine.job.AsyncAbortProcessInstanceHandler;
|
||||
import cn.axzo.workflow.core.engine.job.AsyncApproveTaskJobHandler;
|
||||
import cn.axzo.workflow.core.engine.job.AsyncBpmnProcessActivityJobHandler;
|
||||
@ -30,6 +31,7 @@ import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
@ -56,7 +58,8 @@ public class FlowableConfiguration {
|
||||
BpmnProcessActivityService bpmnProcessActivityService,
|
||||
List<JobProcessor> jobProcessors,
|
||||
NacosServiceManager nacosServiceManager,
|
||||
NacosDiscoveryProperties nacosDiscoveryProperties) {
|
||||
NacosDiscoveryProperties nacosDiscoveryProperties,
|
||||
StringRedisTemplate redisTemplate) {
|
||||
return configuration -> {
|
||||
configuration.setEnableHistoricTaskLogging(true);
|
||||
configuration.setHistoryLevel(HistoryLevel.AUDIT);
|
||||
@ -92,6 +95,9 @@ public class FlowableConfiguration {
|
||||
new CustomWorkflowEngineExceptionHandler(),
|
||||
new CustomAsyncRunnableExceptionExceptionHandler()));
|
||||
configuration.setCommandContextFactory(new CustomCommandContextFactory());
|
||||
configuration.setCustomPreCommandInterceptors(Lists.newArrayList(
|
||||
new CustomRetryInterceptor()
|
||||
));
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,15 @@
|
||||
package cn.axzo.workflow.core.engine.cmd;
|
||||
|
||||
|
||||
import org.flowable.common.engine.impl.interceptor.Command;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024/7/1 13:59
|
||||
*/
|
||||
public abstract class AbstractCommand<T> implements Command<T> {
|
||||
|
||||
public abstract String paramToJsonString();
|
||||
}
|
||||
@ -4,7 +4,7 @@ import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAbo
|
||||
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
|
||||
import cn.axzo.workflow.core.engine.job.AsyncAbortProcessInstanceHandler;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import org.flowable.common.engine.impl.interceptor.Command;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import org.flowable.common.engine.impl.interceptor.CommandContext;
|
||||
import org.flowable.engine.HistoryService;
|
||||
import org.flowable.engine.history.HistoricProcessInstance;
|
||||
@ -23,7 +23,7 @@ import static cn.axzo.workflow.core.common.code.BpmnInstanceRespCode.PROCESS_INS
|
||||
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;
|
||||
|
||||
public class CustomAbortProcessInstanceAsyncCmd implements Command<Void>, Serializable {
|
||||
public class CustomAbortProcessInstanceAsyncCmd extends AbstractCommand<Void> implements Serializable {
|
||||
|
||||
private final BpmnProcessInstanceAbortDTO dto;
|
||||
|
||||
@ -31,6 +31,11 @@ public class CustomAbortProcessInstanceAsyncCmd implements Command<Void>, Serial
|
||||
this.dto = dto;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String paramToJsonString() {
|
||||
return JSON.toJSONString(dto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void execute(CommandContext commandContext) {
|
||||
String processInstanceId = dto.getProcessInstanceId();
|
||||
@ -80,4 +85,5 @@ public class CustomAbortProcessInstanceAsyncCmd implements Command<Void>, Serial
|
||||
jobService.createAsyncJob(job, false);
|
||||
jobService.scheduleAsyncJob(job);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -4,6 +4,8 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
|
||||
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
|
||||
import cn.axzo.workflow.core.engine.operation.DeleteProcessInstanceOperation;
|
||||
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import liquibase.pro.packaged.V;
|
||||
import org.flowable.common.engine.impl.interceptor.Command;
|
||||
import org.flowable.common.engine.impl.interceptor.CommandContext;
|
||||
import org.flowable.engine.HistoryService;
|
||||
@ -44,7 +46,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.createVir
|
||||
* @author wangli
|
||||
* @since 2024/1/2 18:19
|
||||
*/
|
||||
public class CustomAbortProcessInstanceCmd implements Command<Void>, Serializable {
|
||||
public class CustomAbortProcessInstanceCmd extends AbstractCommand<Void> implements Serializable {
|
||||
private final String processInstanceId;
|
||||
private final String tenantId;
|
||||
private final String reason;
|
||||
@ -58,6 +60,15 @@ public class CustomAbortProcessInstanceCmd implements Command<Void>, Serializabl
|
||||
this.extAxHiTaskInstService = extAxHiTaskInstService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String paramToJsonString() {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("processInstanceId", processInstanceId);
|
||||
params.put("tenantId", tenantId);
|
||||
params.put("reason", reason);
|
||||
return JSON.toJSONString(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void execute(CommandContext commandContext) {
|
||||
ProcessEngineConfigurationImpl processEngineConfiguration =
|
||||
@ -102,4 +113,5 @@ public class CustomAbortProcessInstanceCmd implements Command<Void>, Serializabl
|
||||
runtimeService.setVariable(task.getProcessInstanceId(), TASK_COMPLETE_OPERATION_TYPE + task.getId(), ABORTED);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package cn.axzo.workflow.core.engine.cmd;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO;
|
||||
import cn.axzo.workflow.core.engine.job.AsyncApproveTaskJobHandler;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import org.flowable.common.engine.impl.interceptor.Command;
|
||||
import org.flowable.common.engine.impl.interceptor.CommandContext;
|
||||
import org.flowable.engine.TaskService;
|
||||
@ -18,6 +19,8 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask;
|
||||
@ -28,7 +31,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask
|
||||
* @author wangli
|
||||
* @since 2024/1/4 15:50
|
||||
*/
|
||||
public class CustomApproveTaskAsyncCmd implements Command<Void>, Serializable {
|
||||
public class CustomApproveTaskAsyncCmd extends AbstractCommand<Void> implements Serializable {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(CustomApproveTaskAsyncCmd.class);
|
||||
private final BpmnTaskAuditDTO dto;
|
||||
@ -37,6 +40,11 @@ public class CustomApproveTaskAsyncCmd implements Command<Void>, Serializable {
|
||||
this.dto = dto;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String paramToJsonString() {
|
||||
return JSON.toJSONString(dto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void execute(CommandContext commandContext) {
|
||||
ProcessEngineConfigurationImpl processEngineConfiguration =
|
||||
|
||||
@ -4,12 +4,14 @@ 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 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.RuntimeService;
|
||||
import org.flowable.engine.TaskService;
|
||||
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
|
||||
import org.flowable.engine.impl.context.Context;
|
||||
import org.flowable.engine.impl.util.CommandContextUtil;
|
||||
import org.flowable.task.api.Task;
|
||||
import org.flowable.task.api.history.HistoricTaskInstance;
|
||||
@ -20,7 +22,9 @@ import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE;
|
||||
@ -38,7 +42,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask
|
||||
* @author wangli
|
||||
* @since 2024/1/4 15:50
|
||||
*/
|
||||
public class CustomApproveTaskCmd implements Command<Void>, Serializable {
|
||||
public class CustomApproveTaskCmd extends AbstractCommand<Void> implements Serializable {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(CustomApproveTaskCmd.class);
|
||||
private final String taskId;
|
||||
@ -62,6 +66,18 @@ public class CustomApproveTaskCmd implements Command<Void>, Serializable {
|
||||
*/
|
||||
private List<BpmnFlowNodeType> nodeTypes;
|
||||
|
||||
@Override
|
||||
public String paramToJsonString() {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("taskId", taskId);
|
||||
params.put("advice", advice);
|
||||
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);
|
||||
}
|
||||
|
||||
public CustomApproveTaskCmd(BpmnTaskAuditDTO dto) {
|
||||
this(dto, null);
|
||||
|
||||
@ -3,10 +3,13 @@ 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.cmd.helper.CustomTaskHelper;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
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.RuntimeService;
|
||||
import org.flowable.engine.TaskService;
|
||||
import org.flowable.engine.history.HistoricProcessInstance;
|
||||
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
|
||||
import org.flowable.engine.impl.util.CommandContextUtil;
|
||||
import org.flowable.task.api.Task;
|
||||
@ -14,7 +17,9 @@ import org.flowable.task.service.impl.persistence.entity.TaskEntity;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.HIDDEN_ASSIGNEE_ID;
|
||||
@ -22,8 +27,11 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_R
|
||||
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.BpmnProcessInstanceResultEnum.DELETED;
|
||||
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.PROCESSING;
|
||||
import static cn.axzo.workflow.core.common.code.BpmnInstanceRespCode.PROCESS_INSTANCE_ID_NOT_EXISTS;
|
||||
import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.ACTIVITY_BIZ_SET_ASSIGNEE_ERROR;
|
||||
import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.ACTIVITY_CANT_SET_ASSIGNEE;
|
||||
import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.PROCESS_CANT_SET_ASSIGNEE;
|
||||
|
||||
/**
|
||||
* 自定的业务指定审批人命令实现
|
||||
@ -31,7 +39,7 @@ import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.ACTIVITY_CANT_S
|
||||
* @author wangli
|
||||
* @since 2023/12/22 13:51
|
||||
*/
|
||||
public class CustomBizSpecifyAssigneeToTaskCmd implements Command<Boolean>, Serializable {
|
||||
public class CustomBizSpecifyAssigneeToTaskCmd extends AbstractCommand<Boolean> implements Serializable {
|
||||
|
||||
private final String executionId;
|
||||
private final List<BpmnTaskDelegateAssigner> addedAssigners;
|
||||
@ -41,6 +49,14 @@ public class CustomBizSpecifyAssigneeToTaskCmd implements Command<Boolean>, Seri
|
||||
this.addedAssigners = addedAssigners;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String paramToJsonString() {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("executionId", executionId);
|
||||
params.put("addedAssigners", addedAssigners);
|
||||
return JSON.toJSONString(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean execute(CommandContext commandContext) {
|
||||
ProcessEngineConfigurationImpl processEngineConfiguration =
|
||||
@ -53,6 +69,8 @@ public class CustomBizSpecifyAssigneeToTaskCmd implements Command<Boolean>, Seri
|
||||
|
||||
validTask(task);
|
||||
|
||||
validProcessInstance(commandContext, task);
|
||||
|
||||
changeAssigneeSnapshot(commandContext, task);
|
||||
|
||||
addAssignee(commandContext, taskService, task);
|
||||
@ -60,6 +78,20 @@ public class CustomBizSpecifyAssigneeToTaskCmd implements Command<Boolean>, Seri
|
||||
return true;
|
||||
}
|
||||
|
||||
private void validProcessInstance(CommandContext commandContext, Task task) {
|
||||
ProcessEngineConfigurationImpl processEngineConfiguration =
|
||||
CommandContextUtil.getProcessEngineConfiguration(commandContext);
|
||||
HistoryService historyService = processEngineConfiguration.getHistoryService();
|
||||
HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult();
|
||||
if (Objects.isNull(processInstance)) {
|
||||
throw new WorkflowEngineException(PROCESS_INSTANCE_ID_NOT_EXISTS, task.getProcessInstanceId());
|
||||
}
|
||||
if (!Objects.equals(PROCESSING.getStatus(), processInstance.getBusinessStatus())) {
|
||||
throw new WorkflowEngineException(PROCESS_CANT_SET_ASSIGNEE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void changeAssigneeSnapshot(CommandContext commandContext, Task task) {
|
||||
ProcessEngineConfigurationImpl processEngineConfiguration =
|
||||
CommandContextUtil.getProcessEngineConfiguration(commandContext);
|
||||
@ -85,9 +117,7 @@ public class CustomBizSpecifyAssigneeToTaskCmd implements Command<Boolean>, Seri
|
||||
return;
|
||||
}
|
||||
|
||||
addedAssigners.forEach(i -> {
|
||||
CustomTaskHelper.addMultiTask(commandContext, (TaskEntity) task, i);
|
||||
});
|
||||
addedAssigners.forEach(i -> CustomTaskHelper.addMultiTask(commandContext, (TaskEntity) task, i));
|
||||
|
||||
taskService.setAssignee(task.getId(), HIDDEN_ASSIGNEE_ID);
|
||||
((TaskEntity) task).setTransientVariable(TASK_COMPLETE_OPERATION_TYPE + task.getId(), DELETED.getStatus());
|
||||
|
||||
@ -5,7 +5,7 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
|
||||
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
|
||||
import cn.axzo.workflow.core.engine.job.AsyncCancelProcessInstanceHandler;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import org.flowable.common.engine.impl.interceptor.Command;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import org.flowable.common.engine.impl.interceptor.CommandContext;
|
||||
import org.flowable.engine.HistoryService;
|
||||
import org.flowable.engine.history.HistoricProcessInstance;
|
||||
@ -23,7 +23,7 @@ import static cn.axzo.workflow.core.common.code.BpmnInstanceRespCode.PROCESS_INS
|
||||
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;
|
||||
|
||||
public class CustomCancelProcessInstanceAsyncCmd implements Command<Void>, Serializable {
|
||||
public class CustomCancelProcessInstanceAsyncCmd extends AbstractCommand<Void> implements Serializable {
|
||||
|
||||
private final BpmnProcessInstanceCancelDTO dto;
|
||||
|
||||
@ -31,6 +31,11 @@ public class CustomCancelProcessInstanceAsyncCmd implements Command<Void>, Seria
|
||||
this.dto = dto;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String paramToJsonString() {
|
||||
return JSON.toJSONString(dto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void execute(CommandContext commandContext) {
|
||||
String processInstanceId = dto.getProcessInstanceId(), tenantId = dto.getTenantId();
|
||||
@ -81,4 +86,5 @@ public class CustomCancelProcessInstanceAsyncCmd implements Command<Void>, Seria
|
||||
jobService.createAsyncJob(job, false);
|
||||
jobService.scheduleAsyncJob(job);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
package cn.axzo.workflow.core.engine.cmd;
|
||||
|
||||
import cn.axzo.framework.context.validation.SpringValidator;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
|
||||
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
|
||||
import cn.axzo.workflow.core.engine.operation.DeleteProcessInstanceOperation;
|
||||
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import org.flowable.common.engine.impl.interceptor.Command;
|
||||
import org.flowable.common.engine.impl.interceptor.CommandContext;
|
||||
import org.flowable.engine.HistoryService;
|
||||
@ -12,6 +14,7 @@ import org.flowable.engine.history.HistoricProcessInstance;
|
||||
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
|
||||
import org.flowable.engine.impl.util.CommandContextUtil;
|
||||
import org.flowable.task.api.Task;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
@ -41,7 +44,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.createVir
|
||||
* @author wangli
|
||||
* @since 2024/1/2 18:19
|
||||
*/
|
||||
public class CustomCancelProcessInstanceCmd implements Command<Void>, Serializable {
|
||||
public class CustomCancelProcessInstanceCmd extends AbstractCommand<Void> implements Serializable {
|
||||
private final String processInstanceId;
|
||||
private final String tenantId;
|
||||
private final String reason;
|
||||
@ -58,6 +61,16 @@ public class CustomCancelProcessInstanceCmd implements Command<Void>, Serializab
|
||||
this.extAxHiTaskInstService = extAxHiTaskInstService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String paramToJsonString() {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("processInstanceId", processInstanceId);
|
||||
params.put("tenantId", tenantId);
|
||||
params.put("reason", reason);
|
||||
params.put("initiator", initiator);
|
||||
return JSON.toJSONString(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void execute(CommandContext commandContext) {
|
||||
ProcessEngineConfigurationImpl processEngineConfiguration =
|
||||
@ -102,4 +115,5 @@ public class CustomCancelProcessInstanceCmd implements Command<Void>, Serializab
|
||||
addComment(commandContext, task, COMMENT_TYPE_OPERATION_DESC, "已撤回");
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.google.common.collect.Lists;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.bpmn.model.CustomProperty;
|
||||
import org.flowable.bpmn.model.ServiceTask;
|
||||
import org.flowable.common.engine.impl.interceptor.Command;
|
||||
@ -27,12 +28,14 @@ import org.springframework.util.CollectionUtils;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
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.NO_ASSIGNEE;
|
||||
@ -45,7 +48,8 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.removeDup
|
||||
* @author wangli
|
||||
* @since 18/03/2024 11:33
|
||||
*/
|
||||
public class CustomCarbonCopyUserSelectorCmd implements Command<List<BpmnTaskDelegateAssigner>>, Serializable {
|
||||
@Slf4j
|
||||
public class CustomCarbonCopyUserSelectorCmd extends AbstractCommand<List<BpmnTaskDelegateAssigner>> implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final String processInstanceId;
|
||||
@ -83,6 +87,15 @@ public class CustomCarbonCopyUserSelectorCmd implements Command<List<BpmnTaskDel
|
||||
this.execution = execution;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String paramToJsonString() {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("processInstanceId", processInstanceId);
|
||||
params.put("carbons", carbons);
|
||||
params.put("serviceVersion", serviceVersion);
|
||||
return JSON.toJSONString(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BpmnTaskDelegateAssigner> execute(CommandContext commandContext) {
|
||||
if (CollectionUtils.isEmpty(carbons)) {
|
||||
@ -97,6 +110,17 @@ public class CustomCarbonCopyUserSelectorCmd implements Command<List<BpmnTaskDel
|
||||
} else {
|
||||
executions.add((Execution) execution);
|
||||
}
|
||||
//流程为空,表示已经执行完,去历史版本获取
|
||||
if (CollectionUtils.isEmpty(executions)) {
|
||||
List<HistoricVariableInstance> hisVarInst = processEngineConfiguration.getHistoryService().createHistoricVariableInstanceQuery()
|
||||
.processInstanceId(processInstanceId)
|
||||
.variableName(INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + serviceTask.getId()).list();
|
||||
if (!CollectionUtils.isEmpty(hisVarInst)) {
|
||||
return (List<BpmnTaskDelegateAssigner>) hisVarInst.get(0).getValue();
|
||||
}
|
||||
log.warn("executions is empty,get historic task assigner list empty,processInstanceId: {},serviceTaskId: {}", processInstanceId, serviceTask.getId());
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<BpmnTaskDelegateAssigner> assigners = new ArrayList<>();
|
||||
carbons.forEach(carbon -> {
|
||||
CarbonCopyObjectType carbonCopyObjectType = carbon.getCarbonCopyObjectType();
|
||||
@ -108,6 +132,9 @@ public class CustomCarbonCopyUserSelectorCmd implements Command<List<BpmnTaskDel
|
||||
case project_identity:
|
||||
case project_position:
|
||||
case government_role:
|
||||
if (CollectionUtils.isEmpty(executions)) {
|
||||
return;
|
||||
}
|
||||
CustomProperty property = new CustomProperty();
|
||||
property.setName(carbonCopyObjectType.getType());
|
||||
property.setSimpleValue(carbon.getSpecifyValue());
|
||||
@ -116,6 +143,9 @@ public class CustomCarbonCopyUserSelectorCmd implements Command<List<BpmnTaskDel
|
||||
serviceTask, (DelegateExecution) executions.get(0), false));
|
||||
break;
|
||||
case approver_relation:
|
||||
if (CollectionUtils.isEmpty(executions)) {
|
||||
return;
|
||||
}
|
||||
assigners.addAll(getApproverRelationUser(carbon, carbonCopyObjectType,
|
||||
(DelegateExecution) executions.get(0), processEngineConfiguration, processInstanceId));
|
||||
break;
|
||||
@ -210,5 +240,4 @@ public class CustomCarbonCopyUserSelectorCmd implements Command<List<BpmnTaskDel
|
||||
return assigners;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* 对 CommandContext 中的 WorkflowEngineException 进行日志降级
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024/5/21 09:46
|
||||
|
||||
@ -7,6 +7,7 @@ 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;
|
||||
@ -27,7 +28,9 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE;
|
||||
@ -44,7 +47,7 @@ import static org.flowable.task.api.Task.DEFAULT_PRIORITY;
|
||||
* @author wangli
|
||||
* @since 2023/12/26 16:14
|
||||
*/
|
||||
public class CustomCommentTaskCmd implements Command<Void>, Serializable {
|
||||
public class CustomCommentTaskCmd extends AbstractCommand<Void> implements Serializable {
|
||||
private final String processInstanceId;
|
||||
private final BpmnTaskDelegateAssigner operator;
|
||||
private final String comment;
|
||||
@ -63,6 +66,17 @@ public class CustomCommentTaskCmd implements Command<Void>, Serializable {
|
||||
this.extAxHiTaskInstService = extAxHiTaskInstService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String paramToJsonString() {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("processInstanceId", processInstanceId);
|
||||
params.put("operator", operator);
|
||||
params.put("comment", comment);
|
||||
params.put("commentExt", commentExt);
|
||||
params.put("attachmentList", attachmentList);
|
||||
return JSON.toJSONString(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void execute(CommandContext commandContext) {
|
||||
ProcessEngineConfigurationImpl processEngineConfiguration =
|
||||
|
||||
@ -5,6 +5,7 @@ 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 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;
|
||||
@ -16,7 +17,9 @@ import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC;
|
||||
@ -30,7 +33,7 @@ import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.DUMMY_TASK_NOT_
|
||||
* @author wangli
|
||||
* @since 2023/12/27 11:24
|
||||
*/
|
||||
public class CustomCompleteDummyTaskCmd implements Command<Void>, Serializable {
|
||||
public class CustomCompleteDummyTaskCmd extends AbstractCommand<Void> implements Serializable {
|
||||
private final String processInstanceId;
|
||||
private final String taskId;
|
||||
private final String flowNodeName;
|
||||
@ -46,6 +49,16 @@ public class CustomCompleteDummyTaskCmd implements Command<Void>, Serializable {
|
||||
this.extAxHiTaskInstService = extAxHiTaskInstService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String paramToJsonString() {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("processInstanceId", processInstanceId);
|
||||
params.put("taskId", taskId);
|
||||
params.put("flowNodeName", flowNodeName);
|
||||
params.put("operationDesc", operationDesc);
|
||||
return JSON.toJSONString(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void execute(CommandContext commandContext) {
|
||||
ProcessEngineConfigurationImpl processEngineConfiguration =
|
||||
@ -93,4 +106,5 @@ public class CustomCompleteDummyTaskCmd implements Command<Void>, Serializable {
|
||||
taskService.setOwner(i.getId(), null);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package cn.axzo.workflow.core.engine.cmd;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCountersignDTO;
|
||||
import cn.axzo.workflow.core.engine.job.AsyncCountersignUserTaskJobHandler;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import org.flowable.common.engine.impl.interceptor.Command;
|
||||
import org.flowable.common.engine.impl.interceptor.CommandContext;
|
||||
import org.flowable.engine.TaskService;
|
||||
@ -16,17 +17,24 @@ import org.flowable.task.api.history.HistoricTaskInstanceQuery;
|
||||
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask;
|
||||
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTaskAssignerDuplicated;
|
||||
|
||||
public class CustomCountersignUserTaskAsyncCmd implements Command<Void>, Serializable {
|
||||
public class CustomCountersignUserTaskAsyncCmd extends AbstractCommand<Void> implements Serializable {
|
||||
private final BpmnTaskCountersignDTO dto;
|
||||
|
||||
public CustomCountersignUserTaskAsyncCmd(BpmnTaskCountersignDTO dto) {
|
||||
this.dto = dto;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String paramToJsonString() {
|
||||
return JSON.toJSONString(dto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void execute(CommandContext commandContext) {
|
||||
ProcessEngineConfigurationImpl processEngineConfiguration =
|
||||
@ -66,4 +74,5 @@ public class CustomCountersignUserTaskAsyncCmd implements Command<Void>, Seriali
|
||||
jobService.createAsyncJob(job, false);
|
||||
jobService.scheduleAsyncJob(job);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
|
||||
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 lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.common.engine.impl.interceptor.Command;
|
||||
import org.flowable.common.engine.impl.interceptor.CommandContext;
|
||||
@ -19,7 +20,9 @@ import org.flowable.task.api.history.HistoricTaskInstanceQuery;
|
||||
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
|
||||
|
||||
import java.io.Serializable;
|
||||
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.INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT;
|
||||
@ -39,7 +42,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask
|
||||
* @since 2023/12/25 14:05
|
||||
*/
|
||||
@Slf4j
|
||||
public class CustomCountersignUserTaskCmd implements Command<Void>, Serializable {
|
||||
public class CustomCountersignUserTaskCmd extends AbstractCommand<Void> implements Serializable {
|
||||
|
||||
private final BpmnCountersignTypeEnum countersignType;
|
||||
private final String originTaskId;
|
||||
@ -62,6 +65,18 @@ public class CustomCountersignUserTaskCmd implements Command<Void>, Serializable
|
||||
this.extAxHiTaskInstService = extAxHiTaskInstService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String paramToJsonString() {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("countersignType", countersignType.getType());
|
||||
params.put("originTaskId", originTaskId);
|
||||
params.put("originTaskAssignee", originTaskAssignee);
|
||||
params.put("advice", advice);
|
||||
params.put("attachmentList", JSON.toJSONString(attachmentList));
|
||||
params.put("targetTaskAssigneeList", JSON.toJSONString(targetTaskAssigneeList));
|
||||
return JSON.toJSONString(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void execute(CommandContext commandContext) {
|
||||
ProcessEngineConfigurationImpl processEngineConfiguration =
|
||||
@ -139,4 +154,5 @@ public class CustomCountersignUserTaskCmd implements Command<Void>, Serializable
|
||||
addComment(commandContext, virtualTask, COMMENT_TYPE_OPERATION_DESC, message.toString());
|
||||
batchAddAttachment(commandContext, task.getProcessInstanceId(), task.getId(), attachmentList, originTaskAssignee);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@ 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 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;
|
||||
@ -21,7 +22,9 @@ import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC;
|
||||
@ -41,7 +44,7 @@ import static org.flowable.task.api.Task.DEFAULT_PRIORITY;
|
||||
* @author wangli
|
||||
* @since 2023/12/27 10:21
|
||||
*/
|
||||
public class CustomCreateDummyTaskCmd implements Command<String>, Serializable {
|
||||
public class CustomCreateDummyTaskCmd extends AbstractCommand<String> implements Serializable {
|
||||
private final String processInstanceId;
|
||||
private final String flowNodeName;
|
||||
private final String operationDesc;
|
||||
@ -57,6 +60,16 @@ public class CustomCreateDummyTaskCmd implements Command<String>, Serializable {
|
||||
this.extAxHiTaskInstService = extAxHiTaskInstService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String paramToJsonString() {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("processInstanceId", processInstanceId);
|
||||
params.put("flowNodeName", flowNodeName);
|
||||
params.put("operationDesc", operationDesc);
|
||||
params.put("operator", operator);
|
||||
return JSON.toJSONString(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在同一个实例下,不允许创建多个执行中的虚拟任务节点
|
||||
*
|
||||
@ -139,4 +152,5 @@ public class CustomCreateDummyTaskCmd implements Command<String>, Serializable {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -19,7 +19,9 @@ import org.springframework.util.CollectionUtils;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApproverSpecify;
|
||||
|
||||
@ -30,7 +32,7 @@ import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApprove
|
||||
* @since 2023/12/11 17:56
|
||||
*/
|
||||
@Slf4j
|
||||
public class CustomForecastUserTaskAssigneeCmd implements Command<List<BpmnTaskDelegateAssigner>>, Serializable {
|
||||
public class CustomForecastUserTaskAssigneeCmd extends AbstractCommand<List<BpmnTaskDelegateAssigner>> implements Serializable {
|
||||
private final String processInstanceId;
|
||||
private final UserTask userTask;
|
||||
private final EngineExecutionStartListener engineExecutionStartListener;
|
||||
@ -42,6 +44,13 @@ public class CustomForecastUserTaskAssigneeCmd implements Command<List<BpmnTaskD
|
||||
this.engineExecutionStartListener = engineExecutionStartListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String paramToJsonString() {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("processInstanceId", processInstanceId);
|
||||
return JSON.toJSONString(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BpmnTaskDelegateAssigner> execute(CommandContext commandContext) {
|
||||
ProcessEngineConfigurationImpl processEngineConfiguration =
|
||||
@ -81,4 +90,5 @@ public class CustomForecastUserTaskAssigneeCmd implements Command<List<BpmnTaskD
|
||||
JSONUtil.toJsonStr(forecastAssigners));
|
||||
return forecastAssigners;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ import org.flowable.variable.api.history.HistoricVariableInstance;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@ -40,7 +41,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.removeDup
|
||||
* @author wangli
|
||||
* @since 2024/5/11 09:42
|
||||
*/
|
||||
public class CustomNoticeDestinationUserSelectorCmd implements Command<List<BpmnTaskDelegateAssigner>>, Serializable {
|
||||
public class CustomNoticeDestinationUserSelectorCmd extends AbstractCommand<List<BpmnTaskDelegateAssigner>> implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final EngineExecutionStartListener engineExecutionStartListener;
|
||||
private final BpmnHistoricTaskInstanceConverter historicTaskInstanceConverter;
|
||||
@ -63,6 +64,17 @@ public class CustomNoticeDestinationUserSelectorCmd implements Command<List<Bpmn
|
||||
this.initiator = initiator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String paramToJsonString() {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("serviceVersion", serviceVersion);
|
||||
params.put("workspaceType", workspaceType);
|
||||
params.put("noticeProperty", noticeProperty);
|
||||
params.put("processInstanceId", processInstanceId);
|
||||
params.put("initiator", initiator);
|
||||
return JSON.toJSONString(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BpmnTaskDelegateAssigner> execute(CommandContext commandContext) {
|
||||
if (!noticeProperty.getSendMessage()) {
|
||||
@ -170,5 +182,4 @@ public class CustomNoticeDestinationUserSelectorCmd implements Command<List<Bpmn
|
||||
return noticeFlowElement;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
package cn.axzo.workflow.core.engine.cmd;
|
||||
|
||||
import cn.axzo.framework.jackson.utility.JSON;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO;
|
||||
import cn.axzo.workflow.core.engine.job.AsyncRejectTaskJobHandler;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import org.flowable.common.engine.impl.interceptor.Command;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.flowable.common.engine.impl.interceptor.CommandContext;
|
||||
import org.flowable.engine.TaskService;
|
||||
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
|
||||
@ -25,13 +26,18 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask
|
||||
* @author wangli
|
||||
* @since 2024/1/4 13:36
|
||||
*/
|
||||
public class CustomRejectionTaskAsyncCmd implements Command<Void>, Serializable {
|
||||
public class CustomRejectionTaskAsyncCmd extends AbstractCommand<Void> implements Serializable {
|
||||
private final BpmnTaskAuditDTO dto;
|
||||
|
||||
public CustomRejectionTaskAsyncCmd(BpmnTaskAuditDTO dto) {
|
||||
this.dto = dto;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String paramToJsonString() {
|
||||
return JSON.toJSONString(dto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void execute(CommandContext commandContext) {
|
||||
ProcessEngineConfigurationImpl processEngineConfiguration =
|
||||
@ -69,4 +75,5 @@ public class CustomRejectionTaskAsyncCmd implements Command<Void>, Serializable
|
||||
jobService.createAsyncJob(job, false);
|
||||
jobService.scheduleAsyncJob(job);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -6,11 +6,12 @@ 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.operation.DeleteProcessInstanceOperation;
|
||||
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
|
||||
import org.flowable.common.engine.impl.interceptor.Command;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import org.flowable.common.engine.impl.interceptor.CommandContext;
|
||||
import org.flowable.engine.RuntimeService;
|
||||
import org.flowable.engine.TaskService;
|
||||
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
|
||||
import org.flowable.engine.impl.context.Context;
|
||||
import org.flowable.engine.impl.util.CommandContextUtil;
|
||||
import org.flowable.task.api.Task;
|
||||
import org.flowable.task.api.history.HistoricTaskInstance;
|
||||
@ -21,6 +22,7 @@ import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
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;
|
||||
@ -42,7 +44,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask
|
||||
* @author wangli
|
||||
* @since 2024/1/4 13:36
|
||||
*/
|
||||
public class CustomRejectionTaskCmd implements Command<Void>, Serializable {
|
||||
public class CustomRejectionTaskCmd extends AbstractCommand<Void> implements Serializable {
|
||||
|
||||
private final String taskId;
|
||||
private final String advice;
|
||||
@ -60,6 +62,17 @@ public class CustomRejectionTaskCmd implements Command<Void>, Serializable {
|
||||
this.nodeTypes = dto.getNodeTypes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String paramToJsonString() {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("taskId", taskId);
|
||||
params.put("advice", advice);
|
||||
params.put("attachmentList", attachmentList);
|
||||
params.put("approver", approver);
|
||||
params.put("nodeTypes", nodeTypes);
|
||||
return JSON.toJSONString(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void execute(CommandContext commandContext) {
|
||||
ProcessEngineConfigurationImpl processEngineConfiguration =
|
||||
@ -99,4 +112,5 @@ public class CustomRejectionTaskCmd implements Command<Void>, Serializable {
|
||||
.planOperation(new DeleteProcessInstanceOperation(commandContext, task.getProcessInstanceId(),
|
||||
extAxHiTaskInstService));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -3,8 +3,8 @@ package cn.axzo.workflow.core.engine.cmd;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskTransferDTO;
|
||||
import cn.axzo.workflow.core.engine.job.AsyncTransferUserTaskJobHandler;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.google.common.collect.Lists;
|
||||
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;
|
||||
@ -17,6 +17,8 @@ import org.flowable.task.api.history.HistoricTaskInstanceQuery;
|
||||
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask;
|
||||
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTaskAssignerDuplicated;
|
||||
@ -24,7 +26,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask
|
||||
/**
|
||||
* 异步转交任务的命令执行器
|
||||
*/
|
||||
public class CustomTransferUserTaskAsyncCmd implements Command<Void>, Serializable {
|
||||
public class CustomTransferUserTaskAsyncCmd extends AbstractCommand<Void> implements Serializable {
|
||||
|
||||
private final BpmnTaskTransferDTO dto;
|
||||
|
||||
@ -32,6 +34,11 @@ public class CustomTransferUserTaskAsyncCmd implements Command<Void>, Serializab
|
||||
this.dto = dto;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String paramToJsonString() {
|
||||
return JSON.toJSONString(dto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void execute(CommandContext commandContext) {
|
||||
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
|
||||
@ -65,4 +72,5 @@ public class CustomTransferUserTaskAsyncCmd implements Command<Void>, Serializab
|
||||
jobService.createAsyncJob(job, false);
|
||||
jobService.scheduleAsyncJob(job);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package cn.axzo.workflow.core.engine.cmd;
|
||||
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.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;
|
||||
@ -18,7 +19,9 @@ import org.flowable.task.service.impl.persistence.entity.TaskEntity;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
@ -43,7 +46,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask
|
||||
* @author wangli
|
||||
* @since 2023/12/22 10:22
|
||||
*/
|
||||
public class CustomTransferUserTaskCmd implements Command<Void>, Serializable {
|
||||
public class CustomTransferUserTaskCmd extends AbstractCommand<Void> implements Serializable {
|
||||
|
||||
private final String originTaskId;
|
||||
private final BpmnTaskDelegateAssigner originTaskAssignee;
|
||||
@ -60,6 +63,16 @@ public class CustomTransferUserTaskCmd implements Command<Void>, Serializable {
|
||||
this.targetTaskAssignee = targetTaskAssignee;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String paramToJsonString() {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("originTaskId", originTaskId);
|
||||
params.put("originTaskAssignee", originTaskAssignee);
|
||||
params.put("advice", advice);
|
||||
params.put("attachmentList", attachmentList);
|
||||
params.put("targetTaskAssignee", targetTaskAssignee);
|
||||
return JSON.toJSONString(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void execute(CommandContext commandContext) {
|
||||
@ -125,4 +138,5 @@ public class CustomTransferUserTaskCmd implements Command<Void>, Serializable {
|
||||
INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + task.getTaskDefinitionKey(),
|
||||
originAssingeeList);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -25,6 +25,8 @@ public interface MessagePushEvent extends FlowableEvent {
|
||||
|
||||
String getProcessDefinitionId();
|
||||
|
||||
String getProcessDefinitionKey();
|
||||
|
||||
String getCurrentTaskDefinitionKey();
|
||||
|
||||
String getTenantId();
|
||||
|
||||
@ -26,21 +26,21 @@ import static cn.axzo.workflow.core.engine.event.MessagePushEventType.SMS;
|
||||
public class MessagePushEventBuilder {
|
||||
|
||||
public static MessagePushEventImpl createEvent(MessagePushEventType type, List<BpmnTaskDelegateAssigner> assigners,
|
||||
BpmnNoticeConf noticeConf, String processInstanceId,
|
||||
BpmnNoticeConf noticeConf, String processInstanceId, String processDefinitionKey,
|
||||
String tenantId, String taskId) {
|
||||
switch (type) {
|
||||
case NOTICE:
|
||||
return createNoticeEvent(assigners, noticeConf, processInstanceId, tenantId, taskId);
|
||||
return createNoticeEvent(assigners, noticeConf, processInstanceId, processDefinitionKey, tenantId, taskId);
|
||||
case PENDING_PUSH:
|
||||
throw new WorkflowEngineException(MESSAGE_PUSH_EVENT_BUILD_ERROR);
|
||||
case PENDING_COMPLETE:
|
||||
return createPendingCompleteEvent(assigners, noticeConf, processInstanceId, tenantId, taskId);
|
||||
return createPendingCompleteEvent(assigners, noticeConf, processInstanceId, processDefinitionKey, tenantId, taskId);
|
||||
case CARBON_COPY:
|
||||
return createCarbonCopyEvent(assigners, noticeConf, processInstanceId, tenantId);
|
||||
return createCarbonCopyEvent(assigners, noticeConf, processInstanceId, processDefinitionKey, tenantId);
|
||||
case CARBON_COPY_COMPLETE:
|
||||
return createCarbonCopyCompleteEvent(assigners, noticeConf, processInstanceId, tenantId);
|
||||
return createCarbonCopyCompleteEvent(assigners, noticeConf, processInstanceId, processDefinitionKey, tenantId);
|
||||
case SMS:
|
||||
return createSmsEvent(assigners, noticeConf, processInstanceId, tenantId, taskId);
|
||||
return createSmsEvent(assigners, noticeConf, processInstanceId, processDefinitionKey, tenantId, taskId);
|
||||
default:
|
||||
throw new WorkflowEngineException(MES_PUSH_OBJECT_BUILD_ERROR);
|
||||
}
|
||||
@ -48,9 +48,9 @@ public class MessagePushEventBuilder {
|
||||
|
||||
public static MessagePushEventImpl createNoticeEvent(List<BpmnTaskDelegateAssigner> assigners,
|
||||
BpmnNoticeConf noticeConf
|
||||
, String processInstanceId, String tenantId, String taskId) {
|
||||
, String processInstanceId, String processDefinitionKey, String tenantId, String taskId) {
|
||||
MessagePushEventImpl newEvent = new MessagePushEventImpl(NOTICE, assigners, noticeConf, processInstanceId,
|
||||
tenantId, taskId);
|
||||
processDefinitionKey, tenantId, taskId);
|
||||
return newEvent;
|
||||
}
|
||||
|
||||
@ -58,47 +58,54 @@ public class MessagePushEventBuilder {
|
||||
BpmnNoticeConf noticeConf,
|
||||
BpmnApproveConf processApproveConf,
|
||||
String processInstanceId,
|
||||
String processDefinitionId, String currentTaskDefinitionKey,
|
||||
String processDefinitionId,
|
||||
String processDefinitionKey,
|
||||
String currentTaskDefinitionKey,
|
||||
String tenantId, String taskId) {
|
||||
MessagePushEventImpl newEvent = new MessagePushEventImpl(PENDING_PUSH, assigners, noticeConf, processApproveConf, processInstanceId,
|
||||
processDefinitionId, currentTaskDefinitionKey, tenantId, taskId);
|
||||
MessagePushEventImpl newEvent = new MessagePushEventImpl(PENDING_PUSH, assigners, noticeConf, processApproveConf,
|
||||
processInstanceId, processDefinitionId, processDefinitionKey, currentTaskDefinitionKey, tenantId, taskId);
|
||||
return newEvent;
|
||||
}
|
||||
|
||||
public static MessagePushEventImpl createPendingCompleteEvent(List<BpmnTaskDelegateAssigner> assigners,
|
||||
BpmnNoticeConf noticeConf, String processInstanceId,
|
||||
String processDefinitionKey,
|
||||
String tenantId, String taskId) {
|
||||
MessagePushEventImpl newEvent = new MessagePushEventImpl(PENDING_COMPLETE, assigners, noticeConf,
|
||||
processInstanceId,
|
||||
tenantId, taskId);
|
||||
processInstanceId, processDefinitionKey, tenantId, taskId);
|
||||
return newEvent;
|
||||
}
|
||||
|
||||
public static MessagePushEvent createPendingRollbackEvent(String processInstanceId, String tenantId, String taskId, BpmnNoticeConf noticeConf) {
|
||||
return new MessagePushEventImpl(PENDING_ROLLBACK, null, noticeConf, processInstanceId, tenantId, taskId);
|
||||
public static MessagePushEvent createPendingRollbackEvent(String processInstanceId, String processDefinitionKey,
|
||||
String tenantId, String taskId, BpmnNoticeConf noticeConf) {
|
||||
return new MessagePushEventImpl(PENDING_ROLLBACK, null, noticeConf, processInstanceId, processDefinitionKey, tenantId, taskId);
|
||||
}
|
||||
|
||||
public static MessagePushEventImpl createCarbonCopyEvent(List<BpmnTaskDelegateAssigner> assigners,
|
||||
BpmnNoticeConf noticeConf, String processInstanceId,
|
||||
String processDefinitionKey,
|
||||
String tenantId) {
|
||||
MessagePushEventImpl newEvent = new MessagePushEventImpl(CARBON_COPY, assigners, noticeConf,
|
||||
processInstanceId, tenantId, null);
|
||||
processInstanceId, processDefinitionKey, tenantId, null);
|
||||
return newEvent;
|
||||
}
|
||||
|
||||
public static MessagePushEventImpl createCarbonCopyCompleteEvent(List<BpmnTaskDelegateAssigner> assigners,
|
||||
BpmnNoticeConf noticeConf, String processInstanceId,
|
||||
String processDefinitionKey,
|
||||
String tenantId) {
|
||||
MessagePushEventImpl newEvent = new MessagePushEventImpl(CARBON_COPY_COMPLETE, assigners, noticeConf,
|
||||
processInstanceId, tenantId, null);
|
||||
processInstanceId, processDefinitionKey, tenantId, null);
|
||||
return newEvent;
|
||||
}
|
||||
|
||||
public static MessagePushEventImpl createSmsEvent(List<BpmnTaskDelegateAssigner> assigners,
|
||||
BpmnNoticeConf noticeConf,
|
||||
String processInstanceId, String tenantId, String taskId) {
|
||||
String processInstanceId,
|
||||
String processDefinitionKey,
|
||||
String tenantId, String taskId) {
|
||||
MessagePushEventImpl newEvent = new MessagePushEventImpl(SMS, assigners, noticeConf, processInstanceId,
|
||||
tenantId, taskId);
|
||||
processDefinitionKey, tenantId, taskId);
|
||||
return newEvent;
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@ public class MessagePushEventImpl implements MessagePushEvent {
|
||||
private BpmnApproveConf processApproveConfig;
|
||||
private String processInstanceId;
|
||||
private String processDefinitionId;
|
||||
private String processDefinitionKey;
|
||||
private String currentTaskDefinitionKey;
|
||||
private String tenantId;
|
||||
private String taskId;
|
||||
@ -48,11 +49,13 @@ public class MessagePushEventImpl implements MessagePushEvent {
|
||||
* @param tenantId
|
||||
* @param taskId
|
||||
*/
|
||||
public MessagePushEventImpl(FlowableEventType type, List<BpmnTaskDelegateAssigner> assigners, BpmnNoticeConf noticeConfig, String processInstanceId, String tenantId, String taskId) {
|
||||
public MessagePushEventImpl(FlowableEventType type, List<BpmnTaskDelegateAssigner> assigners, BpmnNoticeConf noticeConfig,
|
||||
String processInstanceId, String processDefinitionKey, String tenantId, String taskId) {
|
||||
this.type = type;
|
||||
this.assigners = assigners;
|
||||
this.noticeConfig = noticeConfig;
|
||||
this.processInstanceId = processInstanceId;
|
||||
this.processDefinitionKey = processDefinitionKey;
|
||||
this.tenantId = tenantId;
|
||||
this.taskId = taskId;
|
||||
}
|
||||
@ -75,7 +78,7 @@ public class MessagePushEventImpl implements MessagePushEvent {
|
||||
public MessagePushEventImpl(FlowableEventType type, List<BpmnTaskDelegateAssigner> assigners,
|
||||
BpmnNoticeConf noticeConfig,
|
||||
BpmnApproveConf processApproveConfig,
|
||||
String processInstanceId, String processDefinitionId,
|
||||
String processInstanceId, String processDefinitionId, String processDefinitionKey,
|
||||
String currentTaskDefinitionKey, String tenantId, String taskId) {
|
||||
this.type = type;
|
||||
this.assigners = assigners;
|
||||
@ -141,6 +144,15 @@ public class MessagePushEventImpl implements MessagePushEvent {
|
||||
this.processDefinitionId = processDefinitionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProcessDefinitionKey() {
|
||||
return processDefinitionKey;
|
||||
}
|
||||
|
||||
public void setProcessDefinitionKey(String processDefinitionKey) {
|
||||
this.processDefinitionKey = processDefinitionKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentTaskDefinitionKey() {
|
||||
return currentTaskDefinitionKey;
|
||||
|
||||
@ -0,0 +1,89 @@
|
||||
package cn.axzo.workflow.core.engine.interceptor;
|
||||
|
||||
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
|
||||
import cn.axzo.workflow.core.common.utils.TraceUtil;
|
||||
import cn.axzo.workflow.core.engine.cmd.AbstractCommand;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.ibatis.exceptions.PersistenceException;
|
||||
import org.flowable.common.engine.impl.interceptor.AbstractCommandInterceptor;
|
||||
import org.flowable.common.engine.impl.interceptor.Command;
|
||||
import org.flowable.common.engine.impl.interceptor.CommandConfig;
|
||||
import org.flowable.common.engine.impl.interceptor.CommandExecutor;
|
||||
|
||||
import static cn.axzo.workflow.core.common.code.FlowableEngineRespCode.ENGINE_ASYNC_COMMAND_EXECUTION_RETRY_GIVE_UP;
|
||||
|
||||
/**
|
||||
* 基于 RetryInterceptor 的命令重试拦截器, 本意想用来处理多人同时操作同一个任务, 但会存在超过重试次数后,会丢弃原有的命令.
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024/7/1 13:51
|
||||
*/
|
||||
@Slf4j
|
||||
public class CustomRetryInterceptor extends AbstractCommandInterceptor {
|
||||
|
||||
protected int numOfRetries = 3;
|
||||
protected int waitTimeInMs = 60;
|
||||
protected int waitIncreaseFactor = 5;
|
||||
|
||||
@Override
|
||||
public <T> T execute(CommandConfig config, Command<T> command, CommandExecutor commandExecutor) {
|
||||
long waitTime = waitTimeInMs;
|
||||
int failedAttempts = 0;
|
||||
do {
|
||||
if (failedAttempts > 0) {
|
||||
log.warn("Waiting for {}ms before retrying the command.", waitTime);
|
||||
waitBeforeRetry(waitTime);
|
||||
waitTime *= waitIncreaseFactor;
|
||||
}
|
||||
|
||||
try {
|
||||
// try to execute the command
|
||||
if (AbstractCommand.class.isAssignableFrom(command.getClass())) {
|
||||
// 如果在以后,重试三次也不能解决的话, 可以利用这里的拿到的参数,重新自动构造CMD,并执行.
|
||||
log.info("traceId:{} Executing command params: {}", TraceUtil.traceId(),
|
||||
((AbstractCommand<T>) command).paramToJsonString());
|
||||
}
|
||||
return next.execute(config, command, commandExecutor);
|
||||
|
||||
} catch (PersistenceException e) {
|
||||
log.warn("Caught persistence exception: {}", e.getMessage(), e);
|
||||
}
|
||||
|
||||
failedAttempts++;
|
||||
} while (failedAttempts <= numOfRetries);
|
||||
|
||||
throw new WorkflowEngineException(ENGINE_ASYNC_COMMAND_EXECUTION_RETRY_GIVE_UP, String.valueOf(numOfRetries));
|
||||
}
|
||||
|
||||
protected void waitBeforeRetry(long waitTime) {
|
||||
try {
|
||||
Thread.sleep(waitTime);
|
||||
} catch (InterruptedException e) {
|
||||
log.warn("I am interrupted while waiting for a retry.");
|
||||
}
|
||||
}
|
||||
|
||||
public void setNumOfRetries(int numOfRetries) {
|
||||
this.numOfRetries = numOfRetries;
|
||||
}
|
||||
|
||||
public void setWaitIncreaseFactor(int waitIncreaseFactor) {
|
||||
this.waitIncreaseFactor = waitIncreaseFactor;
|
||||
}
|
||||
|
||||
public void setWaitTimeInMs(int waitTimeInMs) {
|
||||
this.waitTimeInMs = waitTimeInMs;
|
||||
}
|
||||
|
||||
public int getNumOfRetries() {
|
||||
return numOfRetries;
|
||||
}
|
||||
|
||||
public int getWaitIncreaseFactor() {
|
||||
return waitIncreaseFactor;
|
||||
}
|
||||
|
||||
public int getWaitTimeInMs() {
|
||||
return waitTimeInMs;
|
||||
}
|
||||
}
|
||||
@ -19,15 +19,16 @@ public class CustomWorkflowEngineExceptionHandler implements AsyncRunnableExecut
|
||||
@Override
|
||||
public boolean handleException(JobServiceConfiguration jobServiceConfiguration, JobInfo job, Throwable e) {
|
||||
Throwable rootCause = getRootCause(e);
|
||||
if (rootCause.getClass().isAssignableFrom(WorkflowEngineException.class)) {
|
||||
WorkflowEngineException workflowEngineException = (WorkflowEngineException) rootCause;
|
||||
if (Objects.equals(workflowEngineException.getCode(), "99806020")) {
|
||||
log.info("AsyncApproveTaskJobHandler execute exception code: {} info: {}",
|
||||
workflowEngineException.getCode(), rootCause.getMessage(), rootCause);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
// if (rootCause.getClass().isAssignableFrom(WorkflowEngineException.class)) {
|
||||
// WorkflowEngineException workflowEngineException = (WorkflowEngineException) rootCause;
|
||||
// if (Objects.equals(workflowEngineException.getCode(), "99806020")) {
|
||||
// log.info("AsyncApproveTaskJobHandler execute exception code: {} info: {}",
|
||||
// workflowEngineException.getCode(), rootCause.getMessage(), rootCause);
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
log.warn("Async Runnable Execution Exception: {}", rootCause.getMessage(), e);
|
||||
return WorkflowEngineException.class.isAssignableFrom(rootCause.getClass());
|
||||
}
|
||||
|
||||
private Throwable getRootCause(Throwable throwable) {
|
||||
|
||||
@ -38,6 +38,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT;
|
||||
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getCarbonCopyConfigs;
|
||||
import static cn.axzo.workflow.core.listener.AbstractBpmnEventListener.parseProcessDefinitionKey;
|
||||
|
||||
/**
|
||||
* 抄送功能的具体实现
|
||||
@ -110,6 +111,7 @@ public class EngineCarbonCopyEventListener implements JavaDelegate {
|
||||
|
||||
MessagePushEventImpl event = MessagePushEventBuilder.createEvent(MessagePushEventType.CARBON_COPY,
|
||||
carbonUsers, bpmnNoticeConf, execution.getProcessInstanceId(),
|
||||
parseProcessDefinitionKey(execution.getProcessDefinitionId()),
|
||||
execution.getTenantId(), getCarbonTaskId(execution));
|
||||
eventDispatcher.dispatchEvent(event, processEngineConfiguration.getEngineCfgKey());
|
||||
}
|
||||
|
||||
@ -8,7 +8,6 @@ import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper;
|
||||
import cn.axzo.workflow.core.engine.cmd.CustomNoticeDestinationUserSelectorCmd;
|
||||
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.listener.BpmnProcessEventListener;
|
||||
import cn.axzo.workflow.core.service.converter.BpmnHistoricTaskInstanceConverter;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
@ -48,6 +47,7 @@ import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.APPROV
|
||||
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.CANCELLED;
|
||||
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.DELETED;
|
||||
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.REJECTED;
|
||||
import static cn.axzo.workflow.core.engine.event.MessagePushEventType.NOTICE;
|
||||
|
||||
/**
|
||||
* 引擎全局的流程实例事件监听
|
||||
@ -157,8 +157,9 @@ public class EngineProcessInstanceEventListener extends AbstractFlowableEngineEv
|
||||
List<BpmnTaskDelegateAssigner> assigners = processEngineConfiguration.getCommandExecutor()
|
||||
.execute(new CustomNoticeDestinationUserSelectorCmd(engineExecutionStartListener, historicTaskInstanceConverter,
|
||||
serviceVersion, workspaceType, config.getNotice(), event.getProcessInstanceId(), assigner));
|
||||
MessagePushEventImpl messagePushEvent = MessagePushEventBuilder.createEvent(MessagePushEventType.NOTICE,
|
||||
assigners, config, processInstance.getProcessInstanceId(), processInstance.getTenantId(), null);
|
||||
MessagePushEventImpl messagePushEvent = MessagePushEventBuilder.createEvent(NOTICE,
|
||||
assigners, config, processInstance.getProcessInstanceId(), processInstance.getProcessDefinitionKey(),
|
||||
processInstance.getTenantId(), null);
|
||||
log.info("发送通知消息: {}", JSONUtil.toJsonStr(messagePushEvent));
|
||||
eventDispatcher.dispatchEvent(messagePushEvent, processEngineConfiguration.getEngineCfgKey());
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package cn.axzo.workflow.core.listener;
|
||||
import cn.axzo.workflow.core.common.context.OperationContext;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import org.slf4j.MDC;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import static cn.azxo.framework.common.constatns.Constants.CTX_LOG_ID_MDC;
|
||||
|
||||
@ -33,4 +34,11 @@ public abstract class AbstractBpmnEventListener<T extends OperationContext> impl
|
||||
protected String buildCacheKey(String apiUrl, Object request) {
|
||||
return apiUrl + JSONUtil.toJsonStr(request);
|
||||
}
|
||||
|
||||
public static String parseProcessDefinitionKey(String processDefinitionId) {
|
||||
if (!StringUtils.hasText(processDefinitionId)) {
|
||||
return "";
|
||||
}
|
||||
return processDefinitionId.split(":")[0];
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.MQ_OWNERSHIP_APP;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.MQ_OWNERSHIP_APPLICATION;
|
||||
|
||||
/**
|
||||
* 默认的 RocketMQ 事件生产者的装饰器
|
||||
@ -68,7 +68,9 @@ public class CustomRocketMQEventProducer extends RocketMQEventProducer {
|
||||
newHeaders.put(TraceUtils.TRACE_ID, TraceUtils.getOrCreateTraceId());
|
||||
newHeaders.put(TraceUtils.CTX_LOG_ID, TraceUtils.getOrCreateTraceId());
|
||||
newHeaders.put(TraceUtils.TRACE_ID_IN_MDC, TraceUtils.getOrCreateTraceId());
|
||||
newHeaders.put(MQ_OWNERSHIP_APP, applicationName);
|
||||
// FIXME
|
||||
// newHeaders.put(MQ_OWNERSHIP_APPLICATION, applicationName);
|
||||
newHeaders.put(MQ_OWNERSHIP_APPLICATION, "senna");
|
||||
final Context copiedContext = context.toBuilder().headers(newHeaders).build();
|
||||
|
||||
Runnable runnable = () -> {
|
||||
@ -94,7 +96,7 @@ public class CustomRocketMQEventProducer extends RocketMQEventProducer {
|
||||
} else {
|
||||
// 并发会导致事件时序出现问题. 所以串行执行
|
||||
log.info("runnable not transaction event={}", copiedEvent.toJsonString());
|
||||
getAfterCommitExecutor().executeAndRollback(() -> runnable.run(), () -> rollbackRunnable.run());
|
||||
getAfterCommitExecutor().executeAndRollback(runnable, rollbackRunnable);
|
||||
}
|
||||
|
||||
List<Runnable> runnables = getAfterCommitExecutor().getRunnables();
|
||||
|
||||
@ -34,5 +34,9 @@ public class ExtAxProperty extends BaseEntity<ExtAxProperty> {
|
||||
@TableField("value")
|
||||
private String value;
|
||||
|
||||
|
||||
/**
|
||||
* 接入方是否使用了 manageable
|
||||
*/
|
||||
@TableField("manageable")
|
||||
private Boolean manageable;
|
||||
}
|
||||
|
||||
@ -86,9 +86,12 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.validation.Valid;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@ -102,6 +105,7 @@ import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.axzo.workflow.client.config.WorkflowRequestInterceptor.HEADER_SERVER_NAME;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.AND_SIGN_EXPRESSION;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.BIZ_ORG_RELATION;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.BPM_MODEL_CATEGORY;
|
||||
@ -112,6 +116,7 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_PROCESS_AG
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_PROCESS_WORKSPACE_TYPE;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.OLD_INTERNAL_INITIATOR;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.PENDING_TEMPLATE_VARIABLE;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.PROCESS_OWNERSHIP_APPLICATION;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.WORKFLOW_ENGINE_VERSION;
|
||||
import static cn.axzo.workflow.common.enums.ApprovalMethodEnum.autoPassed;
|
||||
import static cn.axzo.workflow.common.enums.ApprovalMethodEnum.autoRejection;
|
||||
@ -320,6 +325,9 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
|
||||
dto.getVariables().put(INTERNAL_PROCESS_AGENT, StringUtils.isNotBlank(definition.getTenantId()));
|
||||
dto.getVariables().put(CREATE_INSTANCE_PARAMS, JSONUtil.toJsonStr(dto));
|
||||
|
||||
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
||||
dto.getVariables().put(PROCESS_OWNERSHIP_APPLICATION, request.getHeader(HEADER_SERVER_NAME));
|
||||
// dto.getVariables().put(MQ_OWNERSHIP_APPLICATION, );
|
||||
// if (Objects.nonNull(dto.getNextApprover())) {
|
||||
// BpmnTaskDelegateAssigner nextApprover = dto.getNextApprover();
|
||||
// nextApprover.setTenantId(Objects.nonNull(nextApprover.getTenantId()) ? nextApprover.getTenantId
|
||||
|
||||
@ -458,7 +458,7 @@ public class BpmnProcessModelServiceImpl implements BpmnProcessModelService {
|
||||
if (CollectionUtils.isEmpty(list)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return list.stream().map(Model::getTenantId).collect(Collectors.toList());
|
||||
return list.stream().map(Model::getTenantId).distinct().collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private void updateProcessDefinitionSuspended(String deploymentId) {
|
||||
|
||||
@ -628,6 +628,7 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
|
||||
MessagePushEventImpl event = MessagePushEventBuilder.createEvent(MessagePushEventType.valueOf(type),
|
||||
Lists.newArrayList(assigner), noticeConfig.orElse(null),
|
||||
processInstance.getProcessInstanceId(),
|
||||
processInstance.getProcessDefinitionKey(),
|
||||
processInstance.getTenantId(), task.getId());
|
||||
event.setProcessInstanceId(processInstance.getProcessInstanceId());
|
||||
event.setTenantId(processInstance.getTenantId());
|
||||
|
||||
@ -5,6 +5,9 @@ import cn.axzo.workflow.core.repository.mapper.ExtAxPropertyMapper;
|
||||
import cn.axzo.workflow.core.service.ExtAxPropertyService;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.CachePut;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@ -23,18 +26,21 @@ public class ExtAxPropertyServiceImpl implements ExtAxPropertyService {
|
||||
@Resource
|
||||
private ExtAxPropertyMapper mapper;
|
||||
|
||||
@CacheEvict(value = "property", key = "#property.name")
|
||||
@Override
|
||||
public ExtAxProperty add(ExtAxProperty property) {
|
||||
mapper.insert(property);
|
||||
return property;
|
||||
}
|
||||
|
||||
@CachePut(value = "property", key = "#property.name")
|
||||
@Override
|
||||
public ExtAxProperty update(ExtAxProperty property) {
|
||||
mapper.updateById(property);
|
||||
return property;
|
||||
}
|
||||
|
||||
@Cacheable(value = "property", key = "#name")
|
||||
@Override
|
||||
public Optional<ExtAxProperty> getByName(String name) {
|
||||
if (!StringUtils.hasText(name)) {
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
package cn.axzo.workflow.core.service.support;
|
||||
|
||||
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
|
||||
import cn.axzo.workflow.core.engine.cmd.AbstractCommand;
|
||||
import cn.azxo.framework.common.utils.StringUtils;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import org.flowable.common.engine.api.delegate.Expression;
|
||||
import org.flowable.common.engine.impl.interceptor.Command;
|
||||
import org.flowable.common.engine.impl.interceptor.CommandContext;
|
||||
@ -10,6 +12,8 @@ import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
|
||||
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.axzo.workflow.core.common.code.FlowableEngineRespCode.ENGINE_EXECUTION_LOST_ID_ERROR;
|
||||
|
||||
@ -20,7 +24,7 @@ import static cn.axzo.workflow.core.common.code.FlowableEngineRespCode.ENGINE_EX
|
||||
* @author wangli
|
||||
* @since 2023/10/9 19:30
|
||||
*/
|
||||
public class ExpressionConditionCmd implements Command<Boolean>, Serializable {
|
||||
public class ExpressionConditionCmd extends AbstractCommand<Boolean> implements Serializable {
|
||||
protected final RuntimeService runtimeService;
|
||||
protected final ProcessEngineConfigurationImpl processEngineConfiguration;
|
||||
protected final String processInstanceId;
|
||||
@ -35,6 +39,14 @@ public class ExpressionConditionCmd implements Command<Boolean>, Serializable {
|
||||
this.exp = exp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String paramToJsonString() {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("processInstanceId", processInstanceId);
|
||||
params.put("exp", exp);
|
||||
return JSON.toJSONString(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean execute(CommandContext commandContext) {
|
||||
Expression expression = processEngineConfiguration.getExpressionManager().createExpression(this.exp);
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
package org.flowable.engine.impl.cmd;
|
||||
|
||||
import cn.axzo.workflow.core.engine.cmd.AbstractCommand;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import liquibase.pro.packaged.M;
|
||||
import org.flowable.common.engine.api.FlowableException;
|
||||
import org.flowable.common.engine.api.FlowableObjectNotFoundException;
|
||||
import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType;
|
||||
@ -22,6 +25,9 @@ import org.flowable.task.api.Task;
|
||||
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 覆盖 Flowable 自带的 CreateAttachmentCmd, 由于 Flowable 5 的实现导致异常,需要覆盖
|
||||
@ -29,7 +35,7 @@ import java.io.InputStream;
|
||||
* @author Tom Baeyens
|
||||
* @author Joram Barrez
|
||||
*/
|
||||
public class CreateAttachmentCmd implements Command<Attachment> {
|
||||
public class CreateAttachmentCmd extends AbstractCommand<Attachment> implements Serializable {
|
||||
|
||||
protected String attachmentType;
|
||||
protected String taskId;
|
||||
@ -50,6 +56,19 @@ public class CreateAttachmentCmd implements Command<Attachment> {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String paramToJsonString() {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("attachmentType", attachmentType);
|
||||
params.put("taskId", taskId);
|
||||
params.put("processInstanceId", processInstanceId);
|
||||
params.put("attachmentName", attachmentName);
|
||||
params.put("attachmentDescription", attachmentDescription);
|
||||
// params.put("content", content);
|
||||
params.put("url", url);
|
||||
return JSON.toJSONString(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Attachment execute(CommandContext commandContext) {
|
||||
|
||||
|
||||
@ -0,0 +1,3 @@
|
||||
alter table ext_ax_property
|
||||
add manageable boolean default false null comment '接入方是否使用了 manageable';
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>workflow-engine-server</artifactId>
|
||||
<name>Workflow Engine Server</name>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
@ -20,6 +21,10 @@
|
||||
<redisson.version>3.25.0</redisson.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<!--<dependency>
|
||||
<groupId>cn.axzo.workflow</groupId>
|
||||
<artifactId>workflow-engine-spring-boot-starter</artifactId>
|
||||
</dependency>-->
|
||||
<dependency>
|
||||
<groupId>cn.axzo.framework</groupId>
|
||||
<artifactId>axzo-web-spring-boot-starter</artifactId>
|
||||
@ -95,10 +100,10 @@
|
||||
<groupId>cn.axzo.maokai</groupId>
|
||||
<artifactId>maokai-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.axzo.tyr</groupId>
|
||||
<artifactId>tyr-api</artifactId>
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>cn.axzo.tyr</groupId>-->
|
||||
<!-- <artifactId>tyr-api</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>cn.axzo.karma</groupId>
|
||||
<artifactId>karma-api</artifactId>
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
package cn.axzo.workflow.server;
|
||||
|
||||
import liquibase.pro.packaged.E;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
@ -12,6 +14,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
@ComponentScan({"cn.axzo.workflow", "cn.axzo.maokai"})
|
||||
@SpringBootApplication(exclude = RabbitAutoConfiguration.class)
|
||||
@EnableTransactionManagement
|
||||
@EnableCaching
|
||||
public class WorkflowEnginApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
@ -2,6 +2,7 @@ package cn.axzo.workflow.server.advice;
|
||||
|
||||
import cn.axzo.framework.autoconfigure.web.exception.RespErrorCodeMappingProperties;
|
||||
import cn.axzo.framework.autoconfigure.web.exception.handler.AbstractExceptionApiResultHandler;
|
||||
import cn.axzo.framework.domain.web.code.BaseCode;
|
||||
import cn.axzo.framework.domain.web.code.IRespCode;
|
||||
import cn.axzo.framework.domain.web.code.RespCode;
|
||||
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
|
||||
@ -30,8 +31,8 @@ public class FlowableExceptionResultHandlerAdvice extends AbstractExceptionApiRe
|
||||
protected IRespCode decode(FlowableException ex, IRespCode fallbackCode) {
|
||||
log.warn("发现 FlowableException Error: ", ex);
|
||||
if (Objects.nonNull(ex.getCause()) && ex.getCause() instanceof WorkflowEngineException) {
|
||||
return new RespCode(UNAVAILABLE_FOR_LEGAL_REASONS.getCode(), ex.getCause().getMessage());
|
||||
return new RespCode(BaseCode.SUCCESS.getCode(), ex.getCause().getMessage());
|
||||
}
|
||||
return new RespCode(UNAVAILABLE_FOR_LEGAL_REASONS.getCode(), ex.getMessage());
|
||||
return new RespCode(BaseCode.SUCCESS.getCode(), ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
package cn.axzo.workflow.server.advice;
|
||||
|
||||
import cn.axzo.framework.autoconfigure.web.exception.RespErrorCodeMappingProperties;
|
||||
import cn.axzo.framework.autoconfigure.web.exception.handler.AbstractExceptionApiResultHandler;
|
||||
import cn.axzo.framework.domain.web.code.BaseCode;
|
||||
import cn.axzo.framework.domain.web.code.IRespCode;
|
||||
import cn.axzo.framework.domain.web.code.RespCode;
|
||||
import org.flowable.common.engine.api.FlowableOptimisticLockingException;
|
||||
import org.flowable.common.engine.impl.interceptor.CommandContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import static cn.axzo.framework.domain.web.code.BaseCode.UNAVAILABLE_FOR_LEGAL_REASONS;
|
||||
|
||||
/**
|
||||
* 降级 FlowableOptimisticLockingException 异常,该异常在 Flowable 框架中是可以忽略的
|
||||
*
|
||||
* @author wangli
|
||||
* @see CommandContext#logException()
|
||||
* @since 2024/6/19 17:32
|
||||
*/
|
||||
@Component
|
||||
public class FlowableOptimisticLockingExceptionHandlerAdvice extends AbstractExceptionApiResultHandler<FlowableOptimisticLockingException> {
|
||||
public FlowableOptimisticLockingExceptionHandlerAdvice(RespErrorCodeMappingProperties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IRespCode decode(FlowableOptimisticLockingException ex, IRespCode fallbackCode) {
|
||||
return new RespCode(BaseCode.SUCCESS.getCode(), ex.getMessage());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
package cn.axzo.workflow.server.advice;
|
||||
|
||||
import cn.axzo.framework.autoconfigure.web.exception.RespErrorCodeMappingProperties;
|
||||
import cn.axzo.framework.autoconfigure.web.exception.handler.AbstractExceptionApiResultHandler;
|
||||
import cn.axzo.framework.domain.web.code.BaseCode;
|
||||
import cn.axzo.framework.domain.web.code.IRespCode;
|
||||
import cn.axzo.framework.domain.web.code.RespCode;
|
||||
import cn.axzo.workflow.client.feign.bpmn.ProcessActivityApi;
|
||||
import cn.axzo.workflow.client.feign.bpmn.ProcessInstanceApi;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAbortDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnActivitySetAssigneeDTO;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.sql.SQLIntegrityConstraintViolationException;
|
||||
|
||||
|
||||
/**
|
||||
* 处理多个接口同时操作一个流程实例时,可能会抛出数据库的异常,这种异常是可以被忽略的
|
||||
* <p>
|
||||
* 例如: {@link ProcessActivityApi#setAssignee(BpmnActivitySetAssigneeDTO)} 于 {@link ProcessInstanceApi#abortProcessInstance(BpmnProcessInstanceAbortDTO)}
|
||||
* 两个接口并发访问时,由于 abort 先执行完,并提交事务后,setAssignee 方法内虽然有判断实例状态,但最后事务提交时突然发现实例状态被中止了就会抛出异常。
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024/6/20 09:42
|
||||
*/
|
||||
@Component
|
||||
public class SQLIntegrityConstraintViolationExceptionHandlerAdvice extends AbstractExceptionApiResultHandler<SQLIntegrityConstraintViolationException> {
|
||||
public SQLIntegrityConstraintViolationExceptionHandlerAdvice(RespErrorCodeMappingProperties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IRespCode decode(SQLIntegrityConstraintViolationException ex, IRespCode fallbackCode) {
|
||||
return new RespCode(BaseCode.SUCCESS.getCode(), ex.getMessage());
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,6 @@
|
||||
package cn.axzo.workflow.server.common.annotation;
|
||||
|
||||
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
|
||||
import cn.axzo.workflow.server.common.util.DingTalkUtils;
|
||||
import cn.azxo.framework.common.utils.LogUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import static cn.axzo.workflow.server.common.aspectj.RepeatSubmitAspect.argsArrayToString;
|
||||
@ -71,10 +69,11 @@ public enum ReporterType {
|
||||
public abstract void executeAction(String profile, String title, Boolean sendDingTalk, Object[] args, String shortString, Throwable e, Boolean downgrade);
|
||||
|
||||
private static void logWarn(Throwable throwable, String shortString) {
|
||||
if (throwable instanceof WorkflowEngineException) {
|
||||
log.warn("引擎内部正常业务异常类型,日志降级: " + throwable.getMessage(), throwable);
|
||||
} else {
|
||||
LogUtil.error(LogUtil.ErrorType.ERROR_BUSINESS, shortString, throwable.getMessage(), throwable);
|
||||
}
|
||||
// 由于框架底层 AbstractExceptionApiResultHandler 默认会打印,所以此处都只是降级打印
|
||||
// if (throwable instanceof WorkflowEngineException) {
|
||||
log.warn("引擎内部正常业务异常类型,日志降级: " + throwable.getMessage(), throwable);
|
||||
// } else {
|
||||
// LogUtil.error(LogUtil.ErrorType.ERROR_BUSINESS, shortString, throwable.getMessage(), throwable);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import cn.axzo.workflow.core.common.event.ApiLogEvent;
|
||||
import cn.axzo.workflow.server.common.annotation.EnvConfig;
|
||||
import cn.axzo.workflow.server.common.annotation.ErrorReporter;
|
||||
import cn.axzo.workflow.server.common.config.property.WorkflowProperties;
|
||||
import com.google.common.collect.Lists;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
@ -26,6 +27,7 @@ import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static cn.axzo.workflow.client.config.WorkflowRequestInterceptor.HEADER_API_VERSION;
|
||||
@ -50,6 +52,7 @@ public class ErrorReportAspect implements Ordered {
|
||||
private ApplicationEventPublisher applicationEventPublisher;
|
||||
@Resource
|
||||
private WorkflowProperties workflowProperties;
|
||||
private static List<String> methodNames = Lists.newArrayList("HealthCheckController.checkDeath()");
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
@ -73,6 +76,10 @@ public class ErrorReportAspect implements Ordered {
|
||||
watch.stop();
|
||||
log.info("StopWatch '{}': running time = {} 's", watch.getLastTaskName(), watch.getTotalTimeSeconds());
|
||||
|
||||
if (!methodNames.contains(watch.getLastTaskName())) {
|
||||
log.info("StopWatch '{}': running time = {} 's", watch.getLastTaskName(), watch.getTotalTimeSeconds());
|
||||
}
|
||||
|
||||
if (!signature.toShortString().contains("ExtAxApiLogServiceImpl")) {
|
||||
String type = getType(joinPoint);
|
||||
ApiLogEvent event = new ApiLogEvent(MDC.get(CTX_LOG_ID_MDC),
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
package cn.axzo.workflow.server.common.filter;
|
||||
|
||||
import cn.azxo.framework.common.constatns.Constants;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import com.google.common.base.Strings;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -9,6 +8,7 @@ import org.apache.skywalking.apm.toolkit.trace.TraceContext;
|
||||
import org.slf4j.MDC;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
@ -18,6 +18,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
import static cn.axzo.workflow.common.constant.LogFieldConstants.X_REQUEST_ID;
|
||||
import static cn.azxo.framework.common.constatns.Constants.CTX_LOG_ID_MDC;
|
||||
|
||||
/**
|
||||
* Http接口日志记录
|
||||
@ -44,18 +45,18 @@ public class HttpTraceLogFilter extends OncePerRequestFilter implements Ordered
|
||||
} else {
|
||||
MDC.put(X_REQUEST_ID, requestId);
|
||||
}
|
||||
String ctxLogId = request.getHeader(Constants.CTX_LOG_ID_MDC);
|
||||
String ctxLogId = request.getHeader(CTX_LOG_ID_MDC);
|
||||
if (Strings.isNullOrEmpty(ctxLogId)) {
|
||||
MDC.put(Constants.CTX_LOG_ID_MDC, getTraceId());
|
||||
MDC.put(CTX_LOG_ID_MDC, getTraceId());
|
||||
} else {
|
||||
MDC.put(Constants.CTX_LOG_ID_MDC, ctxLogId);
|
||||
MDC.put(CTX_LOG_ID_MDC, ctxLogId);
|
||||
}
|
||||
|
||||
try {
|
||||
filterChain.doFilter(request, response);
|
||||
} finally {
|
||||
response.setHeader(Constants.CTX_LOG_ID_MDC, MDC.get(Constants.CTX_LOG_ID_MDC));
|
||||
response.setHeader(X_REQUEST_ID, MDC.get(Constants.CTX_LOG_ID_MDC));
|
||||
response.setHeader(CTX_LOG_ID_MDC, MDC.get(CTX_LOG_ID_MDC));
|
||||
response.setHeader(X_REQUEST_ID, MDC.get(CTX_LOG_ID_MDC));
|
||||
MDC.clear();
|
||||
}
|
||||
}
|
||||
@ -64,4 +65,10 @@ public class HttpTraceLogFilter extends OncePerRequestFilter implements Ordered
|
||||
String contextTraceId = TraceContext.traceId();
|
||||
return Strings.isNullOrEmpty(contextTraceId) ? IdUtil.fastSimpleUUID() : contextTraceId;
|
||||
}
|
||||
|
||||
public static String traceId() {
|
||||
String xRequestId = MDC.get(X_REQUEST_ID);
|
||||
return StringUtils.hasText(xRequestId) ? xRequestId : MDC.get(CTX_LOG_ID_MDC);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,26 +0,0 @@
|
||||
package cn.axzo.workflow.server.common.hook;
|
||||
|
||||
import org.springframework.context.SmartLifecycle;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024/6/6 14:35
|
||||
*/
|
||||
public class NacosShutdownHook implements SmartLifecycle {
|
||||
@Override
|
||||
public void start() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -3,6 +3,7 @@ package cn.axzo.workflow.server.common.interceptor;
|
||||
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
|
||||
import cn.axzo.workflow.core.repository.entity.ExtAxProperty;
|
||||
import cn.axzo.workflow.core.service.ExtAxPropertyService;
|
||||
import cn.axzo.workflow.server.common.util.RedisUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -12,14 +13,17 @@ import org.springframework.web.servlet.HandlerInterceptor;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.time.Duration;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import static cn.axzo.workflow.client.config.WorkflowRequestInterceptor.HEADER_API_VERSION;
|
||||
import static cn.axzo.workflow.client.config.WorkflowRequestInterceptor.HEADER_HTTP_CLIENT;
|
||||
import static cn.axzo.workflow.client.config.WorkflowRequestInterceptor.HEADER_HTTP_CLIENT_VALUE;
|
||||
import static cn.axzo.workflow.client.config.WorkflowRequestInterceptor.HEADER_SERVER_NAME;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.FLOW_SERVER_VERSION_130;
|
||||
import static cn.axzo.workflow.common.constant.StarterConstants.ENABLE_MANAGEABLE;
|
||||
import static cn.axzo.workflow.core.common.code.OtherRespCode.CLIENT_VERSION_SUPPORT;
|
||||
import static cn.axzo.workflow.core.common.code.OtherRespCode.MICRO_SERVER_NEED_REBUILD;
|
||||
|
||||
@ -36,6 +40,8 @@ public class RequestHeaderContextInterceptor implements HandlerInterceptor {
|
||||
private String serviceVersion;
|
||||
@Autowired
|
||||
private ExtAxPropertyService extAxPropertyService;
|
||||
private static final ThreadLocal<String> KEY_CACHE = new ThreadLocal<>();
|
||||
private static final String REPEAT_KEY = "global:api_application:";
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
@ -74,28 +80,52 @@ public class RequestHeaderContextInterceptor implements HandlerInterceptor {
|
||||
|
||||
private void recordClientInfo(HttpServletRequest request, String headerClientVersion,
|
||||
DefaultArtifactVersion clientVersion) {
|
||||
log.info("HEADER_SERVER_NAME : {}", request.getHeader(HEADER_SERVER_NAME));
|
||||
if (!StringUtils.hasText(request.getHeader(HEADER_SERVER_NAME))) {
|
||||
String applicationName = request.getHeader(HEADER_SERVER_NAME);
|
||||
log.info("HEADER_SERVER_NAME : {}", applicationName);
|
||||
if (!StringUtils.hasText(applicationName)) {
|
||||
return;
|
||||
}
|
||||
ExtAxProperty property = extAxPropertyService.getByName(request.getHeader(HEADER_SERVER_NAME)).map(entity -> {
|
||||
entity.setCreated(!Objects.equals(entity.getValue(), serviceVersion));
|
||||
entity.setValue(headerClientVersion);
|
||||
return entity;
|
||||
}).orElseGet(() -> {
|
||||
ExtAxProperty extAxProperty = new ExtAxProperty();
|
||||
extAxProperty.setCreated(true);
|
||||
extAxProperty.setName(request.getHeader(HEADER_SERVER_NAME));
|
||||
extAxProperty.setValue(clientVersion.toString());
|
||||
return extAxProperty;
|
||||
});
|
||||
String manageableStatus = request.getHeader(ENABLE_MANAGEABLE);
|
||||
|
||||
if (property.getCreated()) {
|
||||
if (Objects.isNull(property.getId())) {
|
||||
extAxPropertyService.add(property);
|
||||
} else {
|
||||
extAxPropertyService.update(property);
|
||||
}
|
||||
Optional<ExtAxProperty> extAxProperty = extAxPropertyService.getByName(applicationName);
|
||||
String cacheRepeatKey = REPEAT_KEY + applicationName;
|
||||
log.info("repeatApi key: {}", cacheRepeatKey);
|
||||
|
||||
//success为true表示key不存在,执行成功,false表示key存在,执行失败
|
||||
Boolean success = RedisUtils.trySetObject(cacheRepeatKey, "", Duration.ofSeconds(5));
|
||||
if (success) {
|
||||
KEY_CACHE.set(cacheRepeatKey);
|
||||
insert(extAxProperty, applicationName, clientVersion, manageableStatus);
|
||||
}
|
||||
}
|
||||
|
||||
private void update(Optional<ExtAxProperty> extAxProperty, String requestApplicationName, DefaultArtifactVersion clientVersion, String manageableStatus) {
|
||||
if (!extAxProperty.isPresent()) {
|
||||
return;
|
||||
}
|
||||
ExtAxProperty property = extAxProperty.get();
|
||||
if (Objects.equals(property.getValue(), clientVersion.toString())
|
||||
&& Objects.equals(property.getManageable().toString(), manageableStatus)) {
|
||||
return;
|
||||
}
|
||||
property.setName(requestApplicationName);
|
||||
property.setValue(clientVersion.toString());
|
||||
property.setManageable(Boolean.valueOf(manageableStatus));
|
||||
extAxPropertyService.update(property);
|
||||
}
|
||||
|
||||
private void insert(Optional<ExtAxProperty> extAxProperty, String requestApplicationName, DefaultArtifactVersion clientVersion, String manageableStatus) {
|
||||
if (extAxProperty.isPresent()) {
|
||||
update(extAxProperty, requestApplicationName, clientVersion, manageableStatus);
|
||||
} else {
|
||||
extAxPropertyService.add(extAxProperty.orElseGet(() -> {
|
||||
ExtAxProperty property = new ExtAxProperty();
|
||||
property.setCreated(true);
|
||||
property.setName(requestApplicationName);
|
||||
property.setValue(clientVersion.toString());
|
||||
property.setManageable(Boolean.valueOf(manageableStatus));
|
||||
return property;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@ import org.redisson.api.RAtomicLong;
|
||||
import org.redisson.api.RBatch;
|
||||
import org.redisson.api.RBucket;
|
||||
import org.redisson.api.RBucketAsync;
|
||||
import org.redisson.api.RFuture;
|
||||
import org.redisson.api.RKeys;
|
||||
import org.redisson.api.RList;
|
||||
import org.redisson.api.RMap;
|
||||
@ -23,6 +24,7 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
@ -140,6 +142,16 @@ public class RedisUtils {
|
||||
batch.execute();
|
||||
}
|
||||
|
||||
|
||||
public static <T> Boolean trySetObject(final String key, final T value, final Duration duration) {
|
||||
RBatch batch = CLIENT.createBatch();
|
||||
RBucketAsync<T> bucket = batch.getBucket(key);
|
||||
RFuture<Boolean> future = bucket.trySetAsync(value, duration.toMillis(), TimeUnit.MILLISECONDS);
|
||||
batch.execute();
|
||||
return future.join();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 注册对象监听器
|
||||
* <p>
|
||||
|
||||
@ -25,15 +25,19 @@ import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.FLOW_SERVER_VERSION_121;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.MQ_OWNERSHIP_PROCESS_DEFINITION_KEY;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.WORKFLOW_ENGINE_VERSION;
|
||||
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.APPROVED;
|
||||
import static cn.axzo.workflow.common.enums.ProcessActivityEventEnum.PROCESS_ACTIVITY_END;
|
||||
@ -179,13 +183,18 @@ public class RocketMqBpmActivityEventListener extends AbstractBpmnEventListener<
|
||||
if (!sendMQ) {
|
||||
return;
|
||||
}
|
||||
Map<String, String> header = new HashMap<>();
|
||||
if (StringUtils.hasText(dto.getProcessDefinitionKey())) {
|
||||
log.warn("record process definition key: {}", dto.getProcessDefinitionKey());
|
||||
header.put(MQ_OWNERSHIP_PROCESS_DEFINITION_KEY, dto.getProcessDefinitionKey());
|
||||
}
|
||||
eventProducer.send(Event.builder()
|
||||
.shardingKey(dto.getProcessInstanceId())
|
||||
.eventCode(eventEnum.getEventCode())
|
||||
.targetId(dto.getProcessInstanceId())
|
||||
.targetType(eventEnum.getTag())
|
||||
.targetType(dto.getProcessDefinitionKey())
|
||||
.data(dto)
|
||||
.build());
|
||||
.build(), header);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -31,6 +31,7 @@ import java.util.Optional;
|
||||
import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF;
|
||||
import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.TASK_COMPLETE_FAIL_NOT_EXISTS;
|
||||
import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.TASK_HAS_BEEN_COMPLETE;
|
||||
import static cn.axzo.workflow.core.listener.AbstractBpmnEventListener.parseProcessDefinitionKey;
|
||||
import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.JOB_MOVED_TO_DEADLETTER;
|
||||
|
||||
/**
|
||||
@ -80,7 +81,9 @@ public class ApproveErrorReporterEventListener implements BpmnAsyncJobEventListe
|
||||
Optional<BpmnNoticeConf> noticeConfig = BpmnMetaParserHelper.getNoticeConfig(process);
|
||||
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
|
||||
FlowableEventDispatcher eventDispatcher = processEngineConfiguration.getEventDispatcher();
|
||||
MessagePushEvent event = MessagePushEventBuilder.createPendingRollbackEvent(jobEvent.getProcessInstanceId(), jobInfo.getTenantId(), dto.getTaskId(), noticeConfig.orElse(new BpmnNoticeConf()));
|
||||
MessagePushEvent event = MessagePushEventBuilder.createPendingRollbackEvent(jobEvent.getProcessInstanceId(),
|
||||
parseProcessDefinitionKey(jobEvent.getProcessDefinitionId()),
|
||||
jobInfo.getTenantId(), dto.getTaskId(), noticeConfig.orElse(new BpmnNoticeConf()));
|
||||
log.info("发送恢复待办的流程事件消息: taskDto:{},event:{}", JSONUtil.toJsonStr(dto), JSONUtil.toJsonStr(event));
|
||||
eventDispatcher.dispatchEvent(event, processEngineConfiguration.getEngineCfgKey());
|
||||
}
|
||||
|
||||
@ -54,6 +54,7 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_PROCESS_TY
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_SPECIFY_NEXT_APPROVER;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_INFO;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.MQ_OWNERSHIP_PROCESS_DEFINITION_KEY;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.MULTI_INSTANCE_LOOP_COUNTER;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.NUMBER_OF_INSTANCES;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_COMPLETE_OPERATION_TYPE;
|
||||
@ -244,6 +245,7 @@ public class RocketMqMessagePushEventListener extends AbstractBpmnEventListener<
|
||||
|| !StringUtils.hasText(event.getNoticeConfig().getCarbonCopy().getCarbonCopyMessageId())) {
|
||||
return;
|
||||
}
|
||||
// TODO 这里的抄送人,不建议使用一个 MQ 事件来承载,而是一个人一个事件
|
||||
log.info("RocketMqMessagePushEventListener#onCarbonCopy... cc' templateId: {}, receivePerson: {}, processInstanceId: {}",
|
||||
event.getNoticeConfig().getCarbonCopy().getCarbonCopyMessageId(),
|
||||
JSONUtil.toJsonStr(event.getAssigners()), event.getProcessInstanceId());
|
||||
@ -376,6 +378,7 @@ public class RocketMqMessagePushEventListener extends AbstractBpmnEventListener<
|
||||
Object> variables) {
|
||||
return new MessagePushDTO()
|
||||
.setProcessInstanceId(event.getProcessInstanceId())
|
||||
.setProcessDefinitionKey(event.getProcessDefinitionKey())
|
||||
.setType(type)
|
||||
.setTemplateId(templateId)
|
||||
.setTaskId(event.getTaskId())
|
||||
@ -389,13 +392,18 @@ public class RocketMqMessagePushEventListener extends AbstractBpmnEventListener<
|
||||
if (!sendMQ) {
|
||||
return;
|
||||
}
|
||||
Map<String, String> header = new HashMap<>();
|
||||
if (StringUtils.hasText(dto.getProcessDefinitionKey())) {
|
||||
log.warn("record process definition key: {}", dto.getProcessDefinitionKey());
|
||||
header.put(MQ_OWNERSHIP_PROCESS_DEFINITION_KEY, dto.getProcessDefinitionKey());
|
||||
}
|
||||
eventProducer.send(Event.builder()
|
||||
.shardingKey(dto.getProcessInstanceId())
|
||||
.eventCode(eventEnum.getEventCode())
|
||||
.targetId(dto.getProcessInstanceId())
|
||||
.targetType(eventEnum.getTag())
|
||||
.targetType(dto.getProcessDefinitionKey())
|
||||
.data(dto)
|
||||
.build());
|
||||
.build(), header);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -76,7 +76,7 @@ public class MessagePushProcessEventListener extends AbstractBpmnEventListener<P
|
||||
optNoticeConfig.ifPresent(noticeConfig -> {
|
||||
MessagePushEventImpl messagePushEvent =
|
||||
MessagePushEventBuilder.createEvent(MessagePushEventType.PENDING_COMPLETE, null, noticeConfig,
|
||||
event.getProcessInstanceId(), null, null);
|
||||
event.getProcessInstanceId(), parseProcessDefinitionKey(event.getProcessDefinitionId()), null, null);
|
||||
|
||||
log.info("发送完成实例下所有待办的消息: {}", JSONUtil.toJsonStr(messagePushEvent));
|
||||
|
||||
@ -87,7 +87,7 @@ public class MessagePushProcessEventListener extends AbstractBpmnEventListener<P
|
||||
}
|
||||
MessagePushEventImpl carbonCopyCompleteEvent =
|
||||
MessagePushEventBuilder.createEvent(MessagePushEventType.CARBON_COPY_COMPLETE, null, noticeConfig,
|
||||
event.getProcessInstanceId(), null, null);
|
||||
event.getProcessInstanceId(), parseProcessDefinitionKey(event.getProcessDefinitionId()), null, null);
|
||||
eventDispatcher.dispatchEvent(carbonCopyCompleteEvent, processEngineConfiguration.getEngineCfgKey());
|
||||
log.info("发送完成抄送的消息: {}", JSONUtil.toJsonStr(carbonCopyCompleteEvent));
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user