# 客户管理 · 列表页产品需求说明（PRD）

> 本页为客户主数据台账列表。标注「原型演示」的跳转、导入、导出、详情/编辑仅 Toast 提示。

---

## 1. 模块定位

| 项 | 说明 |
|---|---|
| 模块名称 | 客户管理 — 列表页 |
| 目标用户 | 销售、业务负责人、**法务、财务、业管、运维/资产、风控、管理层** |
| 核心任务 | 按多维度与 KPI 卡片筛选客户；查看并**在列表页维护风险标签**；新增客户（详情/编辑为原型演示） |
| 页面结构 | 面包屑 + **操作角色切换** + 筛选区 + **风险 KPI 卡片** + 工具栏 + 表格 + 分页 |

**重要约束：**

- 风险标签**不在**客户新增页、客户编辑表单中维护，仅在列表页作为操作入口。
- 底层使用统一 `riskTagsByCustomer` 数组（`CustomerRiskTag[]`），前台按**法务 / 财务 / 业管**三分区展示，不按 `legalTags` / `financeTags` 等字段拆散存储。

---

## 2. 客户编号规则（集团多子公司）

- 总长度 7，仅含大写字母 A–Z 与数字 0–9
- 结构：第 1 位 = 签约/归属子公司代码；第 2–7 位 = 6 位数字流水号（000001–999999）
- 流水号在「同一子公司代码」下递增
- 校验正则：`/^[A-Z][0-9]{6}$/`
- 示例：A000001（华东）、B000001（华南）、C000001（华北）等

---

## 3. 数据来源

| 数据 | 来源 | 用途 |
|---|---|---|
| 客户台账 | `data/customers.json`（20 条样例） | 列表、筛选选项 |
| 客户标签（展示投影） | 客户 `labels` 字段 | 列表「风险标签」列、筛选区「标签」多选 |
| 风险标签明细 | `riskTagsByCustomer` 运行时状态 + 种子迁移 | 抽屉、KPI 卡片、审批、日志 |
| 标签目录 | `utils/riskTagConstants.ts` → `TAG_CATALOG`（11 项） | 打标表单、分区展示、KPI 口径 |
| 操作日志 | `data/risk-tag-operation-logs.json` + 运行时追加 | 抽屉「操作日志」Tab |
| 部门-负责人 | 由台账聚合 + `DEPT_MANAGER_MAP` | 筛选联动 |

`labels` 由 `syncRecordLabels` 与**生效中**风险标签自动同步；**待审批**标签不参与 `labels` 投影。

---

## 4. 筛选区

默认展示前 4 项（一行），点击「更多筛选」显示全部。

| 字段 | 控件 | 匹配规则 |
|---|---|---|
| 客户编号 | 可搜索单选 | 精确匹配 `code` |
| 客户名称 | 可搜索单选 | 精确匹配 `name` |
| 标签 | 多选 | 客户 `labels` 包含任一选中标签（OR） |
| 区域 | 可搜索单选 | 精确匹配 `region` |
| 客户状态 | 多选 | `status` 在选中集合内 |
| 业务部门 | 多选 | `department` 在选中集合内 |
| 业务负责人 | 多选 | 随部门联动；`manager` 在选中集合内 |
| 创建时间 | 日期范围 | `createTime` 落在区间内（含边界日） |

### 4.1 操作逻辑

| 操作 | 行为 |
|---|---|
| **查询** | 将当前筛选项写入已应用条件，页码重置为 1，清空行选中 |
| **重置** | 清空待应用与已应用条件；**KPI 卡片回到「全部客户」**；页码重置为 1；清空行选中 |
| 修改筛选项未点查询 | 不影响当前列表 |

### 4.2 与 KPI 卡片的关系

- **KPI 卡片**：点击即生效，基于 `riskTagsByCustomer`（含待审批标签）。
- **筛选区「标签」**：须点「查询」后生效，基于 `labels`（仅生效中标签）。
- 二者叠加时取交集；口径差异见 §5 说明。

---

## 5. 风险 KPI 卡片筛选

