# 工作流执行器和监听器生命周期文档

## 目录
- [概述](#概述)
- [监听器分类与配置方式](#监听器分类与配置方式)
- [架构分层](#架构分层)
- [完整生命周期流程](#完整生命周期流程)
- [事件流转图](#事件流转图)
- [核心组件详解](#核心组件详解)
- [扩展指南](#扩展指南)

---

## 概述

本文档描述了工作流系统中所有执行器（Delegate）和监听器（Listener）的完整生命周期，以及事件驱动的状态同步机制。系统采用分层架构，通过事件解耦，实现业务模块的独立扩展。

### 核心设计理念

1. **事件驱动架构**：Flowable 引擎事件 → 业务事件 → 业务状态同步
2. **职责分离**：工作流模块负责流程，业务模块负责状态
3. **可扩展性**：通过监听业务事件，各业务模块可独立扩展状态同步逻辑

---

## 监听器分类与配置方式

### 为什么要在 XML 中配置监听器？

**Flowable 引擎的监听机制**：
- Flowable 引擎在解析 BPMN XML 时，会识别 XML 中配置的监听器
- 在流程执行到对应节点时，Flowable 会自动调用这些监听器
- 这是 Flowable 的标准机制，必须通过 XML 配置才能被引擎识别和调用

**配置方式分类**：

#### 1. XML 配置的监听器（Flowable 引擎自动调用）

这些监听器必须在 BPMN XML 中配置，Flowable 引擎在解析 XML 时会注册它们，并在流程执行时自动调用。

**ExecutionListener（执行监听器）**：
- 监听节点执行的开始和结束
- 配置方式：`<flowable:executionListener event="start|end" delegateExpression="${beanName}"/>`
- 触发时机：节点执行时自动触发

**TaskListener（任务监听器）**：
- 监听任务的生命周期（create、assignment、complete、delete）
- 配置方式：`<flowable:taskListener event="create" delegateExpression="${beanName}"/>`
- 触发时机：任务创建/分配/完成时自动触发

**JavaDelegate（任务委派）**：
- 执行具体的业务逻辑
- 配置方式：`<serviceTask flowable:delegateExpression="${beanName}"/>`
- 触发时机：ServiceTask 执行时自动调用

#### 2. 代码注册的监听器（Flowable 引擎事件监听）

这些监听器通过代码注册到 Flowable 引擎，监听引擎级别的事件。

**FlowableEventListener**：
- 监听 Flowable 引擎的所有事件（PROCESS_*、ACTIVITY_*、TASK_*、JOB_* 等）
- 注册方式：通过 `ProcessEngineConfiguration.addEventDispatcher()` 注册
- 触发时机：Flowable 引擎事件发生时自动触发

#### 3. Spring 事件监听器（业务事件监听）

这些监听器监听 Spring 应用事件，由业务代码发布的事件触发。

**@EventListener**：
- 监听 Spring 应用事件
- 注册方式：使用 `@EventListener` 注解，Spring 自动注册
- 触发时机：业务代码发布事件时自动触发

---

## 架构分层

### 第一层：Flowable 引擎层（代码注册）

Flowable 引擎在流程执行过程中会触发各种事件，这些事件由 `FlowableEventDispatcher` 统一分发。

#### FlowableEventDispatcher
- **注册方式**：通过 `ProcessEngineConfiguration.addEventListener()` 注册到 Flowable 引擎
- **职责**：接收 Flowable 引擎的所有事件，分发给对应的处理器
- **位置**：`workflow.event.FlowableEventDispatcher`
- **事件类型**：
  - `PROCESS_*`：流程级别事件（PROCESS_CREATED, PROCESS_STARTED, PROCESS_COMPLETED 等）
  - `ACTIVITY_*`：活动级别事件（ACTIVITY_STARTED, ACTIVITY_COMPLETED, ACTIVITY_CANCELLED 等）
  - `TASK_*`：任务级别事件（TASK_CREATED, TASK_ASSIGNED, TASK_COMPLETED 等）
  - `JOB_*`：作业级别事件（JOB_EXECUTION_SUCCESS, JOB_EXECUTION_FAILURE 等）
- **为什么代码注册**：这是 Flowable 引擎的事件分发机制，需要在引擎初始化时注册

### 第二层：Flowable 事件处理器层（代码注册）

将 Flowable 引擎事件转换为业务事件。这些处理器通过 Spring 自动注册。

#### ProcessEventHandler
- **注册方式**：通过 Spring `@Component` 自动注册到 `FlowableEventDispatcher`
- **职责**：处理流程级别事件（PROCESS_CREATED, PROCESS_STARTED, PROCESS_COMPLETED 等）
- **位置**：`workflow.event.handler.ProcessEventHandler`
- **监听事件**：`PROCESS_*` 开头的所有事件
- **状态流转**：
  - `PROCESS_CREATED` → `CREATED`
  - `PROCESS_STARTED` → `RUNNING`
  - `PROCESS_COMPLETED` → 检查节点状态 → `COMPLETED` 或 `COMPLETED_WITH_ERRORS`
  - `PROCESS_CANCELLED` → `FAILED`
  - `PROCESS_SUSPENDED` → `SUSPENDED`
- **输出事件**：`WorkflowInstanceStatusChangeEvent`
- **为什么代码注册**：这是业务事件处理器，通过 Spring 自动注册到 FlowableEventDispatcher

#### ActivityEventHandler
- **注册方式**：通过 Spring `@Component` 自动注册到 `FlowableEventDispatcher`
- **职责**：处理活动级别事件（ACTIVITY_CANCELLED, ACTIVITY_ERROR_RECEIVED 等）
- **位置**：`workflow.event.handler.ActivityEventHandler`
- **监听事件**：`ACTIVITY_*` 开头的所有事件
- **状态流转**：
  - `ACTIVITY_CANCELLED` → `TERMINATED`
  - `ACTIVITY_ERROR_RECEIVED` → `FAILED`
- **输出事件**：`WorkflowNodeInstanceStatusChangeEvent`
- **为什么代码注册**：这是业务事件处理器，通过 Spring 自动注册

#### JobEventHandler
- **注册方式**：通过 Spring `@Component` 自动注册到 `FlowableEventDispatcher`
- **职责**：处理作业级别事件（JOB_EXECUTION_SUCCESS, JOB_EXECUTION_FAILURE 等）
- **位置**：`workflow.event.handler.JobEventHandler`
- **监听事件**：`JOB_EXECUTION_*` 开头的所有事件
- **状态流转**：
  - `JOB_EXECUTION_SUCCESS` → `RUNNING`
  - `JOB_EXECUTION_FAILURE` → `FAILED` → 发布 `TerminationProcessInstanceListenerEvent`
- **为什么代码注册**：这是业务事件处理器，通过 Spring 自动注册

### 第三层：节点执行监听器层（XML 配置）

监听节点执行生命周期，管理节点实例状态。这些监听器在 BPMN XML 中配置，Flowable 引擎自动调用。

#### GlobalNodeStartEndExecutionListener
- **配置方式**：XML 中配置 `<flowable:executionListener event="start|end" delegateExpression="${globalNodeStartEndExecutionListener}"/>`
- **配置位置**：所有非网关节点（ServiceTask、UserTask、StartEvent、EndEvent 等）
- **职责**：监听所有节点的执行生命周期（start/end），发布节点状态变化事件
- **位置**：`workflow.listener.GlobalNodeStartEndExecutionListener`
- **触发时机**：
  - 节点开始执行：`EVENTNAME_START` → 发布 `WorkflowNodeInstanceStatusChangeEvent(status=RUNNING)`
  - 节点执行结束：`EVENTNAME_END` → 读取 `outputs.status` → 发布 `WorkflowNodeInstanceStatusChangeEvent(status=COMPLETED/FAILED)`
- **状态流转**：
  - `EVENTNAME_START` → `RUNNING`
  - `EVENTNAME_END` + `outputs.status=SUCCESS` → `COMPLETED`
  - `EVENTNAME_END` + `outputs.status=FAILURE` → `FAILED`
- **输出事件**：`WorkflowNodeInstanceStatusChangeEvent`
- **为什么在 XML 中配置**：Flowable 引擎需要在节点执行时自动调用，必须通过 XML 配置才能被引擎识别

#### ApprovalEndExecutionListener
- **配置方式**：XML 中配置 `<flowable:executionListener event="end" delegateExpression="${approvalEndExecutionListener}"/>`（仅审批节点）
- **配置位置**：审批节点（UserTask）的 end 事件，在 `globalNodeStartEndExecutionListener` 之前执行
- **职责**：专门处理审批节点的执行结束事件，丰富审批输出（审批用时、节点执行状态等）
- **位置**：`workflow.listener.ApprovalEndExecutionListener`
- **触发时机**：审批节点执行结束（`EVENTNAME_END`）
- **状态流转**：
  - 读取已有的 `NodeContext`（包含临时 outputs）
  - 丰富 `outputs`：设置 `approvalDuration`、`status=SUCCESS`（无论审批结果如何）
  - 保存 `NodeContext` 回流程变量
- **输出事件**：`ApprovalCompletedEvent`（包含审批结果、审批人等信息）
- **为什么在 XML 中配置**：需要在审批节点结束时自动执行，必须在 XML 中配置才能被 Flowable 引擎调用

#### GatewayStartExecutionListener
- **配置方式**：XML 中配置 `<flowable:executionListener event="start" delegateExpression="${gatewayStartExecutionListener}"/>`（仅网关节点）
- **配置位置**：网关节点（ExclusiveGateway、ParallelGateway、InclusiveGateway）
- **职责**：监听网关节点执行（start 事件），发布网关节点状态变化事件
- **位置**：`workflow.listener.GatewayStartExecutionListener`
- **触发时机**：网关节点开始执行（`EVENTNAME_START`）
- **状态流转**：发布 `WorkflowNodeInstanceStatusChangeEvent(status=COMPLETED)`
- **为什么在 XML 中配置**：网关节点需要单独处理，必须在 XML 中配置

### 第四层：任务监听器层（XML 配置）

监听任务（Task）的生命周期，配置任务属性。这些监听器在 BPMN XML 中配置，Flowable 引擎在任务创建时自动调用。

#### ApprovalCreateTaskListener
- **配置方式**：XML 中配置 `<flowable:taskListener event="create" delegateExpression="${approvalCreateTaskListener}"/>`
- **配置位置**：审批节点（UserTask）的 create 事件
- **职责**：在审批任务创建时配置审批人、任务信息等，初始化 NodeContext
- **位置**：`workflow.listener.ApprovalCreateTaskListener`
- **触发时机**：UserTask 创建时（`event="create"`）
- **状态流转**：
  - 解析 `inputMapping`（审批配置）
  - 配置审批人（从 `inputMapping.approverVariable` 解析）
  - 设置任务信息（name、description、dueDate 等）
  - 初始化 `NodeContext`（configs + inputMapping），保存到流程变量
- **输出事件**：`ApprovalTaskCreatedEvent`（包含审批人、任务信息等）
- **为什么在 XML 中配置**：需要在任务创建时自动配置审批人，必须在 XML 中配置才能被 Flowable 引擎调用

#### BaseTaskListener
- **职责**：任务监听器基类，提供通用的任务配置逻辑
- **位置**：`workflow.listener.BaseTaskListener`
- **功能**：
  - 解析 `configs` 和 `inputMapping`
  - 初始化 `NodeContext` 并保存到流程变量
  - 子类实现 `configureTask()` 方法进行具体配置

### 第五层：节点执行器层（Delegate，XML 配置）

执行具体业务逻辑的节点。这些执行器在 BPMN XML 中配置，Flowable 引擎在 ServiceTask 执行时自动调用。

#### BaseNodeDelegate
- **职责**：节点执行器基类，提供通用的节点执行逻辑
- **位置**：`workflow.delegate.BaseNodeDelegate`
- **功能**：
  - 解析 `configs` 和 `inputMapping`
  - 调用子类的 `executeInternal()` 执行具体业务逻辑
  - 创建 `NodeContext` 并保存 outputs
  - 异常处理：创建失败状态的 outputs

#### JenkinsBuildDelegate
- **配置方式**：XML 中配置 `<serviceTask flowable:delegateExpression="${jenkinsBuildDelegate}"/>`
- **配置位置**：Jenkins 构建节点（ServiceTask）
- **职责**：执行 Jenkins 构建任务
- **位置**：`workflow.delegate.JenkinsBuildDelegate`
- **继承**：`BaseNodeDelegate`
- **触发时机**：ServiceTask 执行时
- **状态流转**：
  - 调用 Jenkins API 构建任务
  - 根据构建结果设置 `outputs.status`（SUCCESS/FAILURE）
  - 保存 `NodeContext` 到流程变量
- **为什么在 XML 中配置**：需要在 ServiceTask 执行时自动调用，必须在 XML 中配置

#### ShellNodeDelegate
- **配置方式**：XML 中配置 `<serviceTask flowable:delegateExpression="${shellDelegate}"/>`
- **配置位置**：Shell 脚本节点（ServiceTask）
- **职责**：执行 Shell 脚本
- **位置**：`workflow.delegate.ShellNodeDelegate`
- **继承**：`BaseNodeDelegate`
- **为什么在 XML 中配置**：需要在 ServiceTask 执行时自动调用，必须在 XML 中配置

#### NotificationNodeDelegate
- **配置方式**：XML 中配置 `<serviceTask flowable:delegateExpression="${notificationDelegate}"/>`
- **配置位置**：通知节点（ServiceTask）
- **职责**：发送通知消息
- **位置**：`workflow.delegate.NotificationNodeDelegate`
- **继承**：`BaseNodeDelegate`
- **为什么在 XML 中配置**：需要在 ServiceTask 执行时自动调用，必须在 XML 中配置

### 第六层：业务事件监听器层（Spring 事件监听）

监听业务事件，同步业务模块状态。这些监听器通过 `@EventListener` 注解注册，监听 Spring 应用事件。

#### WorkflowInstanceStatusChangeListener
- **注册方式**：使用 `@EventListener` 注解，Spring 自动注册
- **职责**：监听工作流实例状态变化事件，更新数据库中的工作流实例状态
- **位置**：`workflow.listener.WorkflowInstanceStatusChangeListener`
- **监听事件**：`WorkflowInstanceStatusChangeEvent`
- **状态流转**：
  - 接收 `WorkflowInstanceStatusChangeEvent`
  - 调用 `workflowInstanceService.updateInstanceStatus()`
  - 更新 `WorkflowInstance.status` 和 `endTime`
- **为什么使用 Spring 事件**：解耦工作流模块和数据库操作，通过事件异步处理

#### WorkflowNodeInstanceStatusChangeListener
- **注册方式**：使用 `@EventListener` 注解，Spring 自动注册
- **职责**：监听节点实例状态变化事件，更新数据库中的节点实例状态
- **位置**：`workflow.listener.WorkflowNodeInstanceStatusChangeListener`
- **监听事件**：`WorkflowNodeInstanceStatusChangeEvent`
- **状态流转**：
  - 接收 `WorkflowNodeInstanceStatusChangeEvent`
  - 调用 `workflowNodeInstanceService.saveOrUpdateWorkflowNodeInstance()`
  - 创建或更新 `WorkflowNodeInstance`（状态、时间、变量等）
- **为什么使用 Spring 事件**：解耦节点执行监听器和数据库操作

#### DeployRecordApprovalStatusSyncListener
- **注册方式**：使用 `@EventListener` 注解，Spring 自动注册
- **职责**：监听审批相关事件，同步部署记录状态（审批阶段）
- **位置**：`deploy.listener.DeployRecordApprovalStatusSyncListener`
- **监听事件**：
  - `ApprovalTaskCreatedEvent` → 更新状态为 `PENDING_APPROVAL`
  - `ApprovalCompletedEvent` → 根据审批结果更新状态（`RUNNING` 或 `REJECTED`）
- **状态流转**：
  - `ApprovalTaskCreatedEvent` → `deployRecordService.updateStatusToPendingApproval()` → `PENDING_APPROVAL`
  - `ApprovalCompletedEvent` + `APPROVED` → `deployRecordService.updateStatusFromApproval(true)` → `RUNNING`
  - `ApprovalCompletedEvent` + `REJECTED` → `deployRecordService.updateStatusFromApproval(false)` → `REJECTED`
- **为什么使用 Spring 事件**：解耦工作流模块和部署模块，部署模块独立监听审批事件

#### DeployRecordWorkflowStatusSyncListener
- **注册方式**：使用 `@EventListener` 注解，Spring 自动注册
- **职责**：监听工作流实例状态变化事件，同步部署记录状态（工作流层面）
- **位置**：`deploy.listener.DeployRecordWorkflowStatusSyncListener`
- **监听事件**：`WorkflowInstanceStatusChangeEvent`
- **状态流转**：
  - 判断是否为部署类型工作流（通过分类 code）
  - 检查当前状态是否为终态（状态优先级保护）
  - 如果不是终态 → 调用 `deployRecordService.syncStatusFromWorkflowInstance()` → 状态映射：
    - `CREATED` → `CREATED`
    - `RUNNING` → `RUNNING`
    - `COMPLETED` → `SUCCESS`
    - `COMPLETED_WITH_ERRORS` → `PARTIAL_SUCCESS`
    - `FAILED` → `FAILED`
    - `TERMINATED` → `TERMINATED`
  - 如果是终态（如 `REJECTED`）→ 只更新 `endTime`，不更新状态
- **为什么使用 Spring 事件**：解耦工作流模块和部署模块，部署模块独立监听工作流事件

---

## 完整生命周期流程

### 场景：部署流程（包含审批节点）

#### 阶段1：工作流启动

```
1. Flowable 引擎启动流程
   ↓
2. FlowableEventDispatcher.onEvent()（代码注册，接收 Flowable 引擎事件）
   - 接收 PROCESS_STARTED 事件
   - 分发给 ProcessEventHandler
   ↓
3. ProcessEventHandler.handle()（代码注册，处理流程事件）
   - 发布 WorkflowInstanceStatusChangeEvent(status=RUNNING)
   ↓
4. WorkflowInstanceStatusChangeListener.handleWorkflowStatusChange()（Spring 事件监听）
   - 更新 WorkflowInstance.status = RUNNING
   ↓
5. DeployRecordWorkflowStatusSyncListener.handleWorkflowStatusChange()（Spring 事件监听）
   - 判断是否为部署类型工作流（通过分类 code）
   - 调用 deployRecordService.syncStatusFromWorkflowInstance()
   - 更新 DeployRecord.status = RUNNING
```

#### 阶段2：审批任务创建（已合并到阶段3）

审批任务创建在阶段3中详细说明。

#### 阶段3：审批节点执行

```
1. Flowable 引擎执行审批节点（UserTask）
   ↓
2. ApprovalCreateTaskListener.notify()（XML 配置，任务创建时）
   - 解析 inputMapping（审批配置）
   - 配置审批人（从 inputMapping.approverVariable 解析）
   - 初始化 NodeContext（configs + inputMapping），保存到流程变量
   - 发布 ApprovalTaskCreatedEvent
   ↓
3. DeployRecordApprovalStatusSyncListener.handleApprovalTaskCreated()
   - 判断是否为部署类型工作流（通过 workflowCategoryCode）
   - 调用 deployRecordService.updateStatusToPendingApproval()
   - 更新 DeployRecord.status = PENDING_APPROVAL
   ↓
4. GlobalNodeStartEndExecutionListener.notify(EVENTNAME_START)（XML 配置，节点开始执行）
   - 发布 WorkflowNodeInstanceStatusChangeEvent(status=RUNNING)
   ↓
5. WorkflowNodeInstanceStatusChangeListener.handleNodeStatusChange()
   - 创建/更新 WorkflowNodeInstance.status = RUNNING
   ↓
6. 用户完成审批任务（通过/拒绝）
   - ApprovalTaskServiceImpl.completeTask()
   - 创建临时 ApprovalOutputs（包含审批结果）
   - 保存到流程变量
   ↓
7. ApprovalEndExecutionListener.notify(EVENTNAME_END)（XML 配置，节点结束执行，在 globalNodeStartEndExecutionListener 之前）
   - 读取 NodeContext（包含临时 outputs）
   - 丰富 outputs：设置 approvalDuration、status=SUCCESS
   - 保存 NodeContext 回流程变量
   - 发布 ApprovalCompletedEvent(result=APPROVED/REJECTED, ...)
   ↓
8. GlobalNodeStartEndExecutionListener.notify(EVENTNAME_END)（XML 配置，节点结束执行）
   - 读取 outputs.status（此时已经是 SUCCESS，由 ApprovalEndExecutionListener 设置）
   - 发布 WorkflowNodeInstanceStatusChangeEvent(status=COMPLETED)
   ↓
9. WorkflowNodeInstanceStatusChangeListener.handleNodeStatusChange()
   - 更新 WorkflowNodeInstance.status = COMPLETED
   ↓
10. DeployRecordApprovalStatusSyncListener.handleApprovalCompleted()
    - 判断是否为部署类型工作流（通过 workflowCategoryCode）
    - 根据审批结果：
      * APPROVED → deployRecordService.updateStatusFromApproval(true) → RUNNING
      * REJECTED → deployRecordService.updateStatusFromApproval(false) → REJECTED（终态）
```

#### 阶段4：工作流完成

```
1. Flowable 引擎检测到流程完成
   ↓
2. FlowableEventDispatcher.onEvent()（代码注册，接收 Flowable 引擎事件）
   - 接收 PROCESS_COMPLETED 事件
   - 分发给 ProcessEventHandler
   ↓
3. ProcessEventHandler.handle()（代码注册，处理流程事件）
   - 查询所有节点实例，检查是否有失败节点
   - 如果有失败节点 → status = COMPLETED_WITH_ERRORS
   - 如果没有失败节点 → status = COMPLETED
   - 发布 WorkflowInstanceStatusChangeEvent(status=COMPLETED/COMPLETED_WITH_ERRORS)
   ↓
4. WorkflowInstanceStatusChangeListener.handleWorkflowStatusChange()（Spring 事件监听）
   - 更新 WorkflowInstance.status = COMPLETED/COMPLETED_WITH_ERRORS
   - 更新 WorkflowInstance.endTime
   ↓
5. DeployRecordWorkflowStatusSyncListener.handleWorkflowStatusChange()（Spring 事件监听）
   - 判断是否为部署类型工作流（通过分类 code）
   - 查询部署记录
   - 检查当前状态是否为终态（状态优先级保护）
     * 如果是终态（如 REJECTED）→ 只更新 endTime，不更新状态
     * 如果不是终态 → 调用 deployRecordService.syncStatusFromWorkflowInstance()
       - 状态映射：
         * COMPLETED → SUCCESS
         * COMPLETED_WITH_ERRORS → PARTIAL_SUCCESS
         * FAILED → FAILED
         * TERMINATED → TERMINATED
```

---

## 事件流转图

```
┌─────────────────────────────────────────────────────────────────┐
│                    Flowable 引擎层                                │
│  PROCESS_STARTED │ PROCESS_COMPLETED │ TASK_CREATED │ ...        │
└─────────────────────────────────────────────────────────────────┘
                            ↓
┌─────────────────────────────────────────────────────────────────┐
│              FlowableEventDispatcher (统一分发)                  │
└─────────────────────────────────────────────────────────────────┘
                            ↓
        ┌───────────────────┴───────────────────┐
        ↓                                       ↓
┌───────────────────────┐          ┌──────────────────────────┐
│ ProcessEventHandler   │          │ ApprovalCreateTaskListener │
│ (流程事件处理器)        │          │ (审批任务监听器)          │
└───────────────────────┘          └──────────────────────────┘
        ↓                                       ↓
┌───────────────────────┐          ┌──────────────────────────┐
│ WorkflowInstance      │          │ ApprovalTaskCreatedEvent │
│ StatusChangeEvent     │          └──────────────────────────┘
└───────────────────────┘                    ↓
        ↓                       ┌──────────────────────────────┐
        │                       │ DeployRecordApprovalStatus    │
        │                       │ SyncListener                  │
        │                       │ (更新为 PENDING_APPROVAL)     │
        │                       └──────────────────────────────┘
        ↓
┌─────────────────────────────────────────────────────────────────┐
│        WorkflowInstanceStatusChangeListener                      │
│        (更新 WorkflowInstance 状态)                              │
└─────────────────────────────────────────────────────────────────┘
        ↓
┌─────────────────────────────────────────────────────────────────┐
│        DeployRecordWorkflowStatusSyncListener                    │
│        (更新 DeployRecord 状态 - 工作流层面)                     │
└─────────────────────────────────────────────────────────────────┘

        ↓
┌─────────────────────────────────────────────────────────────────┐
│              GlobalNodeStartEndExecutionListener                │
│              (节点执行监听器)                                     │
└─────────────────────────────────────────────────────────────────┘
        ↓
┌─────────────────────────────────────────────────────────────────┐
│        WorkflowNodeInstanceStatusChangeListener                  │
│        (更新 WorkflowNodeInstance 状态)                          │
└─────────────────────────────────────────────────────────────────┘

        ↓ (审批节点结束时)
┌─────────────────────────────────────────────────────────────────┐
│        ApprovalEndExecutionListener                            │
│        (构建审批输出，发布 ApprovalCompletedEvent)               │
└─────────────────────────────────────────────────────────────────┘
        ↓
┌─────────────────────────────────────────────────────────────────┐
│        DeployRecordApprovalStatusSyncListener                    │
│        (根据审批结果更新 DeployRecord 状态)                      │
│        APPROVED → RUNNING                                       │
│        REJECTED → CANCELLED                                     │
└─────────────────────────────────────────────────────────────────┘
```

---

## 核心组件详解

### 1. 状态同步优先级机制

#### 设计目的
确保审批拒绝后的状态不会被后续工作流完成事件覆盖。

#### 实现位置
`DeployRecordServiceImpl.syncStatusFromWorkflowInstance()`

#### 逻辑
```java
// 如果当前状态已经是终态（特别是审批被拒绝的CANCELLED），不应该被覆盖
if (isFinalState(record.getStatus())) {
    // 只更新时间，不更新状态
    if (instance.getEndTime() != null && record.getEndTime() == null) {
        record.setEndTime(instance.getEndTime());
    }
    return;
}
```

#### 终态定义
- `SUCCESS`
- `FAILED`
- `CANCELLED`
- `TERMINATED`
- `PARTIAL_SUCCESS`

### 2. 事件过滤机制

#### DeployRecordApprovalStatusSyncListener
```java
// 在方法开始就判断，避免不必要的数据库操作
if (!isDeploymentWorkflow(event.getWorkflowCategoryCode())) {
    return;
}
```

#### DeployRecordWorkflowStatusSyncListener
```java
// 查询 WorkflowInstance 后立即判断
WorkflowInstance instance = workflowInstanceRepository.findByProcessInstanceId(...);
if (!isDeploymentWorkflow(instance)) {
    return;
}
```

### 3. 事务管理

所有业务监听器使用 `@Transactional(propagation = Propagation.REQUIRES_NEW)`，确保：
- 独立事务，不影响主流程
- 异常不影响工作流执行
- 状态同步的原子性

---

## 扩展指南

### 扩展其他领域的审批同步

#### 场景示例：订单审批流程

假设需要为订单系统添加审批状态同步功能。

#### 步骤1：创建订单审批状态同步监听器

创建文件：`order/listener/OrderApprovalStatusSyncListener.java`

```java
package com.qqchen.deploy.backend.order.listener;

import com.qqchen.deploy.backend.order.service.IOrderService;
import com.qqchen.deploy.backend.workflow.dto.event.ApprovalTaskCreatedEvent;
import com.qqchen.deploy.backend.workflow.dto.event.ApprovalCompletedEvent;
import com.qqchen.deploy.backend.workflow.enums.ApprovalResultEnum;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Slf4j
@Component
public class OrderApprovalStatusSyncListener {

    private static final String ORDER_CATEGORY_CODE = "ORDER";

    @Resource
    private IOrderService orderService;

    /**
     * 监听审批任务创建事件
     */
    @EventListener
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void handleApprovalTaskCreated(ApprovalTaskCreatedEvent event) {
        // 判断是否为订单类型的工作流
        if (!ORDER_CATEGORY_CODE.equals(event.getWorkflowCategoryCode())) {
            return;
        }

        try {
            log.debug("处理订单审批任务创建事件: workflowInstanceId={}", 
                    event.getWorkflowInstanceId());
            
            // 更新订单状态为待审批
            orderService.updateStatusToPendingApproval(event.getWorkflowInstanceId());
            
            log.info("订单状态已更新为待审批: workflowInstanceId={}", 
                    event.getWorkflowInstanceId());
        } catch (Exception e) {
            log.error("同步订单状态失败（审批任务创建）: workflowInstanceId={}", 
                    event.getWorkflowInstanceId(), e);
        }
    }

    /**
     * 监听审批完成事件
     */
    @EventListener
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void handleApprovalCompleted(ApprovalCompletedEvent event) {
        // 判断是否为订单类型的工作流
        if (!ORDER_CATEGORY_CODE.equals(event.getWorkflowCategoryCode())) {
            return;
        }

        try {
            log.debug("处理订单审批完成事件: workflowInstanceId={}, result={}", 
                    event.getWorkflowInstanceId(), event.getResult());
            
            // 根据审批结果更新订单状态
            if (event.getResult() == ApprovalResultEnum.APPROVED) {
                orderService.updateStatusFromApproval(event.getWorkflowInstanceId(), true);
            } else if (event.getResult() == ApprovalResultEnum.REJECTED) {
                orderService.updateStatusFromApproval(event.getWorkflowInstanceId(), false);
            }
            
            log.info("订单状态已同步（审批完成）: workflowInstanceId={}, result={}", 
                    event.getWorkflowInstanceId(), event.getResult());
        } catch (Exception e) {
            log.error("同步订单状态失败（审批完成）: workflowInstanceId={}", 
                    event.getWorkflowInstanceId(), e);
        }
    }
}
```

#### 步骤2：创建订单工作流状态同步监听器

创建文件：`order/listener/OrderWorkflowStatusSyncListener.java`

```java
package com.qqchen.deploy.backend.order.listener;

import com.qqchen.deploy.backend.order.service.IOrderService;
import com.qqchen.deploy.backend.workflow.dto.event.WorkflowInstanceStatusChangeEvent;
import com.qqchen.deploy.backend.workflow.entity.WorkflowInstance;
import com.qqchen.deploy.backend.workflow.repository.IWorkflowInstanceRepository;
import com.qqchen.deploy.backend.workflow.repository.IWorkflowDefinitionRepository;
import com.qqchen.deploy.backend.workflow.repository.IWorkflowCategoryRepository;
import com.qqchen.deploy.backend.workflow.entity.WorkflowDefinition;
import com.qqchen.deploy.backend.workflow.entity.WorkflowCategory;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Slf4j
@Component
public class OrderWorkflowStatusSyncListener {

    private static final String ORDER_CATEGORY_CODE = "ORDER";

    @Resource
    private IOrderService orderService;

    @Resource
    private IWorkflowInstanceRepository workflowInstanceRepository;

    @Resource
    private IWorkflowDefinitionRepository workflowDefinitionRepository;

    @Resource
    private IWorkflowCategoryRepository workflowCategoryRepository;

    @EventListener
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void handleWorkflowStatusChange(WorkflowInstanceStatusChangeEvent event) {
        try {
            // 1. 查询工作流实例
            WorkflowInstance instance = workflowInstanceRepository
                    .findByProcessInstanceId(event.getProcessInstanceId())
                    .orElse(null);

            if (instance == null) {
                log.warn("工作流实例不存在: processInstanceId={}", event.getProcessInstanceId());
                return;
            }

            // 2. 判断是否为订单类型的工作流（提前校验）
            if (!isOrderWorkflow(instance)) {
                return;
            }

            // 3. 更新工作流实例的结束时间
            if (event.getEndTime() != null && instance.getEndTime() == null) {
                instance.setEndTime(event.getEndTime());
                workflowInstanceRepository.save(instance);
            }

            // 4. 同步订单状态
            orderService.syncStatusFromWorkflowInstance(instance, event.getStatus());

        } catch (Exception e) {
            log.error("同步订单状态失败（工作流状态变化）: processInstanceId={}", 
                    event.getProcessInstanceId(), e);
        }
    }

    /**
     * 判断是否为订单类型的工作流
     */
    private boolean isOrderWorkflow(WorkflowInstance instance) {
        if (instance.getWorkflowDefinitionId() == null) {
            return false;
        }

        WorkflowDefinition definition = workflowDefinitionRepository
                .findById(instance.getWorkflowDefinitionId())
                .orElse(null);

        if (definition == null || definition.getCategoryId() == null) {
            return false;
        }

        WorkflowCategory category = workflowCategoryRepository
                .findById(definition.getCategoryId())
                .orElse(null);

        return category != null && ORDER_CATEGORY_CODE.equals(category.getCode());
    }
}
```

#### 步骤3：在 OrderService 中添加状态同步方法

```java
public interface IOrderService {
    /**
     * 更新订单状态为待审批
     */
    void updateStatusToPendingApproval(Long workflowInstanceId);

    /**
     * 根据审批结果更新订单状态
     */
    void updateStatusFromApproval(Long workflowInstanceId, boolean approved);

    /**
     * 根据工作流实例同步订单状态
     */
    void syncStatusFromWorkflowInstance(WorkflowInstance instance, WorkflowInstanceStatusEnums status);
}
```

#### 步骤4：配置工作流分类

在数据库中添加订单类型的工作流分类：
```sql
INSERT INTO workflow_category (code, name, ...) VALUES ('ORDER', '订单流程', ...);
```

### 扩展要点总结

1. **遵循命名规范**：
   - 监听器：`{业务模块}ApprovalStatusSyncListener`
   - 监听器：`{业务模块}WorkflowStatusSyncListener`

2. **事件过滤**：
   - 必须通过 `workflowCategoryCode` 或 `isXXXWorkflow()` 判断
   - 避免处理不相关的工作流事件

3. **事务管理**：
   - 使用 `@Transactional(propagation = Propagation.REQUIRES_NEW)`
   - 确保异常不影响主流程

4. **状态优先级**：
   - 在 `syncStatusFromWorkflowInstance()` 中实现终态保护
   - 审批拒绝的状态优先级高于工作流完成状态

5. **日志记录**：
   - 记录关键状态转换
   - 异常时记录详细错误信息

---

## 总结

### 架构优势

1. **完全解耦**：工作流模块不依赖业务模块，只发布事件
2. **易于扩展**：新增业务模块只需添加监听器，无需修改工作流代码
3. **状态准确**：通过状态优先级机制，确保最终状态正确
4. **性能优化**：通过事件过滤，避免不必要的数据库操作

### 关键设计模式

1. **事件驱动架构**：通过事件解耦各模块
2. **监听器模式**：业务模块监听工作流事件
3. **策略模式**：不同业务模块实现不同的状态同步策略
4. **责任链模式**：事件在监听器链中传递处理

### 注意事项

1. **事件顺序**：审批事件可能在工作流事件之前或之后触发，需要状态优先级保护
2. **并发安全**：使用乐观锁（@Version）防止并发更新冲突
3. **异常处理**：监听器异常不应影响工作流执行
4. **性能考虑**：避免在监听器中执行耗时操作

---

**文档版本**：v1.0  
**最后更新**：2025-11-04  
**维护者**：开发团队

