团队app配置增加绑定工作流
This commit is contained in:
parent
62dec088fd
commit
d59d21a062
@ -32,7 +32,6 @@ public interface WorkflowInstanceConverter extends BaseConverter<WorkflowInstanc
|
||||
* @param request 工作流启动请求
|
||||
* @param processInstance Flowable 流程实例
|
||||
* @param definition 工作流定义
|
||||
* @param formDataId 表单数据ID(可选)
|
||||
* @return 工作流实例
|
||||
*/
|
||||
@Mapping(target = "id", ignore = true)
|
||||
@ -41,10 +40,9 @@ public interface WorkflowInstanceConverter extends BaseConverter<WorkflowInstanc
|
||||
@Mapping(target = "workflowDefinitionId", source = "definition.id")
|
||||
@Mapping(target = "businessKey", source = "request.businessKey")
|
||||
@Mapping(target = "graphSnapshot", source = "definition.graph")
|
||||
@Mapping(target = "formDataId", source = "formDataId")
|
||||
@Mapping(target = "formData", ignore = true) // 在 @AfterMapping 中处理
|
||||
@Mapping(target = "variables", source = "request.variables")
|
||||
@Mapping(target = "status", constant = "NOT_STARTED")
|
||||
@Mapping(target = "startTime", ignore = true) // 在 @AfterMapping 中设置
|
||||
@Mapping(target = "startTime", expression = "java(java.time.LocalDateTime.now())")
|
||||
@Mapping(target = "endTime", ignore = true)
|
||||
@Mapping(target = "createTime", ignore = true)
|
||||
@Mapping(target = "updateTime", ignore = true)
|
||||
@ -55,25 +53,7 @@ public interface WorkflowInstanceConverter extends BaseConverter<WorkflowInstanc
|
||||
WorkflowInstance toEntity(
|
||||
WorkflowInstanceStartRequest request,
|
||||
ProcessInstance processInstance,
|
||||
WorkflowDefinition definition,
|
||||
Long formDataId
|
||||
WorkflowDefinition definition
|
||||
);
|
||||
|
||||
/**
|
||||
* 后处理:设置 formData 和 startTime
|
||||
*/
|
||||
@AfterMapping
|
||||
default void afterMapping(
|
||||
WorkflowInstanceStartRequest request,
|
||||
Long formDataId,
|
||||
@MappingTarget WorkflowInstance workflowInstance
|
||||
) {
|
||||
// ✅ 只有在没有 FormData ID 时才保存 JSON
|
||||
if (formDataId == null && request.getFormData() != null) {
|
||||
workflowInstance.setFormData(request.getFormData());
|
||||
}
|
||||
|
||||
// ✅ 设置开始时间
|
||||
workflowInstance.setStartTime(LocalDateTime.now());
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,9 +30,9 @@ public class WorkflowInstanceDTO extends BaseDTO {
|
||||
private String businessKey;
|
||||
|
||||
/**
|
||||
* 启动表单数据ID
|
||||
* 工作流定义ID
|
||||
*/
|
||||
private Long formDataId;
|
||||
private Long workflowDefinitionId;
|
||||
|
||||
/**
|
||||
* 实例状态
|
||||
@ -40,10 +40,10 @@ public class WorkflowInstanceDTO extends BaseDTO {
|
||||
private WorkflowInstanceStatusEnums status;
|
||||
|
||||
/**
|
||||
* 表单数据(JSON)
|
||||
* 存储流程启动时传入的表单变量
|
||||
* 流程变量
|
||||
* 存储所有业务数据
|
||||
*/
|
||||
private Map<String, Object> formData;
|
||||
private Map<String, Object> variables;
|
||||
|
||||
/**
|
||||
* 开始时间
|
||||
|
||||
@ -1,24 +1,29 @@
|
||||
package com.qqchen.deploy.backend.workflow.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 工作流实例启动请求
|
||||
*
|
||||
* @author qqchen
|
||||
* @since 2025-11-02
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "工作流实例启动入参")
|
||||
@Schema(description = "工作流实例启动请求")
|
||||
public class WorkflowInstanceStartRequest {
|
||||
|
||||
@Schema(description = "流程定义标识", example = "APPROVAL-AND-DEPLOYMENT")
|
||||
@Schema(description = "流程定义标识(必填)", required = true, example = "standard-deploy")
|
||||
@NotBlank(message = "流程定义标识不能为空")
|
||||
private String processKey;
|
||||
|
||||
@Schema(description = "业务键", example = "DEPLOY-2023-001")
|
||||
@Schema(description = "业务标识(必填)", required = true, example = "DEPLOY-user-service-20251102143000")
|
||||
@NotBlank(message = "业务标识不能为空")
|
||||
private String businessKey;
|
||||
|
||||
@Schema(description = "表单标识(可选,如果有则创建 FormData 记录)", example = "APPROVAL-AND-DEPLOYMENT")
|
||||
private String formKey;
|
||||
|
||||
@Schema(description = "表单数据")
|
||||
private Map<String, Object> formData;
|
||||
|
||||
@Schema(description = "流程变量(可选)", example = "{\"applicationId\":1,\"environmentId\":2,\"deployJob\":\"user-service-prod\"}")
|
||||
private Map<String, Object> variables;
|
||||
}
|
||||
|
||||
@ -46,12 +46,6 @@ public class WorkflowInstance extends Entity<Long> {
|
||||
@Column(name = "business_key")
|
||||
private String businessKey;
|
||||
|
||||
/**
|
||||
* 启动表单数据ID(外键关联form_data)
|
||||
*/
|
||||
@Column(name = "form_data_id")
|
||||
private Long formDataId;
|
||||
|
||||
/**
|
||||
* 实例状态
|
||||
*/
|
||||
@ -60,12 +54,12 @@ public class WorkflowInstance extends Entity<Long> {
|
||||
private WorkflowInstanceStatusEnums status;
|
||||
|
||||
/**
|
||||
* 表单数据(JSON)
|
||||
* 存储流程启动时传入的表单变量
|
||||
* 流程变量
|
||||
* 存储所有业务数据,如部署参数、表单数据等
|
||||
*/
|
||||
@Type(JsonType.class)
|
||||
@Column(name = "form_data", columnDefinition = "json")
|
||||
private Map<String, Object> formData;
|
||||
@Column(name = "variables", columnDefinition = "TEXT")
|
||||
private Map<String, Object> variables;
|
||||
|
||||
/**
|
||||
* 流程图数据快照(启动时保存,用于画布还原)
|
||||
|
||||
@ -19,16 +19,6 @@ import java.util.Map;
|
||||
|
||||
public interface IWorkflowInstanceService extends IBaseService<WorkflowInstance, WorkflowInstanceDTO, WorkflowInstanceQuery, Long> {
|
||||
|
||||
/**
|
||||
* 创建工作流实例并关联Flowable实例
|
||||
*
|
||||
* @param request 工作流实例启动请求
|
||||
* @param processInstance Flowable流程实例
|
||||
* @param formDataId 表单数据ID(可选,如果有则关联)
|
||||
* @return 工作流实例
|
||||
*/
|
||||
WorkflowInstanceDTO createWorkflowInstance(WorkflowInstanceStartRequest request, ProcessInstance processInstance, Long formDataId);
|
||||
|
||||
/**
|
||||
* 更新工作流实例状态
|
||||
*
|
||||
|
||||
@ -86,28 +86,6 @@ public class WorkflowInstanceServiceImpl extends BaseServiceImpl<WorkflowInstanc
|
||||
@Resource
|
||||
private WorkflowNodeInstanceConverter workflowNodeInstanceConverter;
|
||||
|
||||
@Override
|
||||
public WorkflowInstanceDTO createWorkflowInstance(WorkflowInstanceStartRequest request, ProcessInstance processInstance, Long formDataId) {
|
||||
// 1. 查询流程定义,获取 graph 快照
|
||||
WorkflowDefinition definition = workflowDefinitionRepository.findByKey(request.getProcessKey())
|
||||
.orElseThrow(() -> new RuntimeException("Workflow definition not found: " + request.getProcessKey()));
|
||||
|
||||
// 2. 使用 MapStruct Converter 创建实例(处理多源对象映射)
|
||||
WorkflowInstance workflowInstance = workflowInstanceConverter.toEntity(
|
||||
request,
|
||||
processInstance,
|
||||
definition,
|
||||
formDataId
|
||||
);
|
||||
workflowInstanceRepository.save(workflowInstance);
|
||||
|
||||
log.info("创建工作流实例: instanceId={}, definitionId={}, formDataId={}, graph已保存",
|
||||
workflowInstance.getId(), definition.getId(), formDataId);
|
||||
|
||||
// 3. 返回创建结果
|
||||
return workflowInstanceConverter.toDto(workflowInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorkflowInstance updateInstanceStatus(String processInstanceId, WorkflowInstanceStatusEnums status, LocalDateTime endTime) {
|
||||
WorkflowInstance instance = workflowInstanceRepository.findByProcessInstanceId(processInstanceId)
|
||||
@ -190,59 +168,43 @@ public class WorkflowInstanceServiceImpl extends BaseServiceImpl<WorkflowInstanc
|
||||
@Transactional
|
||||
public WorkflowInstanceDTO startWorkflow(WorkflowInstanceStartRequest request) {
|
||||
try {
|
||||
// ✅ 步骤1: 先创建 FormData(如果需要)
|
||||
FormDataDTO formData = null;
|
||||
if (request.getFormKey() != null && request.getFormData() != null && !request.getFormData().isEmpty()) {
|
||||
FormDataCreateFromWorkflowRequest formDataRequest = new FormDataCreateFromWorkflowRequest();
|
||||
formDataRequest.setFormKey(request.getFormKey());
|
||||
formDataRequest.setFormData(request.getFormData());
|
||||
formDataRequest.setBusinessKey(request.getBusinessKey());
|
||||
// 1. 查询流程定义
|
||||
WorkflowDefinition definition = workflowDefinitionRepository.findByKey(request.getProcessKey())
|
||||
.orElseThrow(() -> new RuntimeException("Workflow definition not found: " + request.getProcessKey()));
|
||||
|
||||
formData = formDataService.createFromWorkflowStart(formDataRequest);
|
||||
log.info("FormData 已创建: id={}", formData.getId());
|
||||
} else {
|
||||
log.info("FormData 创建: 跳过(无 formKey 或表单数据)");
|
||||
}
|
||||
// 2. 获取流程变量(如果没有则使用空 Map)
|
||||
Map<String, Object> variables = request.getVariables() != null ? request.getVariables() : new HashMap<>();
|
||||
|
||||
// ✅ 步骤2: 构建 Flowable 变量
|
||||
Map<String, Object> variables = buildFlowableVariables(request);
|
||||
|
||||
// ✅ 步骤3: 启动 Flowable 流程
|
||||
// 3. 启动 Flowable 流程
|
||||
ProcessInstance processInstance = runtimeService.createProcessInstanceBuilder()
|
||||
.processDefinitionKey(request.getProcessKey())
|
||||
.variables(variables)
|
||||
.businessKey(request.getBusinessKey())
|
||||
.startAsync(); // 异步启动,会自动执行 shell 任务
|
||||
.startAsync(); // 异步启动,会自动执行任务
|
||||
|
||||
log.info("Flowable 流程已启动: processInstanceId={}", processInstance.getId());
|
||||
log.info("Flowable 流程已启动: processInstanceId={}, businessKey={}",
|
||||
processInstance.getId(), request.getBusinessKey());
|
||||
|
||||
// ✅ 步骤4: 创建 WorkflowInstance 记录(关联 FormData)
|
||||
return createWorkflowInstance(request, processInstance, formData != null ? formData.getId() : null);
|
||||
// 4. 创建 WorkflowInstance 记录
|
||||
WorkflowInstance workflowInstance = workflowInstanceConverter.toEntity(
|
||||
request,
|
||||
processInstance,
|
||||
definition
|
||||
);
|
||||
workflowInstanceRepository.save(workflowInstance);
|
||||
|
||||
log.info("工作流实例已创建: instanceId={}, definitionId={}, businessKey={}",
|
||||
workflowInstance.getId(), definition.getId(), request.getBusinessKey());
|
||||
|
||||
// 5. 返回创建结果
|
||||
return workflowInstanceConverter.toDto(workflowInstance);
|
||||
} catch (Exception e) {
|
||||
log.error("启动工作流失败: processKey={}", request.getProcessKey(), e);
|
||||
log.error("启动工作流失败: processKey={}, businessKey={}",
|
||||
request.getProcessKey(), request.getBusinessKey(), e);
|
||||
throw new RuntimeException("启动工作流失败: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建 Flowable 流程变量
|
||||
*
|
||||
* @param request 工作流启动请求
|
||||
* @return Flowable 变量 Map
|
||||
*/
|
||||
private Map<String, Object> buildFlowableVariables(WorkflowInstanceStartRequest request) {
|
||||
Map<String, Object> variables = new HashMap<>();
|
||||
|
||||
// 将前端传入的 formData 包装到 "form" 变量中
|
||||
// 这样流程中的 ${form.xxx} 表达式就能正确解析
|
||||
Map<String, Object> formData = request.getFormData() != null ? request.getFormData() : new HashMap<>();
|
||||
if (!formData.isEmpty()) {
|
||||
variables.put("form", formData);
|
||||
}
|
||||
|
||||
return variables;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<WorkflowTemplateWithInstancesDTO> findTemplatesWithRecentInstances(WorkflowDefinitionQuery query) {
|
||||
Pageable pageable = PageRequest.of(query.getPageNum(), query.getPageSize());
|
||||
|
||||
@ -623,16 +623,11 @@ CREATE TABLE workflow_instance
|
||||
process_definition_id VARCHAR(64) NOT NULL COMMENT '流程定义ID',
|
||||
workflow_definition_id BIGINT NOT NULL COMMENT '工作流定义ID',
|
||||
business_key VARCHAR(64) NULL COMMENT '业务标识',
|
||||
form_data_id BIGINT NULL COMMENT '启动表单数据ID(外键关联form_data)',
|
||||
status ENUM('NOT_STARTED','CREATED','RUNNING','SUSPENDED','COMPLETED','COMPLETED_WITH_ERRORS','TERMINATED','FAILED') NOT NULL COMMENT '实例状态',
|
||||
variables TEXT NULL COMMENT '流程变量(JSON)',
|
||||
form_data JSON NULL COMMENT '表单数据(JSON)',
|
||||
variables TEXT NULL COMMENT '流程变量(JSON,包含所有业务数据)',
|
||||
graph_snapshot JSON NULL COMMENT '流程图数据快照(启动时保存,用于画布还原)',
|
||||
start_time DATETIME(6) NULL COMMENT '开始时间',
|
||||
end_time DATETIME(6) NULL COMMENT '结束时间',
|
||||
|
||||
INDEX idx_form_data_id (form_data_id),
|
||||
CONSTRAINT fk_workflow_instance_form_data FOREIGN KEY (form_data_id) REFERENCES form_data (id)
|
||||
end_time DATETIME(6) NULL COMMENT '结束时间'
|
||||
|
||||
-- CONSTRAINT FK_workflow_instance_definition FOREIGN KEY (process_definition_id) REFERENCES workflow_definition(id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='工作流实例表';
|
||||
|
||||
Loading…
Reference in New Issue
Block a user