10 KiB
03 商机主表字段与归属模型
Type: grilling Status: resolved Blocked by: 01
Question
定 opportunity 主表的字段清单与归属模型(对称线索主表,是后面状态机/公海/子表/视图票的地基)。
- 归属字段:
owner_user_id(领取人 = 决策[B],归属归商机主表)、owner_dept_id(部门快照,兼公海可见范围锚点)、creator_user_id(创建人,全生命周期不变)。票 05 定稿删(商机域无池实体)。pool_id - 两条轴的落点:轴1 归属流转状态字段(单字段,取值见 04);轴2 当前阶段字段(
current_stage_id+ 引用哪个阶段模板stage_template_id/版本)。 - 来源字段:
source_lead_id(可空,见 02)+ 带出快照(商机名称/联系电话/需求产品 code 等)。 - 业务字段(从原型 A3-1-1-2-1 新增/编辑商机抽取):商机名称、行业(字典)、招标形式(字典)、甲方/意向客户、地区(国标 code)、预计金额、预计成交时间、备注等——逐字段定必填/类型/长度/校验。
- 两把计时器?(票 05 已答):线索有回收N/失效M两把;商机只有自动回收(无失效态)。回收锚点 =
last_valid_follow_time(最近有效跟进时间,非 claim_time),见簇 B4。
产出:主表 DDL 级字段规格表(字段名/必填/类型/长度/校验/错误提示)。
Answer
三簇拍板(grilling,产品逐条确认)。主表 opportunity 字段规格表如下。
簇 A — 业务字段(原型 A3-1-1-2-1 抽取,纠正若干脑补)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
opp_name 商机名称 |
varchar(200) | ✅ | |
opp_source 商机来源 |
varchar(64) 字典码 | ✅ | 渠道归因;线索转入时商机侧默认置「线索转入」(票 02) |
opp_type 商机类型 |
varchar(64) 字典码 | ✅ | 原型必填 |
industry_code 行业 |
varchar(64) 字典码 | ✅ | |
bid_form 招标形式 |
varchar(64) 字典码 | ✅ | 原型必填 |
locality_type 项目属地 |
varchar(64) 字典码 | ✅ | 本地/异地分类(产品澄清:不是地理坐标,是分类标签) |
party_a_clear 甲方是否明确 |
tinyint 0/1 | ✅ | |
party_a 甲方名称 |
varchar(200) | 条件必填 | party_a_clear=1 时必填 |
province_code 省份 |
varchar(12) | ✅ | 对称 lead |
city_code 市/区 |
varchar(12) | ✅ | 对称 lead 约定:既可填市码也可填区/县码(不单建 district_code) |
remark 备注 |
text | ✕ |
不建:预计金额、预计成交时间(原型 A3-1-1-2-1 必填清单无,尊重原型不脑补,产品确认不建)。✅ 票 10 口径冲突已解(产品二次拍板):「预计成交时间」列从商机列表删除,不上商机主表。它本是方案卡内部字段(票 07),仅存在于方案卡,不进商机四视图列表。故主表无需建 expected_deal_date。
簇 B — 归属 + 两轴 + 来源 + 计时器
B1 归属(票 02 已大半定):
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
owner_user_id 领取人 |
bigint | ✕ | 抛公海后清空;归属+可见性;票 01 |
owner_name_snapshot 领取人姓名快照 |
varchar(64) | ✕ | 对称 lead |
owner_dept_id 领取人部门快照 |
bigint | ✕ | 票 02:调岗不变 |
pool_reason 进入公海原因 |
varchar(32) | ✕ | 票 10 新增:抛公海/回收时写(销售主动释放/特殊原因暂停/领导释放/超期回收,→字典);公海列表筛选。入池前工作节点复用 current_stage_id(不单建快照字段) |
creator_user_id 创建人 |
bigint | ✅ | 全生命周期不变;票 01 |
pool_id 来源公海池 |
― | ― | 票 05 定稿删除(推翻初稿 Amendment):商机域无独立池实体(原型 A7-3-2-5 确认公海=版本化规则,非 lead_pool 实体);公海 = opp_status=1 且 owner 为空 的逻辑视图,可见范围由 owner_dept_id + 匹配规则适用范围判定,不需外键指向池 |
不建(票 05 定稿):dept_id(归属部门)、team_dept_id、pool_name_snapshot——商机主表只用 owner_dept_id(快照)做 DataScope 部门天花板;部门/团队/市场模型全落在 opportunity_pool 族(票 05),不上主表。
B2 两条轴(票 01 定两轴命名):
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
opp_status 状态 |
tinyint | ✅ | 轴 1 归属流转;取值票 04 定 |
current_stage_id 当前阶段 |
bigint | ✅ | 轴 2;指向 opportunity_stage_node.id(绑定模板版本下的某节点,票 06 定稿);新建默认落首节点(客户圈定) |
stage_template_id 阶段模板 |
bigint | ✅ | 票 06 定稿:存模板版本行 id(opportunity_stage_template.id,版本级锁死,非 code);绑定时按适用范围匹配当时最新发布版本,发新版不自动迁移(在途商机续用原版本) |
stage_template_version 阶段模板版本号 |
varchar(20) | ✅ | 票 06 定稿(原占位 int→改 varchar):冗余 version_no(V1.2 等)展示用免 join;版本锁由 stage_template_id 保证 |
B3 来源快照(票 02 拍死,此处对齐):
| 字段 | 类型 | 说明 |
|---|---|---|
source_lead_id 来源线索 |
bigint UNIQUE | 幂等键;NULL 不参与唯一(直接创建可多条 NULL);票 02 |
source_lead_name 线索名快照 |
varchar(200) | |
source_phone 联系电话快照 |
varchar(32) | |
source_product_code 需求产品码快照 |
varchar(64) |
B4 计时器:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
claim_time 领取时刻 |
datetime | ✕ | 归属起点;抛公海时不清(对称 lead) |
last_valid_follow_time 最近有效跟进时间 |
datetime | ✕ | 票 05 定稿回填(推翻初稿 recycle_deadline):自动回收计时锚点。回收判定 = now − last_valid_follow_time ≥ rule.recycle_days(Job 实时算,不预存 deadline)。有效跟进(跟进记录/附件/字段编辑,非浏览)时刷新(票 09 联动) |
不建(票 05 定稿):expire_deadline——商机无「过期失效」态(票 04),线索的失效计时器 M 不对称。
簇 C — 系统字段 + 索引 + DataScope + 高频展示冗余
-
C1 继承
BaseEntity:Opportunity extends BaseEntity,复用 id / 审计(create_time/update_time/creator/updater)/ 逻辑删除,不自建。 -
C2 DataScope 注解:
@DataScope(module="opportunity", ownerColumn="owner_user_id", deptColumn="owner_dept_id")。deptColumn 用owner_dept_id(因 B1a 不建dept_id)。module 名对齐票 01 + ADR-0018(按模块可配)。 -
C3 主要意向客户快照冗余进主表(高频展示,对称 lead 反馈快照冗余):
字段 类型 说明 primary_customer_id主要意向客户 idbigint = 关联客户表中 is_primary_intended=1那条的customer_id(票 13);引用 A4(未建)primary_customer_name_snapshot主客户名快照varchar(200) 高频展示,列表/详情顶部免 join;切换主客户时同步刷新 ✅ 完整关联客户子表 = 票 13(
opportunity_customer,含is_primary_intended主客户标记 +customer_role角色),已从“另议”钉死。一商机有且仅一个主要意向客户;UNIQUE(opportunity_id, customer_id)。主表此两字段仅为主客户冗余快照。 -
C4 起步索引(票 05/10 视图定稿后再补):
UNIQUE idx_source_lead(source_lead_id) — 幂等键(票 02)idx_owner_status(owner_user_id,opp_status) — 「我负责的」视图idx_owner_dept_status(owner_dept_id,opp_status) — 公海视图(opp_status=1)+ 部门天花板(票 05:公海=逻辑视图,无 pool_id)idx_owner_dept(owner_dept_id,opp_status) — 部门天花板
未定/传出决策(不阻塞本票)
opp_status取值域 → 票 04票 06 已定:stage_template_*版本模型stage_template_id=版本行 id 锁版本,stage_template_version=冗余版本号 varchar,current_stage_id→节点 id;绑定不自动迁移。票 05 已答:删 pool_id(无池实体),新增pool_id是否引用商机公海池last_valid_follow_time回收锚点。- 关联客户子表完整字段 → 票 13(
opportunity_customer;customer_id引用挖 A4、下拉选客户能力挂 A4/票 11) dept_id/team_dept_id是否补建 → 票 05 公海规则出结论后回看
已核实事实
- 原型 A3-1-1-2-1 必填清单:商机名称 / 商机来源 / 商机类型 / 商机行业 / 项目阶段 / 招标形式 / 项目区域(省市区) / 项目属地 / 甲方是否明确 / 关联客户 / 客户角色 / 是否主要客户 + 甲方名称(条件)。原型无预计金额/成交时间。
- lead 主表
city_code约定:既可填市码也可填区/县码;商机对称沿用。 - 项目属地 = 本地/异地字典分类(产品澄清,非地理坐标,与项目区域正交)。
Amendment 1 — 新增 project_amount(项目金额)
产品口径变更:商机需记录项目整体总包金额(销售挖掘得来的),本票原「不建预计金额/成交时间」的前一半推翻——项目金额建,预计成交时间仍不建。
业务字段组新增一行:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
project_amount 项目金额 |
decimal(14,2) | ✕ | 项目整体总包金额;销售新增商机时选填(早期未必知,可后编缓补);默认人民币元,不建币种字段 |
与「方案预算」区分(反正两个金额容易混):
- 项目金额
project_amount= 商机主表字段,项目整体总包,一个商机一个值。 - 方案预算
scheme_budget= 方案卡子表字段(票 07),销售对该商机下某个方案卡填的金额,一个商机可多个方案卡→多个预算。商机列表的「方案预算」列 = 关联查主要意向客户(票 13)那张方案卡的预算,主表不冗余(一客户一卡;票 07/13 处理)。