# CRM 客户管理系统 — OpenYida 完整示例应用

> OpenYida 的 "TodoMVC"：一个覆盖全部核心能力的标准基准应用

## 产品定位

CRM 客户管理系统是 OpenYida 的标杆应用——就像 TodoMVC 之于前端框架。选择 CRM 作为基准应用，是因为它天然覆盖企业应用的全部核心场景：多实体关联（客户→商机→合同）、审批流程（合同/报销）、数据看板（销售漏斗）、批量操作（数据录入）、外部集成（API 连接器）。通过构建这一个应用，即可验证 OpenYida 的 19 种字段类型和 14 大功能模块。

## 应用架构总览

### 模块组成

| 类型 | 数量 | 明细 |
|------|------|------|
| 应用 | 1 | CRM 客户管理系统 |
| 表单 | 5 | 客户信息表、商机管理表、合同审批表、费用报销表、客户回访表 |
| 流程 | 2 | 合同审批流程（条件分支）、费用报销流程（顺序审批） |
| 自定义页面 | 2 | CRM 销售仪表盘、批量数据录入 |
| 报表 | 1 | 销售分析报表（6 种图表 + 筛选器） |
| 连接器 | 1 | 外部用户查询 API（BasicAuth） |
| 页面分享 | 1 | 组织内短链分享 |

### 字段类型覆盖（19 种）

| 字段类型 | ComponentName | 使用位置 |
|----------|---------------|----------|
| 流水号 | SerialNumberField | 客户、商机、合同、费用报销 |
| 单行文本 | TextField | 客户、商机、合同 |
| 多行文本 | TextareaField | 客户、商机、合同、费用报销、回访 |
| 数字 | NumberField | 商机、合同、费用报销 |
| 下拉单选 | SelectField | 客户、商机、合同、费用报销 |
| 单选 | RadioField | 客户、商机、回访 |
| 下拉多选 | MultiSelectField | 客户 |
| 复选框 | CheckboxField | 回访 |
| 日期 | DateField | 商机、合同、回访 |
| 日期区间 | CascadeDateField | 合同 |
| 成员 | EmployeeField | 客户、商机、合同、费用报销、回访 |
| 部门 | DepartmentSelectField | 费用报销 |
| 地址 | AddressField | 客户 |
| 国家/地区 | CountrySelectField | 回访 |
| 附件 | AttachmentField | 客户、合同 |
| 图片 | ImageField | 商机 |
| 评分 | RateField | 回访 |
| 子表 | TableField | 客户、商机、费用报销 |
| 关联表单 | AssociationFormField | 商机、合同、费用报销、回访 |

---

## 一、表单设计

### 1.1 客户信息表（普通表单）

基础信息表，作为其他表单的关联数据源。

| 字段名 | ComponentName | 必填 | 说明 |
|--------|---------------|------|------|
| 客户编号 | SerialNumberField | 自动 | 规则：`CUS-yyyyMMdd-0001`，永不重置 |
| 客户名称 | TextField | ✓ | 主字段，用于关联表单显示 |
| 客户类型 | RadioField | | 选项：企业客户、个人客户 |
| 客户级别 | SelectField | | 选项：A级、B级、C级、D级 |
| 联系人 | TextField | | |
| 联系电话 | TextField | | |
| 联系邮箱 | TextField | | |
| 公司地址 | AddressField | | 省市区三级联动 |
| 负责人 | EmployeeField | | 单选成员 |
| 客户来源 | MultiSelectField | | 选项：官网、展会、转介绍、广告、电话（多选） |
| 备注 | TextareaField | | |
| 相关附件 | AttachmentField | | |

**子表：联系人明细**

| 子字段 | ComponentName | 说明 |
|--------|---------------|------|
| 姓名 | TextField | |
| 职位 | TextField | |
| 电话 | TextField | |

### 1.2 商机管理表（普通表单）

跟踪销售机会，关联客户信息。

