团队app配置增加绑定工作流
This commit is contained in:
parent
62dec088fd
commit
d59d21a062
@ -72,4 +72,4 @@ public class PermissionApiController extends BaseController<Permission, Permissi
|
|||||||
protected void exportData(HttpServletResponse response, List<PermissionDTO> data) {
|
protected void exportData(HttpServletResponse response, List<PermissionDTO> data) {
|
||||||
// TODO: 实现导出功能
|
// TODO: 实现导出功能
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -63,8 +63,8 @@ public class UserDetailsServiceImpl implements UserDetailsService {
|
|||||||
|
|
||||||
if (!roleIds.isEmpty()) {
|
if (!roleIds.isEmpty()) {
|
||||||
permissionRepository.findByRoleIds(roleIds).stream()
|
permissionRepository.findByRoleIds(roleIds).stream()
|
||||||
.map(permission -> new SimpleGrantedAuthority(permission.getCode()))
|
.map(permission -> new SimpleGrantedAuthority(permission.getCode()))
|
||||||
.distinct()
|
.distinct()
|
||||||
.forEach(authorities::add);
|
.forEach(authorities::add);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -32,7 +32,6 @@ public interface WorkflowInstanceConverter extends BaseConverter<WorkflowInstanc
|
|||||||
* @param request 工作流启动请求
|
* @param request 工作流启动请求
|
||||||
* @param processInstance Flowable 流程实例
|
* @param processInstance Flowable 流程实例
|
||||||
* @param definition 工作流定义
|
* @param definition 工作流定义
|
||||||
* @param formDataId 表单数据ID(可选)
|
|
||||||
* @return 工作流实例
|
* @return 工作流实例
|
||||||
*/
|
*/
|
||||||
@Mapping(target = "id", ignore = true)
|
@Mapping(target = "id", ignore = true)
|
||||||
@ -41,10 +40,9 @@ public interface WorkflowInstanceConverter extends BaseConverter<WorkflowInstanc
|
|||||||
@Mapping(target = "workflowDefinitionId", source = "definition.id")
|
@Mapping(target = "workflowDefinitionId", source = "definition.id")
|
||||||
@Mapping(target = "businessKey", source = "request.businessKey")
|
@Mapping(target = "businessKey", source = "request.businessKey")
|
||||||
@Mapping(target = "graphSnapshot", source = "definition.graph")
|
@Mapping(target = "graphSnapshot", source = "definition.graph")
|
||||||
@Mapping(target = "formDataId", source = "formDataId")
|
@Mapping(target = "variables", source = "request.variables")
|
||||||
@Mapping(target = "formData", ignore = true) // 在 @AfterMapping 中处理
|
|
||||||
@Mapping(target = "status", constant = "NOT_STARTED")
|
@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 = "endTime", ignore = true)
|
||||||
@Mapping(target = "createTime", ignore = true)
|
@Mapping(target = "createTime", ignore = true)
|
||||||
@Mapping(target = "updateTime", ignore = true)
|
@Mapping(target = "updateTime", ignore = true)
|
||||||
@ -55,25 +53,7 @@ public interface WorkflowInstanceConverter extends BaseConverter<WorkflowInstanc
|
|||||||
WorkflowInstance toEntity(
|
WorkflowInstance toEntity(
|
||||||
WorkflowInstanceStartRequest request,
|
WorkflowInstanceStartRequest request,
|
||||||
ProcessInstance processInstance,
|
ProcessInstance processInstance,
|
||||||
WorkflowDefinition definition,
|
WorkflowDefinition definition
|
||||||
Long formDataId
|
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
|
||||||
* 后处理:设置 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;
|
private String businessKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 启动表单数据ID
|
* 工作流定义ID
|
||||||
*/
|
*/
|
||||||
private Long formDataId;
|
private Long workflowDefinitionId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 实例状态
|
* 实例状态
|
||||||
@ -40,10 +40,10 @@ public class WorkflowInstanceDTO extends BaseDTO {
|
|||||||
private WorkflowInstanceStatusEnums status;
|
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;
|
package com.qqchen.deploy.backend.workflow.dto;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工作流实例启动请求
|
||||||
|
*
|
||||||
|
* @author qqchen
|
||||||
|
* @since 2025-11-02
|
||||||
|
*/
|
||||||
@Data
|
@Data
|
||||||
@Schema(description = "工作流实例启动入参")
|
@Schema(description = "工作流实例启动请求")
|
||||||
public class WorkflowInstanceStartRequest {
|
public class WorkflowInstanceStartRequest {
|
||||||
|
|
||||||
@Schema(description = "流程定义标识", example = "APPROVAL-AND-DEPLOYMENT")
|
@Schema(description = "流程定义标识(必填)", required = true, example = "standard-deploy")
|
||||||
|
@NotBlank(message = "流程定义标识不能为空")
|
||||||
private String processKey;
|
private String processKey;
|
||||||
|
|
||||||
@Schema(description = "业务键", example = "DEPLOY-2023-001")
|
@Schema(description = "业务标识(必填)", required = true, example = "DEPLOY-user-service-20251102143000")
|
||||||
|
@NotBlank(message = "业务标识不能为空")
|
||||||
private String businessKey;
|
private String businessKey;
|
||||||
|
|
||||||
@Schema(description = "表单标识(可选,如果有则创建 FormData 记录)", example = "APPROVAL-AND-DEPLOYMENT")
|
@Schema(description = "流程变量(可选)", example = "{\"applicationId\":1,\"environmentId\":2,\"deployJob\":\"user-service-prod\"}")
|
||||||
private String formKey;
|
private Map<String, Object> variables;
|
||||||
|
|
||||||
@Schema(description = "表单数据")
|
|
||||||
private Map<String, Object> formData;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -46,12 +46,6 @@ public class WorkflowInstance extends Entity<Long> {
|
|||||||
@Column(name = "business_key")
|
@Column(name = "business_key")
|
||||||
private String businessKey;
|
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;
|
private WorkflowInstanceStatusEnums status;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表单数据(JSON)
|
* 流程变量
|
||||||
* 存储流程启动时传入的表单变量
|
* 存储所有业务数据,如部署参数、表单数据等
|
||||||
*/
|
*/
|
||||||
@Type(JsonType.class)
|
@Type(JsonType.class)
|
||||||
@Column(name = "form_data", columnDefinition = "json")
|
@Column(name = "variables", columnDefinition = "TEXT")
|
||||||
private Map<String, Object> formData;
|
private Map<String, Object> variables;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 流程图数据快照(启动时保存,用于画布还原)
|
* 流程图数据快照(启动时保存,用于画布还原)
|
||||||
|
|||||||
@ -19,16 +19,6 @@ import java.util.Map;
|
|||||||
|
|
||||||
public interface IWorkflowInstanceService extends IBaseService<WorkflowInstance, WorkflowInstanceDTO, WorkflowInstanceQuery, Long> {
|
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
|
@Resource
|
||||||
private WorkflowNodeInstanceConverter workflowNodeInstanceConverter;
|
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
|
@Override
|
||||||
public WorkflowInstance updateInstanceStatus(String processInstanceId, WorkflowInstanceStatusEnums status, LocalDateTime endTime) {
|
public WorkflowInstance updateInstanceStatus(String processInstanceId, WorkflowInstanceStatusEnums status, LocalDateTime endTime) {
|
||||||
WorkflowInstance instance = workflowInstanceRepository.findByProcessInstanceId(processInstanceId)
|
WorkflowInstance instance = workflowInstanceRepository.findByProcessInstanceId(processInstanceId)
|
||||||
@ -190,59 +168,43 @@ public class WorkflowInstanceServiceImpl extends BaseServiceImpl<WorkflowInstanc
|
|||||||
@Transactional
|
@Transactional
|
||||||
public WorkflowInstanceDTO startWorkflow(WorkflowInstanceStartRequest request) {
|
public WorkflowInstanceDTO startWorkflow(WorkflowInstanceStartRequest request) {
|
||||||
try {
|
try {
|
||||||
// ✅ 步骤1: 先创建 FormData(如果需要)
|
// 1. 查询流程定义
|
||||||
FormDataDTO formData = null;
|
WorkflowDefinition definition = workflowDefinitionRepository.findByKey(request.getProcessKey())
|
||||||
if (request.getFormKey() != null && request.getFormData() != null && !request.getFormData().isEmpty()) {
|
.orElseThrow(() -> new RuntimeException("Workflow definition not found: " + request.getProcessKey()));
|
||||||
FormDataCreateFromWorkflowRequest formDataRequest = new FormDataCreateFromWorkflowRequest();
|
|
||||||
formDataRequest.setFormKey(request.getFormKey());
|
|
||||||
formDataRequest.setFormData(request.getFormData());
|
|
||||||
formDataRequest.setBusinessKey(request.getBusinessKey());
|
|
||||||
|
|
||||||
formData = formDataService.createFromWorkflowStart(formDataRequest);
|
|
||||||
log.info("FormData 已创建: id={}", formData.getId());
|
|
||||||
} else {
|
|
||||||
log.info("FormData 创建: 跳过(无 formKey 或表单数据)");
|
|
||||||
}
|
|
||||||
|
|
||||||
// ✅ 步骤2: 构建 Flowable 变量
|
// 2. 获取流程变量(如果没有则使用空 Map)
|
||||||
Map<String, Object> variables = buildFlowableVariables(request);
|
Map<String, Object> variables = request.getVariables() != null ? request.getVariables() : new HashMap<>();
|
||||||
|
|
||||||
// ✅ 步骤3: 启动 Flowable 流程
|
// 3. 启动 Flowable 流程
|
||||||
ProcessInstance processInstance = runtimeService.createProcessInstanceBuilder()
|
ProcessInstance processInstance = runtimeService.createProcessInstanceBuilder()
|
||||||
.processDefinitionKey(request.getProcessKey())
|
.processDefinitionKey(request.getProcessKey())
|
||||||
.variables(variables)
|
.variables(variables)
|
||||||
.businessKey(request.getBusinessKey())
|
.businessKey(request.getBusinessKey())
|
||||||
.startAsync(); // 异步启动,会自动执行 shell 任务
|
.startAsync(); // 异步启动,会自动执行任务
|
||||||
|
|
||||||
log.info("Flowable 流程已启动: processInstanceId={}", processInstance.getId());
|
log.info("Flowable 流程已启动: processInstanceId={}, businessKey={}",
|
||||||
|
processInstance.getId(), request.getBusinessKey());
|
||||||
|
|
||||||
// ✅ 步骤4: 创建 WorkflowInstance 记录(关联 FormData)
|
// 4. 创建 WorkflowInstance 记录
|
||||||
return createWorkflowInstance(request, processInstance, formData != null ? formData.getId() : null);
|
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) {
|
} catch (Exception e) {
|
||||||
log.error("启动工作流失败: processKey={}", request.getProcessKey(), e);
|
log.error("启动工作流失败: processKey={}, businessKey={}",
|
||||||
|
request.getProcessKey(), request.getBusinessKey(), e);
|
||||||
throw new RuntimeException("启动工作流失败: " + e.getMessage(), 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
|
@Override
|
||||||
public Page<WorkflowTemplateWithInstancesDTO> findTemplatesWithRecentInstances(WorkflowDefinitionQuery query) {
|
public Page<WorkflowTemplateWithInstancesDTO> findTemplatesWithRecentInstances(WorkflowDefinitionQuery query) {
|
||||||
Pageable pageable = PageRequest.of(query.getPageNum(), query.getPageSize());
|
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',
|
process_definition_id VARCHAR(64) NOT NULL COMMENT '流程定义ID',
|
||||||
workflow_definition_id BIGINT NOT NULL COMMENT '工作流定义ID',
|
workflow_definition_id BIGINT NOT NULL COMMENT '工作流定义ID',
|
||||||
business_key VARCHAR(64) NULL COMMENT '业务标识',
|
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 '实例状态',
|
status ENUM('NOT_STARTED','CREATED','RUNNING','SUSPENDED','COMPLETED','COMPLETED_WITH_ERRORS','TERMINATED','FAILED') NOT NULL COMMENT '实例状态',
|
||||||
variables TEXT NULL COMMENT '流程变量(JSON)',
|
variables TEXT NULL COMMENT '流程变量(JSON,包含所有业务数据)',
|
||||||
form_data JSON NULL COMMENT '表单数据(JSON)',
|
|
||||||
graph_snapshot JSON NULL COMMENT '流程图数据快照(启动时保存,用于画布还原)',
|
graph_snapshot JSON NULL COMMENT '流程图数据快照(启动时保存,用于画布还原)',
|
||||||
start_time DATETIME(6) NULL COMMENT '开始时间',
|
start_time DATETIME(6) NULL COMMENT '开始时间',
|
||||||
end_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)
|
|
||||||
|
|
||||||
-- 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='工作流实例表';
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user