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.
 
 
 
 
 

13 KiB

线索实体与字段模型

Type: grilling Status: resolved Blocked by: 04

Question

定义 crm-lead 的线索实体字段全集,作为 crm-lead 的地基。字段来源:新增线索表单 + 四视图列表字段 + 线索详情。

需在本 ticket 定清:

  1. 基础字段:线索名称、联系电话(含校验:手机/座机)、微信(校验)、电子邮箱(校验)、省份、城市、详细地址、渠道(字典)、品牌(字典)、需求产品(字典)、需求场景(字典)、咨询内容、是否加急。
  2. 流转/归属字段:线索状态(见 ticket 03)、所属公海池(引用 crm-rule 公海池 id)、领取人(AuthUser.id)、销售团队/销售部门(冗余还是从领取人推导?)、新增人员、新增时间、超时回收剩余有效期(计算字段还是存储?)。
  3. 反馈相关字段:反馈情况(有效/无效/未反馈)、反馈内容、最后反馈时间——存最新一条在主表,还是全部在反馈子表由主表冗余最新值?
  4. 关注:关注是"用户×线索"关联(我的关注列表 + 关注总人数),独立关联表。
  5. 客户相关文件:线索详情可下载附件——走 crm-file?关联形态。
  6. 必填/校验/字典绑定:哪些字段绑定哪个字典分组(对齐 crm-dict 的字段-分组绑定约定)。
  7. 哪些字段冗余:为列表筛选/展示性能,哪些跨模块字段(部门/团队/池名)冗余存储 vs 实时 join。

产出:线索实体字段表(名称/类型/必填/字典绑定/来源/冗余策略),写入 ## Answer;术语进 crm-lead/CONTEXT.md。依赖 03(状态)、04(公海池 id)。

Decisions(grill 定稿)

  • [Q1=a] 联系电话单字段 phone varchar(32),正则同时兼容手机/座机/带区号。
  • [Q2=c] 反馈:统一操作日志子表 lead_history + 主表冗余最新反馈 5 列(feedback_status/content/time/by/product)。写反馈时事务内插子表 + 更新主表最新值。历史记录 Tab 复用同一张 lead_history(含领取/释放/反馈/新增/编辑等所有操作类型)。⚠ 见 Amendment 2:拆出 lead_feedback 独立表(草稿/提交双态)。
  • [Q3=a] 团队/部门/领取人名 快照冗余;dept_id 冗余(= 池的 dept_id,因一部门一池永不变);team_dept_id 同理。领取/释放时刷新快照。
  • [Q4=b] recycle_deadline / expire_deadline 存字段。
    • 领取时:recycle_deadline = claim_time + pool.recycle_days
    • 新增反馈时:重置 recycle_deadline = now + pool.recycle_days(反馈重置回收倒计时)
    • expire_deadline = create_time + pool.expire_days(永不清零;仅激活时按 03 重置)
    • pool 配置变更时:批量 UPDATE 该池所有已领取/跟进中线索的对应截止时刻;本身不当日回收,等次日定时任务扫。
  • [Q5=a] 附件走 crm-file;关联表 lead_attachment(id, lead_id, file_id)
  • [Q6=a] 关注纯关联表 lead_follow(id, user_id, lead_id, follow_time)关注总人数COUNT(*) 现算,不主表冗余。
  • [Q7=ii] 字典字段(channel/brand/product/scene)存 code varchar(64),跨环境稳定;展示时 JOIN crm-dict 取 label。

Answer

一、lead 主表字段全集