| 字段名 | ComponentName | 必填 | 说明 |
|--------|---------------|------|------|
| 商机编号 | SerialNumberField | 自动 | 规则：`OPP-0001`，永不重置 |
| 商机名称 | TextField | ✓ | |
| 关联客户 | AssociationFormField | | 关联"客户信息表"，显示客户名称 |
| 商机阶段 | SelectField | | 选项：初步接触、需求确认、方案报价、谈判、赢单、输单 |
| 预计金额 | NumberField | | 单位：万元，精度 2 位 |
| 成交概率 | NumberField | | 单位：%，精度 0 位 |
| 预计成交日期 | DateField | | 格式：YYYY-MM-DD |
| 负责人 | EmployeeField | | 单选成员 |
| 商机来源 | RadioField | | 选项：新开发、老客户、合作伙伴 |
| 商机描述 | TextareaField | | |
| 产品图片 | ImageField | | |

**子表：跟进记录**

| 子字段 | ComponentName | 说明 |
|--------|---------------|------|
| 跟进日期 | DateField | 格式：YYYY-MM-DD |
| 跟进方式 | SelectField | 选项：电话、上门、视频、邮件 |
| 跟进内容 | TextareaField | |

### 1.3 合同审批表（流程表单）

合同签订审批，多重关联客户和商机。

| 字段名 | ComponentName | 必填 | 说明 |
|--------|---------------|------|------|
| 合同编号 | SerialNumberField | 自动 | 规则：`CON-yyyyMM-0001`，永不重置 |
| 合同名称 | TextField | ✓ | |
| 关联客户 | AssociationFormField | | 关联"客户信息表" |
| 关联商机 | AssociationFormField | | 关联"商机管理表" |
| 合同类型 | SelectField | | 选项：销售合同、服务合同、框架协议 |
| 合同金额 | NumberField | ✓ | 单位：万元，精度 2 位，用于流程条件分支 |
| 签订日期 | DateField | | |
| 合同期限 | CascadeDateField | | 日期区间（开始日期~结束日期） |
| 负责人 | EmployeeField | | |
| 合同附件 | AttachmentField | | |
| 合同备注 | TextareaField | | |

### 1.4 费用报销表（流程表单）

销售费用报销，支持明细子表和金额汇总。

| 字段名 | ComponentName | 必填 | 说明 |
|--------|---------------|------|------|
| 报销单号 | SerialNumberField | 自动 | 规则：`EXP-yyyyMMdd-0001`，永不重置 |
| 申请人 | EmployeeField | ✓ | |
| 所属部门 | DepartmentSelectField | ✓ | |
| 关联客户 | AssociationFormField | | 关联"客户信息表"，记录费用归属 |
| 报销类型 | SelectField | ✓ | 选项：差旅、招待、办公、交通、其他 |
| 报销总额 | NumberField | ✓ | 可配置公式自动汇总子表金额 |
| 报销说明 | TextareaField | | |

**子表：报销明细**

| 子字段 | ComponentName | 必填 | 说明 |
|--------|---------------|------|------|
| 消费日期 | DateField | ✓ | |
| 费用类别 | SelectField | ✓ | 选项：餐饮、交通、住宿、办公、其他 |
| 金额 | NumberField | ✓ | |
| 说明 | TextField | | |

### 1.5 客户回访表（普通表单）

记录客户回访和满意度调查。

| 字段名 | ComponentName | 必填 | 说明 |
|--------|---------------|------|------|
| 关联客户 | AssociationFormField | ✓ | 关联"客户信息表" |
| 回访人 | EmployeeField | ✓ | |
| 回访日期 | DateField | ✓ | 格式：YYYY-MM-DD |
| 回访方式 | RadioField | ✓ | 选项：电话、上门、视频、邮件 |
| 满意度 | RateField | ✓ | 5 星评分，支持半星 |
| 反馈标签 | CheckboxField | | 选项：产品满意、服务及时、价格合理、需要改进（多选） |
| 客户区域 | CountrySelectField | | 国家/地区选择 |
| 回访记录 | TextareaField | | |

---

## 二、流程设计

### 2.1 合同审批流程（条件分支）

根据合同金额自动路由到不同审批链：

| 条件 | 审批链 | 说明 |
|------|--------|------|
| 合同金额 ≤ 5万 | 部门经理 | 小额合同快速审批 |
| 5万 < 合同金额 ≤ 20万 | 部门经理 → 财务 | 中额合同需财务复核 |
| 合同金额 > 20万 | 部门经理 → 财务 → 总经理 | 大额合同三级审批 |

**审批节点配置**：
- 所有字段对审批人只读（仅附件可编辑）
- 拒绝时退回发起人修改

### 2.2 费用报销流程（顺序审批）

三级顺序审批，确保费用合规：

