10 KiB
feasibility-customer.md — 客户管理模块(A4)可行性评估
票 08 产出 · 2026-08-30 · 依据:lanhu-pages A4 全 39 页(v29,约 1.9 万控件)关键页精读 + 代码现状盘点 分档口径(map.md,同票 07):小 = 纯 CRUD + 列表过滤 + 详情,无新基础设施;超出即 大。
1. 结论速览
分档:大。 且即使砍掉合并/交割/导入/OCR 做「最小切片」,仍跨入大档(公海机制 + 企查查外部依赖 + 多视图列表是躲不开的最小集)。建议:标记后续迭代,整模块挂起。
特别回答(票面要求的 D-02 口径):已由票 04 以「快照池降级」实现并闭环——customer/search 搜全库 opportunity_customer 快照(按名称模糊、排除本商机、GROUP BY customer_id),不依赖客户主数据;未来客户模块落地后切真源,端点签名与语义不变。详见 §5。
2. 原型盘点(A4 全 39 页)
| 分组 | 页面 | 量级 |
|---|---|---|
| 公海 | A4-1-1/-1-2(列表/分屏视图) | 967/954 控件 |
| 客户总览 | A4-2-1(列表/分屏/卡片三视图) | 782/551/1558 |
| 我的客户 | A4-3-1(三视图)+ A4-3-2 导入 | 1425/541/1565 + 214 |
| 新增编辑 | A4-3-3-1 新增(1057)/3-3-2 编辑/3-3-3 添加联系人/3-3-4 OCR(486) | 最大单页 |
| 客户详情 | A4-4-1~4-10:客户信息/已归档/已被合并/联系人(1130)/跟进/关联商机/关联项目/战略协议(新增+编辑)/团队成员/操作日志 | 9 Tab + 变体 |
| 联系人 | A4-5-1~5-6:列表 2 视图/新增/编辑/导入/详情 2 | 6 页 |
| 查重合并 | A4-6-1/-6-2 查重(卡片/列表)+ A4-6-3 合并 | 3 页 |
| 交割 | A4-7-1 发起(647)/7-2 分配/7-3 记录/7-4 记录详情 | 4 页 |
3. 实体与字段集(精读实锤)
3.1 客户主档(A4-3-1 新增页,30+ 字段)
- 基本信息:客户编号(自动)、*客户名称、*客户类型(字典)、*所属地区(省市区三级)、*行业(字典)、*客户星级、*关系星级、人脉关系单位(多值 tag 输入)、备注、附件
- 企查查工商回填(8 项):法定代表人、统一社会信用代码、成立时间、经营范围、注册资本、公司地址、人员规模、年产值——外部服务依赖(查询/核验/无结果/失败四态 UI)
- 关联信息(教育行业定制):公司决策人、总监近期拜访时间、*是否子客户、*父客户关联、合作系统、不合作原因、是否参加总裁班、总裁班参加人+电话、是否参加产品经理班、产品班参加人+电话
- 跟进人员:*销售部门、*销售负责人、协同人
- 内嵌联系人子表:*联系人、*职务(二级联动字典)、联系电话、是否内线、礼品备注、来源
- 保存时双重查重确认:名称相似弹窗(展示相似客户,无权查看的只提示存在不展示明细)+ 统一社会信用代码相同弹窗
3.2 职务字典(联系人图谱底座)
类别 × 职务 × 层级三段(股东 100/董事长 100/总裁 95/总经理 90/副总经理 80/采购主管 50…);支持模糊搜索、自定义职务(不入公共字典、无层级);职务层级用于自动生成联系人上下级图谱。
3.3 公海机制(A4-1-1 批注)
- 公海定义:档案状态「有效」且销售负责人为空
- 移入拦截:客户存在进行中商机或项目时不可移入(已结束不受限)
- 移入副作用:清空负责人/销售部门/协同成员,记操作日志;原协同成员领取后不自动恢复
- 待跟进计划:移入后停止提醒、不自动转交,新负责人自建
- 入口只在客户总览,公海列表不提供移入
3.4 客户合并(A4-6-3,七节超细规则——最深水区)
- 页面加载查重页已选全部客户,横向滚动 + 左侧字段列固定
- 主客户唯一;客户编号/创建时间/销售负责人/销售部门固定保留主客户值;最近跟进时间取全部客户最晚
- 全量字段合并(不限原型示例字段):一致直接写入;不一致默认主客户值可逐字段改选;空不覆盖非空;多值字段取并集按业务标识去重;必填结果缺失阻止提交
- 合并前阻断:任一非主客户已生成合同/订单禁止合并;客户已删除/已被其他合并处理/负责人变更/权限变化/版本不一致 → 禁止提交
- 关联数据全迁移:联系人/跟进/商机/方案卡/项目/文件/标签/客户关系/团队成员/战略协议全部迁至主客户;团队取并集去重;其他客户负责人降为协同人;战略协议有单客户唯一性约束,迁移后不满足则禁止合并
- 联系人合并:电话完整值相同合并为 1 条(主客户优先);重复联系人字段空不覆盖非空;无电话或电话不同分别保留
- 单事务整体回滚;被合并客户软删标记「已合并」;操作日志不可改
3.5 客户交割(A4-7-1,级联深水区)
- 仅本人可发起(离职/岗位调动/区域调整三原因单选),不允许代发起
- 接收人限直属销售总监:离职时系统自动定唯一直属(定不出则阻止提交);调动/区域调整手动选启用总监
- 离职必须全量交接(不可排除单个客户);调动/调整可勾选(跨分页有效)
- 级联同步:客户负责人变更时,该客户全部关联商机+项目负责人同步变更为同一接收人;整体原子——任一失败全部不生效、不生成交接记录
- 交接编号 + 交接记录 + 进度(待分配 0/N)+ 未完成交接禁止再发起 + 操作日志规则
- 客户分配(A4-7-2):总监把待分配客户分配给范围内启用销售
3.6 OCR 快捷新增(A4-3-3-4)
上传识别 → 只回填空字段(已有输入须确认才覆盖)→ 客户匹配(命中多候选弹窗单选;无权查看的隐藏明细)→ 可选「轻量客户」(只存名称+阶段=潜在客户,必填字段暂空)→ 重复联系人判定(电话完全相同=禁止创建;电话不同+客户+姓名相同=疑似可继续)→ 更新已有联系人(仅确认字段、空不覆盖、版本+电话唯一性再校验)。
3.7 权限模型(A4-3-3-1 批注)
客户读写权限 / 全部查看 / 脱敏查看(仅电话+金额脱敏)/ 无权限四档;联系人无独立 ACL,权限继承所属客户,按「客户团队权限 → 模块权限」顺序校验;查重覆盖全库不受数据范围限制,但命中无权客户只提示存在。
4. 代码现状(盘点实锤)
- 全仓库无 crm-customer 模块(9 模块清单:app/auth/base/dict/file/lead/opportunity/preference/rule)。
- 客户数据仅以商机子表快照存在:
opportunity_customer(opportunityId/customerId/customerNameSnapshot/customerRole/isPrimaryIntended)+ 主表primaryCustomerNameSnapshot冗余列——商机域是客户数据的消费者,不是持有者;customerId 目前是无主引用(票 04 添加客户不做存在性校验)。 - 客户类型/角色走 crm-dict 字典;文件走 crm-file(MinIO)——两项基础设施可复用。
- 票 11 种子已用占位 customerId(920000000000000xxx)造了 12 行关联客户样例——客户模块落地后需迁移为真主档 id。
5. 与商机域耦合点(含 D-02 特别回答)
| 耦合点 | 现状 | 客户模块落地后 |
|---|---|---|
| D-02 关联客户 search | 票 04 已实现快照池降级:POST /api/opportunity/customer/search 搜全库 opportunity_customer 快照按名模糊、排除本商机、GROUP BY customer_id |
切换查询源为客户主数据表即可,端点签名/响应结构不变(快照池语义保留为兜底) |
| 添加关联客户(customer/add) | 引用 id + 名称快照,无存在性校验 | customerId 校验切到真主档;名称快照机制保留(回显不依赖外键) |
| 主客户快照(primaryCustomerNameSnapshot) | API 维护冗余列 | 同上,机制保留 |
| 方案卡 customerId | == primaryCustomerId 语义判定(D-17) | 不变 |
| 票 11 种子占位客户 id | 920000000000000xxx 假 id | 迁移真主档 id(数据脚本一次性 UPDATE) |
结论:商机域对客户模块零硬依赖,快照池降级已把 D-02 风险清零;客户模块可独立立项、独立演进。
6. 端点估算(全量口径)
| 域 | 端点 | 数 |
|---|---|---|
| 客户 CRUD+列表三视图 | 新增/编辑/删除/详情/列表/我负责的/归档 | 7 |
| 企查查 | 企业查询/核验回填 | 2 |
| 公海 | 列表/领取/分配/移入/放弃 | 5 |
| 联系人 | CRUD+列表 2 视图+图谱 | 6 |
| 导入 | 客户导入/联系人导入(模板+上传+结果) | 4 |
| 查重 | 查重查询(名称/信用代码)+保存时确认 | 3 |
| 合并 | 预检/字段对比/提交 | 3 |
| 交割 | 发起/预览/分配/记录列表/记录详情 | 5 |
| OCR | 上传/识别/确认回填 | 2 |
| 操作日志/聚合 | 详情聚合+日志 | 3 |
≈ 40 端点量级(票面预估 25-40 的上沿),新表 ≈ 6-8(客户主档/联系人/公海规则/查重记录/合并记录/交割记录/战略协议/操作日志)。
7. 分档结论
- 全量 = 大:合并(关联数据全迁移+单事务)、交割(跨模块级联+原子性)、导入、企查查外部服务、公海规则、职务字典+联系人图谱——深水区六项,任意一项都超出「无新基础设施」口径。
- 最小切片仍 = 大:哪怕只做客户主档+联系人+公海领取/移入+查重提示(砍掉合并/交割/导入/OCR/战略协议),公海机制(负责人为空=公海+进行中商机拦截)与企查查回填已是躲不开的最小集,端点仍 ≈ 15+。
8. 建议(交用户拍板)
- 选项 A(推荐):整模块挂起记 map.md(P2 级别后续迭代);商机域继续用快照池降级(已闭环,无技术债)。若未来客户模块立项,先做「主档+联系人+公海」三件套(切片 B),合并/交割作为二期。
- 选项 B:不挂起,做最小切片 B(主档+联系人+公海)——工作量仍是大档(15+ 端点 + 企查查依赖 + 3-4 新表),需明确接受。
- 选项 C:只做「真客户池种子表」替代快照池(造 30-50 条真主档数据给商机域引用)——半天量级,能让票 11 种子从假 id 变真 id,但不构成客户管理模块。
分界线:是否接受「公海机制 + 外部企业数据服务」这两个最小集要素。接受才是讨论实现的起点,否则一律挂起。