diff --git a/backend/readme1.md b/backend/readme1.md new file mode 100644 index 00000000..d7135a7e --- /dev/null +++ b/backend/readme1.md @@ -0,0 +1,322 @@ +# 工作流动态表单设计方案 + +## 1. 整体架构 + +### 1.1 数据流向 +``` +1. 流程设计阶段 +┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ +│ 表单设计器 │ │ 流程设计器 │ │ 后端存储 │ +│ Form Designer │ ──> │ Flow Designer │ ──> │ Database │ +└─────────────────┘ └─────────────────┘ └─────────────────┘ + │ │ │ + │ 设计表单 │ 配置节点表单 │ 保存定义 + │ JSON Schema │ 配置数据映射 │ - 表单定义 + │ UI Schema │ 配置权限 │ - 流程定义 + ▼ ▼ ▼ + +2. 流程运行阶段 +┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ +│ 流程发起 │ │ 节点激活 │ │ 表单实例化 │ +│ Start Flow │ ──> │ Node Activated │ ──> │ Form Instance │ +└─────────────────┘ └─────────────────┘ └─────────────────┘ + │ │ + │ 触发监听器 │ 创建表单实例 + │ │ 初始化数据 + ▼ ▼ + +3. 表单处理阶段 +┌─────────────��───┐ ┌─────────────────┐ ┌─────────────────┐ +│ 表单渲染 │ │ 表单交互 │ │ 数据处理 │ +│ Form Render │ ──> │ Form Interact │ ──> │ Data Process │ +└─────────────────┘ └─────────────────┘ └─────────────────┘ + │ │ │ + │ 加载表单定义 │ 用户输入 │ 数据验证 + │ 加载实例数据 │ 数据提交 │ 数据转换 + │ 应用权限 │ │ 变量映射 + ▼ ▼ ▼ + +4. 节点完成阶段 +┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ +│ 表单提交 │ │ 节点完成 │ │ 流程推进 │ +│ Form Submit │ ──> │ Node Complete │ ──> │ Flow Progress │ +└─────────────────┘ └─────────────���───┘ └─────────────────┘ + │ │ + │ 触发监听器 │ 流转到下一节点 + │ 更新流程变量 │ + ▼ ▼ +``` + +### 1.2 数据模型设计 + +1. **表单定义(FormDefinition)** +```java +@Data +@Table(name = "workflow_form_definition") +@Entity +@LogicDelete +public class FormDefinition extends Entity { + @Column(nullable = false) + private String name; // 表单名称 + + @Column(nullable = false, unique = true) + private String code; // 表单编码 + + @Column(columnDefinition = "TEXT") + private String description; // 表单描述 + + @Type(JsonType.class) + @Column(columnDefinition = "json", nullable = false) + private JsonNode schema; // 表单JSON Schema + + @Type(JsonType.class) + @Column(columnDefinition = "json") + private JsonNode uiSchema; // UI渲染Schema + + @Column(nullable = false) + private Boolean enabled = true; // 是否启用 + + @Column(nullable = false) + private Integer version = 1; // 版本号 +} +``` + +2. **表单实例(FormInstance)** +```java +@Data +@Table(name = "workflow_form_instance") +@Entity +@LogicDelete +public class FormInstance extends Entity { + @Column(nullable = false) + private Long formDefinitionId; // 表单定义ID + + @Column(nullable = false) + private String processInstanceId; // 流程实例ID + + @Column(nullable = false) + private String taskId; // 任务ID + + @Type(JsonType.class) + @Column(columnDefinition = "json", nullable = false) + private JsonNode formData; // 表单数据 + + @Column(nullable = false) + @Enumerated(EnumType.STRING) + private FormInstanceStatus status; // 状态 +} +``` + +## 2. 节点表单集成 + +### 2.1 工作流上下文设计 +```java +@Data +public class WorkflowContext { + // 系统上下文 + private SystemContext systemContext; + // 表单上下文 + private FormContext formContext; + // 流程变量上下文 + private ProcessContext processContext; + + @Data + public static class SystemContext { + private JsonNode systemConfig; // 系统配置 + private String executionId; // 执行ID + private String processInstanceId; // 流程实例ID + private String nodeId; // 节点ID + } + + @Data + public static class FormContext { + private Long formInstanceId; // 表单实例ID + private JsonNode formData; // 表单数据 + private JsonNode formConfig; // 表单配置 + private Map mappedData; // 映射后的数据 + } + + @Data + public static class ProcessContext { + private Map variables; // 流程变量 + private Map localVariables; // 节点本地变量 + } +} +``` + +### 2.2 节点定义中的表单配置 +```java +@Data +@Table(name = "workflow_node_definition") +@Entity +@LogicDelete +public class WorkflowNodeDefinition extends Entity { + // ... 现有字段 ... + + /** + * 表单配置 + */ + @Type(JsonType.class) + @Column(columnDefinition = "json") + private JsonNode formConfig; // 节点默认的表单配置 + + /** + * 表单Schema + */ + @Type(JsonType.class) + @Column(columnDefinition = "json") + private JsonNode formSchema; // 节点默认的表单结构 + + /** + * 表单UI Schema + */ + @Type(JsonType.class) + @Column(columnDefinition = "json") + private JsonNode formUiSchema; // 节点默认的UI渲染配置 +} +``` + +## 3. 动态接口支持 + +### 3.1 表单配置中的接口定义 +```json +{ + "formSchema": { + "type": "object", + "properties": { + "department": { + "type": "string", + "title": "部门", + "enum": "@api:getDepartments", + "enumNames": "@api:getDepartmentNames" + }, + "employee": { + "type": "string", + "title": "员工", + "enum": "@api:getEmployeesByDepartment(department)", + "enumNames": "@api:getEmployeeNamesByDepartment(department)" + } + } + } +} +``` + +### 3.2 动态接口注册 +```java +@Service +public class DynamicApiRegistry { + private final Map apiRegistry = new ConcurrentHashMap<>(); + + @PostConstruct + public void init() { + // 注册系统内置API + registerSystemApis(); + } + + // 注册API + public void register(String apiKey, DynamicApi api) { + apiRegistry.put(apiKey, api); + } + + // 获取API + public DynamicApi getApi(String apiKey) { + return apiRegistry.get(apiKey); + } +} +``` + +### 3.3 动态API定义 +```java +@Data +@Builder +public class DynamicApi { + private String url; // API地址 + private HttpMethod method; // 请求方法 + private Function, Map> paramsBuilder; // 参数构建器 + private String transform; // 数据转换路径 + private Map mapping; // 数据映射 + private List dependencies; // 依赖字段 +} +``` + +## 4. 使用示例 + +### 4.1 定义节点表单 +```json +{ + "systemConfig": { + "timeout": 3600, + "retryTimes": 3, + "notifyEmail": "admin@example.com" + }, + "formConfig": { + "formSchema": { /* 表单结构 */ }, + "formUiSchema": { /* UI渲染配置 */ }, + "permissions": { /* 权限配置 */ }, + "dataMapping": { + "input": { /* 输入映射 */ }, + "output": { /* 输出映射 */ } + } + } +} +``` + +### 4.2 注册动态接口 +```java +@Component +public class CustomApiConfig { + + @Resource + private DynamicApiRegistry apiRegistry; + + @PostConstruct + public void init() { + // 注册项目查询API + apiRegistry.register("getProjects", new DynamicApi.builder() + .url("/api/v1/projects") + .method(HttpMethod.GET) + .paramsBuilder(context -> Map.of( + "departmentId", context.get("department"), + "employeeId", context.get("employee") + )) + .transform("data.list") + .mapping(Map.of("value", "id", "label", "name")) + .dependencies(List.of("department", "employee")) + .build() + ); + } +} +``` + +### 4.3 实现委派类 +```java +@Component +@Slf4j +public class ApprovalTaskDelegate extends BaseWorkflowDelegate { + + @Override + protected void doExecute(WorkflowContext context) throws Exception { + // 1. 获取表单数据 + FormContext formContext = context.getFormContext(); + Map mappedData = formContext.getMappedData(); + + String approvalResult = (String) mappedData.get("approvalResult"); + String comments = (String) mappedData.get("comments"); + + // 2. 获取系统配置 + SystemContext systemContext = context.getSystemContext(); + JsonNode systemConfig = systemContext.getSystemConfig(); + String notifyEmail = systemConfig.get("notifyEmail").asText(); + + // 3. 处理审批结果 + ProcessContext processContext = context.getProcessContext(); + processContext.getVariables().put("approved", "APPROVED".equals(approvalResult)); + processContext.getVariables().put("approvalComments", comments); + + // 4. 发送通知 + if (notifyEmail != null) { + notificationService.sendApprovalNotification(notifyEmail, approvalResult, comments); + } + } +} +``` \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/config/FlowableConfig.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/config/FlowableConfig.java index c3bfbd74..9a0ff148 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/config/FlowableConfig.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/config/FlowableConfig.java @@ -27,10 +27,10 @@ public class FlowableConfig implements EngineConfigurationConfigurer ignoredList = Arrays.asList(BOUNDARY_EVENT_ERROR_PREFIX, END_EVENT_ERROR_PREFIX); diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/listener/handler/JobEventHandler.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/listener/handler/JobEventHandler.java index 4a87132e..79283f15 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/listener/handler/JobEventHandler.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/listener/handler/JobEventHandler.java @@ -1,6 +1,8 @@ package com.qqchen.deploy.backend.workflow.listener.handler; import cn.hutool.core.date.DateUtil; +import cn.hutool.json.JSON; +import cn.hutool.json.JSONUtil; import com.qqchen.deploy.backend.workflow.enums.WorkflowNodeInstanceStatusEnums; import com.qqchen.deploy.backend.workflow.event.WorkflowNodeInstanceStatusChangeEvent; import lombok.extern.slf4j.Slf4j; @@ -34,8 +36,9 @@ public class JobEventHandler implements IFlowableEventHandler { if (!(event instanceof FlowableEngineEntityEvent entityEvent)) { return; } -// log.info("Processing job event: {}, jobType: {}", eventType, entityEvent.getType()); + log.info("Processing job event: {}, jobType: {}", eventType, entityEvent.getType()); JobEntityImpl job = (JobEntityImpl) entityEvent.getEntity(); + log.info("Processing job event: {}", JSONUtil.toJsonStr(job)); WorkflowNodeInstanceStatusEnums status = convertToNodeStatus(eventType); if (status != null) { // publisher.publishEvent(WorkflowNodeInstanceStatusChangeEvent.builder() @@ -54,11 +57,11 @@ public class JobEventHandler implements IFlowableEventHandler { private WorkflowNodeInstanceStatusEnums convertToNodeStatus(String eventType) { return switch (eventType) { - case "JOB_EXECUTION_SUCCESS" -> WorkflowNodeInstanceStatusEnums.COMPLETED; - case "JOB_EXECUTION_START" -> WorkflowNodeInstanceStatusEnums.RUNNING; - case "JOB_EXECUTION_FAILURE" -> WorkflowNodeInstanceStatusEnums.FAILED; - case "JOB_EXECUTION_REJECTED" -> WorkflowNodeInstanceStatusEnums.FAILED; - case "JOB_EXECUTION_NOJOB_FOUND" -> WorkflowNodeInstanceStatusEnums.FAILED; + case "JOB_EXECUTION_SUCCESS" -> WorkflowNodeInstanceStatusEnums.RUNNING; +// case "JOB_EXECUTION_START" -> WorkflowNodeInstanceStatusEnums.RUNNING; +// case "JOB_EXECUTION_FAILURE" -> WorkflowNodeInstanceStatusEnums.FAILED; +// case "JOB_EXECUTION_REJECTED" -> WorkflowNodeInstanceStatusEnums.FAILED; +// case "JOB_EXECUTION_NOJOB_FOUND" -> WorkflowNodeInstanceStatusEnums.FAILED; default -> null; }; } diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/service/impl/WorkflowInstanceServiceImpl.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/service/impl/WorkflowInstanceServiceImpl.java index fee4d36d..ae07886a 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/service/impl/WorkflowInstanceServiceImpl.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/service/impl/WorkflowInstanceServiceImpl.java @@ -182,6 +182,7 @@ public class WorkflowInstanceServiceImpl extends BaseServiceImpl