Files
nexus/Project/fonrey/TECH_STACK/楼盘管理技术方案.md
2026-04-28 07:38:30 +08:00

12 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.0
关联数据模型: DATA_MODEL/DATA_MODEL_COMPLEX.md(本方案不重复 DDL
关联契约规范: TECH_STACK/API_CONTRACT.md(全局 API 契约权威)
关联枚举字典: DATA_MODEL/ENUMS.md
最后更新: 2026-04-27


一、文档定位与边界

本文件只定义楼盘模块的:

  1. 服务边界与模块协作
  2. API 端点设计(重点)
  3. HTMX 局刷协议
  4. 权限接入、异步任务、缓存与性能约束
  5. 测试与验收映射

不在本文件展开complexes/buildings/room_units/districts/business_areas/schools 表结构、索引、触发器。以 DATA_MODEL_COMPLEX.md 为唯一权威来源。


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

2.1 P0 必须覆盖

  • US-COMPLEX-001管理员录入与维护楼盘基础信息
  • US-COMPLEX-002经纪人查看楼盘列表与详情
  • US-COMPLEX-003管理员维护区域管理城区/商圈)

2.2 P1/P2 预留(端点可预留,不在当前强制交付)

  • US-COMPLEX-010楼盘照片管理
  • US-COMPLEX-011楼盘价格走势维护
  • US-COMPLEX-012周边配套/学校管理
  • US-COMPLEX-020应用数据标准

三、模块架构边界

3.1 模块职责(apps/complex

  • 维护楼盘基础档案(楼盘、别名、商圈、学校、地铁关联)
  • 维护楼栋与房号结构(供房源录入精准归位)
  • 提供楼盘搜索、联想、详情聚合与区域筛选能力
  • 承担区域与学校主数据管理P0 侧重城区/商圈)

3.2 外部依赖

依赖模块 依赖内容 依赖方式
apps/property 房源数量统计、楼盘详情联动跳转 只读聚合查询
apps/client 客源区域筛选项复用(城区/商圈) 读取共享主数据
apps/org 操作人信息审计 staff_id 写审计
apps/permission 楼盘查看/编辑/区域维护权限校验 PermissionChecker
core/cache.py 楼盘联想缓存、区域字典缓存 Redis key 带 schema 前缀
Celery 完整度重算、价格趋势重算、批量任务 异步任务
地图服务(后续) 周边配套查询、坐标纠偏 适配器层P1

3.3 分层约束

  • views.py 仅做参数校验、鉴权、响应拼装
  • 业务规则(锁校验、命名约束、合并规则)全部下沉 services/
  • 任何写操作必须记录审计日志(操作人、前后值、时间)
  • 耗时 >500ms 的批量操作与重算流程必须异步化

四、API 设计原则

  1. 页面路由与数据 API 分离:
    • 页面:/complex/...
    • 数据:/api/complex/...
  2. 列表筛选、Tab 切换、矩阵加载优先 HTMX 局刷。
  3. 楼盘名称/地址修改遵循数据治理规则:
    • name 不允许普通编辑页直接改
    • address 走纠错流程
  4. 锁定状态前置校验:lock_info/lock_building/lock_room/lock_standard_room
  5. 统一错误协议:
    • JSON: {"error":"...","code":"..."}
    • HTMX: 片段 + HX-Trigger toast

五、端点清单(核心)

5.1 页面路由SSR + HTMX 容器)

路径 方法 鉴权 说明
/complex/list/ GET 楼盘列表主页面(含完整度面板与筛选容器)
/complex/create/ GET 新增楼盘页面
/complex/{complex_id}/ GET 楼盘详情主页面(多 Tab 容器)
/complex/{complex_id}/edit/ GET 编辑楼盘页面
/complex/region/ GET 区域管理(城区/商圈)页面

5.2 HTMX 片段端点

