Quellcode durchsuchen

docs: add design for CRM customer server-side column filters.

Co-authored-by: Cursor <cursoragent@cursor.com>
zlwu vor 1 Monat
Ursprung
Commit
16d382e6aa

+ 222 - 0
docs/superpowers/specs/2026-09-06-crm-customer-server-column-filters-design.md

@@ -0,0 +1,222 @@
+# CRM 客户域:列头漏斗整库服务端筛选(首批)
+
+**日期**:2026-09-06  
+**状态**:待审阅  
+**范围(首批)**:`web-admin` 客户管理 + 客户公海主列表;后端客户/公海 list 与 export 过滤扩展;`useServerColumnFilters` 通用化  
+**后续**:线索/商机/产品/报价/合同等主列表 → 弹窗内列表(本文件仅锁定首批与模式)
+
+**对齐标杆**:`docs/superpowers/specs/2026-09-06-reimburse-apply-server-column-filters-design.md`(报销申请)
+
+---
+
+## 1. 背景与目标
+
+报销申请已落地「列头漏斗 + 整库服务端筛」。CRM 菜单下列表/弹窗表需同一模式。范围大,**分批交付**;首批打通客户域并通用化 composable,再复制到其它 CRM 页。
+
+### 目标
+
+1. 客户管理、客户公海主列表:去掉顶部 `filter-block`,检索 = 列头漏斗 + 快捷搜索(客户页另保留 Tab)。  
+2. 四类列交互与报销一致:日期段、数字运算/区间、字典枚举多选、其余文本模糊。  
+3. 过滤打整库;`total`/换页/导出与列条件一致。  
+4. 藏列清该列条件并重查。  
+5. 将 `useServerColumnFilters.toQueryParams` 从「报销写死字段」升级为可配置 `queryKey`,报销页回归不破。
+
+---
+
+## 2. 已确认产品决策
+
+| # | 决策 |
+|---|------|
+| D1 | 交付方式:分批;先主列表后弹窗内表 |
+| D2 | 首批:客户管理 + 客户公海主列表 |
+| D3 | 规则与报销申请完全一致:去顶部筛;保留 Tab/快捷搜索;四类漏斗整库;藏列清条件;默认值迁列漏斗 |
+| D4 | 原顶部有检索字段但无列 → 先补列;本批顶部字段均已有列 |
+| D5 | 架构:通用化 `ColumnFilterDef` + `toQueryParams`(方案 1),不复制 CRM 专用 composable |
+
+**本页默认值**:客户/公海 `searchForm` 初始均为空,无默认值可迁;规则保留供他页使用。
+
+---
+
+## 3. 首批范围
+
+### 3.1 改造
+
+| 页面 | 路径 |
+|------|------|
+| 客户管理 | `web-admin/src/views/crm/customer/index.vue` |
+| 客户公海 | `web-admin/src/views/crm/customer/pool/index.vue` |
+| Composable | `web-admin/src/composables/useServerColumnFilters.ts` + `useClientColumnFilters.ts`(`ColumnFilterDef`) |
+| 报销回归 | `web-admin/src/views/bx/reimburse/apply/index.vue`(仅补 queryKey 配置) |
+| 后端 | `CustomerListBody` / `PoolCustomerListBody`、`list_customers` / 公海 list、对应 export |
+
+### 3.2 明确不做(首批)
+
+- 其它 CRM 主列表(线索、商机、产品、报价、合同等)  
+- 客户详情/联系人/发票等弹窗内嵌表  
+- 公海规则页、看板/漏斗/统计  
+- OpenSpec 基线归档(标杆稳定后另开)
+
+---
+
+## 4. 产品与交互
+
+### 4.1 布局
+
+- 删除顶部 `filter-block`。  
+- **客户管理**:保留 Tab(全部 / 我的 / 待跟进 / 重点)→ 请求 `viewMode`;与列条件 **AND**。  
+- 保留工具栏快捷搜索 → `keyword`(或现网等价字段);与列条件 **AND**。  
+- 「清空列过滤」只清列条件,不清快捷搜索、不改 Tab。
+
+### 4.2 列头漏斗覆盖
+
+业务数据列全挂漏斗(不含勾选、序号)。覆盖 `listColumnDefs` + 固定列「客户编号」「客户名称」。
+
+| 类型 | 列(示意) |
+|------|------------|
+| enum | customerType、level、source、industry、parkArea、scale、status、dealStatus |
+| datetime | createTime、updateTime、lastTime、nextTime、dealTime、intoPoolTime、claimTime、protectTime |
+| number | dealAmount、followCount、contactCount、opportunityCount、contractCount |
+| text | customerNo、customerName、shortName、mobile、telephone、email、website、province、city、district、address、ownerUserName、createByName、updateByName、createDeptName、remark |
+
+公海列与客户高度同构;列表恒为公海范围(`status=pool` 或等价),列筛叠加 AND。
+
+### 4.3 藏列与默认值
+
+- 隐藏列 → 清空该列已生效条件 → 立即重查。  
+- 再显示列 → 不自动恢复条件。  
+- 「重置列显示」→ 恢复列可见性默认 + 列漏斗 `initialFilters`(本批为空)。  
+- 他页若有顶部默认:仅当对应列默认可见时写入 initial。
+
+### 4.4 导出
+
+导出请求体与当前列表同一套:`keyword` + `viewMode`(若有)+ 列筛参数 + 选中 ids(若有)。
+
+---
+
+## 5. 架构:Composable 通用化
+
+### 5.1 扩展 `ColumnFilterDef`
+
+```ts
+interface ColumnFilterDef {
+  prop: string
+  label: string
+  type: 'text' | 'enum' | 'number' | 'datetime'
+  enumOptions?: ColumnFilterEnumOption[]
+  getValue?: (row: any) => unknown
+  /** 文本主查询键;默认 prop。枚举多选默认 `${queryKey}In` */
+  queryKey?: string
+  /** datetime 起止;默认 `${queryKey}From` / `${queryKey}To` */
+  queryKeyFrom?: string
+  queryKeyTo?: string
+  /** number 键前缀;默认 queryKey → `${prefix}Op` / Min / Max / 单值键=prefix */
+  queryKeyPrefix?: string
+}
+```
+
+### 5.2 `toQueryParams` 规则
+
+| type | 输出 |
+|------|------|
+| text | `q[queryKey] = text.trim()` |
+| enum | `q[`${queryKey}In`] = selected.join(',')` |
+| datetime | From/To 闭区间日期 |
+| number | Op + Min/Max 或单值 |
+
+报销申请页改为显式配置(如 `applyTime` → `applyDateFrom`/`applyDateTo`,`amount` → `amountOp`…,`status` → `statusIn`),行为与现网一致。
+
+---
+
+## 6. API 约定(客户 / 公海)
+
+### 6.1 已有(客户 list)
+
+`POST /web/crm/customer/list`(`CustomerListBody`)已支持:  
+`keyword`、`customerName`、`customerNo`、`customerType`、`level`、`source`、`industry`、`parkArea`、`status`、`dealStatus`、`ownerUserId`、`beginTime`/`endTime`(创建时间)、`viewMode`/`viewType` 等。
+
+### 6.2 首批扩展
+
+在 list / export 共用拼装中增加(命名 camelCase,与前端 `toQueryParams` 对齐):
+
+1. **枚举多选 `*In`**:如 `customerTypeIn`、`levelIn`、`sourceIn`、`statusIn`、`dealStatusIn`、`parkAreaIn`、`industryIn`、`scaleIn`;逗号分隔 → SQL `IN`。保留原单值字段兼容。  
+2. **文本模糊**:对挂漏斗的 text 列补独立参数(如 `shortName`、`mobile`、`telephone`、`email`、`website`、`address`、`ownerUserName`、`remark`、`province`/`city`/`district`、`createByName` 等);`contains`/`like`。  
+3. **其它日期**:`lastTimeFrom`/`To`、`nextTimeFrom`/`To`、`dealTimeFrom`/`To`、`intoPoolTimeFrom`/`To`、`claimTimeFrom`/`To`、`protectTimeFrom`/`To`、`updateTimeFrom`/`To`;创建时间可继续用 `beginTime`/`endTime`,或统一为 `createTimeFrom`/`To`(前端 queryKey 显式映射到现网键,避免双栈)。  
+4. **数字**:`dealAmountOp` + `dealAmount`/`Min`/`Max`,以及 followCount、contactCount、opportunityCount、contractCount 同模式。
+
+### 6.3 公海
+
+`POST /web/crm/customer/pool/list`(及 export)扩展与公海表漏斗列对齐的参数;内部复用 `list_customers`(或同一过滤拼装),并固定公海范围,避免两套逻辑。
+
+### 6.4 语义
+
+- 多列 AND;`keyword` AND;`viewMode` AND。  
+- 租户隔离、数据权限、软删与现网一致。  
+- 非法数字/空 `*In`:忽略该维或 400(与报销一致,倾向忽略空维)。
+
+---
+
+## 7. 数据流
+
+```text
+进入客户页
+  → Tab = viewMode;initialFilters(空)
+  → POST list (page, pageSize, viewMode, keyword?, column params?)
+
+列漏斗确定 → 合并 keyword + viewMode + toQueryParams → page=1 重查
+
+藏列 → 清该列条件 → 重查
+
+清空列过滤 → filters={} → 重查(保留 keyword、Tab)
+
+导出 → 与当前列表相同过滤字段
+```
+
+公海同理(无 Tab / 无 viewMode,或固定 pool)。
+
+---
+
+## 8. 验收标准(首批)
+
+1. 客户、公海无顶部筛选区;有列头漏斗 + 快捷搜索;客户 Tab 可用。  
+2. 四类漏斗行为正确,跨页、`total`、换 pageSize 条件保持。  
+3. 藏带条件列 → 条件清除并刷新;再显示后漏斗空。  
+4. 导出与当前筛选一致(权限范围内)。  
+5. 报销申请列筛回归通过(日期/金额/状态/文本仍服务端生效)。  
+6. 租户与数据权限不弱于改造前。
+
+---
+
+## 9. 风险
+
+- 列多 → 参数多:过滤必须集中函数,禁止 list/export 各写一份。  
+- Tab「重点」与 level 列筛可叠加。  
+- Composable 通用化误伤报销:须显式 queryKey + 回归。  
+- 公海参数今日偏少:扩展时勿破坏 `status=pool` 边界。
+
+---
+
+## 10. 后续批次路线图
+
+| 批次 | 内容 |
+|------|------|
+| 1(本文) | 客户 + 公海 + composable 通用化 + 报销回归 |
+| 2 | 线索、商机主列表 |
+| 3 | 产品、报价/审批、合同/审批等主列表 |
+| 4 | 弹窗/详情内嵌表 |
+
+---
+
+## 11. 建议实现顺序
+
+1. 扩展 `ColumnFilterDef` / `toQueryParams`;报销页补配置并回归。  
+2. 后端客户/公海 list+export 过滤扩展 + 必要单测。  
+3. 改造客户、公海页面 UI 与接线。  
+4. 手工验收 §8。
+
+---
+
+## 12. 修订记录
+
+| 日期 | 说明 |
+|------|------|
+| 2026-09-06 | 初稿:CRM 首批客户+公海;规则对齐报销;composable 通用化;分批路线图 |