分组 字段 类型 必填 来源/说明
主键 id bigint Y PK
基础 lead_name varchar(200) N 线索名称
phone varchar(32) N 单字段兼容手机/座机
wechat varchar(64) N 微信号(校验)
email varchar(128) N 邮箱(校验)
province_region_id bigint Y sys_region level=1
city_region_id bigint Y sys_region level=2/3,联动省
address varchar(255) N 详细地址
业务来源 channel_code varchar(64) Y 字典 code(渠道分组)
brand_code varchar(64) Y 字典 code(品牌分组)
product_code varchar(64) Y 字典 code(需求产品分组)
scene_code varchar(64) N 字典 code(需求场景分组)
核心 consult_content text Y 咨询内容
status tinyint Y 线索状态(见 03,7 态)
is_urgent tinyint Y 是否加急 0/1,默认 0
归属 pool_id bigint Y 公海池外键(crm-rule)
pool_name_snapshot varchar(100) Y 冗余快照,池改名要级联刷
dept_id bigint Y 冗余 = 池的 dept_id,一部门一池永不变
team_dept_id bigint Y 冗余 = 池的 team_dept_id
owner_user_id bigint N 领取人;未领取时 NULL
owner_name_snapshot varchar(64) N 领取人姓名冗余
owner_dept_id_snapshot bigint N 领取时销售所属部门快照(≠ 归属 dept_id,用于审计)
create_by / create_time Y BaseEntity, 新增人=销售
时效 claim_time datetime N 领取时刻
recycle_deadline datetime N 回收截止时刻(存字段,索引)
expire_deadline datetime Y 失效截止时刻 = create_time + pool.M
反馈快照 feedback_status tinyint N 有效/无效/未反馈
feedback_content text N 最新反馈内容
feedback_time datetime N 最新反馈时刻
feedback_by_user_id bigint N 最新反馈人
feedback_product_code varchar(64) N 最新反馈对应需求产品字典 code
BaseEntity update_by/update_time/deleted 逻辑删除;一律不可物理删(见 03)

必填项 = 城市、渠道、品牌、需求产品、咨询内容 5 项(含省份是必填但由城市联动导出)。原型明标 *

索引

  • idx_pool_status (pool_id, status) — 公海视图筛选
  • idx_owner_status (owner_user_id, status) — 我的线索
  • idx_recycle_deadline (recycle_deadline) — 定时回收 job
  • idx_expire_deadline (expire_deadline) — 定时失效 job
  • idx_dept_status (dept_id, status) — 部门负责人/管理员视图筛选

二、关联/子表

lead_history                                    -- 统一操作日志(含反馈)
├─ id, lead_id, op_type, op_time, op_user_id, op_user_dept_name, detail
├─ op_type: CREATE/CLAIM/RELEASE/FEEDBACK/EDIT/ASSIGN/CONVERT/EXPIRE/RECYCLE/ACTIVATE/...
└─ FEEDBACK 类的 detail 含: feedback_status/feedback_content/feedback_product_code

lead_follow(id, user_id, lead_id, follow_time)  -- 关注 M:N
  UNIQUE(user_id, lead_id)

lead_attachment(id, lead_id, file_id)           -- 客户相关文件, file_id 引用 crm-file

关注总人数SELECT COUNT(*) FROM lead_follow WHERE lead_id=? 现算,不入主表冗余。

三、快照刷新时机