路径 方法 用途 返回
/complex/fragments/list-table/ POST 列表筛选/排序/分页局刷 HTML
/complex/fragments/completeness-panel/ GET 顶部完整度指标面板局刷 HTML
/complex/{id}/fragments/tab/{tab}/ GET 详情 Tab 懒加载 HTML
/complex/{id}/fragments/building-list/ POST 楼栋管理列表局刷 HTML
/complex/{id}/fragments/structure-matrix/ POST 结构矩阵局刷 HTML
/complex/region/fragments/district-table/ POST 城区列表局刷 HTML
/complex/region/fragments/business-area-table/ POST 商圈列表局刷 HTML

fragment 端点必须校验 HX-Request=true,否则返回 400。

5.3 JSON APIP0

端点 方法 权限 code建议 说明
/api/complex/ POST complex.base.create.allow 新增楼盘US-001
/api/complex/list/query/ POST complex.base.view.scope 楼盘列表查询US-002
/api/complex/{id}/detail/ GET complex.base.view.scope 楼盘详情聚合US-002
/api/complex/{id}/base-info/ PATCH complex.base.edit.allow 编辑楼盘基础信息US-001
/api/complex/{id}/lock/release/ POST complex.lock.release.allow 解锁楼盘(锁权限)
/api/complex/{id}/buildings/query/ POST complex.base.view.scope 楼栋列表查询
/api/complex/{id}/buildings/ POST complex.building.edit.allow 新增楼栋
/api/complex/{id}/room-units/query/ POST complex.base.view.scope 结构矩阵查询
/api/complex/regions/districts/query/ POST complex.region.manage.allow 城区列表查询US-003
/api/complex/regions/districts/ POST complex.region.manage.allow 新增城区US-003
/api/complex/regions/districts/{id}/ PATCH complex.region.manage.allow 编辑城区
/api/complex/regions/business-areas/query/ POST complex.region.manage.allow 商圈列表查询US-003
/api/complex/regions/business-areas/ POST complex.region.manage.allow 新增商圈US-003
/api/complex/regions/business-areas/{id}/ PATCH complex.region.manage.allow 编辑商圈
/api/complex/regions/business-areas/merge/ POST complex.region.manage.allow 合并商圈
/api/complex/regions/districts/merge/ POST complex.region.manage.allow 合并城区

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

6.1 新增楼盘

POST /api/complex/

{
  "name": "万科城市花园",
  "district_id": "uuid",
  "address": "上海市闵行区XX路XX号",
  "address_summary": "XX路XX弄",
  "property_usage_types": ["residential"],
  "building_structure": "unit_room",
  "business_area_ids": ["uuid1", "uuid2"],
  "school_ids": ["uuid3"]
}

成功 201

{
  "id": "uuid",
  "message": "保存成功",
  "redirect_url": "/complex/uuid/"
}

6.2 楼盘列表查询

POST /api/complex/list/query/

{
  "keyword": "万科",
  "filters": {
    "district_ids": ["uuid"],
    "usage_types": ["residential"],
    "has_coordinate": true
  },
  "sort": {"field": "updated_at", "order": "desc"},
  "pagination": {"mode": "keyset", "cursor": "opaque_cursor", "limit": 20}
}

6.3 编辑楼盘基础信息

PATCH /api/complex/{id}/base-info/

{
  "address_summary": "海波路1000弄",
  "built_years": [2005, 2008],
  "ownership_category": ["commodity_residential"],
  "remarks": "已校验最新物业信息"
}

规则:

  • lock_info=true 且无解锁权限,返回 403
  • name 字段不允许通过该接口修改,返回 400

6.4 新增商圈

POST /api/complex/regions/business-areas/

{
  "district_id": "uuid",
  "name": "江桥新城"
}

规则:

  • district_id + name 唯一
  • 商圈必须归属城区

七、HTMX 交互约定

7.1 Header 约定

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

7.2 模板分片命名

场景 模板
楼盘列表 templates/complex/fragments/list_table.html
完整度面板 templates/complex/fragments/completeness_panel.html
楼栋列表 templates/complex/fragments/building_list.html
结构矩阵 templates/complex/fragments/structure_matrix.html
城区列表 templates/complex/fragments/district_table.html
商圈列表 templates/complex/fragments/business_area_table.html