样式与供应商/车辆管理 KPI 卡片一致（`vm-kpi-*`），位于筛选区与工具栏之间。点击卡片切换列表数据范围并回到第 1 页；右上角「?」展示口径说明。

| KPI 卡片 | 统计/筛选口径 |
|---|---|
| 全部客户 | 台账全部记录 |
| 有风险客户 | 存在**生效中**或**待审批**风险标签 |
| 财务风险 | 含 `tagCategory = finance` 的有效标签（信用与回款、开票异常等） |
| 法务风险 | 含 `tagCategory = legal` 的有效标签（合规与法律类） |
| 业管风险 | 含 `tagCategory = business` 的有效标签（经营与履约、多头签约等） |

代码：`components/RiskKpiCards.tsx`、`utils/riskKpi.ts`。

---

## 6. 列表工具栏

| 按钮 | 行为 |
|---|---|
| 新增客户 | 进入新增客户页 |
| 批量导入 | Toast：批量导入（原型演示） |
| **批量打标** | 勾选 ≥1 行且当前角色有打标权限时显示 |
| 批量导出 | Toast：导出当前列表条数 |

### 6.1 操作角色切换（原型演示）

列表顶部「当前操作角色（原型演示）」下拉，按**角色**切换（非按姓名），模拟 8 类用户：

| 角色 | 演示账号 | 部门 | 打标 | 审批 | 说明 |
|---|---|---|---|---|---|
| 销售 | 陈销售 | 销售一部 | 否 | 否 | 可查看标签/抽屉，操作列「查看标签」 |
| 法务 | 李法务 | 法务部 | 法务分区 | 是 | 维护合规与法律类标签 |
| 财务 | 张财务 | 财务部 | 财务分区 | 否 | 信用与回款 + 开票异常 |
| 业管 | 王业管 | 业管部 | 业管分区 | 否 | 经营与履约 + 多头签约 |
| 运维/资产 | 赵运维 | 运维资产部 | 否 | 否 | 仅查看 |
| 风控 | 刘风控 | 风控部 | 否 | 是 | 可审批待审批标签 |
| 管理层 | 周管理 | 管理层 | 否 | 是 | 可审批；可看财务/法务敏感信息 |
| 系统管理员 | 系统管理员 | 系统管理部 | 全部 | 是 | 全部维护与审批权限 |

切换角色后，Drawer 内**分区维护按钮**、**新增标签可选范围**、**审批/解除按钮**、**敏感信息脱敏**随之联动。

---

## 7. 列表字段说明

| 列 | 说明 |
|---|---|
| 客户编号 | 左固定列 |
| 客户名称 | 超长省略 |
| **风险标签** | 最多展示 **2** 个生效中标签；超出显示 `+N`；悬浮/点击 `+N` 展示全部；按级别着色（低/中/高/致命）；Tooltip 含类型、责任部门、级别、状态；**所有角色**可点击打开 Drawer |
| 客户区域 | 大区名称 |
| 客户状态 | 绿点「正常」/ 红点「黑名单」 |
| 业务部门 / 业务负责人 | 文本 |
| 客户类型 / 所属行业 | 文本 |
| 统一社会信用代码 / 法人 / 注册资本 / 经营状态 | 文本 |
| 详细地址 / 创建时间 | 文本；创建时间不换行 |
| 操作 | 详情、编辑（Toast 演示）、**管理标签** / **查看标签**、删除（Toast 演示） |

支持行多选（checkbox，仅当前页）；横向滚动；操作列右固定。

### 7.1 风险标签列展示样式

| 风险级别 | 样式 |
|---|---|
| 低 | 灰色边框 |
| 中 | 橙色浅底 |
| 高 | 红色浅底 |
| 致命 | 深红浅底 |

无生效中标签但有待审批时，列可展示待审批标识；全无标签显示「—」。

---

## 8. 风险标签目录（11 项）

标签按规范文档四组维护；打标下拉按 **optgroup**（信用与回款 / 合规与法律 / 经营与履约 / 操作与流程）分组。风险级别由目录**自动带出且不可手改**。

