# 线索实体与字段模型 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`(含领取/释放/反馈/新增/编辑等所有操作类型)。 - **[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` 清空 | | 激活(F2) | `expire_deadline = now + pool.M`(03 已定) | | 池改名 | 批量刷 `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-auth**:`AuthUser`/`SysDept`(领取人、部门归属、快照)。 - **crm-rule**:`LeadPool`(外键 + 池名快照)。 - **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` 等不涉及省市字段无需改)。