# 表单引擎 PRD

> 产品需求文档 - 定义表单引擎的功能需求和验收标准

---

## 📋 背景与目标

### 背景

1. **现有问题**
   - 业务表单都是硬编码（如 `work-record-form.tsx`）
   - 每个新表单需要写新代码
   - 表单字段变更需要修改代码部署
   - 无法可视化配置表单

2. **业务场景**
   - **有审批流**: 加班申请、报销、采购、请假
   - **无审批流**: 信息登记、问卷调查、数据收集

### 目标

构建一个动态表单管理系统，实现：

1. **可视化搭建** - 有权限用户可拖拽方式设计表单
2. **审核发布流程** - 表单设计完成后需管理员审核，审核通过后发布
3. **数据驱动渲染** - 表单结构以 JSON Schema 存储，前端根据 Schema 动态渲染
4. **数据持久化** - 用户填写的数据经前端/后端处理后存入数据库

### ⚠️ 边界声明

> **表单引擎仅负责「表单结构定义」与「数据采集」，不负责业务含义与流程逻辑。**
>
> - ❌ 不处理业务逻辑（如：加班时长计算、报销金额限制）
> - ❌ 不负责审批流程编排（由审批引擎负责）
> - ❌ 不负责业务数据写入（由业务系统通过集成完成）
>
> 审批流程、业务规则、业务数据持久化等均通过**集成方式**完成，表单引擎仅提供数据采集能力和标准化的集成接口。

---

## 🔄 核心流程

### 表单生命周期

```
┌─────────────┐     ┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│  表单设计    │ ──> │  提交审核    │ ──> │  管理员审核  │ ──> │  对外发布    │
│  (设计者)    │     │  (设计者)    │     │  (管理员)    │     │  (系统)     │
└─────────────┘     └─────────────┘     └─────────────┘     └─────────────┘
                                               │
                                               ├── 通过 → 发布
                                               └── 驳回 → 返回修改
```

### 数据流

```
┌─────────────────────────────────────────────────────────────────────┐
│                         表单设计阶段                                 │
├─────────────────────────────────────────────────────────────────────┤
│  设计者 ──拖拽设计──> FormVersion (JSON Schema)                      │
│                              ↓                                       │
│                       保存为草稿版本                                  │
│                              ↓                                       │
│                       提交审核申请                                    │
└─────────────────────────────────────────────────────────────────────┘
                               ↓
┌─────────────────────────────────────────────────────────────────────┐
│                         审核发布阶段                                 │
├─────────────────────────────────────────────────────────────────────┤
│  管理员 ──审核──> 通过 → 版本状态变为 PUBLISHED                       │
│                       → 表单对普通用户可见                           │
└─────────────────────────────────────────────────────────────────────┘
                               ↓
┌─────────────────────────────────────────────────────────────────────┐
│                         表单使用阶段                                 │
├─────────────────────────────────────────────────────────────────────┤
│  普通用户 ──访问表单──> 前端获取 FormVersion.schema                   │
│                              ↓                                       │
│                  根据 JSON Schema 动态渲染表单                        │
│                              ↓                                       │
│                  用户填写数据，前端验证                               │
│                              ↓                                       │
│                  提交 → 后端验证 → 存入 FormInstance                 │
│                              ↓                                       │
│                  (可选) 触发审批流程 / 业务系统集成                    │
└─────────────────────────────────────────────────────────────────────┘
```

---

## 👤 用户角色与故事

### 角色定义

| 角色 | 权限 | 说明 |
|------|------|------|
| 表单设计者 | `form:design` | 可设计表单、提交审核 |
| 表单管理员 | `form:admin` | 可审核表单、发布/归档 |
| 普通用户 | `form:use` | 可填写已发布的表单 |

### 表单设计者

```
作为 表单设计者
我希望 通过拖拽方式设计表单结构
以便 无需开发人员介入即可创建新表单
```