**维护归属（权限分责）：**

- **信用与回款** → 财务部
- **合规与法律** → 法务部
- **经营与履约** → 业管部
- **操作与流程**：开票异常 → 财务部；多头签约 → 业管部

### 8.1 信用与回款（财务）

| 代码 | 标签名称 | 展示分区 | 风险级别 | 典型触发 | 待审批 | 黑名单提示 |
|---|---|---|---|---|---|---|
| CR-01 | 逾期预警 | 财务 | 中 | 当前逾期或近 6 个月曾逾期 | 否 | 否 |
| CR-02 | 严重拖欠 | 财务 | 高 | 逾期 > 30 天或历史坏账 | 是 | 是 |
| CR-03 | 频繁改账期 | 财务 | 低 | 一年内延长账期 ≥ 3 次 | 否 | 否 |

### 8.2 合规与法律（法务）

| 代码 | 标签名称 | 展示分区 | 风险级别 | 典型触发 | 待审批 | 黑名单提示 |
|---|---|---|---|---|---|---|
| CP-01 | 资质存疑 | 法务 | 中 | 证照过期、抬头与付款主体不一致 | 否 | 否 |
| CP-02 | 涉诉/仲裁 | 法务 | 高 | 重大未结诉讼/仲裁 | 是 | 是 |
| CP-03 | 制裁/高风险地区 | 法务 | 高 | 制裁/合规名单命中 | 是 | 是 |

### 8.3 经营与履约（业管）

| 代码 | 标签名称 | 展示分区 | 风险级别 | 典型触发 | 待审批 | 黑名单提示 |
|---|---|---|---|---|---|---|
| OP-01 | 频繁争议 | 业管 | 中 | 合同或扣款争议超阈值 | 否 | 否 |
| OP-02 | 车辆/资产高风险 | 业管 | 高 | 违章、事故、疑似骗保等 | 是 | 否 |
| OP-03 | 信息不实 | 业管 | 中 | 联系人/主体核查不实 | 否 | 否 |

### 8.4 操作与流程

| 代码 | 标签名称 | 展示分区 | 维护部门 | 风险级别 | 典型触发 |
|---|---|---|---|---|---|
| PR-01 | 开票异常 | 财务 | 财务部 | 低 | 频繁退票、抬头异常变更 |
| PR-02 | 多头签约 | 业管 | 业管部 | 低 | 同一实控人多主体分别签约 |

---

## 9. 风险标签维护（列表页专属）

### 9.1 入口

| 入口 | 说明 |
|---|---|
| 行操作「管理标签」/「查看标签」 | 打开右侧 Drawer |
| 点击风险标签列 | 同打开 Drawer |
| 工具栏「批量打标」 | 对勾选客户批量提交同一标签 |

**不在**新增页、编辑页维护标签。

### 9.2 管理抽屉结构

| Tab | 内容 |
|---|---|
| 当前标签 | 按 **法务风险 / 财务风险 / 业管风险** 三分区 Card 展示；含分区说明、维护权限提示、标签卡片、空状态 |
| 新增标签 | 角色受限打标表单（见 9.3） |
| 操作日志 | 该客户审计记录，按时间倒序 |

Drawer 标题：**风险标签**；副标题为客户名称与编号。

### 9.3 当前标签页 — 分区与卡片

展示顺序：法务 → 财务 → 业管。

每个分区包含：

1. 分区标题与说明（责任部门、关注范围）
2. 当前角色是否可维护（「可维护」/「当前角色无权维护该类标签」）
3. 「新增该类标签」按钮（有权限时）
4. 标签卡片：名称、级别、状态、时间字段、责任部门、操作人、原因摘要
   - **法务风险**：打标时间、复核周期、下次复核时间、最后复核时间（不展示「有效期至」）
   - **财务/业管**：打标时间、有效期至
5. 空状态：「暂无该类风险标签」

卡片操作：查看详情；审批（新增待审批或**解除待审批**且有权）；**申请解除**（有权且生效中，须走审批流）。

**法务风险复核规则（原型 Mock）：**

