This commit is contained in:
asp_ly 2024-12-14 22:56:04 +08:00
parent adb747f070
commit ccac93e4a8
15 changed files with 806 additions and 897 deletions

View File

@ -69,16 +69,14 @@ public class WorkflowDefinitionApiController extends BaseController<WorkflowDefi
@Operation(summary = "启动工作流实例") @Operation(summary = "启动工作流实例")
@PostMapping("/start") @PostMapping("/start")
public Response<WorkflowInstanceCreateDTO> startWorkflow( public Response<WorkflowInstanceDTO> startWorkflow(
@Parameter(description = "流程标识", required = true) @RequestParam String processKey, @Parameter(description = "流程标识", required = true) @RequestParam String processKey,
@Parameter(description = "业务标识", required = true) @RequestParam String businessKey @Parameter(description = "业务标识", required = true) @RequestParam String businessKey
) { ) {
Map<String, Object> variables = new HashMap<>(); Map<String, Object> variables = new HashMap<>();
try { try {
// 同步创建实例立即返回实例ID // 同步创建实例立即返回实例ID
WorkflowInstanceCreateDTO result = workflowDefinitionService.startWorkflow(processKey, businessKey, variables); return Response.success(workflowDefinitionService.startWorkflow(processKey, businessKey, variables));
return Response.success(result);
} catch (Exception e) { } catch (Exception e) {
log.error("Failed to start workflow", e); log.error("Failed to start workflow", e);
return Response.error(ResponseCode.WORKFLOW_EXECUTION_ERROR); return Response.error(ResponseCode.WORKFLOW_EXECUTION_ERROR);
@ -119,48 +117,49 @@ public class WorkflowDefinitionApiController extends BaseController<WorkflowDefi
WorkflowInstanceDTO instanceDTO = new WorkflowInstanceDTO(); WorkflowInstanceDTO instanceDTO = new WorkflowInstanceDTO();
// instanceDTO.setId(historicProcessInstance.getId()); // instanceDTO.setId(historicProcessInstance.getId());
instanceDTO.setProcessDefinitionId(historicProcessInstance.getProcessDefinitionId()); // instanceDTO.setProcessDefinitionId(historicProcessInstance.getProcessDefinitionId());
instanceDTO.setBusinessKey(historicProcessInstance.getBusinessKey()); // instanceDTO.setBusinessKey(historicProcessInstance.getBusinessKey());
instanceDTO.setStartTime(historicProcessInstance.getStartTime()); // instanceDTO.setStartTime(historicProcessInstance.getStartTime());
instanceDTO.setEndTime(historicProcessInstance.getEndTime()); // instanceDTO.setEndTime(historicProcessInstance.getEndTime());
instanceDTO.setDurationInMillis(historicProcessInstance.getDurationInMillis()); // instanceDTO.setDurationInMillis(historicProcessInstance.getDurationInMillis());
instanceDTO.setStartUserId(historicProcessInstance.getStartUserId()); // instanceDTO.setStartUserId(historicProcessInstance.getStartUserId());
instanceDTO.setStatus(historicProcessInstance.getEndTime() != null ? WorkflowInstanceStatusEnums.COMPLETED : WorkflowInstanceStatusEnums.RUNNING); // instanceDTO.setStatus(historicProcessInstance.getEndTime() != null ? WorkflowInstanceStatusEnums.COMPLETED : WorkflowInstanceStatusEnums.RUNNING);
instanceDTO.setVariables(historicProcessInstance.getProcessVariables()); // instanceDTO.setVariables(historicProcessInstance.getProcessVariables());
//
// 查询活动节点历史 // // 查询活动节点历史
List<HistoricActivityInstance> activities = historyService.createHistoricActivityInstanceQuery() // List<HistoricActivityInstance> activities = historyService.createHistoricActivityInstanceQuery()
.processInstanceId(processInstanceId) // .processInstanceId(processInstanceId)
.orderByHistoricActivityInstanceStartTime() // .orderByHistoricActivityInstanceStartTime()
.asc() // .asc()
.list(); // .list();
//
List<WorkflowInstanceDTO.ActivityInstance> activityInstances = activities.stream() // List<WorkflowInstanceDTO.ActivityInstance> activityInstances = activities.stream()
.map(activity -> { // .map(activity -> {
WorkflowInstanceDTO.ActivityInstance activityInstance = new WorkflowInstanceDTO.ActivityInstance(); // WorkflowInstanceDTO.ActivityInstance activityInstance = new WorkflowInstanceDTO.ActivityInstance();
activityInstance.setId(activity.getId()); // activityInstance.setId(activity.getId());
activityInstance.setActivityId(activity.getActivityId()); // activityInstance.setActivityId(activity.getActivityId());
activityInstance.setActivityName(activity.getActivityName()); // activityInstance.setActivityName(activity.getActivityName());
activityInstance.setActivityType(activity.getActivityType()); // activityInstance.setActivityType(activity.getActivityType());
activityInstance.setStartTime(activity.getStartTime()); // activityInstance.setStartTime(activity.getStartTime());
activityInstance.setEndTime(activity.getEndTime()); // activityInstance.setEndTime(activity.getEndTime());
activityInstance.setDurationInMillis(activity.getDurationInMillis()); // activityInstance.setDurationInMillis(activity.getDurationInMillis());
//
// 如果是Shell任务获取Shell相关变量 // // 如果是Shell任务获取Shell相关变量
if ("serviceTask".equals(activity.getActivityType())) { // if ("serviceTask".equals(activity.getActivityType())) {
Map<String, Object> variables = historicProcessInstance.getProcessVariables(); // Map<String, Object> variables = historicProcessInstance.getProcessVariables();
activityInstance.setShellOutput((String) variables.get("shellOutput")); // activityInstance.setShellOutput((String) variables.get("shellOutput"));
activityInstance.setShellError((String) variables.get("shellError")); // activityInstance.setShellError((String) variables.get("shellError"));
activityInstance.setShellExitCode((Integer) variables.get("shellExitCode")); // activityInstance.setShellExitCode((Integer) variables.get("shellExitCode"));
} // }
//
return activityInstance; // return activityInstance;
}) // })
.collect(Collectors.toList()); // .collect(Collectors.toList());
//
instanceDTO.setActivities(activityInstances); // instanceDTO.setActivities(activityInstances);
//
return Response.success(instanceDTO); // return Response.success(instanceDTO);'
return Response.success();
} }
@Operation(summary = "获取工作流执行状态") @Operation(summary = "获取工作流执行状态")
@ -183,23 +182,24 @@ public class WorkflowDefinitionApiController extends BaseController<WorkflowDefi
.desc() .desc()
.list(); .list();
List<WorkflowInstanceDTO> instanceDTOs = historicProcessInstances.stream() // List<WorkflowInstanceDTO> instanceDTOs = historicProcessInstances.stream()
.map(historicProcessInstance -> { // .map(historicProcessInstance -> {
WorkflowInstanceDTO instanceDTO = new WorkflowInstanceDTO(); // WorkflowInstanceDTO instanceDTO = new WorkflowInstanceDTO();
// instanceDTO.setId(historicProcessInstance.getId()); //// instanceDTO.setId(historicProcessInstance.getId());
instanceDTO.setProcessDefinitionId(historicProcessInstance.getProcessDefinitionId()); // instanceDTO.setProcessDefinitionId(historicProcessInstance.getProcessDefinitionId());
instanceDTO.setBusinessKey(historicProcessInstance.getBusinessKey()); // instanceDTO.setBusinessKey(historicProcessInstance.getBusinessKey());
instanceDTO.setStartTime(historicProcessInstance.getStartTime()); // instanceDTO.setStartTime(historicProcessInstance.getStartTime());
instanceDTO.setEndTime(historicProcessInstance.getEndTime()); // instanceDTO.setEndTime(historicProcessInstance.getEndTime());
instanceDTO.setDurationInMillis(historicProcessInstance.getDurationInMillis()); // instanceDTO.setDurationInMillis(historicProcessInstance.getDurationInMillis());
instanceDTO.setStartUserId(historicProcessInstance.getStartUserId()); // instanceDTO.setStartUserId(historicProcessInstance.getStartUserId());
instanceDTO.setStatus(historicProcessInstance.getEndTime() != null ? WorkflowInstanceStatusEnums.COMPLETED : WorkflowInstanceStatusEnums.RUNNING); // instanceDTO.setStatus(historicProcessInstance.getEndTime() != null ? WorkflowInstanceStatusEnums.COMPLETED : WorkflowInstanceStatusEnums.RUNNING);
instanceDTO.setVariables(historicProcessInstance.getProcessVariables()); // instanceDTO.setVariables(historicProcessInstance.getProcessVariables());
return instanceDTO; // return instanceDTO;
}) // })
.collect(Collectors.toList()); // .collect(Collectors.toList());
return Response.success(instanceDTOs); // return Response.success(instanceDTOs);
return Response.success();
} }
@Operation(summary = "获取节点实时日志") @Operation(summary = "获取节点实时日志")

