9b5805447e
Co-Authored-By: Claude <noreply@anthropic.com>
5.8 KiB
5.8 KiB
协同拜访记录去重 — 设计方案
背景
当前机制:客户经理 A 创建拜访记录并选择协同人员 B 时,后端为 B 生成一条空内容的草稿副本。B 填写后,同一客户、同一天出现两条独立拜访记录,导致周报重复展示、亮灯表重复计数。
设计目标
- 周报中同一客户同一次拜访合并展示为一张卡片
- 亮灯表不重复计数
- 每个参与人的填报进度不受影响(各自计入)
- 每个参与人能独立编辑自己的副本
- 历史数据兼容,不做强制迁移
方案概要
1. 数据库:新增 visit_group_id
ALTER TABLE visits ADD COLUMN visit_group_id UUID;
CREATE INDEX ix_visits_visit_group_id ON visits(visit_group_id);
- 单人拜访:
visit_group_id = NULL - 多人协同拜访:同一次拜访的所有记录共享同一个
visit_group_id
2. 后端:POST /visits/ 改造
原逻辑: 为每个协同人生成一条空内容草稿(communication_content="", photos=[], companions=[])
新逻辑: 为每个协同人生成一条完整副本:
| 副本字段 | 值 | 说明 |
|---|---|---|
customer_id |
同主记录 | |
visit_date |
同主记录 | |
visit_method |
同主记录 | |
time_range |
同主记录 | |
visitor_name |
同主记录 | 实际拜访人不变 |
visitor_phone |
同主记录 | |
communication_content |
原内容 + (协同XXX) |
如:了解项目进度...(协同韦佶秀) |
customer_demand |
同主记录 | |
companions |
[主记录创建人] |
互换:协同人看到主访人 |
companion_names |
同主记录 | |
photos |
同主记录 | |
manager_id |
协同人的 UUID | 归属到协同人名下 |
visit_group_id |
同主记录 | 同一 UUID,关联所有副本 |
前端表现(创建人韦佶秀视角):
相关人员选择了 [韦伦]
→ 保存后韦伦收到一条完整拜访记录
→ 韦伦记录内容末尾自动追加"(协同韦佶秀)"
3. 后端:PUT /visits/{id} 不变
协同人编辑自己的副本时不影响主记录,各自独立。
4. 仪表盘统计:按 visit_group_id 去重
get_dashboard_stats 中的 week_visits 改为:
# 原:count 所有 visit 行
select count(distinct coalesce(visit_group_id, id))
from visits
where visit_date between monday and sunday
每个 visit_group_id 只算一次,跳过 NULL(单人拜访用 id 做 fallback key)。
5. 填报进度:不变
get_reporting_progress 按 manager_id 分组计数,每个参与人各算一次,不受去重影响。
6. 亮灯表:按 (customer_id, visit_date, visit_group_id) 去重
同一客户同一天同一次拜访只亮一盏灯。
7. 周报展示:按 visit_group_id 合并
get_weekly_report 查询时,同一个 visit_group_id 的记录合并成一条输出:
{
"customer_name": "污水处理厂",
"visit_date": "2026-07-30",
"visit_method": "上门",
"time_range": "09:00-10:30",
"visit_group_id": "abc-123",
"participants": [
{
"manager_name": "韦佶秀",
"manager_id": "uuid-1",
"role": "primary",
"communication_content": "了解污水处理新项目...",
"customer_demand": "专线扩容至100M...",
"photos": ["photo_001", "photo_002"]
},
{
"manager_name": "韦伦",
"manager_id": "uuid-2",
"role": "companion",
"communication_content": "了解污水处理新项目...(协同韦佶秀)",
"customer_demand": "专线扩容至100M...",
"photos": ["photo_001", "photo_002"]
}
]
}
前端周报卡片展示:
┌─────────────────────────────────────────────┐
│ 污水处理厂 2026-07-30 上门 │
│ 09:00-10:30 │
│ │
│ ▸ 韦佶秀(主访) │
│ 了解污水处理新项目建设进度,客户计划新增... │
│ 客户需求:专线扩容至100M,新增视频监控... │
│ 📷 2张 │
│ │
│ ▸ 韦伦(协同) │
│ 了解污水处理新项目建设进度...(协同韦佶秀) │
│ 客户需求:专线扩容至100M... │
│ 📷 2张 │
└─────────────────────────────────────────────┘
8. 前端:协同记录编辑提示
协同人打开自己的副本编辑时,沟通内容区域上方显示一行提示:
💡 此记录为协同韦佶秀拜访「污水处理厂」的副本。你可以补充或修改内容,不会影响主记录。
改动清单
| 层 | 文件 | 改动 |
|---|---|---|
| DB | migration | ALTER TABLE visits ADD visit_group_id UUID |
| 后端 | models/visit.py |
新增 visit_group_id 字段 |
| 后端 | schemas/visit.py |
VisitOut 新增 visit_group_id |
| 后端 | api/visits.py POST |
副本改为完整复制 + (协同XXX) 后缀 + 互换 companions + 设置 visit_group_id |
| 后端 | services/dashboard.py |
get_dashboard_stats 的 week_visits 改为 distinct 去重 |
| 后端 | services/dashboard.py |
get_weekly_report 合并同 visit_group_id 记录 |
| 后端 | services/light_board.py |
亮灯计数去重 |
| 前端 | 周报 WeeklyReport.vue |
拜访卡片支持 participants 展开/折叠 |
| 前端 | 移动端 VisitForm.vue |
协同记录编辑时显示提示条 |
兼容性
- 历史数据
visit_group_id = NULL,行为与现在完全一致 - 前端
participants字段回退:单 participant 时展示与现在无差异