@@ -0,0 +1,156 @@
|
||||
# 协同拜访记录去重 — 设计方案
|
||||
|
||||
## 背景
|
||||
|
||||
当前机制:客户经理 A 创建拜访记录并选择协同人员 B 时,后端为 B 生成一条空内容的草稿副本。B 填写后,同一客户、同一天出现两条独立拜访记录,导致周报重复展示、亮灯表重复计数。
|
||||
|
||||
## 设计目标
|
||||
|
||||
1. 周报中同一客户同一次拜访合并展示为一张卡片
|
||||
2. 亮灯表不重复计数
|
||||
3. 每个参与人的填报进度不受影响(各自计入)
|
||||
4. 每个参与人能独立编辑自己的副本
|
||||
5. 历史数据兼容,不做强制迁移
|
||||
|
||||
## 方案概要
|
||||
|
||||
### 1. 数据库:新增 `visit_group_id`
|
||||
|
||||
```sql
|
||||
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` 改为:
|
||||
|
||||
```python
|
||||
# 原: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` 的记录合并成一条输出:
|
||||
|
||||
```json
|
||||
{
|
||||
"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 时展示与现在无差异
|
||||
Reference in New Issue
Block a user