Files
nexus/Project/fonrey/TECH_STACK/客源管理技术方案.md
2026-04-30 20:33:51 +08:00

14 KiB
Raw Blame History

For AI assistants: Read this entire file before writing any code. All decisions here are final. Do not suggest alternatives unless asked.

Fonrey 客源管理技术方案

版本: 1.0
项目: Fonrey 房产经纪管理系统
技术栈: Django 4.x + HTMX + Alpine.js + PostgreSQL 16 + Redis + Celery + Cloudflare R2
关联 PRD: PRD/客源管理/客源管理模块PRD.mdv1.4
关联数据模型: DATA_MODEL/DATA_MODEL_CLIENT.md(本方案不重复 DDL
关联契约规范: TECH_STACK/API_CONTRACT.md(全局 API 契约权威)
关联枚举字典: DATA_MODEL/ENUMS.md
最后更新: 2026-04-27


变更历史

日期 变更人 变更内容
2026-04-30 Atlas 补充“变更历史”章节(文档治理)

一、文档定位与边界

本文件聚焦客源模块的:

  1. 服务边界与模块协作
  2. API 端点设计P0/P1 兼容)
  3. HTMX 局刷与页面分片约定
  4. 权限与数据范围控制
  5. 异步任务、缓存、性能与测试映射

不在本文件展开数据表字段、DDL、索引、触发器。以 DATA_MODEL_CLIENT.md 为唯一权威。


二、范围定义(以 TASK.md 为准)

2.1 P0 必须覆盖Phase 1

US-CLIENT-001 ~ US-CLIENT-017

  • 新增私客、列表筛选、详情、需求编辑、跟进、带看
  • 联系人管理、等级/状态变更、转公客/转成交/转无效
  • 相关员工管理
  • 自动转公、重复检测

2.2 非 P0仅预留端点不实现复杂能力

  • AI 行为解读深度模型
  • 新房推荐高级排序引擎
  • 公客/成交客完整运营闭环P1/P2

三、模块架构边界

3.1 模块职责(apps/client

  • 客源主流程:新增、列表、详情、状态流转
  • 客源关联流程:联系人、需求、跟进、带看、智能配房结果
  • 质量控制:重复检测、自动转公、操作审计

3.2 外部依赖

依赖模块 依赖内容 依赖方式
apps/org 员工、组织树、归属人/首录人 FK + Service
apps/property 配房候选房源、带看房源关联 只读查询 + FK
apps/permission 角色与数据范围权限 PermissionChecker + ScopeQueryBuilder
apps/setting 可配置枚举(来源、跟进目的)与查重规则 TenantSettingsService
core/encryption.py 手机号/证件号加密与哈希 统一工具调用
core/cache.py 列表缓存、重复计数缓存、任务进度 Redis
Celery 自动转公、重复检测统计、配房重算、导出 异步任务
Cloudflare R2 跟进图片、带看附件 预签名上传

四、API 设计原则

  1. 页面路由与数据 API 分离:
    • 页面:/client/...
    • 数据:/api/client/...
  2. 列表筛选、Tab 加载、弹窗提交优先 HTMX。
  3. 手机号明文永不落库;默认脱敏显示。
  4. 重复检测与自动转公走异步批处理 + 局部实时校验组合。
  5. 所有状态变更必须写操作日志(不可省略)。

五、端点清单(核心)

5.1 页面路由SSR

路径 方法 鉴权 说明
/client/list/ GET 客源列表主页面(私客/公客/成交客 Tab 容器)
/client/create/ GET 新增私客页面
/client/{client_id}/ GET 客源详情主页面
/client/{client_id}/edit/ GET 编辑客源页面
/client/{client_id}/operation-logs/ GET 客源操作日志页面

5.2 HTMX 片段端点

路径 方法 用途 返回
/client/fragments/list-table/ POST 列表筛选/排序/分页局刷 HTML
/client/fragments/repeat-counters/ GET 顶部重复统计局刷 HTML
/client/{id}/fragments/tab/{tab}/ GET 详情 Tab 懒加载(需求/跟进/带看/配房) HTML
/client/{id}/fragments/contact-panel/ GET 联系人面板局刷 HTML
/client/{id}/fragments/staff-panel/ GET 相关员工面板局刷 HTML
/client/{id}/fragments/follow-timeline/ POST 跟进筛选后局刷 HTML

fragment 端点必须校验 HX-Request=true,非 HTMX 请求返回 400。

5.3 JSON APIP0 必需)