八、权限与数据范围

8.1 最小权限矩阵P0 建议)

能力 权限 code
查看楼盘列表/详情范围 complex.base.view.scope
新增/编辑楼盘基础信息 complex.base.create.allow / complex.base.edit.allow
解锁楼盘 complex.lock.release.allow
楼栋与结构维护 complex.building.edit.allow
区域管理(城区/商圈) complex.region.manage.allow

8.2 数据域规则

最终可见数据 = scope 过滤业务过滤(启用状态、软删过滤)

  • 所有查询必须 deleted_at IS NULL
  • 区域管理默认只展示 is_active=true,可选查看停用项

九、异步任务与缓存策略

9.1 Celery 任务

任务 触发时机 说明
complex_completeness_recalc_task 数据管理员点击“重新计算” 重算完整度指标面板
complex_price_trend_refresh_task 夜间定时 价格走势数据聚合T+1
complex_merge_cleanup_task 合并楼盘后 处理关联表与索引重建

任务参数必须包含 tenant_schema_name,任务开头显式切 schema。

9.2 Redis Key 规范

Key TTL 说明
{schema}:complex:list:query:{hash} 60s 热门筛选缓存
{schema}:complex:detail:{id} 120s 详情聚合缓存
{schema}:complex:completeness:panel 300s 完整度指标缓存
{schema}:complex:region:districts 300s 城区字典缓存
{schema}:complex:region:business_areas:{district_id} 300s 商圈字典缓存

十、性能与可靠性约束

  1. 列表查询强制 Keyset 分页,禁止 OFFSET 大页深翻。
  2. 楼盘检索优先使用 search_vector + trgm 索引。
  3. 详情页按 Tab 懒加载,避免一次拉全量聚合。
  4. 合并与批量改动使用事务;失败必须回滚。
  5. 区域与楼盘维护接口需限流,防止误操作风暴。

十一、安全与合规

  • 楼盘锁定状态必须在服务层强校验,不允许绕过。
  • 所有写操作记录审计操作人、IP、前后值。
  • 地图类外部 API 调用不得暴露密钥到前端。
  • 删除有关联数据(楼盘、区域)必须返回阻断型错误提示。

十二、错误码建议

code HTTP 场景
COMPLEX_NOT_FOUND 404 楼盘不存在或无权限
COMPLEX_LOCKED_INFO 403 楼盘信息锁定不可编辑
COMPLEX_NAME_EDIT_FORBIDDEN 400 禁止直接修改楼盘名称
COMPLEX_REGION_REQUIRED 400 商圈未归属城区
COMPLEX_REGION_DUPLICATED 409 城区/商圈重名冲突
COMPLEX_PERMISSION_DENIED 403 权限不足

十三、测试映射

13.1 P0 User Story 映射

User Story 最低覆盖
US-COMPLEX-001 新增/编辑楼盘成功、必填校验、锁定校验
US-COMPLEX-002 列表关键词筛选、分页、详情 Tab 懒加载
US-COMPLEX-003 城区商圈新增编辑、归属约束、冲突校验

测试文件:tests/integration/complex/test_us_complex.py

13.2 强制测试约束

  • 集成测试使用 TenantClient
  • HTMX 请求携带 HTTP_HX_REQUEST=true
  • 权限三态覆盖200 / 403 / 302
  • 外部服务(地图/R2/Redis全部 mock

十四、落地顺序建议

  1. 先打通楼盘列表查询 + 详情聚合US-COMPLEX-002
  2. 再完成新增/编辑与锁校验US-COMPLEX-001
  3. 最后完成区域管理US-COMPLEX-003
  4. P1 再接照片、价格走势、学校管理

十五、文档同步规则

  • 枚举变更:同步 DATA_MODEL/ENUMS.md
  • 权限 code 变更:同步 DATA_MODEL/DATA_MODEL_PERMISSION.md
  • 数据结构变更:同步 DATA_MODEL/DATA_MODEL_COMPLEX.md
  • API 变更:同步本文件与 PRD/TASK.md 对应条目