```
作为 表单设计者
我希望 将设计好的表单提交给管理员审核
以便 确保表单质量和规范性
```

```
作为 表单设计者
我希望 管理表单的多个版本
以便 可以迭代更新表单而不影响已提交的数据
```

### 表单管理员

```
作为 表单管理员
我希望 审核设计者提交的表单
以便 确保表单符合业务规范后再发布
```

```
作为 表单管理员
我希望 可以驳回不合格的表单并说明原因
以便 设计者能够修改完善
```

```
作为 表单管理员
我希望 可以发布或归档表单
以便 控制表单的生命周期
```

### 普通用户

```
作为 普通用户
我希望 填写和提交表单
以便 完成业务申请
```

```
作为 普通用户
我希望 保存表单草稿
以便 稍后继续填写
```

```
作为 普通用户
我希望 查看我提交的表单和审批状态
以便 跟踪申请进度
```

---

## 📦 功能需求

### F1: 表单设计（设计者）

| 功能点 | 优先级 | 状态 | 说明 |
|--------|--------|------|------|
| F1.1 可视化拖拽设计 | P0 | ✅ | 拖拽字段到画布 |
| F1.2 字段属性配置 | P0 | ✅ | 配置标签、必填、验证规则 |
| F1.3 实时预览 | P0 | ✅ | 预览表单效果 |
| F1.4 保存草稿版本 | P0 | ✅ | 保存为 DRAFT 状态 |
| F1.5 提交审核 | P0 | 📋 | 提交给管理员审核 |
| F1.6 查看审核结果 | P1 | 📋 | 查看通过/驳回及原因 |

### F2: 表单审核（管理员）

| 功能点 | 优先级 | 状态 | 说明 |
|--------|--------|------|------|
| F2.1 待审核列表 | P0 | 📋 | 查看待审核的表单版本 |
| F2.2 预览表单 | P0 | 📋 | 审核前预览表单效果 |
| F2.3 审核通过 | P0 | 📋 | 通过后版本变为 PUBLISHED |
| F2.4 审核驳回 | P0 | 📋 | 驳回并填写原因 |
| F2.5 审核记录 | P1 | 📋 | 查看历史审核记录 |

### F3: 表单发布（管理员）

| 功能点 | 优先级 | 状态 | 说明 |
|--------|--------|------|------|
| F3.1 发布表单 | P0 | ✅ | 表单对普通用户可见 |
| F3.2 设置默认版本 | P0 | ✅ | 指定默认使用的版本 |
| F3.3 归档表单 | P1 | ✅ | 下线表单 |
| F3.4 版本管理 | P1 | ✅ | 管理多个版本 |

### F4: 表单使用（普通用户）

| 功能点 | 优先级 | 状态 | 说明 |
|--------|--------|------|------|
| F4.1 动态渲染表单 | P0 | ✅ | 根据 Schema 渲染 UI |
| F4.2 填写表单 | P0 | ✅ | 输入数据 |
| F4.3 前端验证 | P0 | ✅ | 实时校验输入 |
| F4.4 保存草稿 | P0 | ✅ | 暂存填写内容 |
| F4.5 提交表单 | P0 | ✅ | 后端验证后存储 |
| F4.6 我的表单 | P0 | ✅ | 查看已提交的表单 |
| F4.7 只读详情模式 | P0 | 📋 | 历史记录/审批详情只读展示 |
| F4.8 详情视图定制 | P2 | 📋 | viewSchema 支持隐藏字段/调整布局 |

### F5: 数据存储

| 功能点 | 优先级 | 状态 | 说明 |
|--------|--------|------|------|
| F5.1 Schema 版本绑定 | P0 | ✅ | 表单数据关联到具体版本 |
| F5.2 后端数据验证 | P0 | ✅ | 根据 Schema 验证数据 |
| F5.3 数据持久化 | P0 | ✅ | 存入 FormInstance |
| F5.4 软删除 | P1 | ✅ | 支持数据恢复 |
| F5.5 业务单号 | P1 | 📋 | 生成 businessKey 便于业务关联 |
| F5.6 区域支持 | P2 | 📋 | regionId 支持多区域差异化表单 |

