15 KiB
02 — 客户主表字段清单
Type: research Status: resolved
⚠ 20260902 复核注记:本文件
archiveStatus仍写三值(有效1/已归档2/已被合并3)。D19 已拍板去掉「已被合并」(合并 Out-of-scope),收敛为有效1/已归档2。以02-answer.md为准。 Blocked by:
问题
定客户主表 customer 的完整字段清单 + 索引 + DataScope 注解。这是扇出最广的票,其他票(三视图/查重/交割/阶段)回填它。
一手证据(蓝湖缓存 txt)
a4-3-3-1_新增客户信息.txt— 新增页字段(基本信息/工商信息/跟进人员/关联信息/补充资料五区)a4-4-1_客户详情_客户信息_.txt— 详情页字段分区(基本信息/关联信息/补充资料/工商信息/系统信息)a4-2-1_客户总览列表_列表视图_.txt— 列表列 + 字段设置项
已知字段线索(待核实归类)
- 系统生成:客户编号
customer_no(KH+日期+序,只读)、创建人/时间、修改人/时间。 - 基本信息:客户名称*、客户类型*(字典)、所属地区*(省市区)、行业*(两级树,复用 crm-dict
industry)、客户星级*(一~五星)、关系星级*(一~五星)、人脉关系单位(标签集)、公司决策人。 - 归属(轴1):
owner_user_id(销售负责人*)+owner_dept_id(销售部门*快照)+协同人(团队子表)。 - 阶段(轴2):
customer_stage(潜在/重潜/已成交)。 - 档案状态:
archive_status(有效/已归档/已被合并)。 - 战略协议(划出):
战略协议等级列在列表出现——但战略协议子域划出,主表是否冗余一个等级快照列供列表展示?→ 本票决定(建议:留strategic_agreement_level快照列供列表,实体本身划出)。 - 已成交VIP客户等级:列表有列 → 主表字段还是 A5 驱动?待定(疑似阶段=已成交后的细分,可能留 seam)。
- 工商信息(企查查回填):统一社会信用代码(唯一)、法定代表人、成立时间、注册资本、经营范围、人员规模、年产值、公司地址、工商名称。
- 关联信息:是否商机勾兑*、总监近期拜访时间、是否子客户*(是→父客户关联必填)、父客户关联(禁自身及下级/防环)、合作系统、不合作原因、是否参加总裁班/产品经理班(+参加人/电话,条件必填)。
- 补充资料:备注(≤500)、附件(crm-file)。
待拍板点(research 中逐一给推荐 + grill)
- 战略协议等级 / 已成交VIP等级 是否主表冗余快照列(战略协议实体划出)?
- 父子客户:自关联
parent_customer_id+ 防环校验口径。 - 客户类型字典分组(
customer_type)取值:甲方(企业/政府/普教/中高职/高校)… 需列全。 - 客户星级/关系星级:字典 or 定长枚举(一~五星)?
- 冗余快照列(列表免 join):最近跟进时间、关联业务计数(商机/项目)、owner 名快照。
- DataScope:
@DataScope(module="customer", ownerColumn="owner_user_id", deptColumn="owner_dept_id")。 - 索引:UNIQUE 统一社会信用代码 / owner+stage / owner_dept+archive_status(公海视图)。
Answer
Status: resolved(P0 已全部销号:customer_type=18值字典/D18、行业二级、星级硬编码/D4-rev1;含 grill Q8/Q15 回填)
Status: resolved
A. 客户主表 customer(crm-customer)
A1. 字段清单
系统字段(BaseEntity 继承)
| Java 字段 | 列名 | 类型 | 说明 |
|---|---|---|---|
| id | id | bigint PK | 自增主键 |
| createTime | create_time | datetime | 创建时间 |
| updateTime | update_time | datetime | 最后修改时间 |
| createBy | create_by | bigint | 创建人 user_id |
| updateBy | update_by | bigint | 最后修改人 user_id |
| deleted | deleted | tinyint(1) default 0 | 逻辑删除 |
业务字段 — 系统生成
| Java 字段 | 列名 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| customerNo | customer_no | varchar(32) | 系统生成 | 唯一编号,格式 KH+yyyyMMdd+4位序;只读不可改 |
业务字段 — 基本信息
| Java 字段 | 列名 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| customerName | customer_name | varchar(100) | ✅ | 客户名称;停输防抖触发相似查重 |
| customerType | customer_type | varchar(50) | ✅ | 客户类型字典 customer_type;见 A3 字典节 |
| provinceCode | province_code | varchar(20) | ✅ | 省(三级地区,与商机对称) |
| cityCode | city_code | varchar(20) | ✅ | 市 |
| districtCode | district_code | varchar(20) | 区/县(客户有三级,商机只二级) | |
| industryCode | industry_code | varchar(50) | ✅ | 行业一级 code(复用 crm-dict industry 两级树;客户选到二级,见商机图 D1「行业字典口径」决策:商机选一级、客户选二级) |
| industryChildCode | industry_child_code | varchar(50) | 行业二级 code(客户额外存二级;商机无此列) | |
| customerStarLevel | customer_star_level | tinyint | ✅ | 客户星级 1~5(枚举,非字典;字典值「一星/二星/…/五星」=前端展示用,存数字) |
| relationStarLevel | relation_star_level | tinyint | ✅ | 关系星级 1~5(同上) |
| networkUnits | network_units | text | 人脉关系单位,JSON 数组存标签名(单个≤50字;非关联 CRM 客户;选填) |
⚠ JPA/Hibernate 孤立单大写字母规则(AGENTS.md):
districtCode/industryCode/industryChildCode/provinceCode/cityCode/customerNo/customerStarLevel/relationStarLevel— 均为「完整词+Code/Level/No」,非孤立单大写,不需加@Column(name=...)。
业务字段 — 归属(轴1)
| Java 字段 | 列名 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| ownerUserId | owner_user_id | bigint | ✅(新增时) | 销售负责人 user_id;公海时为 NULL |
| ownerUserNameSnapshot | owner_user_name_snapshot | varchar(64) | 负责人姓名快照(列表免 join) | |
| ownerDeptId | owner_dept_id | bigint | ✅(新增时) | 销售部门 dept_id 快照;公海时保留最后部门(供公海可见性锚点,对称商机) |
| ownerDeptNameSnapshot | owner_dept_name_snapshot | varchar(64) | 部门名快照 |
协同人(团队成员)= 独立子表
customer_team_member(不在主表)。
业务字段 — 轴2 阶段 + 档案状态
| Java 字段 | 列名 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| customerStage | customer_stage | tinyint default 1 | 客户阶段:潜在1/重潜2/已成交3;只增不减;不可手动改 | |
| archiveStatus | archive_status | tinyint default 1 | 档案状态:有效1/已归档2/已被合并3;正交于归属 |
业务字段 — 快照/冗余(列表免 join)
| Java 字段 | 列名 | 类型 | 说明 |
|---|---|---|---|
| lastValidFollowTime | last_valid_follow_time | datetime | 最近有效跟进时间;超期提醒计时锚点 = 成为「有主」的时刻(新建即指派=create_time;公海领取时=领取时刻;每写一条跟进记录刷新);公海无负责人=NULL不提醒 |
| strategicAgreementLevel | strategic_agreement_level | tinyint | 战略协议等级快照(1~3级;战略协议子域划出但主表留此冗余供列表展示;NULL=未签);由战略协议子系统写入,本图只读 |
| vipCustomerLevel | vip_customer_level | tinyint | 已成交VIP客户等级快照(1~5级;NULL=无;由 A5 项目模块写入,本图只读/留 seam) |
⚠
strategicAgreementLevel→ Hibernate 命名策略孤立单大写字母:Level前面的l是小写 →strategicAgreement+Level整段。实测SpringPhysicalNamingStrategy对strategicAgreementLevel生成strategic_agreement_level✅(Level是完整词,无问题)。但vipCustomerLevel→vip首字母v是小写,C是孤立大写?→ 不是,vip是小写词,Customer是完整词,Level是完整词,不踩坑。
业务字段 — 关联信息
| Java 字段 | 列名 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| companyDecisionMaker | company_decision_maker | varchar(100) | 公司决策人(文本) | |
| isBizNegotiated | is_biz_negotiated | tinyint | ✅ | 是否商机勾兑(是1/否0) |
| directorVisitTime | director_visit_time | datetime | 总监近期拜访时间(人工维护,日期时间) | |
| isChild | is_child | tinyint default 0 | ✅ | 是否子客户(是1/否0);=1时 parent_customer_id 必填 |
| parentCustomerId | parent_customer_id | bigint | 条件必填 | 父客户 id;服务端防环校验;isChild=0时为 NULL |
| parentCustomerNameSnapshot | parent_customer_name_snapshot | varchar(100) | 父客户名称快照 | |
| cooperationSystem | cooperation_system | varchar(200) | 合作系统(文本,选填) | |
| nonCoopReason | non_coop_reason | varchar(200) | 不合作原因(文本,选填) | |
| joinedPresidentClass | joined_president_class | tinyint | 是否参加总裁班(是1/否0/NULL=未选) | |
| presidentClassPerson | president_class_person | varchar(100) | 条件必填 | 总裁班参加人(joinedPresidentClass=1时必填) |
| presidentClassPhone | president_class_phone | varchar(20) | 条件必填 | 总裁班参加人电话 |
| joinedProductClass | joined_product_class | tinyint | 是否参加产品经理班 | |
| productClassPerson | product_class_person | varchar(100) | 条件必填 | 产品班参加人 |
| productClassPhone | product_class_phone | varchar(20) | 条件必填 | 产品班参加人电话 |
业务字段 — 工商信息(企查查回填)
| Java 字段 | 列名 | 类型 | 说明 |
|---|---|---|---|
| unifiedCreditCode | unified_credit_code | varchar(18) | 统一社会信用代码;UNIQUE(NULL 除外,未填时不唯一约束);18 位格式校验 |
| legalRepresentative | legal_representative | varchar(100) | 法定代表人 |
| establishedDate | established_date | date | 成立时间(不得晚于当前日期) |
| registeredCapital | registered_capital | varchar(100) | 注册资本(文本,含单位,如「1000万元」) |
| businessScope | business_scope | text | 经营范围(不套 50 字限制) |
| staffSize | staff_size | varchar(50) | 人员规模 |
| annualRevenue | annual_revenue | varchar(50) | 年产值 |
| businessAddress | business_address | varchar(500) | 工商注册地址(不套 50 字限制) |
| bizNameFromLookup | biz_name_from_lookup | varchar(200) | 企查查确认的工商名称(可与 customer_name 不同;只存不覆盖 customer_name,除非用户确认) |
业务字段 — 补充资料
| Java 字段 | 列名 | 类型 | 说明 |
|---|---|---|---|
| remark | remark | varchar(500) | 备注(≤500字) |
附件 = 独立子表
customer_attachment(复用 crm-file,biz_type=CUSTOMER;不在主表)。
A2. 需要显式 @Column(name=...) 的孤立单大写字母字段
检查全部字段——结论:本表无需加 @Column(name=...)。所有字段均为「完整词 + 完整词」组合,无孤立单大写字母触发 Hibernate 命名策略陷阱。
A3. 字典清单(新增/复用)
| 字典分组 code | 含义 | 状态 | 参考值 |
|---|---|---|---|
customer_type |
客户类型 | 🆕 需新增 | (grill Q8/D18 定稿,18 值) 运营商 / 土建总包 / 机电总包 / 装修总包 / 教育局 / 投资(代建)公司 / 设计院 / 集成商 / 集成商(子客户) / 咨询造价公司 / 甲方(企业用户) / 甲方(普教) / 甲方(中高职) / 甲方(政府机关) / 竞争同行 / 个人用户 / 操手 / 招标代理 |
industry |
行业(两级树) | ✅ 已有(商机图票09已建;9一级+51二级) | 复用 |
customer_star_level |
客户星级 | 硬编码枚举 1~5(D4-rev1 定稿,不走字典) | 1~5 星 |
relation_star_level |
关系星级 | 硬编码枚举 1~5(D4-rev1 定稿,不走字典) | 一星~五星 |
✅ 已定(grill Q8/D18):
customer_type= crm-dict 字典分组,18 值(见上表)。注意含 4 个甲方值 + 14 个非甲方角色值,是通用角色字典,非仅甲方。
A4. DataScope 注解
@DataScope(module = "customer", ownerColumn = "owner_user_id", deptColumn = "owner_dept_id")
复用 crm-auth DataScopeEnum(SELF/DEPT/DEPT_AND_CHILD/ALL),不新建可见性机制。
A5. 索引
| 索引名 | 列 | 说明 |
|---|---|---|
uk_unified_credit_code |
unified_credit_code |
信用代码全局唯一(NULL 不参与唯一约束,MySQL 默认行为) |
idx_owner_stage |
owner_user_id, customer_stage, deleted |
我的客户视图常用过滤 |
idx_dept_stage |
owner_dept_id, archive_status, deleted |
公海/总览部门维度 |
idx_name |
customer_name |
相似查重防抖查询 |
idx_parent |
parent_customer_id |
父子客户查询/防环 |
idx_last_follow |
last_valid_follow_time, owner_user_id |
超期未跟进提醒扫表 |
A6. 待产品确认(⚠ P0)
| # | 问题 | 影响 |
|---|---|---|
| P0-1 | customer_type 完整枚举值 |
字典种子数据 |
| P0-2 | industry_code + industry_child_code 两列;与商机图 D1「商机选一级、客户选二级」一致) |
两列 |
| P0-3 | 存储类型 | |
| P1-1 | vip_customer_level 等级范围(原型列表列有「已成交VIP客户等级」但详情字段写「1~5级」,待确认范围及触发条件,本图只留 seam) |
— |
| P1-2 | strategic_agreement_level 战略协议等级范围(原型见「一级/二级/三级」=1~3;战略协议子域划出,主表只存冗余快照,待战略协议 effort 回填写逻辑) |
— |
A7. 回填 ticket 02 的下游影响
- 票 03(三视图):
archiveStatus过滤(有效1/已归档2,归档=删除见 D19),ownerUserId IS NULL= 公海视图;last_valid_follow_time排序。 - 票 04(查重):
unified_credit_codeUNIQUE 索引 +customer_nameidx 是查重的存储底座。 - 票 05(阶段):
customer_stage默认1,只能 UPDATE SET customer_stage=? WHERE id=? AND customer_stage < ?(只前进)。 - 票 07(oplog):
last_valid_follow_time新建即指派=create_time;公海领取时赋领取时刻;跟进刷新。 - 票 08(交割):
ownerUserId+ownerDeptId是交割换主的操作列。 - 票 10(超期提醒):
last_valid_follow_time是计时锚点 = 成为有主时刻(grill Q15 拍板 A):新建即指派=create_time;公海领取=领取时刻;跟进刷新。公海(NULL)不计时。