You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
4.5 KiB
4.5 KiB
13 商机-客户关联子表(关联客户 + 主要意向客户)
Type: spec Status: resolved Related: 03, 07, 10, 11
背景
原型确认:一个商机维护多个关联客户,其中恰好一个标记为主要意向客户。产品口径拍板(本票):
- 线索转商机时填的「意向客户」→ 落为该商机的主要意向客户(
is_primary_intended=1)。 - 商机侧可添加普通关联客户(
is_primary_intended=0)。 - 可修改主要意向客户(切换标记,事务内旧主→0 新主→1)。
- 商机有且只有一个主要意向客户。
原型证据(概览页 A3-1-1-1-1 / 客户信息页 A3-1-1-1-2,存档 research-a31111-detail-overview.md):
- line 546/763:「主要意向客户」字段;line 769「同一商机原则上仅展示一个主要意向客户」。
- line 1235「取关系标记为『主要意向客户』的关联客户」。
- line 1269-1275「其他关联客户」= 除甲方和主要意向客户以外的关联客户,多条动态展示。
- line 1334 客户角色示例:机电总包/工程商/集成商 → crm-dict 字典。
- line 786「每张方案卡需关联当前商机下的一个客户」+ 810「不允许无客户归属的孤立方案卡」。
之前票 03 line 87-94 把该子表记为「另议/挂 A4 依赖」、map.md 列在 Not yet specified;本票将其钉死并成实体。
决策
实体 opportunity_customer(住 crm-opportunity)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
id |
bigint PK | ✅ | |
opportunity_id |
bigint | ✅ | 所属商机(外键语义,不建物理 FK 视仓库约定) |
customer_id |
bigint | ✅ | 引用 A4 客户模块(未建)→ 先存 id + 名快照,同票 11 走法(引用+快照并存) |
customer_name_snapshot |
varchar(200) | ✅ | 客户名快照,免 join,列表/详情高频展示 |
customer_role |
varchar(32) | 条件 | 客户角色(机电总包/工程商/集成商…)→ crm-dict 新增「客户角色」分组 |
is_primary_intended |
tinyint 0/1 | ✅ | 是否主要意向客户;一商机唯一 =1 |
create_time/create_user_id |
✅ | 审计 |
约束
- 主要意向客户唯一:一商机
is_primary_intended=1至多一条(应用层事务保证;DB 可用「部分唯一索引UNIQUE(opportunity_id) WHERE is_primary_intended=1」或等价手段,视 MySQL 版本,落地时定)。 - 一客户在一商机下只关联一次:
UNIQUE(opportunity_id, customer_id)。 - 无孤立:关联客户必属某商机;删商机级联清理(软删口径随商机)。
入口 / 交互
- 线索转商机(票 11 实现):
cmd.customerId()→ 建一条is_primary_intended=1主要意向客户。 - 商机侧添加关联客户(A3-1-1-2-4):建
is_primary_intended=0普通关联客户。 - 修改主要意向客户:事务内把原
=1置 0、目标置 1;始终保持恰好一条主客户。 - 客户信息 Tab(A3-1-1-1-2):主要意向客户 + 其他关联客户分区展示(原型 line 1269)。
与主表 / 方案卡 / 列表联动
- 主表冗余(票 03 C3):
primary_customer_id+primary_customer_name_snapshot冗余进商机主表(= 主要意向客户 id/名),高频展示免 join;切换主客户时同步刷新主表冗余。 - 方案卡(票 07)一客户一卡:方案卡表加
UNIQUE(opportunity_id, customer_id)(Q2 产品确认)。每张方案卡必挂一个当前商机下的关联客户(无孤立卡)。 - 列表派生列(票 10 / P0-4):
- 方案预算列 = 主要意向客户那张方案卡的
scheme_budget(无卡则空)。 - 方案卡状态列 = 主要意向客户那张方案卡的
card_status(无主客户卡 → 未创建)。 - 不引入
is_primary(主卡):主键是客户不是卡;取值锚点 = 主要意向客户(is_primary_intended)。
- 方案预算列 = 主要意向客户那张方案卡的
依赖 / 遗留
- A4 客户模块(未建):
customer_id引用真实客户实体、"添加关联客户"下拉数据源均依赖 A4。A4 到达前,本子表可建(引用 id + 名快照走法),但下拉选客户能力挂 A4(同票 11)。 - crm-dict 新增「客户角色」分组(机电总包/工程商/集成商…原型示例,实际选项集待产品)。
- ⚠ 遗留(不阻塞建模):客户联系人是否本子表冗余,还是随 A4 客户/联系人查(原型客户信息页展示联系人/职务/电话)——挂 A4 边界,A4 前沿到达再钉。