update(REQ-2516) - 利用 javaparser 生成可用接口
This commit is contained in:
parent
15323a6752
commit
ce23fcbc69
8
pom.xml
8
pom.xml
@ -65,11 +65,11 @@
|
||||
<artifactId>workflow-engine-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<!--<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>workflow-auto-gen</artifactId>
|
||||
<version>1.3.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependency>-->
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>workflow-engine-server</artifactId>
|
||||
@ -136,11 +136,11 @@
|
||||
<artifactId>mapstruct-processor</artifactId>
|
||||
<version>${mapstruct.version}</version>
|
||||
</path>
|
||||
<path>
|
||||
<!--<path>
|
||||
<groupId>cn.axzo.workflow</groupId>
|
||||
<artifactId>workflow-auto-gen</artifactId>
|
||||
<version>1.3.3-SNAPSHOT</version>
|
||||
</path>
|
||||
</path>-->
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
@ -23,10 +23,10 @@
|
||||
<artifactId>workflow-engine-common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<!--<dependency>
|
||||
<groupId>cn.axzo.workflow</groupId>
|
||||
<artifactId>workflow-auto-gen</artifactId>
|
||||
</dependency>
|
||||
</dependency>-->
|
||||
<dependency>
|
||||
<groupId>io.github.openfeign</groupId>
|
||||
<artifactId>feign-httpclient</artifactId>
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package cn.axzo.workflow.client.feign.bpmn;
|
||||
|
||||
import cn.axzo.workflow.client.config.CommonFeignConfiguration;
|
||||
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;
|
||||
@ -24,6 +25,7 @@ import javax.validation.constraints.NotNull;
|
||||
* @since 2023/9/21 16:25
|
||||
*/
|
||||
@FeignClient(name = "workflow-engine", url = "${axzo.service.workflow-engine:http://workflow-engine:8080}", configuration = CommonFeignConfiguration.class)
|
||||
@Manageable
|
||||
public interface ProcessDefinitionApi {
|
||||
|
||||
|
||||
|
||||
@ -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;
|
||||
@ -16,7 +18,6 @@ import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceAd
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstancePageItemVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.ProcessNodeDetailVO;
|
||||
import cn.axzo.workflow.generate.annotition.GenService;
|
||||
import cn.azxo.framework.common.model.CommonResponse;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
@ -35,13 +36,14 @@ 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
|
||||
*/
|
||||
@GenService(genPkgName = "cn.axzo.workflow.starter.api")
|
||||
@FeignClient(name = "workflow-engine", url = "${axzo.service.workflow-engine:http://workflow-engine:8080}", configuration = CommonFeignConfiguration.class)
|
||||
public interface ProcessInstanceApi {
|
||||
/**
|
||||
@ -51,6 +53,7 @@ public interface ProcessInstanceApi {
|
||||
*/
|
||||
@Operation(summary = "查询所有的审批流")
|
||||
@PostMapping("/api/process/instance/page/all")
|
||||
@Manageable
|
||||
CommonResponse<BpmPageResult<BpmnProcessInstanceAdminPageItemVO>> getAllProcessInstancePage(@Validated @RequestBody BpmnProcessInstanceAdminPageReqVO dto);
|
||||
|
||||
/**
|
||||
@ -58,6 +61,7 @@ public interface ProcessInstanceApi {
|
||||
*/
|
||||
@Operation(summary = "我发起的审批列表")
|
||||
@PostMapping("/api/process/instance/page/my")
|
||||
@Manageable
|
||||
CommonResponse<BpmPageResult<BpmnProcessInstancePageItemVO>> getMyProcessInstancePage(@Validated @RequestBody BpmnProcessInstanceMyPageReqVO dto);
|
||||
|
||||
/**
|
||||
@ -73,6 +77,7 @@ public interface ProcessInstanceApi {
|
||||
*/
|
||||
@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);
|
||||
|
||||
/**
|
||||
@ -83,6 +88,7 @@ public interface ProcessInstanceApi {
|
||||
*/
|
||||
@Operation(summary = "创建审批流程并带上表单")
|
||||
@PostMapping("/api/process/instance/form/create")
|
||||
@Manageable
|
||||
CommonResponse<String> createProcessInstanceWith(@Validated @RequestBody BpmnProcessInstanceCreateWithFormDTO dto);
|
||||
|
||||
/**
|
||||
@ -149,6 +155,7 @@ public interface ProcessInstanceApi {
|
||||
*/
|
||||
@Operation(summary = "更新指定流程定义的版本的状态, 处于 suspended 状态的流程模型将不能再发起实例")
|
||||
@PutMapping("/api/process/instance/status/update")
|
||||
@Manageable
|
||||
CommonResponse<Boolean> updateProcessStatus(@NotBlank(message = "流程定义 ID 不能为空") @RequestParam String processDefinitionId,
|
||||
@NotNull(message = "状态不能为空") @RequestParam Integer status);
|
||||
|
||||
@ -161,6 +168,7 @@ public interface ProcessInstanceApi {
|
||||
*/
|
||||
@Operation(summary = "获取审批流程实例的运行图")
|
||||
@GetMapping("/api/process/instance/graphical")
|
||||
@Manageable
|
||||
CommonResponse<ObjectNode> processInstanceGraphical(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId,
|
||||
@Nullable @RequestParam(required = false) String tenantId);
|
||||
|
||||
@ -171,6 +179,7 @@ public interface ProcessInstanceApi {
|
||||
*/
|
||||
@Operation(summary = "推断指定流程实例的所有节点执行顺序")
|
||||
@GetMapping("/api/process/instance/node/forecasting")
|
||||
@Manageable
|
||||
CommonResponse<List<ProcessNodeDetailVO>> processInstanceNodeForecast(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam(required = false) String processInstanceId,
|
||||
@Nullable @RequestParam(required = false) String tenantId);
|
||||
|
||||
@ -183,6 +192,7 @@ public interface ProcessInstanceApi {
|
||||
*/
|
||||
@Operation(summary = "推断指定流程实例的过滤掉部分节点执行顺序")
|
||||
@GetMapping("/api/process/instance/node/filter/forecasting")
|
||||
@Manageable
|
||||
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,
|
||||
@ -207,6 +217,7 @@ public interface ProcessInstanceApi {
|
||||
*/
|
||||
@Operation(summary = "查询实例的租户集合")
|
||||
@GetMapping("/api/process/instance/tenant/ids")
|
||||
@Manageable
|
||||
CommonResponse<List<String>> getTenantIds();
|
||||
|
||||
/**
|
||||
@ -216,5 +227,6 @@ public interface ProcessInstanceApi {
|
||||
*/
|
||||
@Operation(summary = "校验指定流程实例下,是否存在指定的审批人")
|
||||
@PostMapping("/api/process/instance/check/approver")
|
||||
@Manageable
|
||||
CommonResponse<Boolean> checkInstanceApprover(@Validated @RequestBody BpmnProcessInstanceCheckApproverDTO dto);
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package cn.axzo.workflow.client.feign.bpmn;
|
||||
|
||||
import cn.axzo.workflow.client.config.CommonFeignConfiguration;
|
||||
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;
|
||||
@ -29,6 +30,7 @@ import java.util.List;
|
||||
* @since 2023/9/21 15:47
|
||||
*/
|
||||
@FeignClient(name = "workflow-engine", url = "${axzo.service.workflow-engine:http://workflow-engine:8080}", configuration = CommonFeignConfiguration.class)
|
||||
@Manageable
|
||||
public interface ProcessModelApi {
|
||||
|
||||
/**
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package cn.axzo.workflow.client.feign.bpmn;
|
||||
|
||||
import cn.axzo.workflow.client.config.CommonFeignConfiguration;
|
||||
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;
|
||||
@ -17,7 +18,6 @@ import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstance
|
||||
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskDonePageItemVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskInstanceVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskTodoPageItemVO;
|
||||
import cn.axzo.workflow.generate.annotition.GenService;
|
||||
import cn.azxo.framework.common.model.CommonResponse;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
@ -41,7 +41,6 @@ import java.util.Map;
|
||||
* @since 2023/9/21 16:26
|
||||
*/
|
||||
@FeignClient(name = "workflow-engine", url = "${axzo.service.workflow-engine:http://workflow-engine:8080}", configuration = CommonFeignConfiguration.class)
|
||||
@GenService(genPkgName = "cn.axzo.workflow.starter.api")
|
||||
public interface ProcessTaskApi {
|
||||
|
||||
/**
|
||||
@ -49,6 +48,7 @@ public interface ProcessTaskApi {
|
||||
*/
|
||||
@Operation(summary = "待审核列表")
|
||||
@GetMapping("/api/process/task/page/todo")
|
||||
@Manageable
|
||||
CommonResponse<BpmPageResult<BpmnTaskTodoPageItemVO>> getTodoTaskPage(@Validated @RequestBody BpmnTaskPageSearchDTO dto);
|
||||
|
||||
/**
|
||||
@ -56,6 +56,7 @@ public interface ProcessTaskApi {
|
||||
*/
|
||||
@Operation(summary = "已完成的审批列表")
|
||||
@GetMapping("/api/process/task/page/done")
|
||||
@Manageable
|
||||
CommonResponse<BpmPageResult<BpmnTaskDonePageItemVO>> getDoneTaskPage(@Validated @RequestBody BpmnTaskPageSearchDTO dto);
|
||||
|
||||
/**
|
||||
@ -65,6 +66,7 @@ public interface ProcessTaskApi {
|
||||
*/
|
||||
@Operation(summary = "获取指定流程实例的审批过程信息")
|
||||
@GetMapping("/api/process/task/list/flat")
|
||||
@Manageable
|
||||
CommonResponse<List<BpmnHistoricTaskInstanceVO>> getTaskListFlatByProcessInstanceId(@NotBlank(message = "流程实例 ID " +
|
||||
"不能为空") @RequestParam String processInstanceId, @Nullable @RequestParam(required = false) String tenantId);
|
||||
|
||||
@ -75,6 +77,7 @@ public interface ProcessTaskApi {
|
||||
*/
|
||||
@Operation(summary = "获取指定流程实例的审批过程信息")
|
||||
@GetMapping("/api/process/task/list/group")
|
||||
@Manageable
|
||||
CommonResponse<List<BpmnHistoricTaskInstanceGroupVO>> getTaskListGroupByProcessInstanceId(@NotBlank(message =
|
||||
"流程实例 ID 不能为空") @RequestParam String processInstanceId, @Nullable @RequestParam(required = false) String tenantId);
|
||||
|
||||
@ -83,6 +86,7 @@ public interface ProcessTaskApi {
|
||||
*/
|
||||
@Operation(summary = "获取实例正在审核的人列表")
|
||||
@GetMapping("/api/process/task/active/list")
|
||||
@Manageable
|
||||
CommonResponse<List<BpmnTaskInstanceVO>> getActiveTasksByProcessInstanceId(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId,
|
||||
@NotBlank(message = "租户不能为空") @RequestParam String tenantId);
|
||||
|
||||
@ -171,6 +175,7 @@ public interface ProcessTaskApi {
|
||||
*/
|
||||
@Operation(summary = "添加附件")
|
||||
@PostMapping("/api/process/task/attachment")
|
||||
@Manageable
|
||||
CommonResponse<Void> addAttachment(@Validated @RequestBody BpmnTaskAttachmentDTO dto);
|
||||
|
||||
/**
|
||||
@ -191,6 +196,7 @@ public interface ProcessTaskApi {
|
||||
*/
|
||||
@Operation(summary = "审批流程催办")
|
||||
@PostMapping("/api/process/task/remind")
|
||||
@Manageable
|
||||
CommonResponse<Boolean> remindTask(@Validated @RequestBody BpmnTaskRemindDTO dto);
|
||||
|
||||
/**
|
||||
@ -220,6 +226,7 @@ public interface ProcessTaskApi {
|
||||
*/
|
||||
@Operation(summary = "根据实例 ID 和自然人 ID 查询对应待处理的任务 ID")
|
||||
@GetMapping("/api/process/task/find")
|
||||
@Manageable
|
||||
CommonResponse<String> findTaskIdByInstanceIdAndPersonId(@RequestParam(required = false) @NotBlank(message = "流程实例 ID 不能为空") String processInstanceId,
|
||||
@RequestParam(required = false) @NotBlank(message = "自然人 ID 不能为空") String personId);
|
||||
|
||||
@ -230,6 +237,7 @@ public interface ProcessTaskApi {
|
||||
*/
|
||||
@Operation(summary = "根据实例 ID列表 和自然人 ID 查询对应待处理的任务 ID")
|
||||
@GetMapping("/api/process/task/batch/find")
|
||||
@Manageable
|
||||
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,7 @@
|
||||
package cn.axzo.workflow.client.feign.bpmn;
|
||||
|
||||
import cn.axzo.workflow.client.config.CommonFeignConfiguration;
|
||||
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;
|
||||
@ -17,6 +18,7 @@ import javax.validation.constraints.NotBlank;
|
||||
* 流程变量api
|
||||
*/
|
||||
@FeignClient(name = "workflow-engine", url = "${axzo.service.workflow-engine:http://workflow-engine:8080}", configuration = CommonFeignConfiguration.class)
|
||||
@Manageable
|
||||
public interface ProcessVariableApi {
|
||||
|
||||
/**
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package cn.axzo.workflow.client.feign.manage;
|
||||
|
||||
import cn.axzo.workflow.client.config.CommonFeignConfiguration;
|
||||
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;
|
||||
@ -9,7 +10,6 @@ import cn.axzo.workflow.common.model.request.category.CategoryUpdateDTO;
|
||||
import cn.axzo.workflow.common.model.response.BpmPageResult;
|
||||
import cn.axzo.workflow.common.model.response.category.CategoryConfigItemVO;
|
||||
import cn.axzo.workflow.common.model.response.category.CategoryItemVO;
|
||||
import cn.axzo.workflow.generate.annotition.Management;
|
||||
import cn.azxo.framework.common.model.CommonResponse;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
@ -33,7 +33,7 @@ import java.util.List;
|
||||
*/
|
||||
|
||||
@FeignClient(name = "workflow-engine", url = "${axzo.service.workflow-engine:http://workflow-engine:8080}", configuration = CommonFeignConfiguration.class)
|
||||
@Management
|
||||
@Manageable
|
||||
public interface ProcessCategoryApi {
|
||||
|
||||
/**
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package cn.axzo.workflow.client.feign.manage;
|
||||
|
||||
import cn.axzo.workflow.client.config.CommonFeignConfiguration;
|
||||
import cn.axzo.workflow.generate.annotition.Management;
|
||||
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;
|
||||
@ -19,7 +19,7 @@ import java.util.List;
|
||||
*/
|
||||
|
||||
@FeignClient(name = "workflow-engine", url = "${axzo.service.workflow-engine:http://workflow-engine:8080}", configuration = CommonFeignConfiguration.class)
|
||||
@Management
|
||||
@Manageable
|
||||
public interface ProcessConfigApi {
|
||||
|
||||
/**
|
||||
|
||||
@ -217,7 +217,7 @@ public class TestController {
|
||||
RestBpmnProcessVariable variable = new RestBpmnProcessVariable();
|
||||
variable.setName("testVar");
|
||||
variable.setValue("testValue");
|
||||
workflowCoreService.createVariable(processInstanceId, variable);
|
||||
// workflowCoreService.createVariable(processInstanceId, variable);
|
||||
return CommonResponse.success(null);
|
||||
}
|
||||
|
||||
|
||||
@ -19,10 +19,10 @@
|
||||
<groupId>cn.axzo.workflow</groupId>
|
||||
<artifactId>workflow-engine-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<!--<dependency>
|
||||
<groupId>cn.axzo.workflow</groupId>
|
||||
<artifactId>workflow-auto-gen</artifactId>
|
||||
</dependency>
|
||||
</dependency>-->
|
||||
<dependency>
|
||||
<groupId>cn.axzo.framework.rocketmq</groupId>
|
||||
<artifactId>axzo-common-rocketmq</artifactId>
|
||||
|
||||
@ -1,11 +1,18 @@
|
||||
package cn.axzo.workflow.starter.api;
|
||||
|
||||
import cn.axzo.workflow.common.annotation.InvokeMode;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.RestBpmnProcessVariable;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAbortDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCancelDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCarbonCopyDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCreateDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceQueryDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnActivitySetAssigneeDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCompleteDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCreateDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCommentDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCountersignDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskTransferDTO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.BatchOperationResultVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceVO;
|
||||
import cn.axzo.workflow.common.util.ThreadUtil;
|
||||
@ -15,7 +22,6 @@ import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
@ -28,44 +34,233 @@ import java.util.Map;
|
||||
import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.ASYNC;
|
||||
import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.SYNC;
|
||||
|
||||
|
||||
/**
|
||||
* 模拟生成的受限访问的接口定义
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024/5/28 16:12
|
||||
* Workflow Engine Starter Core Service
|
||||
*/
|
||||
@FeignClient(name = "workflow-engine-starter",
|
||||
url = "${axzo.service.workflow-engine:workflow-engine:8080}",
|
||||
configuration = WorkflowEngineStarterFeignConfiguration.class)
|
||||
@FeignClient(name = "workflow-engine-starter", url = "${axzo.service.workflow-engine:workflow-engine:8080}", configuration = WorkflowEngineStarterFeignConfiguration.class)
|
||||
public interface WorkflowCoreService {
|
||||
|
||||
/**
|
||||
* 业务节点唤醒
|
||||
* <p>
|
||||
* TODO 接口需要合并,但需要考虑客户端与服务端不同版本间如何兼容
|
||||
*/
|
||||
@GetMapping("/api/process/activity/old/trigger")
|
||||
Boolean trigger(@NotBlank(message = "触发 ID 不能为空") @RequestParam String triggerId);
|
||||
|
||||
@Operation(summary = "业务节点唤醒")
|
||||
@GetMapping("/api/process/activity/trigger")
|
||||
Boolean trigger(@NotBlank(message = "触发 ID 不能为空") @RequestParam String triggerId, @RequestParam(required = false, defaultValue = "false") Boolean async);
|
||||
|
||||
/**
|
||||
* 业务节点设置审批人, 不支持重复设置
|
||||
*
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/api/process/activity/assignee/set")
|
||||
@Operation(summary = "业务节点设置审批人,不支持重复调用设置审批人,需一次性传入所有审批人")
|
||||
Boolean setAssignee(@Validated @RequestBody BpmnActivitySetAssigneeDTO dto);
|
||||
|
||||
/**
|
||||
* 创建审批流程
|
||||
*
|
||||
* <pre>
|
||||
* MQ 触发规则:
|
||||
* 1. 当前流程实例会依次触发 process-instance-created 和 process-instance-started 事件
|
||||
* 2. 第一个审批任务会依次触发 process-task-assigned 和 process-task-created 事件
|
||||
* </pre>
|
||||
*
|
||||
* @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)
|
||||
String createProcessInstance(@Validated @RequestBody BpmnProcessInstanceCreateDTO dto);
|
||||
|
||||
@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")
|
||||
Boolean approveTask(@Validated @RequestBody BpmnTaskAuditDTO dto);
|
||||
/**
|
||||
* 发起人主动撤回审核
|
||||
*
|
||||
* <pre>
|
||||
* MQ 触发规则:
|
||||
* 1. 当前流程实例中现存的任务会依次触发 process-task-deleted 事件
|
||||
* 2. 当前流程实例会触发 process-instance-cancelled 事件
|
||||
* </pre>
|
||||
*
|
||||
* @param dto {@link BpmnProcessInstanceCancelDTO}
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "发起人主动撤回审核,MQ 触发规则:1. 当前流程实例中现存的任务会依次触发 process-task-deleted 事件,2. 当前流程实例会触发 process-instance-cancelled 事件")
|
||||
@DeleteMapping("/api/process/instance/cancel")
|
||||
Boolean cancelProcessInstance(@Validated @RequestBody BpmnProcessInstanceCancelDTO dto);
|
||||
|
||||
@Operation(summary = "获得流程实例")
|
||||
@GetMapping("/api/process/instance/get")
|
||||
BpmnProcessInstanceVO getProcessInstanceVO(@Validated @RequestBody BpmnProcessInstanceQueryDTO dto);
|
||||
|
||||
@Operation(summary = "获取指定流程实例的流程变量")
|
||||
@GetMapping("/api/process/instance/cooperation-org")
|
||||
Map<String, Object> getProcessVariables(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId,
|
||||
@Nullable @RequestParam(required = false) String tenantId);
|
||||
|
||||
@Operation(summary = "为指定流程新增变量")
|
||||
@GetMapping("/api/process/variable/create/{executionId}")
|
||||
void createVariable(@PathVariable @NotBlank(message = "流程实例 ID 不能为空") String executionId,
|
||||
@RequestBody @Validated RestBpmnProcessVariable restVariable);
|
||||
/**
|
||||
* 中止流程实例
|
||||
*
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "中止流程实例")
|
||||
@DeleteMapping("/api/process/instance/abort")
|
||||
Boolean abortProcessInstance(@Validated @RequestBody BpmnProcessInstanceAbortDTO dto);
|
||||
|
||||
/**
|
||||
* 批量中止流程实例
|
||||
*
|
||||
* @param dtos
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "批量中止流程实例")
|
||||
@DeleteMapping("/api/process/instance/batch/abort")
|
||||
BatchOperationResultVO batchAbortProcessInstance(@Validated @RequestBody List<BpmnProcessInstanceAbortDTO> dtos);
|
||||
|
||||
/**
|
||||
* 抄送流程实例
|
||||
*
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "抄送流程实例")
|
||||
@PostMapping("/api/process/instance/carbon-copy")
|
||||
Boolean carbonCopyProcessInstance(@Validated @RequestBody BpmnProcessInstanceCarbonCopyDTO dto);
|
||||
|
||||
/**
|
||||
* 获得流程实例
|
||||
*
|
||||
* @param dto {@link BpmnProcessInstanceQueryDTO} 可根据 Id,BusinessKey进行查询
|
||||
* @return 流程实例, 租户Id不必传
|
||||
*/
|
||||
@Operation(summary = "获得流程实例")
|
||||
@GetMapping("/api/process/instance/get")
|
||||
BpmnProcessInstanceVO getProcessInstanceVO(@Validated @RequestBody BpmnProcessInstanceQueryDTO dto);
|
||||
|
||||
/**
|
||||
* 获取指定流程实例的流程变量
|
||||
*
|
||||
* @param processInstanceId
|
||||
* @param tenantId
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "获取指定流程实例的流程变量")
|
||||
@GetMapping("/api/process/instance/cooperation-org")
|
||||
Map<String, Object> getProcessVariables(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId, @Nullable @RequestParam(required = false) String tenantId);
|
||||
|
||||
@GetMapping("/api/process/job/dead-letter/resume")
|
||||
Void executeDeadLetterJobAction(@RequestParam(required = false) String jobId, @RequestParam(required = false) String procInstId);
|
||||
|
||||
/**
|
||||
* 同意
|
||||
*
|
||||
* <pre>
|
||||
* 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 事件
|
||||
* </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")
|
||||
Boolean approveTask(@Validated @RequestBody BpmnTaskAuditDTO dto);
|
||||
|
||||
/**
|
||||
* 批量同意
|
||||
*
|
||||
* @param dtos
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "批量同意")
|
||||
@PostMapping("/api/process/task/batch/approve")
|
||||
BatchOperationResultVO batchApproveTask(@Validated @RequestBody List<BpmnTaskAuditDTO> dtos);
|
||||
|
||||
/**
|
||||
* 驳回
|
||||
*
|
||||
* <pre>
|
||||
* MQ 触发规则:
|
||||
* 1. 当前审批任务会触发 process-task-deleted 事件
|
||||
* 2. 当前流程实例会触发 process-instance-rejected 事件
|
||||
* </pre>
|
||||
*/
|
||||
@Operation(summary = "驳回,MQ 触发规则:1. 当前审批任务会触发 process-task-deleted 事件, 2. 当前流程实例会触发 process-instance-rejected 事件")
|
||||
@PostMapping("/api/process/task/reject")
|
||||
Boolean rejectTask(@Validated @RequestBody BpmnTaskAuditDTO dto);
|
||||
|
||||
/**
|
||||
* 批量驳回
|
||||
*
|
||||
* @param dtos 批量请求参数
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/api/process/task/batch/reject")
|
||||
BatchOperationResultVO batchRejectTask(@Validated @RequestBody List<BpmnTaskAuditDTO> dtos);
|
||||
|
||||
/**
|
||||
* 转交
|
||||
*
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "直接修改审批任务的审批人")
|
||||
@PostMapping("/api/process/task/transfer")
|
||||
Boolean transferTask(@Validated @RequestBody BpmnTaskTransferDTO dto);
|
||||
|
||||
/**
|
||||
* 批量转交
|
||||
*
|
||||
* @param dtos
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "批量修改审批任务的审批人")
|
||||
@PostMapping("/api/process/task/batch/transfer")
|
||||
BatchOperationResultVO batchTransferTask(@Validated @RequestBody List<BpmnTaskTransferDTO> dtos);
|
||||
|
||||
/**
|
||||
* 评论
|
||||
*
|
||||
* @param dto 评论请求参数
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "审批流程评论")
|
||||
@PostMapping("/api/process/task/comment")
|
||||
Boolean commentTask(@Validated @RequestBody BpmnTaskCommentDTO dto);
|
||||
|
||||
/**
|
||||
* 加签
|
||||
*
|
||||
* @param dto 加签请求参数
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "审批流程加签")
|
||||
@PostMapping("/api/process/task/countersign")
|
||||
Boolean countersignTask(@Validated @RequestBody BpmnTaskCountersignDTO dto);
|
||||
|
||||
/**
|
||||
* 暂停流程任务,并创建机器人节点,等待业务推动
|
||||
*
|
||||
* @param dto
|
||||
* @return 返回机器人节点任务 ID
|
||||
*/
|
||||
@Operation(summary = "创建机器人节点, 暂停流程任务")
|
||||
@PostMapping("/api/process/task/robot/create")
|
||||
String createRobotTask(@Validated @RequestBody BpmnRobotTaskCreateDTO dto);
|
||||
|
||||
/**
|
||||
* 完成机器人节点
|
||||
*
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "完成机器人节点, 继续流程任务")
|
||||
@PostMapping("/api/process/task/robot/complete")
|
||||
Boolean completeRobotTask(@Validated @RequestBody BpmnRobotTaskCompleteDTO dto);
|
||||
|
||||
/**
|
||||
* 强制使用‘异步’模式调用该方法,请在调用真实方法前调用该方法
|
||||
* <pre>
|
||||
* workflowCoreService.async().createProcessInstance();
|
||||
* </pre>
|
||||
*/
|
||||
default WorkflowCoreService sync() {
|
||||
ThreadUtil.set(SYNC);
|
||||
return this;
|
||||
@ -75,5 +270,4 @@ public interface WorkflowCoreService {
|
||||
ThreadUtil.set(ASYNC);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,299 +0,0 @@
|
||||
// --auto generated by workflow auto-gen plugin--
|
||||
package cn.axzo.workflow.starter.api;
|
||||
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAbortDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAdminPageReqVO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCancelDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCarbonCopyDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCheckApproverDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCreateDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCreateWithFormDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceMyPageReqVO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceQueryDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCompleteDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCreateDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAttachmentDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCommentDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCountersignDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskPageSearchDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskRemindDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskTransferDTO;
|
||||
import cn.axzo.workflow.common.model.response.BpmPageResult;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.BatchOperationResultVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceAdminPageItemVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstancePageItemVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.ProcessNodeDetailVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceGroupVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskDonePageItemVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskInstanceVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskTodoPageItemVO;
|
||||
import cn.azxo.framework.common.model.CommonResponse;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import java.lang.Boolean;
|
||||
import java.lang.Integer;
|
||||
import java.lang.Object;
|
||||
import java.lang.String;
|
||||
import java.lang.Void;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
public interface WorkflowCoreService_Gen {
|
||||
@Operation(
|
||||
summary = "待审核列表"
|
||||
)
|
||||
@GetMapping("/api/process/task/page/todo")
|
||||
CommonResponse<BpmPageResult<BpmnTaskTodoPageItemVO>> getTodoTaskPage(
|
||||
@Validated @RequestBody BpmnTaskPageSearchDTO dto);
|
||||
|
||||
@Operation(
|
||||
summary = "已完成的审批列表"
|
||||
)
|
||||
@GetMapping("/api/process/task/page/done")
|
||||
CommonResponse<BpmPageResult<BpmnTaskDonePageItemVO>> getDoneTaskPage(
|
||||
@Validated @RequestBody BpmnTaskPageSearchDTO dto);
|
||||
|
||||
@Operation(
|
||||
summary = "获取指定流程实例的审批过程信息"
|
||||
)
|
||||
@GetMapping("/api/process/task/list/flat")
|
||||
CommonResponse<List<BpmnHistoricTaskInstanceVO>> getTaskListFlatByProcessInstanceId(
|
||||
@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId,
|
||||
@Nullable @RequestParam(required = false) String tenantId);
|
||||
|
||||
@Operation(
|
||||
summary = "获取指定流程实例的审批过程信息"
|
||||
)
|
||||
@GetMapping("/api/process/task/list/group")
|
||||
CommonResponse<List<BpmnHistoricTaskInstanceGroupVO>> getTaskListGroupByProcessInstanceId(
|
||||
@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId,
|
||||
@Nullable @RequestParam(required = false) String tenantId);
|
||||
|
||||
@Operation(
|
||||
summary = "获取实例正在审核的人列表"
|
||||
)
|
||||
@GetMapping("/api/process/task/active/list")
|
||||
CommonResponse<List<BpmnTaskInstanceVO>> getActiveTasksByProcessInstanceId(
|
||||
@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId,
|
||||
@NotBlank(message = "租户不能为空") @RequestParam String tenantId);
|
||||
|
||||
@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);
|
||||
|
||||
@Operation(
|
||||
summary = "批量同意"
|
||||
)
|
||||
@PostMapping("/api/process/task/batch/approve")
|
||||
CommonResponse<BatchOperationResultVO> batchApproveTask(
|
||||
@Validated @RequestBody List<BpmnTaskAuditDTO> dtos);
|
||||
|
||||
@Operation(
|
||||
summary = "驳回,MQ 触发规则:1. 当前审批任务会触发 process-task-deleted 事件, 2. 当前流程实例会触发 process-instance-rejected 事件"
|
||||
)
|
||||
@PostMapping("/api/process/task/reject")
|
||||
CommonResponse<Boolean> rejectTask(@Validated @RequestBody BpmnTaskAuditDTO dto);
|
||||
|
||||
@PostMapping("/api/process/task/batch/reject")
|
||||
CommonResponse<BatchOperationResultVO> batchRejectTask(
|
||||
@Validated @RequestBody List<BpmnTaskAuditDTO> dtos);
|
||||
|
||||
@Operation(
|
||||
summary = "直接修改审批任务的审批人"
|
||||
)
|
||||
@PostMapping("/api/process/task/transfer")
|
||||
CommonResponse<Boolean> transferTask(@Validated @RequestBody BpmnTaskTransferDTO dto);
|
||||
|
||||
@Operation(
|
||||
summary = "批量修改审批任务的审批人"
|
||||
)
|
||||
@PostMapping("/api/process/task/batch/transfer")
|
||||
CommonResponse<BatchOperationResultVO> batchTransferTask(
|
||||
@Validated @RequestBody List<BpmnTaskTransferDTO> dtos);
|
||||
|
||||
@Operation(
|
||||
summary = "审批流程评论"
|
||||
)
|
||||
@PostMapping("/api/process/task/comment")
|
||||
CommonResponse<Boolean> commentTask(@Validated @RequestBody BpmnTaskCommentDTO dto);
|
||||
|
||||
@Operation(
|
||||
summary = "添加附件"
|
||||
)
|
||||
@PostMapping("/api/process/task/attachment")
|
||||
CommonResponse<Void> addAttachment(@Validated @RequestBody BpmnTaskAttachmentDTO dto);
|
||||
|
||||
@Operation(
|
||||
summary = "审批流程加签"
|
||||
)
|
||||
@PostMapping("/api/process/task/countersign")
|
||||
CommonResponse<Boolean> countersignTask(@Validated @RequestBody BpmnTaskCountersignDTO dto);
|
||||
|
||||
@Operation(
|
||||
summary = "审批流程催办"
|
||||
)
|
||||
@PostMapping("/api/process/task/remind")
|
||||
CommonResponse<Boolean> remindTask(@Validated @RequestBody BpmnTaskRemindDTO dto);
|
||||
|
||||
@Operation(
|
||||
summary = "创建机器人节点, 暂停流程任务"
|
||||
)
|
||||
@PostMapping("/api/process/task/robot/create")
|
||||
CommonResponse<String> createRobotTask(@Validated @RequestBody BpmnRobotTaskCreateDTO dto);
|
||||
|
||||
@Operation(
|
||||
summary = "完成机器人节点, 继续流程任务"
|
||||
)
|
||||
@PostMapping("/api/process/task/robot/complete")
|
||||
CommonResponse<Boolean> completeRobotTask(@Validated @RequestBody BpmnRobotTaskCompleteDTO dto);
|
||||
|
||||
@Operation(
|
||||
summary = "根据实例 ID 和自然人 ID 查询对应待处理的任务 ID"
|
||||
)
|
||||
@GetMapping("/api/process/task/find")
|
||||
CommonResponse<String> findTaskIdByInstanceIdAndPersonId(
|
||||
@RequestParam(required = false) @NotBlank(message = "流程实例 ID 不能为空") String processInstanceId,
|
||||
@RequestParam(required = false) @NotBlank(message = "自然人 ID 不能为空") String personId);
|
||||
|
||||
@Operation(
|
||||
summary = "根据实例 ID列表 和自然人 ID 查询对应待处理的任务 ID"
|
||||
)
|
||||
@GetMapping("/api/process/task/batch/find")
|
||||
CommonResponse<Map<String, String>> findTaskIdByInstanceIdsAndPersonId(
|
||||
@RequestParam(required = false) @NotEmpty(message = "流程实例 ID列表 不能为空") List<String> processInstanceIds,
|
||||
@RequestParam(required = false) @NotBlank(message = "自然人 ID 不能为空") String personId);
|
||||
|
||||
@Operation(
|
||||
summary = "查询所有的审批流"
|
||||
)
|
||||
@PostMapping("/api/process/instance/page/all")
|
||||
CommonResponse<BpmPageResult<BpmnProcessInstanceAdminPageItemVO>> getAllProcessInstancePage(
|
||||
@Validated @RequestBody BpmnProcessInstanceAdminPageReqVO dto);
|
||||
|
||||
@Operation(
|
||||
summary = "我发起的审批列表"
|
||||
)
|
||||
@PostMapping("/api/process/instance/page/my")
|
||||
CommonResponse<BpmPageResult<BpmnProcessInstancePageItemVO>> getMyProcessInstancePage(
|
||||
@Validated @RequestBody BpmnProcessInstanceMyPageReqVO dto);
|
||||
|
||||
@Operation(
|
||||
summary = "创建审批流程, MQ 触发规则:1. 当前流程实例会依次触发 process-instance-created 和 process-instance-started 事件,2. 第一个审批任务会依次触发 process-task-assigned 和 process-task-created 事件"
|
||||
)
|
||||
@PostMapping("/api/process/instance/create")
|
||||
CommonResponse<String> createProcessInstance(
|
||||
@Validated @RequestBody BpmnProcessInstanceCreateDTO dto);
|
||||
|
||||
@Operation(
|
||||
summary = "创建审批流程并带上表单"
|
||||
)
|
||||
@PostMapping("/api/process/instance/form/create")
|
||||
CommonResponse<String> createProcessInstanceWith(
|
||||
@Validated @RequestBody BpmnProcessInstanceCreateWithFormDTO dto);
|
||||
|
||||
@Operation(
|
||||
summary = "发起人主动撤回审核,MQ 触发规则:1. 当前流程实例中现存的任务会依次触发 process-task-deleted 事件,2. 当前流程实例会触发 process-instance-cancelled 事件"
|
||||
)
|
||||
@DeleteMapping("/api/process/instance/cancel")
|
||||
CommonResponse<Boolean> cancelProcessInstance(
|
||||
@Validated @RequestBody BpmnProcessInstanceCancelDTO dto);
|
||||
|
||||
@Operation(
|
||||
summary = "中止流程实例"
|
||||
)
|
||||
@DeleteMapping("/api/process/instance/abort")
|
||||
CommonResponse<Boolean> abortProcessInstance(
|
||||
@Validated @RequestBody BpmnProcessInstanceAbortDTO dto);
|
||||
|
||||
@Operation(
|
||||
summary = "批量中止流程实例"
|
||||
)
|
||||
@DeleteMapping("/api/process/instance/batch/abort")
|
||||
CommonResponse<BatchOperationResultVO> batchAbortProcessInstance(
|
||||
@Validated @RequestBody List<BpmnProcessInstanceAbortDTO> dtos);
|
||||
|
||||
@Operation(
|
||||
summary = "抄送流程实例"
|
||||
)
|
||||
@PostMapping("/api/process/instance/carbon-copy")
|
||||
CommonResponse<Boolean> carbonCopyProcessInstance(
|
||||
@Validated @RequestBody BpmnProcessInstanceCarbonCopyDTO dto);
|
||||
|
||||
@Operation(
|
||||
summary = "获得流程实例"
|
||||
)
|
||||
@GetMapping("/api/process/instance/get")
|
||||
CommonResponse<BpmnProcessInstanceVO> getProcessInstanceVO(
|
||||
@Validated @RequestBody BpmnProcessInstanceQueryDTO dto);
|
||||
|
||||
@Operation(
|
||||
summary = "更新指定流程定义的版本的状态, 处于 suspended 状态的流程模型将不能再发起实例"
|
||||
)
|
||||
@PutMapping("/api/process/instance/status/update")
|
||||
CommonResponse<Boolean> updateProcessStatus(
|
||||
@NotBlank(message = "流程定义 ID 不能为空") @RequestParam String processDefinitionId,
|
||||
@NotNull(message = "状态不能为空") @RequestParam Integer status);
|
||||
|
||||
@Operation(
|
||||
summary = "获取审批流程实例的运行图"
|
||||
)
|
||||
@GetMapping("/api/process/instance/graphical")
|
||||
CommonResponse<ObjectNode> processInstanceGraphical(
|
||||
@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId,
|
||||
@Nullable @RequestParam(required = false) String tenantId);
|
||||
|
||||
@Operation(
|
||||
summary = "推断指定流程实例的所有节点执行顺序"
|
||||
)
|
||||
@GetMapping("/api/process/instance/node/forecasting")
|
||||
CommonResponse<List<ProcessNodeDetailVO>> processInstanceNodeForecast(
|
||||
@NotBlank(message = "流程实例 ID 不能为空") @RequestParam(required = false) String processInstanceId,
|
||||
@Nullable @RequestParam(required = false) String tenantId);
|
||||
|
||||
@Operation(
|
||||
summary = "推断指定流程实例的过滤掉部分节点执行顺序"
|
||||
)
|
||||
@GetMapping("/api/process/instance/node/filter/forecasting")
|
||||
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);
|
||||
|
||||
@Operation(
|
||||
summary = "获取指定流程实例的流程变量"
|
||||
)
|
||||
@GetMapping("/api/process/instance/cooperation-org")
|
||||
CommonResponse<Map<String, Object>> getProcessVariables(
|
||||
@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId,
|
||||
@Nullable @RequestParam(required = false) String tenantId);
|
||||
|
||||
@Operation(
|
||||
summary = "查询实例的租户集合"
|
||||
)
|
||||
@GetMapping("/api/process/instance/tenant/ids")
|
||||
CommonResponse<List<String>> getTenantIds();
|
||||
|
||||
@Operation(
|
||||
summary = "校验指定流程实例下,是否存在指定的审批人"
|
||||
)
|
||||
@PostMapping("/api/process/instance/check/approver")
|
||||
CommonResponse<Boolean> checkInstanceApprover(
|
||||
@Validated @RequestBody BpmnProcessInstanceCheckApproverDTO dto);
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
package cn.axzo.workflow.starter.api;
|
||||
|
||||
import cn.axzo.workflow.common.annotation.Manageable;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024/6/11 16:32
|
||||
*/
|
||||
public interface WorkflowManageService {
|
||||
|
||||
/**
|
||||
* 查询实例的租户集合
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "查询实例的租户集合")
|
||||
@GetMapping("/api/process/instance/tenant/ids")
|
||||
@Manageable
|
||||
List<String> getTenantIds();
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
package cn.axzo.workflow.starter.feign.ext;
|
||||
|
||||
import feign.Feign;
|
||||
import feign.Target;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024/6/11 15:40
|
||||
*/
|
||||
public class WorkflowEngineStarterFeign {
|
||||
|
||||
public static WorkflowEngineStarterFeign.Builder builder() {
|
||||
return new WorkflowEngineStarterFeign.Builder();
|
||||
}
|
||||
|
||||
public static final class Builder extends Feign.Builder {
|
||||
|
||||
@Override
|
||||
public <T> T target(Target<T> target) {
|
||||
return super.build().newInstance(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6,6 +6,7 @@ import cn.axzo.workflow.common.util.ThreadUtil;
|
||||
import cn.axzo.workflow.starter.WorkflowEngineStarterProperties;
|
||||
import cn.azxo.framework.common.constatns.Constants;
|
||||
import feign.Client;
|
||||
import feign.Feign;
|
||||
import feign.RequestInterceptor;
|
||||
import feign.Retryer;
|
||||
import feign.Target;
|
||||
@ -17,6 +18,7 @@ import org.springframework.beans.factory.ObjectFactory;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
|
||||
import org.springframework.cloud.openfeign.FeignBuilderCustomizer;
|
||||
import org.springframework.cloud.openfeign.Targeter;
|
||||
import org.springframework.cloud.openfeign.support.ResponseEntityDecoder;
|
||||
import org.springframework.cloud.openfeign.support.SpringDecoder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@ -45,6 +47,16 @@ public class WorkflowEngineStarterFeignConfiguration {
|
||||
return new Retryer.Default(100, SECONDS.toMillis(1), 3);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Feign.Builder workflowEngineStarterFeignBuilder() {
|
||||
return WorkflowEngineStarterFeign.builder();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Targeter workflowEngineStarterFeignTargeter(WorkflowEngineStarterProperties starterProperties) {
|
||||
return new WorkflowEngineStarterTargeter(starterProperties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Client complexInvokeClient(WorkflowEngineStarterProperties starterProperties,
|
||||
@Qualifier("workflowEngineStarterEventProducer") EventProducer eventProducer,
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
package cn.axzo.workflow.starter.feign.ext;
|
||||
|
||||
import feign.Target;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024/6/11 17:00
|
||||
*/
|
||||
public class WorkflowEngineStarterTarget<T> extends Target.HardCodedTarget<T> {
|
||||
private final Class<?> manageableInterface;
|
||||
|
||||
public WorkflowEngineStarterTarget(Class<T> type, String url, Class<?> manageableInterface) {
|
||||
super(type, url);
|
||||
this.manageableInterface = manageableInterface;
|
||||
}
|
||||
|
||||
public WorkflowEngineStarterTarget(Class<T> type, String name, String url, Class<?> manageableInterface) {
|
||||
super(type, name, url);
|
||||
this.manageableInterface = manageableInterface;
|
||||
}
|
||||
|
||||
public Class<?> getManageableInterface() {
|
||||
return manageableInterface;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
package cn.axzo.workflow.starter.feign.ext;
|
||||
|
||||
import cn.axzo.workflow.starter.WorkflowEngineStarterProperties;
|
||||
import cn.axzo.workflow.starter.api.WorkflowManageService;
|
||||
import feign.Feign;
|
||||
import feign.Target;
|
||||
import org.springframework.cloud.openfeign.FeignClientFactoryBean;
|
||||
import org.springframework.cloud.openfeign.FeignContext;
|
||||
import org.springframework.cloud.openfeign.Targeter;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024/6/11 16:12
|
||||
*/
|
||||
public class WorkflowEngineStarterTargeter implements Targeter {
|
||||
private final WorkflowEngineStarterProperties properties;
|
||||
|
||||
public WorkflowEngineStarterTargeter(WorkflowEngineStarterProperties starterProperties) {
|
||||
this.properties = starterProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T target(FeignClientFactoryBean factory, Feign.Builder feign, FeignContext context, Target.HardCodedTarget<T> target) {
|
||||
if (!(feign instanceof WorkflowEngineStarterFeign.Builder)) {
|
||||
return feign.target(target);
|
||||
}
|
||||
Class<?> clazz = null;
|
||||
if (properties.getManageable()) {
|
||||
clazz = WorkflowManageService.class;
|
||||
}
|
||||
Target<T> newTarget = new WorkflowEngineStarterTarget<>(target.type(), target.name(), target.url(), clazz);
|
||||
return feign.target(newTarget);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,415 @@
|
||||
/**
|
||||
* Copyright 2012-2020 The Feign Authors
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package feign;
|
||||
|
||||
import cn.axzo.workflow.starter.feign.ext.WorkflowEngineStarterTarget;
|
||||
import feign.InvocationHandlerFactory.MethodHandler;
|
||||
import feign.Param.Expander;
|
||||
import feign.Request.Options;
|
||||
import feign.codec.Decoder;
|
||||
import feign.codec.EncodeException;
|
||||
import feign.codec.Encoder;
|
||||
import feign.codec.ErrorDecoder;
|
||||
import feign.template.UriUtils;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
|
||||
import static feign.Util.checkArgument;
|
||||
import static feign.Util.checkNotNull;
|
||||
|
||||
public class ReflectiveFeign extends Feign {
|
||||
|
||||
private final ParseHandlersByName targetToHandlersByName;
|
||||
private final InvocationHandlerFactory factory;
|
||||
private final QueryMapEncoder queryMapEncoder;
|
||||
|
||||
ReflectiveFeign(ParseHandlersByName targetToHandlersByName, InvocationHandlerFactory factory,
|
||||
QueryMapEncoder queryMapEncoder) {
|
||||
this.targetToHandlersByName = targetToHandlersByName;
|
||||
this.factory = factory;
|
||||
this.queryMapEncoder = queryMapEncoder;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates an api binding to the {@code target}. As this invokes reflection, care should be taken
|
||||
* to cache the result.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> T newInstance(Target<T> target) {
|
||||
Map<String, MethodHandler> nameToHandler = targetToHandlersByName.apply(target);
|
||||
Map<Method, MethodHandler> methodToHandler = new LinkedHashMap<Method, MethodHandler>();
|
||||
List<DefaultMethodHandler> defaultMethodHandlers = new LinkedList<DefaultMethodHandler>();
|
||||
|
||||
for (Method method : target.type().getMethods()) {
|
||||
if (method.getDeclaringClass() == Object.class) {
|
||||
continue;
|
||||
} else if (Util.isDefault(method)) {
|
||||
DefaultMethodHandler handler = new DefaultMethodHandler(method);
|
||||
defaultMethodHandlers.add(handler);
|
||||
methodToHandler.put(method, handler);
|
||||
} else {
|
||||
methodToHandler.put(method, nameToHandler.get(Feign.configKey(target.type(), method)));
|
||||
}
|
||||
}
|
||||
InvocationHandler handler = factory.create(target, methodToHandler);
|
||||
List<Class<?>> classList = new ArrayList<>();
|
||||
classList.add(target.type());
|
||||
if (target instanceof WorkflowEngineStarterTarget) {
|
||||
Class<?> manageableInterface = ((WorkflowEngineStarterTarget<T>) target).getManageableInterface();
|
||||
if (Objects.nonNull(manageableInterface)) {
|
||||
classList.add(manageableInterface);
|
||||
}
|
||||
}
|
||||
T proxy = (T) Proxy.newProxyInstance(target.type().getClassLoader(),
|
||||
classList.toArray(new Class<?>[0]), handler);
|
||||
|
||||
for (DefaultMethodHandler defaultMethodHandler : defaultMethodHandlers) {
|
||||
defaultMethodHandler.bindTo(proxy);
|
||||
}
|
||||
return proxy;
|
||||
}
|
||||
|
||||
static class FeignInvocationHandler implements InvocationHandler {
|
||||
|
||||
private final Target target;
|
||||
private final Map<Method, MethodHandler> dispatch;
|
||||
|
||||
FeignInvocationHandler(Target target, Map<Method, MethodHandler> dispatch) {
|
||||
this.target = checkNotNull(target, "target");
|
||||
this.dispatch = checkNotNull(dispatch, "dispatch for %s", target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
if ("equals".equals(method.getName())) {
|
||||
try {
|
||||
Object otherHandler =
|
||||
args.length > 0 && args[0] != null ? Proxy.getInvocationHandler(args[0]) : null;
|
||||
return equals(otherHandler);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return false;
|
||||
}
|
||||
} else if ("hashCode".equals(method.getName())) {
|
||||
return hashCode();
|
||||
} else if ("toString".equals(method.getName())) {
|
||||
return toString();
|
||||
}
|
||||
|
||||
return dispatch.get(method).invoke(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof FeignInvocationHandler) {
|
||||
FeignInvocationHandler other = (FeignInvocationHandler) obj;
|
||||
return target.equals(other.target);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return target.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return target.toString();
|
||||
}
|
||||
}
|
||||
|
||||
static final class ParseHandlersByName {
|
||||
|
||||
private final Contract contract;
|
||||
private final Options options;
|
||||
private final Encoder encoder;
|
||||
private final Decoder decoder;
|
||||
private final ErrorDecoder errorDecoder;
|
||||
private final QueryMapEncoder queryMapEncoder;
|
||||
private final SynchronousMethodHandler.Factory factory;
|
||||
|
||||
ParseHandlersByName(
|
||||
Contract contract,
|
||||
Options options,
|
||||
Encoder encoder,
|
||||
Decoder decoder,
|
||||
QueryMapEncoder queryMapEncoder,
|
||||
ErrorDecoder errorDecoder,
|
||||
SynchronousMethodHandler.Factory factory) {
|
||||
this.contract = contract;
|
||||
this.options = options;
|
||||
this.factory = factory;
|
||||
this.errorDecoder = errorDecoder;
|
||||
this.queryMapEncoder = queryMapEncoder;
|
||||
this.encoder = checkNotNull(encoder, "encoder");
|
||||
this.decoder = checkNotNull(decoder, "decoder");
|
||||
}
|
||||
|
||||
public Map<String, MethodHandler> apply(Target target) {
|
||||
List<MethodMetadata> metadata = contract.parseAndValidateMetadata(target.type());
|
||||
Map<String, MethodHandler> result = new LinkedHashMap<String, MethodHandler>();
|
||||
for (MethodMetadata md : metadata) {
|
||||
BuildTemplateByResolvingArgs buildTemplate;
|
||||
if (!md.formParams().isEmpty() && md.template().bodyTemplate() == null) {
|
||||
buildTemplate =
|
||||
new BuildFormEncodedTemplateFromArgs(md, encoder, queryMapEncoder, target);
|
||||
} else if (md.bodyIndex() != null) {
|
||||
buildTemplate = new BuildEncodedTemplateFromArgs(md, encoder, queryMapEncoder, target);
|
||||
} else {
|
||||
buildTemplate = new BuildTemplateByResolvingArgs(md, queryMapEncoder, target);
|
||||
}
|
||||
if (md.isIgnored()) {
|
||||
result.put(md.configKey(), args -> {
|
||||
throw new IllegalStateException(md.configKey() + " is not a method handled by feign");
|
||||
});
|
||||
} else {
|
||||
result.put(md.configKey(),
|
||||
factory.create(target, md, buildTemplate, options, decoder, errorDecoder));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private static class BuildTemplateByResolvingArgs implements RequestTemplate.Factory {
|
||||
|
||||
private final QueryMapEncoder queryMapEncoder;
|
||||
|
||||
protected final MethodMetadata metadata;
|
||||
protected final Target<?> target;
|
||||
private final Map<Integer, Expander> indexToExpander = new LinkedHashMap<Integer, Expander>();
|
||||
|
||||
private BuildTemplateByResolvingArgs(MethodMetadata metadata, QueryMapEncoder queryMapEncoder,
|
||||
Target target) {
|
||||
this.metadata = metadata;
|
||||
this.target = target;
|
||||
this.queryMapEncoder = queryMapEncoder;
|
||||
if (metadata.indexToExpander() != null) {
|
||||
indexToExpander.putAll(metadata.indexToExpander());
|
||||
return;
|
||||
}
|
||||
if (metadata.indexToExpanderClass().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (Entry<Integer, Class<? extends Expander>> indexToExpanderClass : metadata
|
||||
.indexToExpanderClass().entrySet()) {
|
||||
try {
|
||||
indexToExpander
|
||||
.put(indexToExpanderClass.getKey(), indexToExpanderClass.getValue().newInstance());
|
||||
} catch (InstantiationException e) {
|
||||
throw new IllegalStateException(e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestTemplate create(Object[] argv) {
|
||||
RequestTemplate mutable = RequestTemplate.from(metadata.template());
|
||||
mutable.feignTarget(target);
|
||||
if (metadata.urlIndex() != null) {
|
||||
int urlIndex = metadata.urlIndex();
|
||||
checkArgument(argv[urlIndex] != null, "URI parameter %s was null", urlIndex);
|
||||
mutable.target(String.valueOf(argv[urlIndex]));
|
||||
}
|
||||
Map<String, Object> varBuilder = new LinkedHashMap<String, Object>();
|
||||
for (Entry<Integer, Collection<String>> entry : metadata.indexToName().entrySet()) {
|
||||
int i = entry.getKey();
|
||||
Object value = argv[entry.getKey()];
|
||||
if (value != null) { // Null values are skipped.
|
||||
if (indexToExpander.containsKey(i)) {
|
||||
value = expandElements(indexToExpander.get(i), value);
|
||||
}
|
||||
for (String name : entry.getValue()) {
|
||||
varBuilder.put(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RequestTemplate template = resolve(argv, mutable, varBuilder);
|
||||
if (metadata.queryMapIndex() != null) {
|
||||
// add query map parameters after initial resolve so that they take
|
||||
// precedence over any predefined values
|
||||
Object value = argv[metadata.queryMapIndex()];
|
||||
Map<String, Object> queryMap = toQueryMap(value);
|
||||
template = addQueryMapQueryParameters(queryMap, template);
|
||||
}
|
||||
|
||||
if (metadata.headerMapIndex() != null) {
|
||||
template =
|
||||
addHeaderMapHeaders((Map<String, Object>) argv[metadata.headerMapIndex()], template);
|
||||
}
|
||||
|
||||
return template;
|
||||
}
|
||||
|
||||
private Map<String, Object> toQueryMap(Object value) {
|
||||
if (value instanceof Map) {
|
||||
return (Map<String, Object>) value;
|
||||
}
|
||||
try {
|
||||
return queryMapEncoder.encode(value);
|
||||
} catch (EncodeException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private Object expandElements(Expander expander, Object value) {
|
||||
if (value instanceof Iterable) {
|
||||
return expandIterable(expander, (Iterable) value);
|
||||
}
|
||||
return expander.expand(value);
|
||||
}
|
||||
|
||||
private List<String> expandIterable(Expander expander, Iterable value) {
|
||||
List<String> values = new ArrayList<String>();
|
||||
for (Object element : value) {
|
||||
if (element != null) {
|
||||
values.add(expander.expand(element));
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private RequestTemplate addHeaderMapHeaders(Map<String, Object> headerMap,
|
||||
RequestTemplate mutable) {
|
||||
for (Entry<String, Object> currEntry : headerMap.entrySet()) {
|
||||
Collection<String> values = new ArrayList<String>();
|
||||
|
||||
Object currValue = currEntry.getValue();
|
||||
if (currValue instanceof Iterable<?>) {
|
||||
Iterator<?> iter = ((Iterable<?>) currValue).iterator();
|
||||
while (iter.hasNext()) {
|
||||
Object nextObject = iter.next();
|
||||
values.add(nextObject == null ? null : nextObject.toString());
|
||||
}
|
||||
} else {
|
||||
values.add(currValue == null ? null : currValue.toString());
|
||||
}
|
||||
|
||||
mutable.header(currEntry.getKey(), values);
|
||||
}
|
||||
return mutable;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private RequestTemplate addQueryMapQueryParameters(Map<String, Object> queryMap,
|
||||
RequestTemplate mutable) {
|
||||
for (Entry<String, Object> currEntry : queryMap.entrySet()) {
|
||||
Collection<String> values = new ArrayList<String>();
|
||||
|
||||
boolean encoded = metadata.queryMapEncoded();
|
||||
Object currValue = currEntry.getValue();
|
||||
if (currValue instanceof Iterable<?>) {
|
||||
Iterator<?> iter = ((Iterable<?>) currValue).iterator();
|
||||
while (iter.hasNext()) {
|
||||
Object nextObject = iter.next();
|
||||
values.add(nextObject == null ? null
|
||||
: encoded ? nextObject.toString()
|
||||
: UriUtils.encode(nextObject.toString()));
|
||||
}
|
||||
} else if (currValue instanceof Object[]) {
|
||||
for (Object value : (Object[]) currValue) {
|
||||
values.add(value == null ? null
|
||||
: encoded ? value.toString() : UriUtils.encode(value.toString()));
|
||||
}
|
||||
} else {
|
||||
values.add(currValue == null ? null
|
||||
: encoded ? currValue.toString() : UriUtils.encode(currValue.toString()));
|
||||
}
|
||||
|
||||
mutable.query(encoded ? currEntry.getKey() : UriUtils.encode(currEntry.getKey()), values);
|
||||
}
|
||||
return mutable;
|
||||
}
|
||||
|
||||
protected RequestTemplate resolve(Object[] argv,
|
||||
RequestTemplate mutable,
|
||||
Map<String, Object> variables) {
|
||||
return mutable.resolve(variables);
|
||||
}
|
||||
}
|
||||
|
||||
private static class BuildFormEncodedTemplateFromArgs extends BuildTemplateByResolvingArgs {
|
||||
|
||||
private final Encoder encoder;
|
||||
|
||||
private BuildFormEncodedTemplateFromArgs(MethodMetadata metadata, Encoder encoder,
|
||||
QueryMapEncoder queryMapEncoder, Target target) {
|
||||
super(metadata, queryMapEncoder, target);
|
||||
this.encoder = encoder;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RequestTemplate resolve(Object[] argv,
|
||||
RequestTemplate mutable,
|
||||
Map<String, Object> variables) {
|
||||
Map<String, Object> formVariables = new LinkedHashMap<String, Object>();
|
||||
for (Entry<String, Object> entry : variables.entrySet()) {
|
||||
if (metadata.formParams().contains(entry.getKey())) {
|
||||
formVariables.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
try {
|
||||
encoder.encode(formVariables, Encoder.MAP_STRING_WILDCARD, mutable);
|
||||
} catch (EncodeException e) {
|
||||
throw e;
|
||||
} catch (RuntimeException e) {
|
||||
throw new EncodeException(e.getMessage(), e);
|
||||
}
|
||||
return super.resolve(argv, mutable, variables);
|
||||
}
|
||||
}
|
||||
|
||||
private static class BuildEncodedTemplateFromArgs extends BuildTemplateByResolvingArgs {
|
||||
|
||||
private final Encoder encoder;
|
||||
|
||||
private BuildEncodedTemplateFromArgs(MethodMetadata metadata, Encoder encoder,
|
||||
QueryMapEncoder queryMapEncoder, Target target) {
|
||||
super(metadata, queryMapEncoder, target);
|
||||
this.encoder = encoder;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RequestTemplate resolve(Object[] argv,
|
||||
RequestTemplate mutable,
|
||||
Map<String, Object> variables) {
|
||||
Object body = argv[metadata.bodyIndex()];
|
||||
checkArgument(body != null, "Body parameter %s was null", metadata.bodyIndex());
|
||||
try {
|
||||
encoder.encode(body, metadata.bodyType(), mutable);
|
||||
} catch (EncodeException e) {
|
||||
throw e;
|
||||
} catch (RuntimeException e) {
|
||||
throw new EncodeException(e.getMessage(), e);
|
||||
}
|
||||
return super.resolve(argv, mutable, variables);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,78 +0,0 @@
|
||||
package cn.axzo.workflow.support.api;
|
||||
|
||||
import cn.axzo.workflow.client.config.WorkflowEngineClientAutoConfiguration;
|
||||
import cn.axzo.workflow.common.annotation.InvokeMode;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCreateDTO;
|
||||
import cn.axzo.workflow.starter.WorkflowEngineStarterAutoConfiguration;
|
||||
import com.github.javaparser.ParseResult;
|
||||
import com.github.javaparser.ParserConfiguration;
|
||||
import com.github.javaparser.ast.CompilationUnit;
|
||||
import com.github.javaparser.ast.Modifier;
|
||||
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
|
||||
import com.github.javaparser.ast.body.MethodDeclaration;
|
||||
import com.github.javaparser.ast.body.Parameter;
|
||||
import com.github.javaparser.ast.expr.NormalAnnotationExpr;
|
||||
import com.github.javaparser.printer.DefaultPrettyPrinter;
|
||||
import com.github.javaparser.printer.Printer;
|
||||
import com.github.javaparser.utils.CodeGenerationUtils;
|
||||
import com.github.javaparser.utils.SourceRoot;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024/6/7 17:14
|
||||
*/
|
||||
public class CodeGeneration {
|
||||
|
||||
@SneakyThrows
|
||||
public static void main(String[] args) {
|
||||
Path sourceCodeRoot = CodeGenerationUtils.mavenModuleRoot(WorkflowEngineClientAutoConfiguration.class).resolve("src/main/java/cn/axzo/workflow/client/feign/");
|
||||
SourceRoot sourceRoot = new SourceRoot(sourceCodeRoot);
|
||||
sourceRoot.getParserConfiguration().setLanguageLevel(ParserConfiguration.LanguageLevel.JAVA_8);
|
||||
Printer printer = new DefaultPrettyPrinter();
|
||||
sourceRoot.setPrinter(printer::print);
|
||||
|
||||
List<ParseResult<CompilationUnit>> parseResults = sourceRoot.tryToParse();
|
||||
List<CompilationUnit> compilationUnits = sourceRoot.getCompilationUnits();
|
||||
compilationUnits.forEach(compilationUnit -> {
|
||||
// System.out.println("compilationUnit = " + compilationUnit);
|
||||
});
|
||||
|
||||
// https://www.jianshu.com/p/04b413c97988
|
||||
Path outputCodeRoot = CodeGenerationUtils.mavenModuleRoot(WorkflowEngineStarterAutoConfiguration.class).resolve(Paths.get("src/main/java/cn/axzo/workflow/starter/api"));
|
||||
SourceRoot outputCodeSR = new SourceRoot(outputCodeRoot);
|
||||
outputCodeSR.saveAll(StandardCharsets.UTF_8);
|
||||
|
||||
CompilationUnit compilationUnit = new CompilationUnit();
|
||||
ClassOrInterfaceDeclaration workflowCoreServiceTest = compilationUnit.addInterface("WorkflowCoreServiceTest").setPublic(true);
|
||||
workflowCoreServiceTest.setInterface(true);
|
||||
MethodDeclaration a = workflowCoreServiceTest.addMethod("a", Modifier.Keyword.PUBLIC).removeBody();
|
||||
a.setJavadocComment("创建审批流程");
|
||||
Parameter dto = a.addAndGetParameter(BpmnProcessInstanceCreateDTO.class, "dto");
|
||||
dto.addAnnotation(Validated.class).addAnnotation(RequestBody.class);
|
||||
a.setType(String.class);
|
||||
|
||||
NormalAnnotationExpr postMapping = a.addAndGetAnnotation(PostMapping.class);
|
||||
postMapping.addPair("value", "/api/process/instance/create");
|
||||
// postMapping.setName("/api/process/instance/create");
|
||||
|
||||
NormalAnnotationExpr invokeMode = a.addAndGetAnnotation(InvokeMode.class);
|
||||
invokeMode.addPair("value", "SYNC");
|
||||
|
||||
// compilationUnit.setPackageDeclaration("cn.axzo.workflow.starter.api");
|
||||
compilationUnit.addImport(BpmnProcessInstanceCreateDTO.class);
|
||||
|
||||
String string = workflowCoreServiceTest.toString();
|
||||
System.out.println("string = " + string);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,190 @@
|
||||
package cn.axzo.workflow.support.api;
|
||||
|
||||
import cn.axzo.workflow.client.config.WorkflowEngineClientAutoConfiguration;
|
||||
import cn.axzo.workflow.common.annotation.Manageable;
|
||||
import cn.axzo.workflow.starter.WorkflowEngineStarterAutoConfiguration;
|
||||
import cn.axzo.workflow.starter.feign.ext.WorkflowEngineStarterFeignConfiguration;
|
||||
import com.github.javaparser.ParserConfiguration;
|
||||
import com.github.javaparser.ast.CompilationUnit;
|
||||
import com.github.javaparser.ast.ImportDeclaration;
|
||||
import com.github.javaparser.ast.Modifier;
|
||||
import com.github.javaparser.ast.NodeList;
|
||||
import com.github.javaparser.ast.body.BodyDeclaration;
|
||||
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
|
||||
import com.github.javaparser.ast.body.MethodDeclaration;
|
||||
import com.github.javaparser.ast.expr.ClassExpr;
|
||||
import com.github.javaparser.ast.expr.MethodCallExpr;
|
||||
import com.github.javaparser.ast.expr.NameExpr;
|
||||
import com.github.javaparser.ast.expr.StringLiteralExpr;
|
||||
import com.github.javaparser.ast.expr.ThisExpr;
|
||||
import com.github.javaparser.ast.stmt.BlockStmt;
|
||||
import com.github.javaparser.ast.stmt.ExpressionStmt;
|
||||
import com.github.javaparser.ast.stmt.ReturnStmt;
|
||||
import com.github.javaparser.ast.type.ClassOrInterfaceType;
|
||||
import com.github.javaparser.ast.type.Type;
|
||||
import com.github.javaparser.printer.DefaultPrettyPrinter;
|
||||
import com.github.javaparser.printer.Printer;
|
||||
import com.github.javaparser.utils.CodeGenerationUtils;
|
||||
import com.github.javaparser.utils.SourceRoot;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* 生成 WorkflowCoreService 接口
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024/6/7 17:14
|
||||
*/
|
||||
public class CoreServiceCodeGenerator {
|
||||
|
||||
@SneakyThrows
|
||||
public static void main(String[] args) {
|
||||
String newClassName = "WorkflowCoreService";
|
||||
CompilationUnit originFile = parseOriginFile(newClassName);
|
||||
|
||||
CompilationUnit testGeneric = genericCode("cn.axzo.workflow.starter.api", newClassName);
|
||||
writeToStarter(testGeneric, newClassName);
|
||||
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private static CompilationUnit parseOriginFile(String newClassName) {
|
||||
Path sourceCodeRoot = CodeGenerationUtils.mavenModuleRoot(WorkflowEngineStarterAutoConfiguration.class).resolve("src/main/java/cn/axzo/workflow/starter/api/");
|
||||
SourceRoot sourceRoot = new SourceRoot(sourceCodeRoot);
|
||||
sourceRoot.getParserConfiguration().setLanguageLevel(ParserConfiguration.LanguageLevel.JAVA_8);
|
||||
Printer printer = new DefaultPrettyPrinter();
|
||||
sourceRoot.setPrinter(printer::print);
|
||||
sourceRoot.tryToParse();
|
||||
|
||||
List<CompilationUnit> compilationUnits = sourceRoot.getCompilationUnits();
|
||||
for (CompilationUnit cu : compilationUnits) {
|
||||
Optional<String> primaryTypeName = cu.getPrimaryTypeName();
|
||||
if (primaryTypeName.isPresent() && primaryTypeName.get().equals(newClassName)) {
|
||||
System.out.println("compilationUnit = " + cu);
|
||||
return cu;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void writeToStarter(CompilationUnit cu, String newClassName) {
|
||||
String projectRootDir = System.getProperty("user.dir");
|
||||
String genericFilePath = Paths.get(projectRootDir, "/workflow-engine-spring-boot-starter/src/main/java/cn/axzo/workflow/starter/api/", newClassName + ".java").toString();
|
||||
try (FileWriter fileWriter = new FileWriter(genericFilePath)) {
|
||||
fileWriter.append(cu.toString());
|
||||
} catch (IOException e) {
|
||||
// nothing to do
|
||||
}
|
||||
}
|
||||
|
||||
public static CompilationUnit genericCode(String pkg, String newClassName) {
|
||||
CompilationUnit cu = new CompilationUnit(pkg);
|
||||
ClassOrInterfaceDeclaration interfaceDeclaration = setCommon(cu, newClassName);
|
||||
|
||||
addMethods(interfaceDeclaration, cu);
|
||||
addDefaultMethods(interfaceDeclaration);
|
||||
return cu;
|
||||
}
|
||||
|
||||
private static void addDefaultMethods(ClassOrInterfaceDeclaration interfaceDeclaration) {
|
||||
MethodDeclaration sync = createDefaultMethod("sync", interfaceDeclaration);
|
||||
sync.setJavadocComment("强制使用‘同步’模式调用该方法,请在调用真实方法前调用该方法\r\n" +
|
||||
"<pre>\r\n" +
|
||||
"workflowCoreService.sync().createProcessInstance();\r\n" +
|
||||
"</pre>");
|
||||
|
||||
MethodDeclaration async = createDefaultMethod("async", interfaceDeclaration);
|
||||
sync.setJavadocComment("强制使用‘异步’模式调用该方法,请在调用真实方法前调用该方法\r\n" +
|
||||
"<pre>\r\n" +
|
||||
"workflowCoreService.async().createProcessInstance();\r\n" +
|
||||
"</pre>");
|
||||
}
|
||||
|
||||
private static MethodDeclaration createDefaultMethod(String methodName, ClassOrInterfaceDeclaration interfaceDeclaration) {
|
||||
// 将sync方法添加到WorkflowCoreService类中
|
||||
MethodDeclaration methodDeclaration = interfaceDeclaration.addMethod(methodName, Modifier.Keyword.DEFAULT);
|
||||
methodDeclaration.setType(new ClassOrInterfaceType("WorkflowCoreService"));
|
||||
|
||||
// 创建方法体
|
||||
BlockStmt methodBody = new BlockStmt();
|
||||
|
||||
MethodCallExpr setMethodCall = new MethodCallExpr(new NameExpr("ThreadUtil"), "set");
|
||||
setMethodCall.addArgument(new NameExpr(methodName.toUpperCase())); // 使用NameExpr来表示枚举常量
|
||||
ExpressionStmt setStatement = new ExpressionStmt(setMethodCall);
|
||||
|
||||
methodBody.addStatement(setStatement);
|
||||
// 创建return this;的语句
|
||||
ReturnStmt returnStmt = new ReturnStmt(new ThisExpr());
|
||||
methodBody.addStatement(returnStmt);
|
||||
|
||||
// 将方法体设置到sync方法中
|
||||
methodDeclaration.setBody(methodBody);
|
||||
return methodDeclaration;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private static void addMethods(ClassOrInterfaceDeclaration interfaceDeclaration, CompilationUnit cu) {
|
||||
Path sourceCodeRoot = CodeGenerationUtils.mavenModuleRoot(WorkflowEngineClientAutoConfiguration.class).resolve("src/main/java/cn/axzo/workflow/client/feign/");
|
||||
SourceRoot sourceRoot = new SourceRoot(sourceCodeRoot);
|
||||
sourceRoot.getParserConfiguration().setLanguageLevel(ParserConfiguration.LanguageLevel.JAVA_8);
|
||||
Printer printer = new DefaultPrettyPrinter();
|
||||
sourceRoot.setPrinter(printer::print);
|
||||
sourceRoot.tryToParse();
|
||||
|
||||
List<CompilationUnit> compilationUnits = sourceRoot.getCompilationUnits();
|
||||
NodeList<BodyDeclaration<?>> targetMethods = interfaceDeclaration.getMembers();
|
||||
for (CompilationUnit apiCU : compilationUnits) {
|
||||
if (!apiCU.getPrimaryType().filter(e -> e.getAnnotationByClass(Manageable.class).isPresent()).isPresent()) {
|
||||
addImports(apiCU, cu);
|
||||
// 类上含有 @Manageable,不进行解析
|
||||
String interfaceName = apiCU.getPrimaryTypeName().get();
|
||||
List<MethodDeclaration> methods = apiCU.getInterfaceByName(interfaceName).get().findAll(MethodDeclaration.class);
|
||||
for (MethodDeclaration method : methods) {
|
||||
if (!method.getAnnotationByClass(Manageable.class).isPresent()) {
|
||||
MethodDeclaration methodDeclaration = method.clone();
|
||||
methodDeclaration.setType(changeReturnType(methodDeclaration.getType()));
|
||||
targetMethods.add(methodDeclaration);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Type changeReturnType(Type type) {
|
||||
if (type instanceof ClassOrInterfaceType && type.asClassOrInterfaceType().getTypeArguments().isPresent()) {
|
||||
NodeList<Type> types = type.asClassOrInterfaceType().getTypeArguments().orElse(new NodeList<>());
|
||||
if (types.size() != 1) {
|
||||
throw new RuntimeException("workflow-engine-api 中的接口返回类型有误");
|
||||
}
|
||||
return types.getFirst().get();
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
private static void addImports(CompilationUnit apiCU, CompilationUnit cu) {
|
||||
for (ImportDeclaration sourceImport : apiCU.getImports()) {
|
||||
cu.addImport(sourceImport.clone());
|
||||
}
|
||||
}
|
||||
|
||||
private static ClassOrInterfaceDeclaration setCommon(CompilationUnit cu, String newClassName) {
|
||||
ClassOrInterfaceDeclaration classOrInterfaceDeclaration = cu.addInterface(newClassName).setPublic(true);
|
||||
classOrInterfaceDeclaration.setJavadocComment("Workflow Engine Starter Core Service");
|
||||
classOrInterfaceDeclaration.addAndGetAnnotation(FeignClient.class)
|
||||
.addPair("name", new StringLiteralExpr("workflow-engine-starter"))
|
||||
.addPair("url", new StringLiteralExpr("${axzo.service.workflow-engine:workflow-engine:8080}"))
|
||||
.addPair("configuration", new ClassExpr(new ClassOrInterfaceType(null, WorkflowEngineStarterFeignConfiguration.class.getSimpleName())));
|
||||
cu.addImport("cn.axzo.workflow.starter.feign.ext.WorkflowEngineStarterFeignConfiguration", false, false);
|
||||
cu.addImport("cn.axzo.workflow.common.util.ThreadUtil", false, false);
|
||||
cu.addImport("cn.axzo.workflow.common.enums.RpcInvokeModeEnum.ASYNC", true, false);
|
||||
cu.addImport("cn.axzo.workflow.common.enums.RpcInvokeModeEnum.SYNC", true, false);
|
||||
return classOrInterfaceDeclaration;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,166 @@
|
||||
package cn.axzo.workflow.support.api;
|
||||
|
||||
import cn.axzo.workflow.client.config.WorkflowEngineClientAutoConfiguration;
|
||||
import cn.axzo.workflow.common.annotation.Manageable;
|
||||
import cn.axzo.workflow.starter.feign.ext.WorkflowEngineStarterFeignConfiguration;
|
||||
import com.github.javaparser.ParserConfiguration;
|
||||
import com.github.javaparser.ast.CompilationUnit;
|
||||
import com.github.javaparser.ast.ImportDeclaration;
|
||||
import com.github.javaparser.ast.Modifier;
|
||||
import com.github.javaparser.ast.NodeList;
|
||||
import com.github.javaparser.ast.body.BodyDeclaration;
|
||||
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
|
||||
import com.github.javaparser.ast.body.MethodDeclaration;
|
||||
import com.github.javaparser.ast.expr.ClassExpr;
|
||||
import com.github.javaparser.ast.expr.MethodCallExpr;
|
||||
import com.github.javaparser.ast.expr.NameExpr;
|
||||
import com.github.javaparser.ast.expr.StringLiteralExpr;
|
||||
import com.github.javaparser.ast.expr.ThisExpr;
|
||||
import com.github.javaparser.ast.stmt.BlockStmt;
|
||||
import com.github.javaparser.ast.stmt.ExpressionStmt;
|
||||
import com.github.javaparser.ast.stmt.ReturnStmt;
|
||||
import com.github.javaparser.ast.type.ClassOrInterfaceType;
|
||||
import com.github.javaparser.ast.type.Type;
|
||||
import com.github.javaparser.printer.DefaultPrettyPrinter;
|
||||
import com.github.javaparser.printer.Printer;
|
||||
import com.github.javaparser.utils.CodeGenerationUtils;
|
||||
import com.github.javaparser.utils.SourceRoot;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 生成 WorkflowManageService 接口
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024/6/11 17:38
|
||||
*/
|
||||
public class ManageServiceCodeGenerator {
|
||||
@SneakyThrows
|
||||
public static void main(String[] args) {
|
||||
String newClassName = "WorkflowManageService";
|
||||
|
||||
CompilationUnit testGeneric = genericCode("cn.axzo.workflow.starter.api", newClassName);
|
||||
writeToStarter(testGeneric, newClassName);
|
||||
|
||||
}
|
||||
|
||||
private static void writeToStarter(CompilationUnit cu, String newClassName) {
|
||||
String projectRootDir = System.getProperty("user.dir");
|
||||
String genericFilePath = Paths.get(projectRootDir, "/workflow-engine-spring-boot-starter/src/main/java/cn/axzo/workflow/starter/api/", newClassName + ".java").toString();
|
||||
try (FileWriter fileWriter = new FileWriter(genericFilePath)) {
|
||||
fileWriter.append(cu.toString());
|
||||
} catch (IOException e) {
|
||||
// nothing to do
|
||||
}
|
||||
}
|
||||
|
||||
public static CompilationUnit genericCode(String pkg, String newClassName) {
|
||||
CompilationUnit cu = new CompilationUnit(pkg);
|
||||
ClassOrInterfaceDeclaration interfaceDeclaration = setCommon(cu, newClassName);
|
||||
|
||||
addMethods(interfaceDeclaration, cu);
|
||||
addDefaultMethods(interfaceDeclaration);
|
||||
return cu;
|
||||
}
|
||||
|
||||
private static void addDefaultMethods(ClassOrInterfaceDeclaration interfaceDeclaration) {
|
||||
MethodDeclaration sync = createDefaultMethod("sync", interfaceDeclaration);
|
||||
sync.setJavadocComment("强制使用‘同步’模式调用该方法,请在调用真实方法前调用该方法\r\n" +
|
||||
"<pre>\r\n" +
|
||||
"workflowCoreService.sync().createProcessInstance();\r\n" +
|
||||
"</pre>");
|
||||
|
||||
MethodDeclaration async = createDefaultMethod("async", interfaceDeclaration);
|
||||
sync.setJavadocComment("强制使用‘异步’模式调用该方法,请在调用真实方法前调用该方法\r\n" +
|
||||
"<pre>\r\n" +
|
||||
"workflowCoreService.async().createProcessInstance();\r\n" +
|
||||
"</pre>");
|
||||
}
|
||||
|
||||
private static MethodDeclaration createDefaultMethod(String methodName, ClassOrInterfaceDeclaration interfaceDeclaration) {
|
||||
// 将sync方法添加到WorkflowCoreService类中
|
||||
MethodDeclaration methodDeclaration = interfaceDeclaration.addMethod(methodName, Modifier.Keyword.DEFAULT);
|
||||
methodDeclaration.setType(new ClassOrInterfaceType("WorkflowCoreService"));
|
||||
|
||||
// 创建方法体
|
||||
BlockStmt methodBody = new BlockStmt();
|
||||
|
||||
MethodCallExpr setMethodCall = new MethodCallExpr(new NameExpr("ThreadUtil"), "set");
|
||||
setMethodCall.addArgument(new NameExpr(methodName.toUpperCase())); // 使用NameExpr来表示枚举常量
|
||||
ExpressionStmt setStatement = new ExpressionStmt(setMethodCall);
|
||||
|
||||
methodBody.addStatement(setStatement);
|
||||
// 创建return this;的语句
|
||||
ReturnStmt returnStmt = new ReturnStmt(new ThisExpr());
|
||||
methodBody.addStatement(returnStmt);
|
||||
|
||||
// 将方法体设置到sync方法中
|
||||
methodDeclaration.setBody(methodBody);
|
||||
return methodDeclaration;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private static void addMethods(ClassOrInterfaceDeclaration interfaceDeclaration, CompilationUnit cu) {
|
||||
Path sourceCodeRoot = CodeGenerationUtils.mavenModuleRoot(WorkflowEngineClientAutoConfiguration.class).resolve("src/main/java/cn/axzo/workflow/client/feign/");
|
||||
SourceRoot sourceRoot = new SourceRoot(sourceCodeRoot);
|
||||
sourceRoot.getParserConfiguration().setLanguageLevel(ParserConfiguration.LanguageLevel.JAVA_8);
|
||||
Printer printer = new DefaultPrettyPrinter();
|
||||
sourceRoot.setPrinter(printer::print);
|
||||
sourceRoot.tryToParse();
|
||||
|
||||
List<CompilationUnit> compilationUnits = sourceRoot.getCompilationUnits();
|
||||
NodeList<BodyDeclaration<?>> targetMethods = interfaceDeclaration.getMembers();
|
||||
for (CompilationUnit apiCU : compilationUnits) {
|
||||
if (!apiCU.getPrimaryType().filter(e -> e.getAnnotationByClass(Manageable.class).isPresent()).isPresent()) {
|
||||
addImports(apiCU, cu);
|
||||
// 类上含有 @Manageable,不进行解析
|
||||
String interfaceName = apiCU.getPrimaryTypeName().get();
|
||||
List<MethodDeclaration> methods = apiCU.getInterfaceByName(interfaceName).get().findAll(MethodDeclaration.class);
|
||||
for (MethodDeclaration method : methods) {
|
||||
if (!method.getAnnotationByClass(Manageable.class).isPresent()) {
|
||||
MethodDeclaration methodDeclaration = method.clone();
|
||||
methodDeclaration.setType(changeReturnType(methodDeclaration.getType()));
|
||||
targetMethods.add(methodDeclaration);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Type changeReturnType(Type type) {
|
||||
if (type instanceof ClassOrInterfaceType && type.asClassOrInterfaceType().getTypeArguments().isPresent()) {
|
||||
NodeList<Type> types = type.asClassOrInterfaceType().getTypeArguments().orElse(new NodeList<>());
|
||||
if (types.size() != 1) {
|
||||
throw new RuntimeException("workflow-engine-api 中的接口返回类型有误");
|
||||
}
|
||||
return types.getFirst().get();
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
private static void addImports(CompilationUnit apiCU, CompilationUnit cu) {
|
||||
for (ImportDeclaration sourceImport : apiCU.getImports()) {
|
||||
cu.addImport(sourceImport.clone());
|
||||
}
|
||||
}
|
||||
|
||||
private static ClassOrInterfaceDeclaration setCommon(CompilationUnit cu, String newClassName) {
|
||||
ClassOrInterfaceDeclaration classOrInterfaceDeclaration = cu.addInterface(newClassName).setPublic(true);
|
||||
classOrInterfaceDeclaration.setJavadocComment("Workflow Engine Starter Management Service");
|
||||
classOrInterfaceDeclaration.addAndGetAnnotation(FeignClient.class)
|
||||
.addPair("name", new StringLiteralExpr("workflow-engine-starter"))
|
||||
.addPair("url", new StringLiteralExpr("${axzo.service.workflow-engine:workflow-engine:8080}"))
|
||||
.addPair("configuration", new ClassExpr(new ClassOrInterfaceType(null, WorkflowEngineStarterFeignConfiguration.class.getSimpleName())));
|
||||
cu.addImport("cn.axzo.workflow.starter.feign.ext.WorkflowEngineStarterFeignConfiguration", false, false);
|
||||
cu.addImport("cn.axzo.workflow.common.util.ThreadUtil", false, false);
|
||||
cu.addImport("cn.axzo.workflow.common.enums.RpcInvokeModeEnum.ASYNC", true, false);
|
||||
cu.addImport("cn.axzo.workflow.common.enums.RpcInvokeModeEnum.SYNC", true, false);
|
||||
return classOrInterfaceDeclaration;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user