触发 刷新
领取 claim_time owner_user_id owner_name_snapshot owner_dept_id_snapshot recycle_deadline
反馈 feedback_* 5 列 + recycle_deadline = now + pool.N
释放/超时回收 owner_* 清空、claim_time/recycle_deadline 清空;反馈 5 列不清空(grill #5)
激活(F2) expire_deadline = now + pool.M + recycle_deadline = now + pool.N(grill #6,N 也重置)
池改名 批量刷 pool_name_snapshot
池 recycle_days 变 批量刷该池已领取/跟进中的 recycle_deadline = claim_time + new_N
池 expire_days 变 批量刷该池全部非终态的 expire_deadline = create_time + new_M

四、字段-字典绑定(对齐 crm-dict)

字段 字典分组 code
channel_code lead.channel
brand_code lead.brand
product_code lead.product(反馈中的 feedback_product_code 同 group)
scene_code lead.scene

存 code,展示 JOIN crm-dict 取 label。

五、依赖声明

  • crm-authAuthUser/SysDept(领取人、部门归属、快照)。
  • crm-ruleLeadPool(外键 + 池名快照)。
  • crm-dict:4 个字典分组(channel/brand/product/scene)。
  • crm-region(ticket 02=1a 新建):sys_region 省市区。
  • crm-file:附件文件 id。

六、CONTEXT 登记

  • crm-lead/CONTEXT.md:线索术语(领取/反馈/释放/关注/加急/回收截止/失效截止)、快照策略、字典绑定、7 状态引用。
  • CONTEXT-MAP.md 已有 crm-lead 行,无需新增。

七、下游影响

  • 08 转商机 port:转商机时传的字段集从本表选取(Q 待 08 定)。
  • 05 权限方向dept_id@DataScope 的 dept 列已在 05 定,本表落地。
  • 04 池配置变更:pool save service 需触发本表批量刷 recycle_deadline/expire_deadline/pool_name_snapshot

Status

本 ticket 字段模型已定稿可交付 → resolved。

Amendment(08 追加)—— 省市字段改存 code

原 Answer 中 province_region_id / city_region_id(bigint FK)修正为存国标 code

原字段 修正为 说明
province_region_id bigint province_code varchar(12) 国标 GB/T 2260 省代码(6位,如 440000
city_region_id bigint city_code varchar(12) 国标 GB/T 2260 市/区代码(如 440100广州市 或 440106天河区)

理由

  1. 存 code 与 crm-dict 存 code 的既有约定一致(Q7=ii)
  2. 支持前缀 LIKE 祖先查询(WHERE city_code LIKE '4401%' 命中广州市本级 + 所有区),无需 JOIN sys_region
  3. code 是国标稳定标识,跨环境/跨系统对齐

依赖:sys_region 表 code UNIQUE 字段(见 02 Amendment)。

其余 06 定稿不变:字段名、必填标记、其他字段、索引/子表全部保留(相关索引 idx_dept_status 等不涉及省市字段无需改)。

Amendment 2(2026-08-12 grill)—— 拆出 lead_feedback 独立表 + 快照保留 + 激活重置 N

A2.1 [Q2=c] 改写:拆出 lead_feedback 独立表(grill #3)

改前:反馈直接写 lead_history FEEDBACK 记录(detail 含 content),主表冗余最新值。

改后:拆出独立的 lead_feedback 表,支持草稿/提交双态:

lead_feedback
├─ id, lead_id, user_id
├─ feedback_status, content, product_code
├─ attachment_ids  json     -- crm-file 文件 id 列表
├─ record_status   tinyint  -- 1=DRAFT, 2=SUBMITTED
├─ created_at, submitted_at
└─ INDEX(lead_id, user_id, record_status)
  • 【保存草稿】:写/更新 lead_feedbackrecord_status='DRAFT',不校验必填,不改状态机,不写 lead_history,不刷主表快照。
  • 【保存】(正式提交)lead_feedbackrecord_status='SUBMITTED',主表更新 5 列快照,状态迁移(已领取→跟进中),N 重置,写 lead_history FEEDBACK 记录(detail 引用 lead_feedback.id不冗余内容)。

理由:原型有“保存草稿”按钮,spec 未覆盖;拆表后草稿不污染操作日志,历史 Tab 从 lead_history 取,反馈内容从 lead_feedback 取。

⚠(C) 已解决:反馈可上传附件,存 lead_feedback.attachment_ids

A2.2 快照刷新表修正(grill #5 + #6)

触发 原规则 修正后
释放/超时回收 owner_* 清空、claim_time/recycle_deadline 清空、反馈 5 列也清空 owner_*claim_timerecycle_deadline 清空;反馈 5 列不清空(保留供下一位参考)
激活 expire_deadline = now + pool.M expire_deadline = now + pool.M + recycle_deadline = now + pool.N(N 也重置)

A2.3 池 N 改动刷新修正

原快照表“池 recycle_days 变”行写的是 recycle_deadline = claim_time + new_N,对已领取和跟进中未区分。

修正

  • 已领取:recycle_deadline = claim_time + new_N
  • 跟进中:recycle_deadline = last_feedback_time + new_N

Amendment 3(2026-08-13 续 grill)

A3.1 lead_history 全量 11 种类型,页面只展示 5 种(G3)

lead_history.type 为枚举,全量落库 11 种:CREATE / CLAIM / ASSIGN / FEEDBACK / CONVERT / RELEASE / RECYCLE / EXPIRE / ACTIVATE / VOID / EDIT。

  • 写入口径:11 种动作全部落库,作为管理员审计与纠纷排查的唯一来源。
  • 展示口径:详情页「历史记录」Tab 只 WHERE type IN (CLAIM, RELEASE, FEEDBACK, CONVERT, EDIT) 展示 5 种(领取/释放/反馈/转商机/编辑)。
  • 作废审计:VOID 记录 detail 保留原持有人 owner_user_id(作废清 owner 前留痕);lead_feedback.user_id(谁反馈无效)与 lead_history 均不受清 owner 影响,无主只是当前归属,历史全程可追溯。

详见 PRD §6.10。