Files
shanxia2.0/docs/crm-migration/plans/clue/05-special.md
T
2026-06-01 08:21:21 +08:00

5.7 KiB
Raw Blame History

线索管理模块迁移方案 — 05 业务逻辑与特殊场景

原则(第六步):本节为开发门禁文档。未在本节逐条对照 Java 实现前,不得修改 backend/app/crud/crm/clue*.py 或新增路由。


1. 定时任务 / 触发器 / 监听器

类型 线索模块 说明
MySQL 触发器 无 sx.sql 无 crm_clue 触发器
Quartz / SnailJob 无 无 *Clue*Job
Spring 事件监听 无 转化/跟进均在 Service 同步事务内完成

结论:线索无独立后台任务;与 公海池规则定时回收 无关。


2. 线索状态机

new(新线索)
  → follow(跟进中)     # 首次新增跟进记录时自动切换
  → invalid(无效)      # 手动标记无效
  → converted(已转化) # 转化客户成功
规则 Java 行为(须对齐)
已转化 is_converted=1,不可再编辑/删除/分配/再转化
无效 status=invalid,不可转化
转化条件 checkConvertible:至少 1 次跟进、非 invalid、未转化
删除 已转化线索校验不通过则拒绝(deleteWithValidByIds)

3. 新增线索 insertByBo

  • 校验手机号租户内唯一
  • 默认 status=new,level=unrated(若未传)
  • 填充 owner_user_id:未传时取当前登录用户
  • 冗余 owner_user_name(UserService 翻译)
  • 数据权限:列表查询带 @DataPermission(门户用角色数据范围 union)

4. 修改线索 updateByBo

  • 已转化不可改
  • 改手机号时排除自身查重
  • 更新 update_by / update_time

5. 批量分配 assignClues

  • 参数:ids[]、ownerUserId、remark(可选)
  • 已转化线索跳过或整批失败(以 Java 异常信息为准,实施时读 assignClues 源码定稿)
  • 写 assign_time、assign_by,更新负责人姓名冗余

6. 转化客户 convertToCustomer(事务)

必须在同一事务内:

  1. 校验 checkConvertible
  2. 创建 crm_customer(字段映射见 CrmClueConvertBo + 客户模块既有逻辑)
  3. 创建主联系人 crm_contact(姓名、手机等从线索带出)
  4. 更新线索:status=converted、is_converted=1、converted_time、customer_id、converted_by
  5. 客户表回写 clue_id 关联来源线索

禁止:只更新线索不建客户,或先 commit 客户后更新线索。


7. 标记无效 markAsInvalid

  • 支持批量 ids[] + reason
  • 已转化不可标记无效

8. 新增跟进 CrmClueFollowServiceImpl.insertByBo(关键)

新增跟进后 级联更新线索(门户 CRUD 必须保持一致):

线索字段 更新规则
last_time 当前时间
follow_count +1
next_time 跟进记录的 next_time(若有)
status 若当前为 new → 改为 follow

修改跟进时:若 next_time 变更,同步回写线索 next_time。

删除跟进:是否回减 follow_count —— 以 Java deleteWithValidByIds 为准(实施前读源码)。


9. 列表视图(多 Tab)

视图 Java 方法 过滤要点
全部 queryPageList 租户 + 数据权限
我的 queryMyClues owner_user_id = 当前用户
待跟进 queryToFollowClues next_time <= now 且状态 in (new,follow)
今日新增 原 GET /todayNew 或列表加日期条件 create_time 当天
已转化 前端筛 status=converted 或 is_converted=1 与 Java 筛选项一致

门户 API 建议:POST /web/crm/clue/list + viewType 枚举,与现 Python list_clues 对齐。


10. 导入导出

能力 Java 门户现状
导出 Excel POST /export,*Vo + @ExcelDictFormat ✅ POST /web/crm/clue/export,经 CLUE_EXPORT_COLUMNS + export_rows_to_xlsx_response 字典翻译
导入模板 POST /importTemplate ✅
批量导入 POST /import + MultipartFile ✅

线索导出字典列(须与列表展示一致):

列 dict_type
客户类型 crm_customer_type
线索来源 crm_clue_source
线索等级 crm_clue_level
线索状态 crm_clue_status
所属行业 crm_industry
所在园区 crm_customer_park

Java 对照:shanxia/crm/.../vo/CrmClueVo.java。门户列定义:backend/app/utils/crm_export_columns.py → CLUE_EXPORT_COLUMNS。


11. 统计分析(5 接口)

后端五路由已实现;前端统计菜单隐藏(sqxp.ts isHide: true),页面保留供后续启用。


12. 查重 checkDuplicate

  • 入参:mobile、company、excludeId
  • 返回可能重复的线索列表
  • 门户 未实现;表单失焦/保存前可选对接

13. 跨模块依赖

依赖 说明
客户模块 转化时复用 create customer / create contact
用户下拉 GET /web/admin/users/options 或 fetchUserList
字典 useDictStore / dictStore.getOptions('crm_clue_*')
附件 MinIO;跟进 attachments 逗号分隔 URL
园区 Java 已废弃 parkAreaList API,改用字典 crm_customer_park

14. 权限标识(sys_menu)

与公海池/客户一致:crm:clue:list|query|add|edit|remove|export|import|assign|follow|convert|invalid。

v-auth 使用动作短码:add、edit、remove 等(门户 auth.ts)。


15. 开发顺序建议

  1. 读本节 + 04-api-spec.md
  2. 对照 CrmClueServiceImpl.java 逐方法打勾
  3. 先写/改 CRUD 单测或 Postman 集合
  4. 再挂 api/crm.py 路由
  5. 最后适配前端(step-03)