View File

@ -0,0 +1,15 @@
package com.qqchen.deploy.backend.workflow.converter;
import com.qqchen.deploy.backend.framework.converter.BaseConverter;
import com.qqchen.deploy.backend.workflow.dto.WorkflowDefinitionDTO;
import com.qqchen.deploy.backend.workflow.dto.WorkflowInstanceDTO;
import com.qqchen.deploy.backend.workflow.entity.WorkflowDefinition;
import com.qqchen.deploy.backend.workflow.entity.WorkflowInstance;
import org.mapstruct.Mapper;
/**
* 工作流定义转换器
*/
@Mapper(config = BaseConverter.class)
public interface WorkflowInstanceConverter extends BaseConverter<WorkflowInstance, WorkflowInstanceDTO> {
}

View File

@ -1,21 +1,47 @@
package com.qqchen.deploy.backend.workflow.dto; package com.qqchen.deploy.backend.workflow.dto;
import com.qqchen.deploy.backend.framework.dto.BaseDTO; import com.qqchen.deploy.backend.framework.dto.BaseDTO;
import com.qqchen.deploy.backend.workflow.enums.WorkflowInstanceStatusEnums;
import lombok.Data; import lombok.Data;
import java.time.LocalDateTime;
@Data @Data
public class WorkflowInstanceCreateDTO extends BaseDTO { public class WorkflowInstanceCreateDTO extends BaseDTO {
private String processInstanceId;
private String processDefinitionKey;
private String businessKey;
private String status; // CREATING, RUNNING, ERROR
public static WorkflowInstanceCreateDTO of(String processInstanceId, String processDefinitionKey, String businessKey) { /**
WorkflowInstanceCreateDTO dto = new WorkflowInstanceCreateDTO(); * 流程实例ID
dto.setProcessInstanceId(processInstanceId); */
dto.setProcessDefinitionKey(processDefinitionKey); private String processInstanceId;
dto.setBusinessKey(businessKey);
dto.setStatus("CREATING"); /**
return dto; * 流程定义ID
} */
private Long processDefinitionId;
/**
* 业务标识
*/
private String businessKey;
/**
* 实例状态
*/
private WorkflowInstanceStatusEnums status;
/**
* 流程变量(JSON)
*/
private String variables;
/**
* 开始时间
*/
private LocalDateTime startTime;
/**
* 结束时间
*/
private LocalDateTime endTime;
} }

View File

@ -4,6 +4,8 @@ import com.qqchen.deploy.backend.framework.dto.BaseDTO;
import com.qqchen.deploy.backend.workflow.enums.WorkflowInstanceStatusEnums; import com.qqchen.deploy.backend.workflow.enums.WorkflowInstanceStatusEnums;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import java.time.LocalDateTime;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -12,64 +14,39 @@ import java.util.Map;
@Schema(description = "工作流实例信息") @Schema(description = "工作流实例信息")
public class WorkflowInstanceDTO extends BaseDTO { public class WorkflowInstanceDTO extends BaseDTO {
@Schema(description = "流程定义ID") /**
* 流程实例ID
*/
private String processInstanceId;
/**
* 流程定义ID
*/
private String processDefinitionId; private String processDefinitionId;
@Schema(description = "业务标识") /**
* 业务标识
*/
private String businessKey; private String businessKey;
@Schema(description = "开始时间") /**
private Date startTime; * 实例状态
*/
@Schema(description = "结束时间")
private Date endTime;
@Schema(description = "执行时长(毫秒)")
private Long durationInMillis;
@Schema(description = "启动用户ID")
private String startUserId;
@Schema(description = "状态(RUNNING/COMPLETED/FAILED)")
private WorkflowInstanceStatusEnums status; private WorkflowInstanceStatusEnums status;
@Data /**
@Schema(description = "活动节点信息") * 流程变量(JSON)
public static class ActivityInstance { */
@Schema(description = "活动ID") private String variables;
private String id;
@Schema(description = "活动定义ID") /**
private String activityId; * 开始时间
*/
private LocalDateTime startTime;
@Schema(description = "活动名称") /**
private String activityName; * 结束时间
*/
private LocalDateTime endTime;
@Schema(description = "活动类型")
private String activityType;
@Schema(description = "开始时间")
private Date startTime;
@Schema(description = "结束时间")
private Date endTime;
@Schema(description = "执行时长(毫秒)")
private Long durationInMillis;
@Schema(description = "Shell输出")
private String shellOutput;
@Schema(description = "Shell错误")
private String shellError;
@Schema(description = "Shell退出码")
private Integer shellExitCode;
}
@Schema(description = "活动节点列表")
private List<ActivityInstance> activities;
@Schema(description = "流程变量")
private Map<String, Object> variables;
} }

View File

@ -37,6 +37,9 @@ public class WorkflowDefinition extends Entity<Long> {
@Column(name = "`key`", nullable = false) @Column(name = "`key`", nullable = false)
private String key; private String key;
@Column(name = "process_definition_id", nullable = false)
private String processDefinitionId;
/** /**
* 流程版本 * 流程版本
*/ */

View File

@ -30,7 +30,10 @@ public class WorkflowInstance extends Entity<Long> {
* 流程定义ID * 流程定义ID
*/ */
@Column(name = "process_definition_id", nullable = false) @Column(name = "process_definition_id", nullable = false)
private Long processDefinitionId; private String processDefinitionId;
@Column(name = "workflow_definition_id", nullable = false)
private Long workflowDefinitionId;
/** /**
* 业务标识 * 业务标识

View File

@ -4,6 +4,8 @@ import com.qqchen.deploy.backend.framework.repository.IBaseRepository;
import com.qqchen.deploy.backend.workflow.entity.WorkflowDefinition; import com.qqchen.deploy.backend.workflow.entity.WorkflowDefinition;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import java.util.Optional;
/** /**
* 工作流定义仓库 * 工作流定义仓库
*/ */
@ -18,4 +20,6 @@ public interface IWorkflowDefinitionRepository extends IBaseRepository<WorkflowD
* 检查流程标识是否存在 * 检查流程标识是否存在
*/ */
boolean existsByKeyAndDeletedFalse(String key); boolean existsByKeyAndDeletedFalse(String key);
Optional<WorkflowDefinition> findByKey(String businessKey);
} }

View File

@ -8,7 +8,7 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
@Repository @Repository
public interface WorkflowInstanceRepository extends JpaRepository<WorkflowInstance, Long> { public interface IWorkflowInstanceRepository extends JpaRepository<WorkflowInstance, Long> {
/** /**
* 根据Flowable流程实例ID查询工作流实例 * 根据Flowable流程实例ID查询工作流实例
@ -20,8 +20,4 @@ public interface WorkflowInstanceRepository extends JpaRepository<WorkflowInstan
*/ */
List<WorkflowInstance> findByBusinessKey(String businessKey); List<WorkflowInstance> findByBusinessKey(String businessKey);
/**
* 根据流程定义ID查询工作流实例列表
*/
List<WorkflowInstance> findByProcessDefinitionId(Long processDefinitionId);
} }

View File