### F6: 字段类型

#### 基础字段（P0/P1）

| 字段类型 | 优先级 | 状态 | 说明 |
|----------|--------|------|------|
| 单行文本 | P0 | ✅ | 基础文本输入 |
| 多行文本 | P0 | ✅ | 长文本输入 |
| 数字 | P0 | ✅ | 数值输入 |
| 日期/时间 | P0 | ✅ | 日期时间选择 |
| 下拉选择 | P0 | ✅ | 静态选项 |
| 单选/多选 | P0 | ✅ | Radio/Checkbox |
| 开关 | P1 | ✅ | 布尔值 |
| 文件上传 | P1 | ✅ | 附件上传 |
| 邮箱/手机 | P1 | ✅ | 格式校验 |

#### 高级字段（P2 - 规划中）

| 字段类型 | 优先级 | 状态 | 说明 |
|----------|--------|------|------|
| 动态表格（子表） | P2 | 📋 | 支持多行数据录入 |
| 计算字段 / 公式字段 | P2 | 📋 | 如 `amount = qty * price` |
| 条件显示 | P2 | 📋 | 根据其他字段值显示/隐藏 |
| 关联字段 | P2 | 📋 | 从用户、部门、字典中选择 |
| 级联选择 | P2 | 📋 | 如：国家 → 省份 → 城市 |

### F7: 审批集成（可选）

| 功能点 | 优先级 | 状态 | 说明 |
|--------|--------|------|------|
| F7.1 配置审批流程 | P1 | ✅ | 表单提交后启动审批 |
| F7.2 审批状态同步 | P1 | ✅ | 审批结果回写表单 |

---

## 🗄️ 数据模型

### 核心概念

```
FormDefinition (表单定义)
    ├── 基本信息：key, name, category, status
    ├── 权限配置：requiresApproval, approvalProcessKey
    └── 关联 FormVersion[]

FormVersion (表单版本)
    ├── 版本号：version
    ├── 表单结构：schema (JSON Schema) ← 数据化存储
    ├── 状态：DRAFT → PENDING_REVIEW → PUBLISHED / REJECTED
    ├── 审核信息：reviewedBy, reviewedAt, reviewComment
    └── 是否默认：isDefault

FormInstance (表单实例)
    ├── 关联版本：formVersionId ← 绑定具体版本（不可变）
    ├── 业务单号：businessKey ← 业务关联标识
    ├── 区域标识：regionId ← 区域隔离/差异化（规划中）
    ├── 用户数据：data (JSON)
    ├── 状态：DRAFT → SUBMITTED → APPROVED/REJECTED
    └── 创建者：createdBy
```

### 🔒 数据不可变性原则

> **FormInstance 一旦创建，`formVersionId` 不可变（除非执行数据迁移）。**
>
> 这确保了：
> - ✅ **历史可追溯** - 任何时候都能还原当时的表单结构
> - ✅ **数据一致性** - 历史数据永远按**当时所用的版本** Schema 渲染和校验
> - ✅ **审计合规** - 满足合规审计对数据不可篡改的要求
>
> **重要**：历史数据**不随最新 Schema 变化**。查看历史表单时，系统自动使用提交时绑定的版本进行渲染。

### 版本状态流转

```
DRAFT ──提交审核──> PENDING_REVIEW ──审核通过──> PUBLISHED
                         │
                         └──审核驳回──> REJECTED ──修改后重新提交──> PENDING_REVIEW
```

### Schema 与数据的关系