| 节点 | 审批人 | 职责 |
|------|--------|------|
| 直属主管审批 | 发起人主管 | 确认费用真实性 |
| 财务审核 | 财务人员 | 核实金额和票据（可编辑备注） |
| 出纳确认 | 出纳人员 | 确认并安排付款 |

---

## 三、权限设计

**3×5 权限矩阵**：

| 角色 | 客户信息表 | 商机管理表 | 合同审批表 | 费用报销表 | 客户回访表 |
|------|------------|------------|------------|------------|------------|
| 销售团队 | 读写 | 读写 | 只读 | 读写 | 读写 |
| 财务团队 | 只读 | 只读 | 读写 | 读写 | 只读 |
| 管理层 | 只读 | 只读 | 只读 | 只读 | 只读 |

---

## 四、自定义页面

### 4.1 CRM 销售仪表盘

实时展示销售核心指标的数据看板，支持密度切换和自动刷新。

#### 数据源配置

| 指标 | 数据表 | 查询方式 | 取值字段 |
|------|--------|----------|----------|
| 客户总数 | 客户信息表 | searchFormDatas (pageSize=1) | totalCount |
| 商机总数 | 商机管理表 | searchFormDatas (pageSize=100) | totalCount |
| 合同总额 | 合同审批表 | searchFormDatas 遍历累加 | 合同金额字段 |
| 本月新增 | 客户信息表 | searchFormDatas + createFrom/createTo 时间过滤 | totalCount |
| 阶段统计 | 商机管理表 | 遍历 data 数组统计各阶段数量 | 商机阶段字段 |
| 最近商机 | 商机管理表 | 复用商机查询，取前 10 条 | data.slice(0, 10) |

#### 布局结构

```
┌────────────────────────────────────────────────┐
│  顶部标题栏：标题 + 刷新按钮 + 密度切换按钮组    │
├────────────────────────────────────────────────┤
│  指标卡行（4 张卡片，flex 横向排列，移动端换行） │
│  [客户总数] [商机总数] [合同总额] [本月新增]    │
├──────────────────┬─────────────────────────────┤
│  商机阶段分布     │  最近商机列表               │
│  (固定宽 360px)  │  (flex: 1 自适应)           │
│  6 行进度条      │  表格：名称/阶段/金额/负责人 │
└──────────────────┴─────────────────────────────┘
```

#### 密度设计规格

| 参数 | compact（紧凑） | comfortable（舒适） |
|------|-----------------|---------------------|
| 卡片内边距 | 8px 12px | 16px 20px |
| 基础字号 | 12px | 14px |
| 行高 | 1.4 | 1.6 |
| 区块间距 | 8px | 16px |
| 标题字号 | 14px | 16px |
| 指标数值字号 | 20px | 28px |
| 表格行高 | 32px | 44px |

#### API 调用模式

- **合并查询策略**：商机数据一次请求获取 totalCount + stageStats + recentList，避免并发限流
- **分页处理**：数据超过 100 条时自动分页加载（合同金额累加、阶段统计完善）
- **并行加载**：Promise.all 同时发起客户/商机/合同/本月新增四类查询
- **错误处理**：单个查询失败不影响其他数据展示，toast 提示具体错误

#### 自动刷新机制

- **刷新间隔**：30 秒定时器（setInterval）
- **生命周期**：didMount 启动定时器，didUnmount 清理定时器
- **手动刷新**：点击刷新按钮立即触发 loadAllData，toast 提示"刷新成功"

#### 指标卡规格

| 卡片 | 标题 | 数值格式 | 单位 | 颜色 |
|------|------|----------|------|------|
| 1 | 客户总数 | 整数 | 家 | #1677FF |
| 2 | 商机总数 | 整数 | 个 | #722ED1 |
| 3 | 合同总额 | ¥ + formatMoney（≥1万显示 X.X万） | - | #52C41A |
| 4 | 本月新增客户 | 整数 | 家 | #FA8C16 |

#### 商机阶段分布

- **阶段列表**：初步接触、需求确认、方案报价、谈判、赢单、输单（6 个）
- **可视化**：每行显示阶段名称（60px）+ 进度条（flex:1）+ 数量（50px）
- **进度条**：按比例填充，带颜色映射和 0.3s 过渡动画
- **颜色映射**：初步接触=#1677FF，需求确认=#722ED1，方案报价=#FA8C16，谈判=#13C2C2，赢单=#52C41A，输单=#FF4D4F

