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 = "启动工作流实例")
@PostMapping("/start")
public Response<WorkflowInstanceCreateDTO> startWorkflow(
public Response<WorkflowInstanceDTO> startWorkflow(
@Parameter(description = "流程标识", required = true) @RequestParam String processKey,
@Parameter(description = "业务标识", required = true) @RequestParam String businessKey
) {
Map<String, Object> variables = new HashMap<>();
try {
// 同步创建实例立即返回实例ID
WorkflowInstanceCreateDTO result = workflowDefinitionService.startWorkflow(processKey, businessKey, variables);
return Response.success(result);
return Response.success(workflowDefinitionService.startWorkflow(processKey, businessKey, variables));
} catch (Exception e) {
log.error("Failed to start workflow", e);
return Response.error(ResponseCode.WORKFLOW_EXECUTION_ERROR);
@ -119,48 +117,49 @@ public class WorkflowDefinitionApiController extends BaseController<WorkflowDefi
WorkflowInstanceDTO instanceDTO = new WorkflowInstanceDTO();
// instanceDTO.setId(historicProcessInstance.getId());
instanceDTO.setProcessDefinitionId(historicProcessInstance.getProcessDefinitionId());
instanceDTO.setBusinessKey(historicProcessInstance.getBusinessKey());
instanceDTO.setStartTime(historicProcessInstance.getStartTime());
instanceDTO.setEndTime(historicProcessInstance.getEndTime());
instanceDTO.setDurationInMillis(historicProcessInstance.getDurationInMillis());
instanceDTO.setStartUserId(historicProcessInstance.getStartUserId());
instanceDTO.setStatus(historicProcessInstance.getEndTime() != null ? WorkflowInstanceStatusEnums.COMPLETED : WorkflowInstanceStatusEnums.RUNNING);
instanceDTO.setVariables(historicProcessInstance.getProcessVariables());
// 查询活动节点历史
List<HistoricActivityInstance> activities = historyService.createHistoricActivityInstanceQuery()
.processInstanceId(processInstanceId)
.orderByHistoricActivityInstanceStartTime()
.asc()
.list();
List<WorkflowInstanceDTO.ActivityInstance> activityInstances = activities.stream()
.map(activity -> {
WorkflowInstanceDTO.ActivityInstance activityInstance = new WorkflowInstanceDTO.ActivityInstance();
activityInstance.setId(activity.getId());
activityInstance.setActivityId(activity.getActivityId());
activityInstance.setActivityName(activity.getActivityName());
activityInstance.setActivityType(activity.getActivityType());
activityInstance.setStartTime(activity.getStartTime());
activityInstance.setEndTime(activity.getEndTime());
activityInstance.setDurationInMillis(activity.getDurationInMillis());
// 如果是Shell任务获取Shell相关变量
if ("serviceTask".equals(activity.getActivityType())) {
Map<String, Object> variables = historicProcessInstance.getProcessVariables();
activityInstance.setShellOutput((String) variables.get("shellOutput"));
activityInstance.setShellError((String) variables.get("shellError"));
activityInstance.setShellExitCode((Integer) variables.get("shellExitCode"));
}
return activityInstance;
})
.collect(Collectors.toList());
instanceDTO.setActivities(activityInstances);
return Response.success(instanceDTO);
// instanceDTO.setProcessDefinitionId(historicProcessInstance.getProcessDefinitionId());
// instanceDTO.setBusinessKey(historicProcessInstance.getBusinessKey());
// instanceDTO.setStartTime(historicProcessInstance.getStartTime());
// instanceDTO.setEndTime(historicProcessInstance.getEndTime());
// instanceDTO.setDurationInMillis(historicProcessInstance.getDurationInMillis());
// instanceDTO.setStartUserId(historicProcessInstance.getStartUserId());
// instanceDTO.setStatus(historicProcessInstance.getEndTime() != null ? WorkflowInstanceStatusEnums.COMPLETED : WorkflowInstanceStatusEnums.RUNNING);
// instanceDTO.setVariables(historicProcessInstance.getProcessVariables());
//
// // 查询活动节点历史
// List<HistoricActivityInstance> activities = historyService.createHistoricActivityInstanceQuery()
// .processInstanceId(processInstanceId)
// .orderByHistoricActivityInstanceStartTime()
// .asc()
// .list();
//
// List<WorkflowInstanceDTO.ActivityInstance> activityInstances = activities.stream()
// .map(activity -> {
// WorkflowInstanceDTO.ActivityInstance activityInstance = new WorkflowInstanceDTO.ActivityInstance();
// activityInstance.setId(activity.getId());
// activityInstance.setActivityId(activity.getActivityId());
// activityInstance.setActivityName(activity.getActivityName());
// activityInstance.setActivityType(activity.getActivityType());
// activityInstance.setStartTime(activity.getStartTime());
// activityInstance.setEndTime(activity.getEndTime());
// activityInstance.setDurationInMillis(activity.getDurationInMillis());
//
// // 如果是Shell任务获取Shell相关变量
// if ("serviceTask".equals(activity.getActivityType())) {
// Map<String, Object> variables = historicProcessInstance.getProcessVariables();
// activityInstance.setShellOutput((String) variables.get("shellOutput"));
// activityInstance.setShellError((String) variables.get("shellError"));
// activityInstance.setShellExitCode((Integer) variables.get("shellExitCode"));
// }
//
// return activityInstance;
// })
// .collect(Collectors.toList());
//
// instanceDTO.setActivities(activityInstances);
//
// return Response.success(instanceDTO);'
return Response.success();
}
@Operation(summary = "获取工作流执行状态")
@ -183,23 +182,24 @@ public class WorkflowDefinitionApiController extends BaseController<WorkflowDefi
.desc()
.list();
List<WorkflowInstanceDTO> instanceDTOs = historicProcessInstances.stream()
.map(historicProcessInstance -> {
WorkflowInstanceDTO instanceDTO = new WorkflowInstanceDTO();
// instanceDTO.setId(historicProcessInstance.getId());
instanceDTO.setProcessDefinitionId(historicProcessInstance.getProcessDefinitionId());
instanceDTO.setBusinessKey(historicProcessInstance.getBusinessKey());
instanceDTO.setStartTime(historicProcessInstance.getStartTime());
instanceDTO.setEndTime(historicProcessInstance.getEndTime());
instanceDTO.setDurationInMillis(historicProcessInstance.getDurationInMillis());
instanceDTO.setStartUserId(historicProcessInstance.getStartUserId());
instanceDTO.setStatus(historicProcessInstance.getEndTime() != null ? WorkflowInstanceStatusEnums.COMPLETED : WorkflowInstanceStatusEnums.RUNNING);
instanceDTO.setVariables(historicProcessInstance.getProcessVariables());
return instanceDTO;
})
.collect(Collectors.toList());
// List<WorkflowInstanceDTO> instanceDTOs = historicProcessInstances.stream()
// .map(historicProcessInstance -> {
// WorkflowInstanceDTO instanceDTO = new WorkflowInstanceDTO();
//// instanceDTO.setId(historicProcessInstance.getId());
// instanceDTO.setProcessDefinitionId(historicProcessInstance.getProcessDefinitionId());
// instanceDTO.setBusinessKey(historicProcessInstance.getBusinessKey());
// instanceDTO.setStartTime(historicProcessInstance.getStartTime());
// instanceDTO.setEndTime(historicProcessInstance.getEndTime());
// instanceDTO.setDurationInMillis(historicProcessInstance.getDurationInMillis());
// instanceDTO.setStartUserId(historicProcessInstance.getStartUserId());
// instanceDTO.setStatus(historicProcessInstance.getEndTime() != null ? WorkflowInstanceStatusEnums.COMPLETED : WorkflowInstanceStatusEnums.RUNNING);
// instanceDTO.setVariables(historicProcessInstance.getProcessVariables());
// return instanceDTO;
// })
// .collect(Collectors.toList());
return Response.success(instanceDTOs);
// return Response.success(instanceDTOs);
return Response.success();
}
@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;
import com.qqchen.deploy.backend.framework.dto.BaseDTO;
import com.qqchen.deploy.backend.workflow.enums.WorkflowInstanceStatusEnums;
import lombok.Data;
import java.time.LocalDateTime;
@Data
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();
dto.setProcessInstanceId(processInstanceId);
dto.setProcessDefinitionKey(processDefinitionKey);
dto.setBusinessKey(businessKey);
dto.setStatus("CREATING");
return dto;
}
/**
* 流程实例ID
*/
private String processInstanceId;
/**
* 流程定义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 io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Map;
@ -12,64 +14,39 @@ import java.util.Map;
@Schema(description = "工作流实例信息")
public class WorkflowInstanceDTO extends BaseDTO {
@Schema(description = "流程定义ID")
/**
* 流程实例ID
*/
private String processInstanceId;
/**
* 流程定义ID
*/
private String processDefinitionId;
@Schema(description = "业务标识")
/**
* 业务标识
*/
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;
@Data
@Schema(description = "活动节点信息")
public static class ActivityInstance {
@Schema(description = "活动ID")
private String id;
/**
* 流程变量(JSON)
*/
private String variables;
@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)
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
*/
@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 org.springframework.stereotype.Repository;
import java.util.Optional;
/**
* 工作流定义仓库
*/
@ -18,4 +20,6 @@ public interface IWorkflowDefinitionRepository extends IBaseRepository<WorkflowD
* 检查流程标识是否存在
*/
boolean existsByKeyAndDeletedFalse(String key);
Optional<WorkflowDefinition> findByKey(String businessKey);
}