端点 方法 权限 code建议 说明
/api/client/ POST client.private.create.allow 新增私客US-001
/api/client/list/query/ POST client.private.view.scope 私客列表筛选US-002
/api/client/{id}/detail/ GET client.private.view.scope 详情聚合US-004
/api/client/{id}/requirements/ PATCH client.private.edit.allow 编辑需求US-005
/api/client/{id}/follow-logs/ POST client.private.follow.create.allow 写入跟进US-006
/api/client/{id}/follow-logs/query/ POST client.private.follow.view.scope 跟进查询US-006
/api/client/{id}/viewings/ POST client.private.viewing.create.allow 新增带看US-007
/api/client/{id}/viewings/query/ POST client.private.viewing.view.scope 带看查询US-007
/api/client/{id}/contacts/ POST client.private.contact.create.allow 新增联系人US-008
/api/client/{id}/contacts/{contact_id}/ PATCH client.private.contact.edit.allow 编辑联系人US-008
/api/client/{id}/grade/change/ POST client.private.grade.change.allow 改等级US-009
/api/client/{id}/status/change/ POST client.private.status.change.allow 改状态US-010
/api/client/{id}/transfer-public/ POST client.private.transfer_public.allow 手动转公客US-011
/api/client/{id}/transfer-transacted/ POST client.private.transfer_transacted.allow 转成交US-012
/api/client/{id}/mark-invalid/ POST client.private.mark_invalid.allow 转无效US-013
/api/client/{id}/base-info/ PATCH client.private.edit.allow 编辑基础信息US-014
/api/client/{id}/related-staff/ PATCH client.private.related_staff.edit.allow 修改首录/归属人US-015
/api/client/duplicate/check/ POST client.private.create.allow 手机号实时重复检测US-001/017
/api/client/duplicate/summary/ GET client.private.view.scope 重复统计(私客-成交、公客US-017
/api/client/matches/{id}/query/ GET client.private.view.scope 智能配房结果查询US-020预留P0可简版
/api/client/export/jobs/ POST client.private.export.scope 导出任务创建US-002
/api/client/export/jobs/{job_id}/ GET client.private.export.scope 导出任务状态
/api/client/export/jobs/{job_id}/download/ GET client.private.export.scope 导出下载

六、关键 API 规范(请求/响应)

6.1 新增私客

POST /api/client/

{
  "contacts": [
    {
      "name": "李雷",
      "gender": "male",
      "phone_country_code": "+86",
      "phone": "13800000000",
      "phone2": null,
      "wechat": "lilei_wechat"
    }
  ],
  "base_info": {
    "status": "buying",
    "property_usage": "residential",
    "grade": "B",
    "source": "store_reception"
  }
}

成功 201

{
  "id": "uuid",
  "client_no": "KY202604270001",
  "redirect_url": "/client/uuid/",
  "message": "保存成功"
}

6.2 列表查询Keyset

POST /api/client/list/query/

{
  "client_type": "private",
  "tab": "buying",
  "keyword": "1380000",
  "filters": {
    "grade": ["A", "B"],
    "status": ["buying", "buy_rent"],
    "budget": {"min": 200, "max": 500}
  },
  "sort": {"field": "last_follow_at", "order": "desc"},
  "pagination": {"mode": "keyset", "cursor": "opaque_cursor", "limit": 20}
}

6.3 手机号重复检测

POST /api/client/duplicate/check/

{
  "phone_country_code": "+86",
  "phone": "13800000000",
  "scene": "create",
  "client_id": null
}

响应:

{
  "duplicated": true,
  "scope": "dept",
  "hits": [
    {
      "client_id": "uuid",
      "client_type": "private",
      "owner_name": "王店长",
      "created_at": "2026-04-27T10:00:00+08:00"
    }
  ]
}

6.4 状态与转化类接口(统一协议)

  • 改状态:/status/change/
  • 转公:/transfer-public/
  • 转成交:/transfer-transacted/
  • 转无效:/mark-invalid/

统一请求字段:

{
  "reason": "客户需求变化",
  "payload": {}
}

额外示例(转成交):

{
  "reason": "已签约",
  "payload": {
    "transacted_date": "2026-04-27",
    "transacted_price": "365.00",
    "transacted_type": "bought",
    "property_id": "uuid"
  }
}

七、HTMX 交互约定

7.1 Header 约定

  • 请求:HX-Request: true
  • 成功:HX-Trigger: {"toast":{"level":"success","message":"操作成功"}}
  • 失败:HX-Trigger: {"toast":{"level":"error","message":"操作失败"}}
  • 跳转:HX-Redirect: /client/{id}/

7.2 模板分片命名

场景 模板
列表 templates/client/fragments/list_table.html
重复计数条 templates/client/fragments/repeat_counters.html
跟进时间线 templates/client/fragments/follow_timeline.html
带看时间线 templates/client/fragments/viewing_timeline.html
联系人侧栏 templates/client/fragments/contact_panel.html
相关员工侧栏 templates/client/fragments/staff_panel.html

八、权限与数据范围

8.1 最小权限矩阵P0

能力 权限 code
查看私客列表范围 client.private.view.scope
新增私客 client.private.create.allow
编辑私客信息 client.private.edit.allow
写跟进 client.private.follow.create.allow
查看跟进 client.private.follow.view.scope
管理联系人 client.private.contact.create.allow / client.private.contact.edit.allow
改等级/改状态 client.private.grade.change.allow / client.private.status.change.allow
转公/转成交/转无效 client.private.transfer_public.allow / client.private.transfer_transacted.allow / client.private.mark_invalid.allow
导出 client.private.export.scope

8.2 数据范围叠加逻辑

最终可见数据 = 权限 scopeclient_type 过滤业务状态过滤

  • 禁止不带 client_type 的全量查询
  • 私客、公客、成交客必须分流查询

8.3 敏感信息查看审计

查看号码动作必须:

  1. 校验查看权限与日限额(若配置)
  2. 仅本次响应返回明文
  3. 自动写 client_follow_logs(log_type='sensitive_view')
  4. sensitive_view 记录不可删除

九、异步任务与缓存策略

9.1 状态机与规则

  • private -> public(手动转公或自动转公)
  • private -> transacted(转成交)
  • private/public/transacted -> invalid(状态字段,不改变历史)

必须通过 service 校验状态机,禁止跳转。

最低规则P0

  • buying <-> buy_rent
  • renting <-> buy_rent
  • buying/renting/buy_rent -> paused
  • paused -> buying/renting
  • 任意可跟进状态 -> invalid(必须填写原因)

9.2 Celery 任务

任务 触发时机 说明
client_auto_transfer_public_task 每小时 超时未跟进私客自动转公US-016
client_duplicate_summary_task 每日/按需 重复统计US-017
client_match_recompute_task 需求变更后 重新计算配房结果
client_export_task 导出任务创建后 异步导出 Excel

所有任务必须传入 tenant_schema_name 并在任务开头切 schema。

9.3 Redis Key 规范

Key TTL 说明
{schema}:client:list:query:{hash} 60s 热门列表筛选缓存
{schema}:client:repeat:summary 300s 顶部重复计数缓存
{schema}:client:detail:{id} 120s 详情聚合缓存
{schema}:client:export:{job_id} 24h 导出任务状态

十、性能与可靠性约束

  1. 客源列表、跟进时间线全部使用 Keyset 分页。
  2. 高频筛选列建立组合索引(见数据模型文档)。
  3. 手机号、证件号统一加密 + hash 索引;禁止明文。
  4. 附件上传限制:bmp/jpg/jpeg/png/gif20MB/文件。
  5. 导出、重复统计、自动转公均走异步,禁止阻塞请求线程。

十一、安全与合规

  1. 手机号、证件号默认脱敏显示,明文查看需权限与审计。
  2. 跟进/转化等关键动作必须记录操作者与来源。
  3. 重复检测接口不得泄露超出权限范围的完整客户信息。

十二、错误码建议

code HTTP 场景
CLIENT_NOT_FOUND 404 客源不存在或无权限
CLIENT_DUPLICATED_PHONE 409 号码重复(按租户规则)
CLIENT_INVALID_TRANSITION 400 非法状态/类型流转
CLIENT_CONTACT_PHONE_INVALID 400 联系人电话格式错误
CLIENT_PERMISSION_DENIED 403 权限不足
CLIENT_EXPORT_JOB_NOT_READY 409 导出未完成

十三、测试映射P0

US 最低覆盖
US-CLIENT-001 新增成功/必填失败/重复检测提示
US-CLIENT-002 组合筛选 + Keyset 分页 + 导出
US-CLIENT-003 批量操作权限与审计
US-CLIENT-004~006 详情/需求/跟进流程
US-CLIENT-007~008 带看与联系人新增编辑
US-CLIENT-009~013 等级/状态/转公/转成交/转无效
US-CLIENT-014~015 编辑完整信息 + 相关员工变更
US-CLIENT-016 自动转公定时任务
US-CLIENT-017 重复统计任务与查询接口

测试落点:tests/integration/client/test_us_client.py


十四、落地顺序建议

  1. 列表查询 + scope 权限US-002
  2. 新增私客 + 重复检测US-001/017
  3. 详情 + 需求/跟进US-004~006
  4. 联系人/带看US-007/008
  5. 状态与转化US-009~013
  6. 自动任务与导出US-016/017 + 导出)

十五、文档同步规则

  • 枚举变更同步:DATA_MODEL/ENUMS.md
  • 权限 code 变更同步:DATA_MODEL/DATA_MODEL_PERMISSION.md
  • 新增配置项同步:DATA_MODEL/DATA_MODEL_SETTING.md
  • API 变更同步:本文件 + 对应 PRD 验收条目