#### 最近商机列表

| 列名 | 数据来源 | 格式化 |
|------|----------|--------|
| 商机名称 | formData.商机名称字段 | 文本，超长省略 |
| 阶段 | formData.商机阶段字段 | 标签样式，带阶段颜色背景 |
| 预计金额 | formData.预计金额字段 | ¥ + formatMoney |
| 负责人 | originator.name.zh_CN | 多语言兼容取值 |

- **空状态**：居中显示"暂无商机数据"，灰色文字
- **加载状态**：居中显示"数据加载中..."

#### 响应式适配

- 检测方式：this.utils.isMobile()
- 移动端：指标卡 flex-wrap 换行，下方区域改为纵向堆叠（column）
- 桌面端：指标卡横向 4 列，下方区域左右分栏

---

### 4.2 批量数据录入

高效录入客户、商机、回访数据的批量操作页面，支持 Excel 粘贴和草稿暂存。

#### 多表单配置

| 表单 | 可编辑列 |
|------|----------|
| 客户信息 | 客户名称（必填）、客户类型（单选）、客户级别（下拉）、联系人、联系电话、联系邮箱 |
| 商机管理 | 商机名称（必填）、商机阶段（下拉）、预计金额(万)（数字）、成交概率(%)（数字）、商机来源（单选） |
| 客户回访 | 回访方式（单选）、满意度(1-5)（数字）、回访记录 |

#### 行编辑规格

| 操作 | 行为 |
|------|------|
| 添加行 | 追加一行空数据（所有字段为空字符串），自动生成唯一 rowId |
| 删除行 | 从列表移除指定行，如删后为空则自动补充一行空行 |
| 删除选中 | 批量删除所有勾选行，需先选中至少一行 |
| 清空 | 重置为 3 行空数据，清除 localStorage 草稿 |
| 全选/取消 | 表头复选框切换所有行的选中状态 |

#### 字段验证规则

| 验证类型 | 规则 | 错误提示 |
|----------|------|----------|
| 必填检查 | 标记 required=true 的列不能为空 | "{字段名}不能为空" |
| 数字检查 | type=number 的列必须是合法数字 | "{字段名}必须是数字" |

- 验证时机：提交前统一验证所有行
- 错误展示：输入框红色边框 + 下方红色错误文字

#### Excel 粘贴导入

- **触发方式**：全局 paste 事件监听（didMount 绑定，didUnmount 解绑）
- **解析逻辑**：按 `\n` 分行 → 按 `\t` 分列 → 按列顺序映射到字段
- **追加模式**：过滤现有全空行后，将新行追加到末尾
- **空行过滤**：粘贴数据中的全空行自动忽略
- **成功提示**：toast 显示"已导入 X 行数据"

#### 草稿暂存机制

| 配置项 | 值 |
|--------|----|
| localStorage key | `yida_crm_batch_entry_{formType}`（如 yida_crm_batch_entry_customer） |
| 保存时机 | 添加行、删除行、单元格编辑、切换表单时 |
| 恢复时机 | didMount 或切换表单时，优先加载草稿，无草稿则初始化 3 行空数据 |
| 清除时机 | 提交全部成功后、手动点击清空 |

#### 批量提交流程

1. **验证阶段**：遍历所有行执行 validateRow，标记 _status 和 _errors
2. **过滤空行**：只提交至少有一个字段有值的行
3. **并发提交**：Promise.all 并发调用 saveFormData（每行一个请求）
4. **进度反馈**：实时更新 current/total，进度条百分比动画
5. **结果统计**：记录 success/failed 数量，展示结果卡片

#### 提交状态与样式

| 状态 | 行背景色 | 操作列显示 |
|------|----------|------------|
| valid | 白色 | 删除按钮 |
| invalid | #fff2f0（浅红） | 删除按钮 |
| submitting | #e6f7ff（浅蓝） | "提交中"文字 |
| submitted | #f6ffed（浅绿） | ✓ 对勾图标 |

#### 错误处理

- 验证失败：toast 提示"请修正表格中的错误后再提交"，不发起任何请求
- 部分失败：结果卡片显示"X 条成功，Y 条失败（请修正红色行后重新提交）"
- 全部成功：清除草稿，重置为 3 行空数据，toast 提示"全部提交成功，共 X 条"

---