View File

@ -8,7 +8,7 @@ import java.util.List;
import java.util.Optional;
@Repository
public interface WorkflowInstanceRepository extends JpaRepository<WorkflowInstance, Long> {
public interface IWorkflowInstanceRepository extends JpaRepository<WorkflowInstance, Long> {
/**
* 根据Flowable流程实例ID查询工作流实例
@ -20,8 +20,4 @@ public interface WorkflowInstanceRepository extends JpaRepository<WorkflowInstan
*/
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.WorkflowExecutionDTO;
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 org.flowable.engine.repository.Deployment;
import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.transaction.annotation.Transactional;
@ -24,7 +26,7 @@ public interface IWorkflowDefinitionService extends IBaseService<WorkflowDefinit
* @param dto 工作流定义DTO
* @return 工作流定义DTO
*/
void deployWorkflow(WorkflowDefinition workflowDefinition);
Deployment deployWorkflow(WorkflowDefinition workflowDefinition);
/**
* 启动工作流实例
@ -34,7 +36,7 @@ public interface IWorkflowDefinitionService extends IBaseService<WorkflowDefinit
* @param variables 流程变量
* @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实例
*
* @param processInstance Flowable流程实例
* @param variables 流程变量
* @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;
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.WorkflowExecutionDTO;
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.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.WorkflowStatusEnums;
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.IWorkflowInstanceService;
import com.qqchen.deploy.backend.workflow.util.BpmnConverter;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
@ -24,6 +29,7 @@ import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.bpmn.model.Process;
@ -31,6 +37,7 @@ import org.flowable.bpmn.model.FlowElement;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@ -38,7 +45,6 @@ import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 工作流定义服务实现
*/
@ -64,9 +70,12 @@ public class WorkflowDefinitionServiceImpl extends BaseServiceImpl<WorkflowDefin
@Resource
private IWorkflowDefinitionRepository workflowDefinitionRepository;
@Resource
private BpmnConverter bpmnConverter;
@Resource
private IWorkflowInstanceService workflowInstanceService;
@Override
@Transactional(rollbackFor = Exception.class)
@ -78,14 +87,15 @@ public class WorkflowDefinitionServiceImpl extends BaseServiceImpl<WorkflowDefin
@Override
@Transactional(rollbackFor = Exception.class)
public void deployWorkflow(WorkflowDefinition workflowDefinition) {
public Deployment deployWorkflow(WorkflowDefinition workflowDefinition) {
try {
// 部署流程
repositoryService.createDeployment()
Deployment deployment = repositoryService.createDeployment()
.addString(workflowDefinition.getKey() + ".bpmn20.xml", workflowDefinition.getBpmnXml())
.name(workflowDefinition.getName())
.deploy();
log.info("Successfully deployed workflow: {}", workflowDefinition.getName());
return deployment;
} catch (Exception e) {
log.error("Failed to deploy workflow: {}", workflowDefinition.getName(), e);
throw new RuntimeException("Failed to deploy workflow", e);
@ -93,25 +103,18 @@ public class WorkflowDefinitionServiceImpl extends BaseServiceImpl<WorkflowDefin
}
@Override
@Transactional
public WorkflowInstanceCreateDTO startWorkflow(String processKey, String businessKey, Map<String, Object> variables) {
@Transactional(rollbackFor = Exception.class)
public WorkflowInstanceDTO startWorkflow(String processKey, String businessKey, Map<String, Object> variables) {
try {
// 2. 创建工作流实例记录
WorkflowDefinition workflowDefinition = workflowDefinitionRepository.findByKey(processKey).orElseThrow(() -> new RuntimeException("Workflow definition process key not found: " + processKey));
// 1. 创建并异步启动流程实例
ProcessInstance processInstance = runtimeService.createProcessInstanceBuilder()
.processDefinitionKey(processKey)
.businessKey(businessKey)
.variables(variables)
.startAsync(); // 异步启动会自动执行 shell 任务
// .start();
// 2. 返回实例信息
WorkflowInstanceCreateDTO dto = new WorkflowInstanceCreateDTO();
dto.setProcessInstanceId(processInstance.getId());
dto.setProcessDefinitionKey(processKey);
dto.setBusinessKey(businessKey);
dto.setStatus("RUNNING"); // 因为实例已经在运行了
return dto;
return workflowInstanceService.createWorkflowInstance(workflowDefinition.getId(), businessKey, processInstance);
} catch (Exception e) {
log.error("Failed to create workflow: {}", processKey, 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));
WorkflowDefinitionGraph graph = definition.getGraph();
definition.setBpmnXml(bpmnConverter.convertToXml(graph, definition.getKey()));
Deployment deployment = this.deployWorkflow(definition);
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult();
definition.setStatus(WorkflowStatusEnums.PUBLISHED);
this.deployWorkflow(definition);
definition.setFlowVersion(1);
definition.setProcessDefinitionId(processDefinition.getId());
workflowDefinitionRepository.save(definition);
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.databind.ObjectMapper;
import com.qqchen.deploy.backend.workflow.converter.WorkflowInstanceConverter;
import com.qqchen.deploy.backend.workflow.dto.WorkflowInstanceDTO;
import com.qqchen.deploy.backend.workflow.entity.WorkflowInstance;
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 jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.HistoryService;
@ -25,29 +27,30 @@ import java.util.stream.Collectors;
@RequiredArgsConstructor
public class WorkflowInstanceServiceImpl implements IWorkflowInstanceService {
private final WorkflowInstanceRepository workflowInstanceRepository;
private final IWorkflowInstanceRepository workflowInstanceRepository;
private final RuntimeService runtimeService;
private final HistoryService historyService;
private final ObjectMapper objectMapper;
@Resource
private WorkflowInstanceConverter workflowInstanceConverter;
@Override
@Transactional
public WorkflowInstance createWorkflowInstance(ProcessInstance processInstance, Map<String, Object> variables) {
WorkflowInstance instance = new WorkflowInstance();
instance.setProcessInstanceId(processInstance.getId());
instance.setProcessDefinitionId(Long.valueOf(processInstance.getProcessDefinitionId().split(":")[0]));
instance.setBusinessKey(processInstance.getBusinessKey());
instance.setStatus(WorkflowInstanceStatusEnums.RUNNING);
instance.setStartTime(LocalDateTime.now());
try {
instance.setVariables(objectMapper.writeValueAsString(variables));
} catch (JsonProcessingException e) {
log.error("Failed to serialize variables", e);
instance.setVariables("{}");
}
return workflowInstanceRepository.save(instance);
public WorkflowInstanceDTO createWorkflowInstance(Long workflowDefinitionId, String businessKey, ProcessInstance processInstance) {
WorkflowInstance workflowInstance = new WorkflowInstance();
workflowInstance.setProcessInstanceId(processInstance.getId());
workflowInstance.setProcessDefinitionId(processInstance.getProcessDefinitionId());
workflowInstance.setWorkflowDefinitionId(workflowDefinitionId);
workflowInstance.setBusinessKey(businessKey);
workflowInstance.setStatus(WorkflowInstanceStatusEnums.CREATED);
workflowInstance.setStartTime(LocalDateTime.now());
workflowInstanceRepository.save(workflowInstance);
// 3. 返回创建结果
return workflowInstanceConverter.toDto(workflowInstance);
}
@Override
@ -69,42 +72,43 @@ public class WorkflowInstanceServiceImpl implements IWorkflowInstanceService {
WorkflowInstance instance = workflowInstanceRepository.findByProcessInstanceId(processInstanceId)
.orElseThrow(() -> new RuntimeException("Workflow instance not found: " + processInstanceId));
WorkflowInstanceDTO dto = new WorkflowInstanceDTO();
// dto.setId(instance.getProcessInstanceId());
dto.setProcessDefinitionId(String.valueOf(instance.getProcessDefinitionId()));
dto.setBusinessKey(instance.getBusinessKey());
dto.setStatus(instance.getStatus());
// WorkflowInstanceDTO dto = new WorkflowInstanceDTO();
//// dto.setId(instance.getProcessInstanceId());
// dto.setProcessDefinitionId(String.valueOf(instance.getProcessDefinitionId()));
// dto.setBusinessKey(instance.getBusinessKey());
// 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
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()));
return dto;
// return dto;
return null;
}
@Override
@ -135,24 +139,24 @@ public class WorkflowInstanceServiceImpl implements IWorkflowInstanceService {
workflowInstanceRepository.save(instance);
}
private WorkflowInstanceDTO.ActivityInstance convertToActivityInstance(HistoricActivityInstance hai) {
WorkflowInstanceDTO.ActivityInstance ai = new WorkflowInstanceDTO.ActivityInstance();
ai.setId(hai.getId());
ai.setActivityId(hai.getActivityId());
ai.setActivityName(hai.getActivityName());
ai.setActivityType(hai.getActivityType());
ai.setStartTime(hai.getStartTime());
ai.setEndTime(hai.getEndTime());
ai.setDurationInMillis(hai.getDurationInMillis());
// Get shell task execution details from variables if available
if ("serviceTask".equals(hai.getActivityType())) {
Map<String, Object> variables = runtimeService.getVariables(hai.getExecutionId());
ai.setShellOutput((String) variables.get("shellOutput"));
ai.setShellError((String) variables.get("shellError"));
ai.setShellExitCode((Integer) variables.get("shellExitCode"));
}
return ai;
}
// private WorkflowInstanceDTO.ActivityInstance convertToActivityInstance(HistoricActivityInstance hai) {
// WorkflowInstanceDTO.ActivityInstance ai = new WorkflowInstanceDTO.ActivityInstance();
// ai.setId(hai.getId());
// ai.setActivityId(hai.getActivityId());
// ai.setActivityName(hai.getActivityName());
// ai.setActivityType(hai.getActivityType());
// ai.setStartTime(hai.getStartTime());
// ai.setEndTime(hai.getEndTime());
// ai.setDurationInMillis(hai.getDurationInMillis());
//
// // Get shell task execution details from variables if available
// if ("serviceTask".equals(hai.getActivityType())) {
// Map<String, Object> variables = runtimeService.getVariables(hai.getExecutionId());
// ai.setShellOutput((String) variables.get("shellOutput"));
// ai.setShellError((String) variables.get("shellError"));
// ai.setShellExitCode((Integer) variables.get("shellExitCode"));
// }
//
// 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 (
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
create_by VARCHAR(255) NULL COMMENT '创建人',
create_time DATETIME(6) NULL COMMENT '创建时间',
CREATE TABLE IF NOT EXISTS sys_tenant
(
id
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已删除',
update_by VARCHAR(255) NULL COMMENT '更新人',
update_time DATETIME(6) NULL COMMENT '更新时间',
update_by VARCHAR
(
255
) NULL COMMENT '更新人',
update_time DATETIME
(
6
) NULL COMMENT '更新时间',
version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号',
code VARCHAR(50) NOT NULL COMMENT '租户编码',
name VARCHAR(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 '联系人邮箱',
code VARCHAR
(
50
) NOT NULL COMMENT '租户编码',
NAME VARCHAR
(
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启用',
CONSTRAINT UK_tenant_code UNIQUE (code)
CONSTRAINT UK_tenant_code UNIQUE
(
code
)
) 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',
create_by VARCHAR(255) 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='部门表';
-- 用户表
CREATE TABLE IF NOT EXISTS sys_user (
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
create_by VARCHAR(255) NULL COMMENT '创建人',
create_time DATETIME(6) NULL COMMENT '创建时间',
CREATE TABLE IF NOT EXISTS sys_user
(
id
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已删除',
update_by VARCHAR(255) NULL COMMENT '更新人',
update_time DATETIME(6) NULL COMMENT '更新时间',
update_by VARCHAR
(
255
) NULL COMMENT '更新人',
update_time DATETIME
(
6
) NULL COMMENT '更新时间',
version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号',
username VARCHAR(50) NOT NULL COMMENT '用户名',
password VARCHAR(255) NOT NULL COMMENT '密码',
nickname VARCHAR(50) NULL COMMENT '昵称',
email VARCHAR(100) NULL COMMENT '邮箱',
phone VARCHAR(20) NULL COMMENT '手机号',
username VARCHAR
(
50
) NOT 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',
enabled BIT NOT NULL DEFAULT 1 COMMENT '是否启用0禁用1启用',
CONSTRAINT UK_user_username UNIQUE (username),
CONSTRAINT FK_user_department FOREIGN KEY (department_id) REFERENCES sys_department(id)
CONSTRAINT UK_user_username UNIQUE
(
username
),
CONSTRAINT FK_user_department FOREIGN KEY
(
department_id
) REFERENCES sys_department
(
id
)
) 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',
create_by VARCHAR(255) 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',
create_by VARCHAR(255) 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='菜单表';
-- 角色表
CREATE TABLE sys_role (
CREATE TABLE sys_role
(
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
create_by VARCHAR(255) 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='角色表';
-- 角色标签表
CREATE TABLE sys_role_tag (
CREATE TABLE sys_role_tag
(
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
create_by VARCHAR(255) 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='角色标签表';
-- 角色标签关联表
CREATE TABLE sys_role_tag_relation (
CREATE TABLE sys_role_tag_relation
(
role_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='角色标签关联表';
-- 用户角色关联表
CREATE TABLE sys_user_role (
CREATE TABLE sys_user_role
(
user_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='用户角色关联表';
-- 角色菜单关联表
CREATE TABLE sys_role_menu (
CREATE TABLE sys_role_menu
(
role_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='角色菜单关联表';
-- 权限模板表
CREATE TABLE sys_permission_template (
CREATE TABLE sys_permission_template
(
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
create_by VARCHAR(255) 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='权限模板表';
-- 模板菜单关联表
CREATE TABLE sys_template_menu (
CREATE TABLE sys_template_menu
(
template_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='模板菜单关联表';
-- 权限表
CREATE TABLE sys_permission (
CREATE TABLE sys_permission
(
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
create_by VARCHAR(255) 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',
create_by VARCHAR(255) 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',
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_parent_id (parent_id) COMMENT '父级ID索引',
INDEX idx_path (path) COMMENT '路径索引',
UNIQUE INDEX uk_external_system_group_path (external_system_id, path) COMMENT '外部系统下路径唯一',
INDEX idx_path ( PATH) COMMENT '路径索引',
UNIQUE INDEX uk_external_system_group_path (external_system_id, PATH) COMMENT '外部系统下路径唯一',
-- 外键约束
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='代码仓库组表';
-- 代码仓库项目表
CREATE TABLE deploy_repo_project (
CREATE TABLE deploy_repo_project
(
-- 基础字段
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
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_group_id (group_id) COMMENT '组ID索引',
INDEX idx_path (path) COMMENT '路径索引',
UNIQUE INDEX uk_external_system_project_path (external_system_id, path) COMMENT '外部系统下路径唯一',
INDEX idx_path ( PATH) COMMENT '路径索引',
UNIQUE INDEX uk_external_system_project_path (external_system_id, PATH) COMMENT '外部系统下路径唯一',
-- 外键约束
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='代码仓库项目表';
-- 代码仓库分支表
CREATE TABLE deploy_repo_branch (
CREATE TABLE deploy_repo_branch
(
-- 基础字段
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
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_external_system_id (external_system_id) COMMENT '外部系统ID索引',
INDEX idx_name (name) COMMENT '分支名称索引',
UNIQUE INDEX uk_project_branch_name (project_id, name) COMMENT '项目下分支名称唯一',
INDEX idx_name ( NAME) COMMENT '分支名称索引',
UNIQUE INDEX uk_project_branch_name (project_id, NAME) COMMENT '项目下分支名称唯一',
-- 外键约束
CONSTRAINT fk_branch_project FOREIGN KEY (project_id)
@ -391,6 +489,7 @@ CREATE TABLE workflow_definition
-- 基础信息
name 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 '流程版本',
description TEXT COMMENT '流程描述',
category VARCHAR(100) COMMENT '流程分类',
@ -420,7 +519,8 @@ CREATE TABLE workflow_definition
COLLATE = utf8mb4_unicode_ci COMMENT ='工作流定义表';
-- 工作流实例表
CREATE TABLE workflow_instance (
CREATE TABLE workflow_instance
(
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
create_by VARCHAR(255) NULL COMMENT '创建人',
create_time DATETIME(6) NULL COMMENT '创建时间',
@ -430,18 +530,20 @@ CREATE TABLE workflow_instance (
version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号',
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 '业务标识',
status VARCHAR(32) NOT NULL COMMENT '实例状态',
variables TEXT NULL COMMENT '流程变量(JSON)',
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='工作流实例表';
-- 工作流节点实例表
CREATE TABLE workflow_node_instance (
CREATE TABLE workflow_node_instance
(
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
create_by VARCHAR(255) 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='工作流节点实例表';
-- 工作流日志表
CREATE TABLE workflow_log (
CREATE TABLE workflow_log
(
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
create_by VARCHAR(255) 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='工作流日志表';
-- 创建工作流节点定义表
CREATE TABLE workflow_node_definition (
CREATE TABLE workflow_node_definition
(
id BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
type VARCHAR(50) 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 '版本号',
deleted BOOLEAN NOT NULL DEFAULT FALSE COMMENT '是否删除',
PRIMARY KEY (id),
UNIQUE KEY uk_type (type)
UNIQUE KEY uk_type (TYPE)
) 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 (
-- 基础信息
name, `key`, flow_version, description, category,
name, `key`, process_definition_id, flow_version, description, category,
-- 流程配置
graph, form_config, tags,
-- 流程属性
@ -168,7 +168,7 @@ INSERT INTO workflow_definition (
) VALUES
-- 简单脚本流程:开始 -> 脚本任务 -> 结束
(
'简单脚本流程', 'simple_script_flow', 1, '一个包含脚本任务的简单流程', 'test',
'简单脚本流程', 'simple_script_flow', null, 1, '一个包含脚本任务的简单流程', 'test',
'{
"nodes" : [ {
"id" : "startEvent1",
@ -337,7 +337,7 @@ INSERT INTO workflow_definition (
-- 复杂业务流程:开始 -> 脚本任务A -> 脚本任务B -> 结束
(
'复杂业务流程', 'complex_business_flow', 1, '包含多个脚本任务节点的业务流程', 'business',
'复杂业务流程', 'complex_business_flow', null, 1, '包含多个脚本任务节点的业务流程', 'business',
'{
"nodes" : [ {
"id" : "startEvent1",