```
FormVersion.schema (设计时)          FormInstance.data (填写时)
┌─────────────────────────┐          ┌─────────────────────────┐
│ {                       │          │ {                       │
│   "type": "object",     │   渲染   │   "name": "张三",        │
│   "properties": {       │  ────>   │   "amount": 1500,       │
│     "name": {...},      │          │   "date": "2025-01-01"  │
│     "amount": {...},    │  <────   │ }                       │
│     "date": {...}       │   验证   │                         │
│   }                     │          │                         │
│ }                       │          │                         │
└─────────────────────────┘          └─────────────────────────┘
        ↓                                     ↓
   后端存储（不对外展示）               后端存储（业务数据）
```

### 业务单号（businessKey）

`FormInstance.businessKey` 用于与外部业务系统和审批流程关联：

| 示例 | 说明 |
|------|------|
| `overtime_2025_0001` | 加班申请单号 |
| `expense_2025_0042` | 报销单号 |
| `leave_2025_0103` | 请假单号 |

**生成规则**（可配置）：
- 格式：`{formKey}_{year}_{sequence}`
- 由后端自动生成，保证唯一性
- 可用于：审批系统关联、业务系统查询、日志追踪

---

## 📐 非功能需求

### 性能

| 指标 | 要求 |
|------|------|
| 表单渲染时间 | < 500ms |
| 设计器响应 | < 100ms |
| API 响应时间 | < 200ms |
| 支持字段数 | ≥ 100 个 |

### 可用性

| 指标 | 要求 |
|------|------|
| 浏览器支持 | Chrome/Firefox/Safari/Edge 最新版 |
| 移动端适配 | 表单填写支持，设计器仅桌面端 |
| 拖拽体验 | 流畅无卡顿 |

### 安全性

| 指标 | 要求 |
|------|------|
| 权限控制 | 基于 RBAC，分设计者/管理员/用户 |
| 数据验证 | 前后端双重验证 |
| XSS 防护 | 输入输出转义 |

---

## ✅ 验收标准

### 表单设计验收（设计者）

- [ ] 可拖拽字段到画布
- [ ] 可配置字段属性（标签、必填、验证）
- [ ] 可实时预览表单效果
- [ ] 可保存为草稿版本
- [ ] 可提交版本给管理员审核

### 表单审核验收（管理员）

- [ ] 可查看待审核表单列表
- [ ] 可预览表单效果
- [ ] 可通过审核，版本变为 PUBLISHED
- [ ] 可驳回审核，并填写驳回原因
- [ ] 可发布/归档表单

### 表单使用验收（普通用户）

- [ ] 只能看到已发布的表单
- [ ] 表单根据 Schema 动态渲染
- [ ] 可填写数据并前端验证
- [ ] 可保存草稿
- [ ] 可提交，后端验证后存储
- [ ] 可查看我的表单列表

### 数据存储验收

- [ ] Schema 存储在 FormVersion.schema
- [ ] 用户数据存储在 FormInstance.data
- [ ] FormInstance.formVersionId 创建后不可变
- [ ] 历史数据按当时版本渲染，不受新版本影响
- [ ] FormInstance 有唯一的 businessKey

---

## 📅 里程碑

| 阶段 | 内容 | 状态 |
|------|------|------|
| M1: MVP | 基础设计器、渲染、提交 | ✅ 已完成 |
| M2: 审核流程 | 版本审核、发布流程 | 📋 开发中 |
| M3: 权限完善 | 角色权限细分 | 📋 规划中 |
| M4: 高级字段 | 关联字段、级联选择、公式字段、子表 | 📋 规划中 |
| M5: 区域支持 | regionId 支持多区域差异化表单 | 📋 规划中 |
| M6: 优化 | 性能优化、移动端适配、JSONB 索引 | 📋 规划中 |

---

## 📚 相关文档

- [架构设计](ARCHITECTURE.md)
- [API 接口文档](API.md)
- [开发待办](TODO.md)
- [变更记录](CHANGELOG.md)

---

**创建日期**: 2025-11-20  
**最后更新**: 2025-12-05  
**版本**: v2.2
