# 工单状态映射表

## 设计原则

项目模块（`rmdc-project-management`）与工单模块（`rmdc-work-procedure`）之间需要双向协作：
1. **项目 → 工单**：项目模块调用工单模块创建/转换工单
2. **工单 → 项目**：工单状态变更后同步更新项目生命周期状态

当前系统采用 **"模块化单体"架构**，使用 **接口注入（依赖注入）** 方式实现模块间回调。

## 填写工单 (project_detail)

| 工单事件 | 工单From状态 | 工单To状态 | 项目生命周期状态 | 说明 |
|:---|:---|:---|:---|:---|
| `create` | - | `created` | `INIT→DRAFTING` | 创建填写工单 |
| `accept` | `assigned` | `in_progress` | `DRAFTING` (保持) | 填写人开始填写 |
| `draft_save` | `in_progress` | `in_progress` | `DRAFTING` (保持) | 保存草稿 |
| `submit/complete` | `in_progress` | `pending_review` | `REVIEWING` | 提交审核 |
| `return` | `pending_review` | `returned` | `DRAFTING` | 审核人打回 |
| `resubmit` | `returned` | `pending_review` | `REVIEWING` | 重新提交 |
| `approve` | `pending_review` | `approved` | `RELEASED` | 审核通过 |
| `revoke` | any | `revoked` | `INIT` | 撤销工单 |

## 修改工单 (project_modify)

| 工单事件 | 工单From状态 | 工单To状态 | 项目生命周期状态 | 说明 |
|:---|:---|:---|:---|:---|
| `create` | - | `created` | `RELEASED→MODIFYING` | 发起修改工单 |
| `accept` | `assigned` | `in_progress` | `MODIFYING` (保持) | 开始修改 |
| `draft_save` | `in_progress` | `in_progress` | `MODIFYING` (保持) | 保存草稿 |
| `submit/complete` | `in_progress` | `pending_review` | `REVIEWING` | 提交审核 |
| `return` | `pending_review` | `returned` | `MODIFYING` | 审核人打回 |
| `resubmit` | `returned` | `pending_review` | `REVIEWING` | 重新提交 |
| `approve` | `pending_review` | `approved` | `RELEASED` | 审核通过 |
| `revoke` | any | `revoked` | `RELEASED` | 撤销工单 |

## 回调接口定义

### 项目模块提供的回调接口

```go
// ProjectLifecycleUpdater 项目生命周期状态更新接口
// 由 rmdc-core 在初始化时注入，工单模块状态变更时调用
type ProjectLifecycleUpdater interface {
    // UpdateLifecycleStatus 更新项目生命周期状态
    UpdateLifecycleStatus(projectID, lifecycleStatus string) error

    // SetLifecycleToDrafting 设置为填写中状态（工单被打回后）
    SetLifecycleToDrafting(projectID string) error

    // SetLifecycleToReviewing 设置为审核中状态（提交审核时）
    SetLifecycleToReviewing(projectID string) error

    // SetLifecycleToReleased 设置为已发布状态（审批通过时）
    SetLifecycleToReleased(projectID string) error

    // SetLifecycleToModifying 设置为变更中状态（发起修改工单时）
    SetLifecycleToModifying(projectID string) error
}
```

### 项目模块调用工单模块的接口

```go
// WorkflowTransitioner 工单状态转换接口
// 由 rmdc-core 在初始化时注入，项目模块通过此接口调用工单模块
type WorkflowTransitioner interface {
    // TransitionWorkflow 触发工单状态转换
    TransitionWorkflow(workflowID, event string, operatorID uint64,
                       operatorName string, remark string) (newStatus string, err error)
}

// WorkflowCreator 工单创建接口
type WorkflowCreator interface {
    // CreateProjectWorkflow 创建项目相关工单
    CreateProjectWorkflow(req CreateWorkflowRequest) (workflowID string, err error)
}
```

## 依赖注入流程

在 `rmdc-core/cmd/main.go` 中完成模块间的依赖注入：

```go
// 1. 初始化项目和工单服务
projectSvc := projectHandler.RegisterRoutes(r, dbs.Project, authMiddleware)
workflowSvc := workflowHandler.RegisterRoutes(r, dbs.Workflow, authMiddleware)

// 2. 注入工单→项目的回调（状态同步）
projectCallbackSvc := initProjectWorkflowCallbacks(dbs.Project)
workflowSvc.SetProjectLifecycleUpdater(projectCallbackSvc)

// 3. 注入项目→工单的调用（创建/转换工单）
workflowCreator := initProjectWorkflowCreator(workflowSvc)
projectSvc.SetWorkflowCreator(workflowCreator)

workflowTransitioner := initProjectWorkflowTransitioner(workflowSvc)
projectSvc.SetWorkflowTransitioner(workflowTransitioner)
```

## 回调处理实现

工单模块状态转换后，自动调用已注入的 `ProjectLifecycleUpdater` 接口更新项目状态：

```go
// 工单模块 - 状态转换后触发项目状态更新
func (s *WorkflowService) handleProjectLifecycleCallback(workflow *entity.Workflow, event string) {
    // 从业务载荷中获取项目ID
    projectID, ok := workflow.BusinessPayload["project_id"].(string)
    if !ok || projectID == "" {
        return
    }

    // 根据事件类型更新项目生命周期状态
    if s.projectLifecycleUpdater != nil {
        switch event {
        case entity.EventApprove:
            s.projectLifecycleUpdater.SetLifecycleToReleased(projectID)
        case entity.EventReturn:
            s.projectLifecycleUpdater.SetLifecycleToDrafting(projectID)
        case entity.EventComplete, entity.EventResubmit:
            s.projectLifecycleUpdater.SetLifecycleToReviewing(projectID)
        }
    }
}
```

## 回调处理要点

1. **幂等性**: 使用 `projectID + event + timestamp` 作为幂等键，防止重复处理
2. **事务边界**: 状态更新与版本快照生成应在同一事务
3. **审计日志**: 记录状态变更操作到 `rmdc-audit-log`
4. **错误处理**: 回调失败不应阻塞工单状态转换，记录日志后继续

## 与 HTTP 回调的对比

| 特性 | 接口注入（当前实现） | HTTP 回调 |
|:---|:---|:---|
| **模块解耦** | ⚠️ 接口级解耦 | ✅ 完全解耦 |
| **分布式支持** | ❌ 不支持 | ✅ 支持 |
| **性能** | ✅ 进程内调用 | ⚠️ 网络开销 |
| **复杂度** | ✅ 简单直接 | ⚠️ 需要重试/幂等处理 |
| **事务一致性** | ✅ 强一致性 | ⚠️ 最终一致性 |
| **适用场景** | 模块化单体架构 | 微服务架构 |

> 如果未来系统需要微服务化，可参考备选文档迁移到 HTTP 回调方案。