@ -5,7 +5,9 @@ import com.qqchen.deploy.backend.workflow.dto.WorkflowDefinitionDTO;
import com.qqchen.deploy.backend.workflow.dto.WorkflowDesignDTO; import com.qqchen.deploy.backend.workflow.dto.WorkflowDesignDTO;
import com.qqchen.deploy.backend.workflow.dto.WorkflowExecutionDTO; import com.qqchen.deploy.backend.workflow.dto.WorkflowExecutionDTO;
import com.qqchen.deploy.backend.workflow.dto.WorkflowInstanceCreateDTO; import com.qqchen.deploy.backend.workflow.dto.WorkflowInstanceCreateDTO;
import com.qqchen.deploy.backend.workflow.dto.WorkflowInstanceDTO;
import com.qqchen.deploy.backend.workflow.entity.WorkflowDefinition; import com.qqchen.deploy.backend.workflow.entity.WorkflowDefinition;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.runtime.ProcessInstance; import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -24,7 +26,7 @@ public interface IWorkflowDefinitionService extends IBaseService<WorkflowDefinit
* @param dto 工作流定义DTO * @param dto 工作流定义DTO
* @return 工作流定义DTO * @return 工作流定义DTO
*/ */
void deployWorkflow(WorkflowDefinition workflowDefinition); Deployment deployWorkflow(WorkflowDefinition workflowDefinition);
/** /**
* 启动工作流实例 * 启动工作流实例
@ -34,7 +36,7 @@ public interface IWorkflowDefinitionService extends IBaseService<WorkflowDefinit
* @param variables 流程变量 * @param variables 流程变量
* @return 流程实例 * @return 流程实例
*/ */
WorkflowInstanceCreateDTO startWorkflow(String processKey, String businessKey, Map<String, Object> variables); WorkflowInstanceDTO startWorkflow(String processKey, String businessKey, Map<String, Object> variables);
/** /**
* 挂起工作流实例 * 挂起工作流实例

View File

@ -14,10 +14,9 @@ public interface IWorkflowInstanceService {
* 创建工作流实例并关联Flowable实例 * 创建工作流实例并关联Flowable实例
* *
* @param processInstance Flowable流程实例 * @param processInstance Flowable流程实例
* @param variables 流程变量
* @return 工作流实例 * @return 工作流实例
*/ */
WorkflowInstance createWorkflowInstance(ProcessInstance processInstance, Map<String, Object> variables); WorkflowInstanceDTO createWorkflowInstance(Long workflowDefinitionId, String businessKey, ProcessInstance processInstance);
/** /**
* 更新工作流实例状态 * 更新工作流实例状态

View File

@ -1,15 +1,20 @@
package com.qqchen.deploy.backend.workflow.service.impl; package com.qqchen.deploy.backend.workflow.service.impl;
import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl; import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl;
import com.qqchen.deploy.backend.workflow.converter.WorkflowInstanceConverter;
import com.qqchen.deploy.backend.workflow.dto.WorkflowDefinitionDTO; import com.qqchen.deploy.backend.workflow.dto.WorkflowDefinitionDTO;
import com.qqchen.deploy.backend.workflow.dto.WorkflowExecutionDTO; import com.qqchen.deploy.backend.workflow.dto.WorkflowExecutionDTO;
import com.qqchen.deploy.backend.workflow.dto.WorkflowInstanceCreateDTO; import com.qqchen.deploy.backend.workflow.dto.WorkflowInstanceCreateDTO;
import com.qqchen.deploy.backend.workflow.dto.WorkflowInstanceDTO;
import com.qqchen.deploy.backend.workflow.dto.graph.WorkflowDefinitionGraph; import com.qqchen.deploy.backend.workflow.dto.graph.WorkflowDefinitionGraph;
import com.qqchen.deploy.backend.workflow.entity.WorkflowDefinition; import com.qqchen.deploy.backend.workflow.entity.WorkflowDefinition;
import com.qqchen.deploy.backend.workflow.entity.WorkflowInstance;
import com.qqchen.deploy.backend.workflow.enums.WorkflowInstanceStatusEnums; import com.qqchen.deploy.backend.workflow.enums.WorkflowInstanceStatusEnums;
import com.qqchen.deploy.backend.workflow.enums.WorkflowStatusEnums; import com.qqchen.deploy.backend.workflow.enums.WorkflowStatusEnums;
import com.qqchen.deploy.backend.workflow.repository.IWorkflowDefinitionRepository; import com.qqchen.deploy.backend.workflow.repository.IWorkflowDefinitionRepository;
import com.qqchen.deploy.backend.workflow.repository.IWorkflowInstanceRepository;
import com.qqchen.deploy.backend.workflow.service.IWorkflowDefinitionService; import com.qqchen.deploy.backend.workflow.service.IWorkflowDefinitionService;
import com.qqchen.deploy.backend.workflow.service.IWorkflowInstanceService;
import com.qqchen.deploy.backend.workflow.util.BpmnConverter; import com.qqchen.deploy.backend.workflow.util.BpmnConverter;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -24,6 +29,7 @@ import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.bpmn.model.BpmnModel; import org.flowable.bpmn.model.BpmnModel;
import org.flowable.engine.repository.Deployment; import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.Execution; import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance; import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.bpmn.model.Process; import org.flowable.bpmn.model.Process;
@ -31,6 +37,7 @@ import org.flowable.bpmn.model.FlowElement;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -38,7 +45,6 @@ import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
* 工作流定义服务实现 * 工作流定义服务实现
*/ */
@ -64,9 +70,12 @@ public class WorkflowDefinitionServiceImpl extends BaseServiceImpl<WorkflowDefin
@Resource @Resource
private IWorkflowDefinitionRepository workflowDefinitionRepository; private IWorkflowDefinitionRepository workflowDefinitionRepository;
@Resource @Resource
private BpmnConverter bpmnConverter; private BpmnConverter bpmnConverter;
@Resource
private IWorkflowInstanceService workflowInstanceService;
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@ -78,14 +87,15 @@ public class WorkflowDefinitionServiceImpl extends BaseServiceImpl<WorkflowDefin
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void deployWorkflow(WorkflowDefinition workflowDefinition) { public Deployment deployWorkflow(WorkflowDefinition workflowDefinition) {
try { try {
// 部署流程 // 部署流程
repositoryService.createDeployment() Deployment deployment = repositoryService.createDeployment()
.addString(workflowDefinition.getKey() + ".bpmn20.xml", workflowDefinition.getBpmnXml()) .addString(workflowDefinition.getKey() + ".bpmn20.xml", workflowDefinition.getBpmnXml())
.name(workflowDefinition.getName()) .name(workflowDefinition.getName())
.deploy(); .deploy();
log.info("Successfully deployed workflow: {}", workflowDefinition.getName()); log.info("Successfully deployed workflow: {}", workflowDefinition.getName());
return deployment;
} catch (Exception e) { } catch (Exception e) {
log.error("Failed to deploy workflow: {}", workflowDefinition.getName(), e); log.error("Failed to deploy workflow: {}", workflowDefinition.getName(), e);
throw new RuntimeException("Failed to deploy workflow", e); throw new RuntimeException("Failed to deploy workflow", e);
@ -93,25 +103,18 @@ public class WorkflowDefinitionServiceImpl extends BaseServiceImpl<WorkflowDefin
} }
@Override @Override
@Transactional @Transactional(rollbackFor = Exception.class)
public WorkflowInstanceCreateDTO startWorkflow(String processKey, String businessKey, Map<String, Object> variables) { public WorkflowInstanceDTO startWorkflow(String processKey, String businessKey, Map<String, Object> variables) {
try { try {
// 2. 创建工作流实例记录
WorkflowDefinition workflowDefinition = workflowDefinitionRepository.findByKey(processKey).orElseThrow(() -> new RuntimeException("Workflow definition process key not found: " + processKey));
// 1. 创建并异步启动流程实例 // 1. 创建并异步启动流程实例
ProcessInstance processInstance = runtimeService.createProcessInstanceBuilder() ProcessInstance processInstance = runtimeService.createProcessInstanceBuilder()
.processDefinitionKey(processKey) .processDefinitionKey(processKey)
.businessKey(businessKey) .businessKey(businessKey)
.variables(variables) .variables(variables)
.startAsync(); // 异步启动会自动执行 shell 任务 .startAsync(); // 异步启动会自动执行 shell 任务
// .start(); return workflowInstanceService.createWorkflowInstance(workflowDefinition.getId(), businessKey, processInstance);
// 2. 返回实例信息
WorkflowInstanceCreateDTO dto = new WorkflowInstanceCreateDTO();
dto.setProcessInstanceId(processInstance.getId());
dto.setProcessDefinitionKey(processKey);
dto.setBusinessKey(businessKey);
dto.setStatus("RUNNING"); // 因为实例已经在运行了
return dto;
} catch (Exception e) { } catch (Exception e) {
log.error("Failed to create workflow: {}", processKey, e); log.error("Failed to create workflow: {}", processKey, e);
throw new RuntimeException("Failed to create workflow", e); throw new RuntimeException("Failed to create workflow", e);
@ -345,9 +348,11 @@ public class WorkflowDefinitionServiceImpl extends BaseServiceImpl<WorkflowDefin
.orElseThrow(() -> new RuntimeException("Workflow definition not found: " + workflowDefinitionId)); .orElseThrow(() -> new RuntimeException("Workflow definition not found: " + workflowDefinitionId));
WorkflowDefinitionGraph graph = definition.getGraph(); WorkflowDefinitionGraph graph = definition.getGraph();
definition.setBpmnXml(bpmnConverter.convertToXml(graph, definition.getKey())); definition.setBpmnXml(bpmnConverter.convertToXml(graph, definition.getKey()));
Deployment deployment = this.deployWorkflow(definition);
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult();
definition.setStatus(WorkflowStatusEnums.PUBLISHED); definition.setStatus(WorkflowStatusEnums.PUBLISHED);
this.deployWorkflow(definition);
definition.setFlowVersion(1); definition.setFlowVersion(1);
definition.setProcessDefinitionId(processDefinition.getId());
workflowDefinitionRepository.save(definition); workflowDefinitionRepository.save(definition);
log.info("Successfully published workflow definition: {}", workflowDefinitionId); log.info("Successfully published workflow definition: {}", workflowDefinitionId);
} }

View File

@ -2,11 +2,13 @@ package com.qqchen.deploy.backend.workflow.service.impl;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.qqchen.deploy.backend.workflow.converter.WorkflowInstanceConverter;
import com.qqchen.deploy.backend.workflow.dto.WorkflowInstanceDTO; import com.qqchen.deploy.backend.workflow.dto.WorkflowInstanceDTO;
import com.qqchen.deploy.backend.workflow.entity.WorkflowInstance; import com.qqchen.deploy.backend.workflow.entity.WorkflowInstance;
import com.qqchen.deploy.backend.workflow.enums.WorkflowInstanceStatusEnums; import com.qqchen.deploy.backend.workflow.enums.WorkflowInstanceStatusEnums;
import com.qqchen.deploy.backend.workflow.repository.WorkflowInstanceRepository; import com.qqchen.deploy.backend.workflow.repository.IWorkflowInstanceRepository;
import com.qqchen.deploy.backend.workflow.service.IWorkflowInstanceService; import com.qqchen.deploy.backend.workflow.service.IWorkflowInstanceService;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.HistoryService; import org.flowable.engine.HistoryService;
@ -25,29 +27,30 @@ import java.util.stream.Collectors;
@RequiredArgsConstructor @RequiredArgsConstructor
public class WorkflowInstanceServiceImpl implements IWorkflowInstanceService { public class WorkflowInstanceServiceImpl implements IWorkflowInstanceService {
private final WorkflowInstanceRepository workflowInstanceRepository; private final IWorkflowInstanceRepository workflowInstanceRepository;
private final RuntimeService runtimeService; private final RuntimeService runtimeService;
private final HistoryService historyService; private final HistoryService historyService;
private final ObjectMapper objectMapper; private final ObjectMapper objectMapper;
@Resource
private WorkflowInstanceConverter workflowInstanceConverter;
@Override @Override
@Transactional @Transactional
public WorkflowInstance createWorkflowInstance(ProcessInstance processInstance, Map<String, Object> variables) { public WorkflowInstanceDTO createWorkflowInstance(Long workflowDefinitionId, String businessKey, ProcessInstance processInstance) {
WorkflowInstance instance = new WorkflowInstance(); WorkflowInstance workflowInstance = new WorkflowInstance();
instance.setProcessInstanceId(processInstance.getId()); workflowInstance.setProcessInstanceId(processInstance.getId());
instance.setProcessDefinitionId(Long.valueOf(processInstance.getProcessDefinitionId().split(":")[0])); workflowInstance.setProcessDefinitionId(processInstance.getProcessDefinitionId());
instance.setBusinessKey(processInstance.getBusinessKey()); workflowInstance.setWorkflowDefinitionId(workflowDefinitionId);
instance.setStatus(WorkflowInstanceStatusEnums.RUNNING); workflowInstance.setBusinessKey(businessKey);
instance.setStartTime(LocalDateTime.now()); workflowInstance.setStatus(WorkflowInstanceStatusEnums.CREATED);
workflowInstance.setStartTime(LocalDateTime.now());
try { workflowInstanceRepository.save(workflowInstance);
instance.setVariables(objectMapper.writeValueAsString(variables)); // 3. 返回创建结果
} catch (JsonProcessingException e) { return workflowInstanceConverter.toDto(workflowInstance);
log.error("Failed to serialize variables", e);
instance.setVariables("{}");
}
return workflowInstanceRepository.save(instance);
} }
@Override @Override
@ -69,42 +72,43 @@ public class WorkflowInstanceServiceImpl implements IWorkflowInstanceService {
WorkflowInstance instance = workflowInstanceRepository.findByProcessInstanceId(processInstanceId) WorkflowInstance instance = workflowInstanceRepository.findByProcessInstanceId(processInstanceId)
.orElseThrow(() -> new RuntimeException("Workflow instance not found: " + processInstanceId)); .orElseThrow(() -> new RuntimeException("Workflow instance not found: " + processInstanceId));
WorkflowInstanceDTO dto = new WorkflowInstanceDTO(); // WorkflowInstanceDTO dto = new WorkflowInstanceDTO();
// dto.setId(instance.getProcessInstanceId()); //// dto.setId(instance.getProcessInstanceId());
dto.setProcessDefinitionId(String.valueOf(instance.getProcessDefinitionId())); // dto.setProcessDefinitionId(String.valueOf(instance.getProcessDefinitionId()));
dto.setBusinessKey(instance.getBusinessKey()); // dto.setBusinessKey(instance.getBusinessKey());
dto.setStatus(instance.getStatus()); // dto.setStatus(instance.getStatus());
//
// // Convert LocalDateTime to Date
// dto.setStartTime(java.sql.Timestamp.valueOf(instance.getStartTime()));
// if (instance.getEndTime() != null) {
// dto.setEndTime(java.sql.Timestamp.valueOf(instance.getEndTime()));
// }
//
// // Calculate duration if both start and end time exist
// if (instance.getStartTime() != null && instance.getEndTime() != null) {
// dto.setDurationInMillis(java.time.Duration.between(instance.getStartTime(), instance.getEndTime()).toMillis());
// }
//
// // Get variables
// try {
// @SuppressWarnings("unchecked")
// Map<String, Object> variables = objectMapper.readValue(instance.getVariables(), Map.class);
// dto.setVariables(variables);
// } catch (JsonProcessingException e) {
// log.error("Failed to deserialize variables", e);
// dto.setVariables(new HashMap<>());
// }
//
// // Get activity instances
// List<HistoricActivityInstance> activities = historyService.createHistoricActivityInstanceQuery()
// .processInstanceId(processInstanceId)
// .orderByHistoricActivityInstanceStartTime().asc()
// .list();
//
// dto.setActivities(activities.stream().map(this::convertToActivityInstance).collect(Collectors.toList()));
// Convert LocalDateTime to Date // return dto;
dto.setStartTime(java.sql.Timestamp.valueOf(instance.getStartTime())); return null;
if (instance.getEndTime() != null) {
dto.setEndTime(java.sql.Timestamp.valueOf(instance.getEndTime()));
}
// Calculate duration if both start and end time exist
if (instance.getStartTime() != null && instance.getEndTime() != null) {
dto.setDurationInMillis(java.time.Duration.between(instance.getStartTime(), instance.getEndTime()).toMillis());
}
// Get variables
try {
@SuppressWarnings("unchecked")
Map<String, Object> variables = objectMapper.readValue(instance.getVariables(), Map.class);
dto.setVariables(variables);
} catch (JsonProcessingException e) {
log.error("Failed to deserialize variables", e);
dto.setVariables(new HashMap<>());
}
// Get activity instances
List<HistoricActivityInstance> activities = historyService.createHistoricActivityInstanceQuery()
.processInstanceId(processInstanceId)
.orderByHistoricActivityInstanceStartTime().asc()
.list();
dto.setActivities(activities.stream().map(this::convertToActivityInstance).collect(Collectors.toList()));
return dto;
} }
@Override @Override
@ -135,24 +139,24 @@ public class WorkflowInstanceServiceImpl implements IWorkflowInstanceService {
workflowInstanceRepository.save(instance); workflowInstanceRepository.save(instance);
} }
private WorkflowInstanceDTO.ActivityInstance convertToActivityInstance(HistoricActivityInstance hai) { // private WorkflowInstanceDTO.ActivityInstance convertToActivityInstance(HistoricActivityInstance hai) {
WorkflowInstanceDTO.ActivityInstance ai = new WorkflowInstanceDTO.ActivityInstance(); // WorkflowInstanceDTO.ActivityInstance ai = new WorkflowInstanceDTO.ActivityInstance();
ai.setId(hai.getId()); // ai.setId(hai.getId());
ai.setActivityId(hai.getActivityId()); // ai.setActivityId(hai.getActivityId());
ai.setActivityName(hai.getActivityName()); // ai.setActivityName(hai.getActivityName());
ai.setActivityType(hai.getActivityType()); // ai.setActivityType(hai.getActivityType());
ai.setStartTime(hai.getStartTime()); // ai.setStartTime(hai.getStartTime());
ai.setEndTime(hai.getEndTime()); // ai.setEndTime(hai.getEndTime());
ai.setDurationInMillis(hai.getDurationInMillis()); // ai.setDurationInMillis(hai.getDurationInMillis());
//
// Get shell task execution details from variables if available // // Get shell task execution details from variables if available
if ("serviceTask".equals(hai.getActivityType())) { // if ("serviceTask".equals(hai.getActivityType())) {
Map<String, Object> variables = runtimeService.getVariables(hai.getExecutionId()); // Map<String, Object> variables = runtimeService.getVariables(hai.getExecutionId());
ai.setShellOutput((String) variables.get("shellOutput")); // ai.setShellOutput((String) variables.get("shellOutput"));
ai.setShellError((String) variables.get("shellError")); // ai.setShellError((String) variables.get("shellError"));
ai.setShellExitCode((Integer) variables.get("shellExitCode")); // ai.setShellExitCode((Integer) variables.get("shellExitCode"));
} // }
//
return ai; // return ai;
} // }
} }

View File

@ -1,229 +0,0 @@
//package com.qqchen.deploy.backend.workflow.util;
//
//import com.fasterxml.jackson.databind.ObjectMapper;
//import com.qqchen.deploy.backend.workflow.dto.graph.*;
//import com.qqchen.deploy.backend.workflow.enums.NodeTypeEnums;
//import lombok.Data;
//import lombok.extern.slf4j.Slf4j;
//
//import java.util.ArrayList;
//import java.util.HashMap;
//import java.util.List;
//import java.util.Map;
//
///**
// * 工作流定义图形生成工具类
// * 用于生成示例工作流定义包括
// * 1. 简单工作流开始 -> 脚本任务 -> 结束
// * 2. 复杂工作流开始 -> 脚本任务A -> 脚本任务B -> 结束
// */
//@Data
//@Slf4j
//public class WorkflowDefinitionGraph {
// private static final ObjectMapper mapper = new ObjectMapper();
//
// /**
// * 节点列表
// */
// private List<WorkflowDefinitionNode> nodes;
//
// /**
// * 边列表
// */
// private List<WorkflowDefinitionEdge> edges;
//
// /**
// * 生成简单工作流
// * 开始 -> 脚本任务 -> 结束
// */
// public static WorkflowDefinitionGraph generateSimpleWorkflow() {
// WorkflowDefinitionGraph graph = new WorkflowDefinitionGraph();
// List<WorkflowDefinitionNode> nodes = new ArrayList<>();
// List<WorkflowDefinitionEdge> edges = new ArrayList<>();
//
// // 开始节点
// WorkflowDefinitionNode startNode = createNode(
// "startEvent1",
// NodeTypeEnums.START_EVENT,
// "开始",
// 100, 100,
// createNodeConfig("开始节点", "启动流程")
// );
// nodes.add(startNode);
//
// // 脚本任务节点
// Map<String, Object> scriptConfig = createNodeConfig("脚本任务", "执行一个简单的Shell脚本");
// scriptConfig.put("script", "echo 'Hello World'");
// scriptConfig.put("language", "shell");
//
// WorkflowDefinitionNode scriptNode = createNode(
// "scriptTask1",
// NodeTypeEnums.SCRIPT_TASK,
// "执行脚本",
// 300, 100,
// scriptConfig
// );
// nodes.add(scriptNode);
//
// // 结束节点
// WorkflowDefinitionNode endNode = createNode(
// "endEvent1",
// NodeTypeEnums.END_EVENT,
// "结束",
// 500, 100,
// createNodeConfig("结束节点", "流程结束")
// );
// nodes.add(endNode);
//
// // 添加连线
// edges.add(createEdge("flow1", "startEvent1", "scriptTask1", "开始到脚本"));
// edges.add(createEdge("flow2", "scriptTask1", "endEvent1", "脚本到结束"));
//
// graph.setNodes(nodes);
// graph.setEdges(edges);
// return graph;
// }
//
// /**
// * 生成复杂工作流
// * 开始 -> 脚本任务A -> 脚本任务B -> 结束
// */
// public static WorkflowDefinitionGraph generateComplexWorkflow() {
// WorkflowDefinitionGraph graph = new WorkflowDefinitionGraph();
// List<WorkflowDefinitionNode> nodes = new ArrayList<>();
// List<WorkflowDefinitionEdge> edges = new ArrayList<>();
//
// // 开始节点
// WorkflowDefinitionNode startNode = createNode(
// "startEvent1",
// NodeTypeEnums.START_EVENT,
// "开始",
// 100, 100,
// createNodeConfig("开始节点", "启动流程")
// );
// nodes.add(startNode);
//
// // 脚本任务A
// Map<String, Object> scriptConfigA = createNodeConfig("脚本任务A", "数据处理");
// scriptConfigA.put("script", "process_data.sh");
// scriptConfigA.put("language", "shell");
//
// WorkflowDefinitionNode scriptNodeA = createNode(
// "scriptTask1",
// NodeTypeEnums.SCRIPT_TASK,
// "数据处理",
// 300, 100,
// scriptConfigA
// );
// nodes.add(scriptNodeA);
//
// // 脚本任务B
// Map<String, Object> scriptConfigB = createNodeConfig("脚本任务B", "生成报告");
// scriptConfigB.put("script", "generate_report.sh");
// scriptConfigB.put("language", "shell");
//
// WorkflowDefinitionNode scriptNodeB = createNode(
// "scriptTask2",
// NodeTypeEnums.SCRIPT_TASK,
// "生成报告",
// 500, 100,
// scriptConfigB
// );
// nodes.add(scriptNodeB);
//
// // 结束节点
// WorkflowDefinitionNode endNode = createNode(
// "endEvent1",
// NodeTypeEnums.END_EVENT,
// "结束",
// 700, 100,
// createNodeConfig("结束节点", "流程结束")
// );
// nodes.add(endNode);
//
// // 添加连线
// edges.add(createEdge("flow1", "startEvent1", "scriptTask1", "开始到处理"));
// edges.add(createEdge("flow2", "scriptTask1", "scriptTask2", "处理到报告"));
// edges.add(createEdge("flow3", "scriptTask2", "endEvent1", "报告到结束"));
//
// graph.setNodes(nodes);
// graph.setEdges(edges);
// return graph;
// }
//
// /**
// * 创建节点
// */
// private static WorkflowDefinitionNode createNode(String id, NodeTypeEnums type, String name, int x, int y, Map<String, Object> config) {
// WorkflowDefinitionNode node = new WorkflowDefinitionNode();
// node.setId(id);
// node.setCode(type.getCode());
// node.setType(type);
// node.setName(name);
// node.setConfig(config);
//
// // 从枚举的uiConfig中获取配置并创建新的图形配置
// WorkflowNodeGraph originalConfig = type.getUiConfig();
// WorkflowNodeGraph nodeGraph = new WorkflowNodeGraph()
// .setShape(originalConfig.getShape())
// .setSize(originalConfig.getSize().getWidth(), originalConfig.getSize().getHeight())
// .setStyle(originalConfig.getStyle().getFill(),
// originalConfig.getStyle().getStroke(),
// originalConfig.getStyle().getIcon())
// .configPorts(originalConfig.getPorts().getTypes())
// .setPosition(x, y);
//
// node.setGraph(nodeGraph);
// return node;
// }
//
// /**
// * 创建节点配置
// */
// private static Map<String, Object> createNodeConfig(String name, String description) {
// Map<String, Object> config = new HashMap<>();
// config.put("name", name);
// config.put("description", description);
// return config;
// }
//
// /**
// * 创建连线
// */
// private static WorkflowDefinitionEdge createEdge(String id, String from, String to, String name) {
// return createEdge(id, from, to, name, null);
// }
//
// /**
// * 创建带条件的连线
// */
// private static WorkflowDefinitionEdge createEdge(String id, String from, String to, String name, String condition) {
// WorkflowDefinitionEdge edge = new WorkflowDefinitionEdge();
// edge.setId(id);
// edge.setFrom(from);
// edge.setTo(to);
// edge.setName(name);
//
// // 设置边配置
// WorkflowDefinitionEdgeConfig config = new WorkflowDefinitionEdgeConfig();
// config.setType("sequence");
// if (condition != null) {
// config.setCondition(condition);
// config.setConditionExpression(condition);
// }
// edge.setConfig(config);
//
// return edge;
// }
//
// public static void main(String[] args) {
// try {
// System.out.println("=== 简单工作流 ===");
// System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(generateSimpleWorkflow()));
// System.out.println("\n=== 复杂工作流 ===");
// System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(generateComplexWorkflow()));
// } catch (Exception e) {
// log.error("生成工作流定义失败", e);
// }
// }
//}

View File

@ -3,28 +3,69 @@
-- -------------------------------------------------------------------------------------- -- --------------------------------------------------------------------------------------
-- 租户表 -- 租户表
CREATE TABLE IF NOT EXISTS sys_tenant ( CREATE TABLE IF NOT EXISTS sys_tenant
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID', (
create_by VARCHAR(255) NULL COMMENT '创建人', id
create_time DATETIME(6) NULL COMMENT '创建时间', BIGINT
AUTO_INCREMENT
PRIMARY
KEY
COMMENT
'主键ID',
create_by
VARCHAR
(
255
) NULL COMMENT '创建人',
create_time DATETIME
(
6
) NULL COMMENT '创建时间',
deleted BIT NOT NULL DEFAULT 0 COMMENT '是否删除0未删除1已删除', deleted BIT NOT NULL DEFAULT 0 COMMENT '是否删除0未删除1已删除',
update_by VARCHAR(255) NULL COMMENT '更新人', update_by VARCHAR
update_time DATETIME(6) NULL COMMENT '更新时间', (
255
) NULL COMMENT '更新人',
update_time DATETIME
(
6
) NULL COMMENT '更新时间',
version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号', version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号',
code VARCHAR(50) NOT NULL COMMENT '租户编码', code VARCHAR
name VARCHAR(100) NOT NULL COMMENT '租户名称', (
address VARCHAR(255) NULL COMMENT '租户地址', 50
contact_name VARCHAR(50) NULL COMMENT '联系人姓名', ) NOT NULL COMMENT '租户编码',
contact_phone VARCHAR(20) NULL COMMENT '联系人电话', NAME VARCHAR
email VARCHAR(100) NULL COMMENT '联系人邮箱', (
100
) NOT NULL COMMENT '租户名称',
address VARCHAR
(
255
) NULL COMMENT '租户地址',
contact_name VARCHAR
(
50
) NULL COMMENT '联系人姓名',
contact_phone VARCHAR
(
20
) NULL COMMENT '联系人电话',
email VARCHAR
(
100
) NULL COMMENT '联系人邮箱',
enabled BIT NOT NULL DEFAULT 1 COMMENT '是否启用0禁用1启用', enabled BIT NOT NULL DEFAULT 1 COMMENT '是否启用0禁用1启用',
CONSTRAINT UK_tenant_code UNIQUE
CONSTRAINT UK_tenant_code UNIQUE (code) (
code
)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE =utf8mb4_unicode_ci COMMENT='租户表'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE =utf8mb4_unicode_ci COMMENT='租户表';
-- 部门表 -- 部门表
CREATE TABLE sys_department ( CREATE TABLE sys_department
(
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID', id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
create_by VARCHAR(255) NULL COMMENT '创建人', create_by VARCHAR(255) NULL COMMENT '创建人',
create_time DATETIME(6) NULL COMMENT '创建时间', create_time DATETIME(6) NULL COMMENT '创建时间',
@ -46,29 +87,73 @@ CREATE TABLE sys_department (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='部门表'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='部门表';
-- 用户表 -- 用户表
CREATE TABLE IF NOT EXISTS sys_user ( CREATE TABLE IF NOT EXISTS sys_user
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID', (
create_by VARCHAR(255) NULL COMMENT '创建人', id
create_time DATETIME(6) NULL COMMENT '创建时间', BIGINT
AUTO_INCREMENT
PRIMARY
KEY
COMMENT
'主键ID',
create_by
VARCHAR
(
255
) NULL COMMENT '创建人',
create_time DATETIME
(
6
) NULL COMMENT '创建时间',
deleted BIT NOT NULL DEFAULT 0 COMMENT '是否删除0未删除1已删除', deleted BIT NOT NULL DEFAULT 0 COMMENT '是否删除0未删除1已删除',
update_by VARCHAR(255) NULL COMMENT '更新人', update_by VARCHAR
update_time DATETIME(6) NULL COMMENT '更新时间', (
255
) NULL COMMENT '更新人',
update_time DATETIME
(
6
) NULL COMMENT '更新时间',
version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号', version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号',
username VARCHAR(50) NOT NULL COMMENT '用户名', username VARCHAR
password VARCHAR(255) NOT NULL COMMENT '密码', (
nickname VARCHAR(50) NULL COMMENT '昵称', 50
email VARCHAR(100) NULL COMMENT '邮箱', ) NOT NULL COMMENT '用户名',
phone VARCHAR(20) NULL COMMENT '手机号', password VARCHAR
(
255
) NOT NULL COMMENT '密码',
nickname VARCHAR
(
50
) NULL COMMENT '昵称',
email VARCHAR
(
100
) NULL COMMENT '邮箱',
phone VARCHAR
(
20
) NULL COMMENT '手机号',
department_id BIGINT NULL COMMENT '所属部门ID', department_id BIGINT NULL COMMENT '所属部门ID',
enabled BIT NOT NULL DEFAULT 1 COMMENT '是否启用0禁用1启用', enabled BIT NOT NULL DEFAULT 1 COMMENT '是否启用0禁用1启用',
CONSTRAINT UK_user_username UNIQUE
CONSTRAINT UK_user_username UNIQUE (username), (
CONSTRAINT FK_user_department FOREIGN KEY (department_id) REFERENCES sys_department(id) username
),
CONSTRAINT FK_user_department FOREIGN KEY
(
department_id
) REFERENCES sys_department
(
id
)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE =utf8mb4_unicode_ci COMMENT='用户表'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE =utf8mb4_unicode_ci COMMENT='用户表';
-- 系统参数表 -- 系统参数表
CREATE TABLE sys_param ( CREATE TABLE sys_param
(
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID', id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
create_by VARCHAR(255) NULL COMMENT '创建人', create_by VARCHAR(255) NULL COMMENT '创建人',
create_time DATETIME(6) NULL COMMENT '创建时间', create_time DATETIME(6) NULL COMMENT '创建时间',
@ -92,7 +177,8 @@ CREATE TABLE sys_param (
-- -------------------------------------------------------------------------------------- -- --------------------------------------------------------------------------------------
-- 菜单表 -- 菜单表
CREATE TABLE sys_menu ( CREATE TABLE sys_menu
(
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID', id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
create_by VARCHAR(255) NULL COMMENT '创建人', create_by VARCHAR(255) NULL COMMENT '创建人',
create_time DATETIME(6) NULL COMMENT '创建时间', create_time DATETIME(6) NULL COMMENT '创建时间',
@ -116,7 +202,8 @@ CREATE TABLE sys_menu (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='菜单表'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='菜单表';
-- 角色表 -- 角色表
CREATE TABLE sys_role ( CREATE TABLE sys_role
(
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID', id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
create_by VARCHAR(255) NULL COMMENT '创建人', create_by VARCHAR(255) NULL COMMENT '创建人',
create_time DATETIME(6) NULL COMMENT '创建时间', create_time DATETIME(6) NULL COMMENT '创建时间',
@ -135,7 +222,8 @@ CREATE TABLE sys_role (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='角色表'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='角色表';
-- 角色标签表 -- 角色标签表
CREATE TABLE sys_role_tag ( CREATE TABLE sys_role_tag
(
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID', id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
create_by VARCHAR(255) NULL COMMENT '创建人', create_by VARCHAR(255) NULL COMMENT '创建人',
create_time DATETIME(6) NULL COMMENT '创建时间', create_time DATETIME(6) NULL COMMENT '创建时间',
@ -149,7 +237,8 @@ CREATE TABLE sys_role_tag (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='角色标签表'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='角色标签表';
-- 角色标签关联表 -- 角色标签关联表
CREATE TABLE sys_role_tag_relation ( CREATE TABLE sys_role_tag_relation
(
role_id BIGINT NOT NULL COMMENT '角色ID', role_id BIGINT NOT NULL COMMENT '角色ID',
tag_id BIGINT NOT NULL COMMENT '标签ID', tag_id BIGINT NOT NULL COMMENT '标签ID',
@ -159,7 +248,8 @@ CREATE TABLE sys_role_tag_relation (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='角色标签关联表'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='角色标签关联表';
-- 用户角色关联表 -- 用户角色关联表
CREATE TABLE sys_user_role ( CREATE TABLE sys_user_role
(
user_id BIGINT NOT NULL COMMENT '用户ID', user_id BIGINT NOT NULL COMMENT '用户ID',
role_id BIGINT NOT NULL COMMENT '角色ID', role_id BIGINT NOT NULL COMMENT '角色ID',
@ -170,7 +260,8 @@ CREATE TABLE sys_user_role (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户角色关联表'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户角色关联表';
-- 角色菜单关联表 -- 角色菜单关联表
CREATE TABLE sys_role_menu ( CREATE TABLE sys_role_menu
(
role_id BIGINT NOT NULL COMMENT '角色ID', role_id BIGINT NOT NULL COMMENT '角色ID',
menu_id BIGINT NOT NULL COMMENT '菜单ID', menu_id BIGINT NOT NULL COMMENT '菜单ID',
@ -180,7 +271,8 @@ CREATE TABLE sys_role_menu (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='角色菜单关联表'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='角色菜单关联表';
-- 权限模板表 -- 权限模板表
CREATE TABLE sys_permission_template ( CREATE TABLE sys_permission_template
(
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID', id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
create_by VARCHAR(255) NULL COMMENT '创建人', create_by VARCHAR(255) NULL COMMENT '创建人',
create_time DATETIME(6) NULL COMMENT '创建时间', create_time DATETIME(6) NULL COMMENT '创建时间',
@ -199,7 +291,8 @@ CREATE TABLE sys_permission_template (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='权限模板表'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='权限模板表';
-- 模板菜单关联表 -- 模板菜单关联表
CREATE TABLE sys_template_menu ( CREATE TABLE sys_template_menu
(
template_id BIGINT NOT NULL COMMENT '模板ID', template_id BIGINT NOT NULL COMMENT '模板ID',
menu_id BIGINT NOT NULL COMMENT '菜单ID', menu_id BIGINT NOT NULL COMMENT '菜单ID',
@ -209,7 +302,8 @@ CREATE TABLE sys_template_menu (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='模板菜单关联表'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='模板菜单关联表';
-- 权限表 -- 权限表
CREATE TABLE sys_permission ( CREATE TABLE sys_permission
(
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID', id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
create_by VARCHAR(255) NULL COMMENT '创建人', create_by VARCHAR(255) NULL COMMENT '创建人',
create_time DATETIME(6) NULL COMMENT '创建时间', create_time DATETIME(6) NULL COMMENT '创建时间',
@ -234,7 +328,8 @@ CREATE TABLE sys_permission (
-- -------------------------------------------------------------------------------------- -- --------------------------------------------------------------------------------------
-- 外部系统表 -- 外部系统表
CREATE TABLE sys_external_system ( CREATE TABLE sys_external_system
(
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID', id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
create_by VARCHAR(255) NULL COMMENT '创建人', create_by VARCHAR(255) NULL COMMENT '创建人',
create_time DATETIME(6) NULL COMMENT '创建时间', create_time DATETIME(6) NULL COMMENT '创建时间',
@ -264,7 +359,8 @@ CREATE TABLE sys_external_system (
-- 代码仓库组表 -- 代码仓库组表
CREATE TABLE deploy_repo_group ( CREATE TABLE deploy_repo_group
(
-- 基础字段 -- 基础字段
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID', id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
create_by VARCHAR(100) NULL COMMENT '创建人', create_by VARCHAR(100) NULL COMMENT '创建人',
@ -289,8 +385,8 @@ CREATE TABLE deploy_repo_group (
-- 索引 -- 索引
INDEX idx_external_system_group_id (external_system_id, group_id) COMMENT '外部系统组ID索引', INDEX idx_external_system_group_id (external_system_id, group_id) COMMENT '外部系统组ID索引',
INDEX idx_parent_id (parent_id) COMMENT '父级ID索引', INDEX idx_parent_id (parent_id) COMMENT '父级ID索引',
INDEX idx_path (path) COMMENT '路径索引', INDEX idx_path ( PATH) COMMENT '路径索引',
UNIQUE INDEX uk_external_system_group_path (external_system_id, path) COMMENT '外部系统下路径唯一', UNIQUE INDEX uk_external_system_group_path (external_system_id, PATH) COMMENT '外部系统下路径唯一',
-- 外键约束 -- 外键约束
CONSTRAINT fk_group_parent FOREIGN KEY (parent_id) CONSTRAINT fk_group_parent FOREIGN KEY (parent_id)
@ -300,7 +396,8 @@ CREATE TABLE deploy_repo_group (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='代码仓库组表'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='代码仓库组表';
-- 代码仓库项目表 -- 代码仓库项目表
CREATE TABLE deploy_repo_project ( CREATE TABLE deploy_repo_project
(
-- 基础字段 -- 基础字段
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID', id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
create_by VARCHAR(100) NULL COMMENT '创建人', create_by VARCHAR(100) NULL COMMENT '创建人',
@ -329,8 +426,8 @@ CREATE TABLE deploy_repo_project (
-- 索引 -- 索引
INDEX idx_external_system_project_id (external_system_id, project_id) COMMENT '外部系统项目ID索引', INDEX idx_external_system_project_id (external_system_id, project_id) COMMENT '外部系统项目ID索引',
INDEX idx_group_id (group_id) COMMENT '组ID索引', INDEX idx_group_id (group_id) COMMENT '组ID索引',
INDEX idx_path (path) COMMENT '路径索引', INDEX idx_path ( PATH) COMMENT '路径索引',
UNIQUE INDEX uk_external_system_project_path (external_system_id, path) COMMENT '外部系统下路径唯一', UNIQUE INDEX uk_external_system_project_path (external_system_id, PATH) COMMENT '外部系统下路径唯一',
-- 外键约束 -- 外键约束
CONSTRAINT fk_project_group FOREIGN KEY (group_id) CONSTRAINT fk_project_group FOREIGN KEY (group_id)
@ -340,7 +437,8 @@ CREATE TABLE deploy_repo_project (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='代码仓库项目表'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='代码仓库项目表';
-- 代码仓库分支表 -- 代码仓库分支表
CREATE TABLE deploy_repo_branch ( CREATE TABLE deploy_repo_branch
(
-- 基础字段 -- 基础字段
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID', id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
create_by VARCHAR(100) NULL COMMENT '创建人', create_by VARCHAR(100) NULL COMMENT '创建人',
@ -368,8 +466,8 @@ CREATE TABLE deploy_repo_branch (
-- 索引 -- 索引
INDEX idx_project_id (project_id) COMMENT '项目ID索引', INDEX idx_project_id (project_id) COMMENT '项目ID索引',
INDEX idx_external_system_id (external_system_id) COMMENT '外部系统ID索引', INDEX idx_external_system_id (external_system_id) COMMENT '外部系统ID索引',
INDEX idx_name (name) COMMENT '分支名称索引', INDEX idx_name ( NAME) COMMENT '分支名称索引',
UNIQUE INDEX uk_project_branch_name (project_id, name) COMMENT '项目下分支名称唯一', UNIQUE INDEX uk_project_branch_name (project_id, NAME) COMMENT '项目下分支名称唯一',
-- 外键约束 -- 外键约束
CONSTRAINT fk_branch_project FOREIGN KEY (project_id) CONSTRAINT fk_branch_project FOREIGN KEY (project_id)
@ -391,6 +489,7 @@ CREATE TABLE workflow_definition
-- 基础信息 -- 基础信息
name VARCHAR(255) NOT NULL COMMENT '流程名称', name VARCHAR(255) NOT NULL COMMENT '流程名称',
`key` VARCHAR(255) NOT NULL COMMENT '流程标识', `key` VARCHAR(255) NOT NULL COMMENT '流程标识',
process_definition_id VARCHAR(100) NULL COMMENT '工作流定义ID',
flow_version INT NOT NULL COMMENT '流程版本', flow_version INT NOT NULL COMMENT '流程版本',
description TEXT COMMENT '流程描述', description TEXT COMMENT '流程描述',
category VARCHAR(100) COMMENT '流程分类', category VARCHAR(100) COMMENT '流程分类',
@ -420,7 +519,8 @@ CREATE TABLE workflow_definition
COLLATE = utf8mb4_unicode_ci COMMENT ='工作流定义表'; COLLATE = utf8mb4_unicode_ci COMMENT ='工作流定义表';
-- 工作流实例表 -- 工作流实例表
CREATE TABLE workflow_instance ( CREATE TABLE workflow_instance
(
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID', id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
create_by VARCHAR(255) NULL COMMENT '创建人', create_by VARCHAR(255) NULL COMMENT '创建人',
create_time DATETIME(6) NULL COMMENT '创建时间', create_time DATETIME(6) NULL COMMENT '创建时间',
@ -430,18 +530,20 @@ CREATE TABLE workflow_instance (
version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号', version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号',
process_instance_id VARCHAR(64) NOT NULL COMMENT '流程实例ID', process_instance_id VARCHAR(64) NOT NULL COMMENT '流程实例ID',
process_definition_id BIGINT NOT NULL COMMENT '流程定义ID', process_definition_id VARCHAR(64) NOT NULL COMMENT '流程定义ID',
workflow_definition_id BIGINT NOT NULL COMMENT '工作流定义ID',
business_key VARCHAR(64) NULL COMMENT '业务标识', business_key VARCHAR(64) NULL COMMENT '业务标识',
status VARCHAR(32) NOT NULL COMMENT '实例状态', status VARCHAR(32) NOT NULL COMMENT '实例状态',
variables TEXT NULL COMMENT '流程变量(JSON)', variables TEXT NULL COMMENT '流程变量(JSON)',
start_time DATETIME(6) NOT NULL COMMENT '开始时间', start_time DATETIME(6) NOT NULL COMMENT '开始时间',
end_time DATETIME(6) NULL COMMENT '结束时间', end_time DATETIME(6) NULL COMMENT '结束时间'
CONSTRAINT FK_workflow_instance_definition FOREIGN KEY (process_definition_id) REFERENCES workflow_definition(id) -- CONSTRAINT FK_workflow_instance_definition FOREIGN KEY (process_definition_id) REFERENCES workflow_definition(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='工作流实例表'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='工作流实例表';
-- 工作流节点实例表 -- 工作流节点实例表
CREATE TABLE workflow_node_instance ( CREATE TABLE workflow_node_instance
(
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID', id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
create_by VARCHAR(255) NULL COMMENT '创建人', create_by VARCHAR(255) NULL COMMENT '创建人',
create_time DATETIME(6) NULL COMMENT '创建时间', create_time DATETIME(6) NULL COMMENT '创建时间',
@ -464,7 +566,8 @@ CREATE TABLE workflow_node_instance (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='工作流节点实例表'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='工作流节点实例表';
-- 工作流日志表 -- 工作流日志表
CREATE TABLE workflow_log ( CREATE TABLE workflow_log
(
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID', id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
create_by VARCHAR(255) NULL COMMENT '创建人', create_by VARCHAR(255) NULL COMMENT '创建人',
create_time DATETIME(6) NULL COMMENT '创建时间', create_time DATETIME(6) NULL COMMENT '创建时间',
@ -484,7 +587,8 @@ CREATE TABLE workflow_log (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='工作流日志表'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='工作流日志表';
-- 创建工作流节点定义表 -- 创建工作流节点定义表
CREATE TABLE workflow_node_definition ( CREATE TABLE workflow_node_definition
(
id BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID', id BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
type VARCHAR(50) NOT NULL COMMENT '节点类型编码', type VARCHAR(50) NOT NULL COMMENT '节点类型编码',
name VARCHAR(100) NOT NULL COMMENT '节点名称', name VARCHAR(100) NOT NULL COMMENT '节点名称',
@ -500,5 +604,5 @@ CREATE TABLE workflow_node_definition (
version INT NOT NULL DEFAULT 1 COMMENT '版本号', version INT NOT NULL DEFAULT 1 COMMENT '版本号',
deleted BOOLEAN NOT NULL DEFAULT FALSE COMMENT '是否删除', deleted BOOLEAN NOT NULL DEFAULT FALSE COMMENT '是否删除',
PRIMARY KEY (id), PRIMARY KEY (id),
UNIQUE KEY uk_type (type) UNIQUE KEY uk_type (TYPE)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='工作流节点定义表'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='工作流节点定义表';

View File

@ -158,7 +158,7 @@ INSERT INTO sys_external_system (
-- 工作流定义测试数据 -- 工作流定义测试数据
INSERT INTO workflow_definition ( INSERT INTO workflow_definition (
-- 基础信息 -- 基础信息
name, `key`, flow_version, description, category, name, `key`, process_definition_id, flow_version, description, category,
-- 流程配置 -- 流程配置
graph, form_config, tags, graph, form_config, tags,
-- 流程属性 -- 流程属性
@ -168,7 +168,7 @@ INSERT INTO workflow_definition (
) VALUES ) VALUES
-- 简单脚本流程:开始 -> 脚本任务 -> 结束 -- 简单脚本流程:开始 -> 脚本任务 -> 结束
( (
'简单脚本流程', 'simple_script_flow', 1, '一个包含脚本任务的简单流程', 'test', '简单脚本流程', 'simple_script_flow', null, 1, '一个包含脚本任务的简单流程', 'test',
'{ '{
"nodes" : [ { "nodes" : [ {
"id" : "startEvent1", "id" : "startEvent1",
@ -337,7 +337,7 @@ INSERT INTO workflow_definition (
-- 复杂业务流程:开始 -> 脚本任务A -> 脚本任务B -> 结束 -- 复杂业务流程:开始 -> 脚本任务A -> 脚本任务B -> 结束
( (
'复杂业务流程', 'complex_business_flow', 1, '包含多个脚本任务节点的业务流程', 'business', '复杂业务流程', 'complex_business_flow', null, 1, '包含多个脚本任务节点的业务流程', 'business',
'{ '{
"nodes" : [ { "nodes" : [ {
"id" : "startEvent1", "id" : "startEvent1",