- 法务标签自打标后持续生效，**不会因到期自动解除**
- 距 `nextReviewAt` ≤ 7 天：卡片显示「即将复核」
- 当前日期超过 `nextReviewAt`：状态显示「待复核」，标签仍保留
- **不在 Drawer 内完成复核**；系统自动向**法务工作台**推送待办，法务查验后回到本页「申请解除」
- 打开 Drawer 且存在待复核法务标签时，页顶 Banner 提示待办已推送，并写入操作日志（工作台待办）
- 确认可解除时：填写解除原因 → 提交解除申请（走审批流）；通过后记录 `removedAt`

**解除审批（原型 Mock）：**

- 任意标签解除均提交申请，状态为「解除待审批」
- 申请解除弹窗说明：**法务标签**提示「法务查验完成后…」；**财务/业管标签**仅提示「提交解除申请，经审批后生效」（不含法务查验文案）
- 法务/风控/管理层/系统管理员可审批：通过 → 已解除；驳回 → 恢复生效并清除申请标记

### 9.4 新增标签表单

| 字段 | 必填 | 规则 |
|---|---|---|
| 标签类型 | 是 | 非 admin：按角色自动带出法务/财务/业管并置灰；admin 可选三分区 |
| 标签名称 | 是 | 按 8.1–8.4 optgroup；仅当前角色可维护的标签；不可重复有效同名标签 |
| 风险级别 | 是 | 选标签后自动带出，置灰 |
| 打标时间 | 是 | 日期（只读置灰） | **取操作当天**，不可编辑 |
| 复核周期 | 法务必填 | 下拉 | 1 / 2 / 3 / 6 个月；变更时自动推算下次复核时间 |
| 下次复核时间 | 法务必填 | 日期（只读置灰） | 根据打标时间 + 复核周期**自动推算**，不可编辑；下方提示「到期仅提醒责任人复核，不会自动解除标签。」 |
| 有效期至 | 财务/业管必填 | 日期 | ≥ 打标时间；业务有效期，与复核提醒无关 |
| 原因说明 | 是 | ≥ 10 字 |
| 附件 | 高/致命必填 | .pdf / .jpg / .png / .xlsx |

**法务 vs 财务/业管字段差异：**

- 法务标签**不展示**「有效期至」，使用「下次复核时间」驱动定期复核提醒
- 财务/业管保留「有效期至」，不在 UI 上与复核时间混用

提交规则：

- 低/中：直接 **生效中**
- 高/致命：**待审批**；提交前二次确认
- 涉诉/仲裁、严重拖欠、制裁/高风险地区：Toast 提示可能触发黑名单审批

销售/运维/风控/管理层（非 admin）：新增 Tab 展示无权限说明。

### 9.5 批量打标

- 已选客户 chips（>6 显示 +N）
- 表单与单客户一致
- 已存在同名有效标签的客户自动跳过
- 写入批量操作日志

### 9.6 统一数据模型 `CustomerRiskTag`

| 字段 | 说明 |
|---|---|
| id / customerId | 标识 |
| tagCode / tagName | 目录代码与名称 |
| tagCategory / tagCategoryName | legal / finance / business |
| responsibleDept / editableRoles | 责任部门与可编辑角色 |
| riskLevel / riskLevelName | low / medium / high / fatal |
| status / statusName | active / pending / expired / removed / rejected |
| source / sourceName | system / manual |
| reason / taggedAt / nextReviewAt / reviewCycle | 原因与复核时间（法务） |
| expireDate | 财务/业管业务有效期 |
| lastReviewedAt / reviewStatus / reviewLogs | 法务复核记录 |
| removedAt / removeReason | 解除时间与原因 |
| createdBy / createdAt / approvedBy / approvedAt | 操作与审批 |
| attachments / sensitiveLevel / financeDetail | 附件与脱敏 |
| removalRequested | 解除申请标记（原型） |

### 9.7 标签生命周期