## 五、报表设计

销售分析报表，包含 6 种图表和时间筛选器：

| 图表类型 | 标题 | 数据源 | 说明 |
|----------|------|--------|------|
| 指标卡 | 客户总数 | 客户信息表 | 汇总统计 |
| 漏斗图 | 商机销售漏斗 | 商机管理表 | 按阶段展示转化 |
| 折线图 | 月度合同趋势 | 合同审批表 | 按月汇总合同金额 |
| 饼图 | 客户类型分布 | 客户信息表 | 企业/个人客户占比 |
| 柱状图 | 销售业绩排名 | 商机管理表 | 按负责人汇总金额 |
| 透视表 | 客户级别×商机阶段 | 商机管理表 | 二维交叉分析 |

**筛选器**：时间范围（按预计成交日期筛选），联动漏斗图、柱状图、透视表。

---

## 六、集成自动化

### HTTP 连接器配置

| 配置项 | 值 |
|--------|-----|
| 连接器名称 | 外部 CRM 用户查询 |
| 基础 URL | `https://jsonplaceholder.typicode.com` |
| 鉴权方式 | BasicAuth |

**操作：获取外部客户列表**

| 配置项 | 值 |
|--------|-----|
| 操作 ID | getExternalUsers |
| 请求方法 | GET |
| 路径 | `/users` |
| 响应字段 | id（用户ID）、name（用户名称）、email（邮箱）、phone（电话） |

---

## 七、页面分享

| 配置项 | 值 |
|--------|-----|
| 分享页面 | CRM 销售仪表盘 |
| 分享范围 | 组织内 |
| 短链地址 | `/s/crm-dashboard` |

---

## 八、模拟数据

### 客户数据（5 条）

| 客户名称 | 客户类型 | 客户级别 | 联系人 | 负责人 |
|----------|----------|----------|--------|--------|
| 阿里云计算 | 企业客户 | A级 | 张经理 | 销售一 |
| 腾讯科技 | 企业客户 | A级 | 李总监 | 销售一 |
| 字节跳动 | 企业客户 | B级 | 王经理 | 销售二 |
| 个人客户-陈先生 | 个人客户 | C级 | 陈先生 | 销售二 |
| 美团点评 | 企业客户 | B级 | 赵经理 | 销售一 |

### 商机数据（8 条）

| 商机名称 | 关联客户 | 商机阶段 | 预计金额 | 成交概率 |
|----------|----------|----------|----------|----------|
| 阿里云-年度服务合作 | 阿里云计算 | 方案报价 | 50万 | 70% |
| 腾讯-数字化转型项目 | 腾讯科技 | 谈判 | 120万 | 85% |
| 字节-内部工具定制 | 字节跳动 | 需求确认 | 30万 | 50% |
| 陈先生-个人订购 | 个人客户-陈先生 | 赢单 | 2万 | 100% |
| 美团-供应链系统 | 美团点评 | 初步接触 | 80万 | 30% |
| 阿里云-二期扩展 | 阿里云计算 | 需求确认 | 35万 | 60% |
| 腾讯-运维自动化 | 腾讯科技 | 输单 | 45万 | 0% |
| 美团-数据分析平台 | 美团点评 | 方案报价 | 60万 | 55% |

### 合同数据（3 条）

| 合同名称 | 关联客户 | 合同金额 | 合同类型 |
|----------|----------|----------|----------|
| 陈先生-年度服务协议 | 个人客户-陈先生 | 2万 | 服务合同 |
| 阿里云-框架协议2026 | 阿里云计算 | 8万 | 框架协议 |
| 腾讯-项目一期合同 | 腾讯科技 | 25万 | 销售合同 |

### 费用报销数据（2 条）

| 报销类型 | 关联客户 | 报销总额 | 申请人 |
|----------|----------|----------|--------|
| 差旅 | 腾讯科技 | 3500元 | 销售一 |
| 招待 | 阿里云计算 | 1200元 | 销售二 |

### 客户回访数据（3 条）

| 关联客户 | 回访方式 | 满意度 | 反馈标签 |
|----------|----------|--------|----------|
| 阿里云计算 | 电话 | 4.5星 | 产品满意、服务及时 |
| 腾讯科技 | 上门 | 5星 | 产品满意、价格合理 |
| 个人客户-陈先生 | 视频 | 4星 | 服务及时、需要改进 |
