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

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 审计

约束

  1. 主要意向客户唯一:一商机 is_primary_intended=1 至多一条(应用层事务保证;DB 可用「部分唯一索引 UNIQUE(opportunity_id) WHERE is_primary_intended=1」或等价手段,视 MySQL 版本,落地时定)。
  2. 一客户在一商机下只关联一次UNIQUE(opportunity_id, customer_id)
  3. 无孤立:关联客户必属某商机;删商机级联清理(软删口径随商机)。

入口 / 交互

  • 线索转商机(票 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 前沿到达再钉。