| 状态 | 说明 | 同步至 `labels` |
|---|---|---|
| 生效中 | 正常展示 | 是 |
| 待复核 | 法务标签超过下次复核时间，**仍生效** | 是 |
| 待审批 | 高/致命新增后 | 否 |
| 已驳回 | 审批拒绝 | 否 |
| 已解除 | 解除成功（含复核确认解除并审批通过） | 否 |
| 已失效 | 预留（法务标签**不会**自动进入此状态） | 否 |

**法务复核与解除规则：**

- 法务标签持续生效，系统仅按 `nextReviewAt` 提醒复核，**不自动解除**
- 复核维持：在工作台完成查验（原型阶段以 Toast + 日志表示）；如需解除使用「申请解除」
- 复核确认风险解除：填写解除原因 → 提交解除申请 → 审批通过后 `status → 已解除` 并记录 `removedAt`
- 任意路径的解除均需审批，不允许系统自动解除法务标签

### 9.8 敏感信息脱敏

| 场景 | 规则 |
|---|---|
| 财务敏感 | 非 finance / manager / admin 不可见逾期金额、账单编号等；提示「财务敏感信息已隐藏」 |
| 法务附件 | 非 legal / riskControl / manager / admin 不可见法务附件；提示「法务敏感附件仅授权角色可见」 |
| 操作日志 | 财务类日志 reason 对非授权角色脱敏 |

---

## 10. 权限与审批

### 10.1 分区维护（打标 / 解除）

| 角色 | 可维护分区 | 可选标签范围 |
|---|---|---|
| 财务 | 财务风险 | 信用与回款 + 开票异常 |
| 法务 | 法务风险 | 合规与法律 |
| 业管 | 业管风险 | 经营与履约 + 多头签约 |
| 系统管理员 | 全部 | 全部 11 项 |
| 销售 / 运维 / 风控 / 管理层 | — | 不可新增（风控/管理层可审批） |

### 10.2 审批权限

法务、风控、管理层、系统管理员可审批「待审批」新增标签，以及「解除待审批」的解除申请；支持通过/驳回，驳回须填原因。

### 10.3 查看权限

所有角色可打开 Drawer 查看标签名称与级别；敏感字段按 §9.8 脱敏。

---

## 11. 操作日志

记录：新增标签、解除标签、提交审批、审批通过、审批驳回、**工作台待办**、批量打标。

| 字段 | 说明 |
|---|---|
| 操作时间 | `YYYY-MM-DD HH:mm:ss` |
| 操作人 / 操作角色 | 姓名 + 角色 |
| 操作类型 | 见上 |
| 标签名称 / 标签类型 | tagName + tagCategoryName |
| 操作原因 | reason |
| 变更前/后状态 | statusBefore → statusAfter |

抽屉内按客户过滤、时间倒序；不同类型以 Tag 区分。

---

## 12. 原型边界（当前实现）

| 能力 | 状态 |
|---|---|
| 列表 + KPI + 风险标签 Drawer | 已实现 |
| 详情 / 编辑 / 查看页 | Toast 演示 |
| 新增客户落库 | Toast 演示，不写回列表 |
| 高风险解除申请审批闭环 | 已实现：申请 → 审批通过/驳回 |
| 黑名单与标签联动 | 仅 Toast 提示，不自动改 `status` |
| 定时复核任务 | 仅前端 Mock 提示 |

---

## 13. 原型实现索引

| 能力 | 代码位置 |
|---|---|
| 列表编排 | `index.tsx` |
| KPI 卡片 | `components/RiskKpiCards.tsx`、`utils/riskKpi.ts` |
| 风险标签列 | `components/RiskLabelTags.tsx` |
| 管理抽屉 | `components/RiskTagDrawer.tsx` |
| 批量打标 | `components/BatchRiskTagModal.tsx` |
| 打标表单 / 详情 | `components/RiskTagForm.tsx` |
| 标签目录 | `utils/riskTagConstants.ts` |
| 权限 | `utils/permissions.ts` |
| 业务逻辑 | `utils/riskTagStore.ts` |
| 列表筛选 | `utils/filters.ts` |
| 类型定义 | `types/riskTag.ts`、`types.ts` |
