This commit is contained in:
Neo
2026-03-15 10:15:02 +08:00
parent 2dd217522c
commit 72bb11b34f
916 changed files with 65306 additions and 16102803 deletions

View File

@@ -27,7 +27,90 @@
- AC7跳档激励"到达XXX即得YYY"计算正确
- AC8任务卡片展示应用 4 的一句话总结ai_cache 缓存读取)
- AC9备注卡片以打星方式展示应用 6 评分1-10 分,映射公式:`星数 = score ÷ 2`5 颗星,支持半星;如 score=7 → 3.5 星)
- AC10维客线索提供者按 source 字段显示"By:系统"或"By:备注",不显示具体人名
- AC10维客线索提供者按规则显示(见下方"维客线索提供者显示规则"章节)
---
## 维客线索提供者显示规则
### 后端过滤策略(安全性优先)
⚠️ **重要**:维客线索的过滤必须在后端完成,客户端不进行任何过滤逻辑,以防止数据泄露风险。
**后端返回规则**
当客户端请求任务详情时,后端应返回已过滤的维客线索列表,仅包含以下类型:
| 线索类型 | 返回条件 | 说明 |
|---------|--------|------|
| 系统生成 | 总是返回 | `source = 'ai_consumption'`(应用 3 消费分析) |
| 我的记录 | 总是返回 | `source = 'manual'``recorded_by_assistant_id = 当前登录用户ID` |
| 他人记录 | 返回脱敏版本 | `source = 'manual'``recorded_by_assistant_id ≠ 当前登录用户ID`,返回时需脱敏 |
| 备注分析 | 返回脱敏版本 | `source = 'ai_note'`,返回时需脱敏 |
**脱敏规则**
对于"他人记录"和"备注分析"类型的线索,后端返回时应:
- 移除或不返回 `recorded_by_assistant_id` 字段
- 移除或不返回 `recorded_by_name` 字段
- 保留 `source` 字段用于前端判断显示"By:某人"
### 前端显示规则
前端接收后端返回的维客线索后,直接根据 `source` 字段显示,无需额外过滤:
| source 值 | 显示文案 |
|----------|--------|
| `ai_consumption` | By:系统 |
| `manual` 且有 `recordedByAssistantId` | By:我 |
| `manual``ai_note` 且无 `recordedByAssistantId` | By:某人 |
**注意**
- "某人"是字符串字面量,不是真实人名
- 不显示具体的助教姓名或ID
- 与客户详情页不同(客户详情页显示具体人名)
### 多人情况处理
当同一客户有多条维客线索时,前端按以下规则展示:
1. **按时间排序**:按 `created_at` 升序排列(最早的在前)
2. **取最先反馈**
- 如果有"By:系统"的线索,优先显示最早的"By:系统"
- 如果没有"By:系统",则显示最早的"By:我"或"By:某人"
3. **单条展示**:维客线索卡片中仅显示一条(最优先的),其他线索可通过"查看全部"或列表展开查看
### 前端实现示例
```typescript
// 前端:直接根据后端返回的数据显示,无需过滤
function getClueProvider(clue: RetentionClue): string {
if (clue.source === 'ai_consumption') {
return 'By:系统'
}
// 后端已确保:如果是 manual 且有 recordedByAssistantId则是当前用户
if (clue.source === 'manual' && clue.recordedByAssistantId) {
return 'By:我'
}
// 其他情况manual 无 ID、ai_note都显示"By:某人"
return 'By:某人'
}
// 前端:从多条线索中选择最优先的
function selectPrimaryClue(clues: RetentionClue[]): RetentionClue {
// 1. 按 createdAt 升序排序
const sorted = clues.sort((a, b) =>
new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()
)
// 2. 优先返回 source='ai_consumption' 的最早线索
const systemClue = sorted.find(c => c.source === 'ai_consumption')
if (systemClue) return systemClue
// 3. 否则返回最早的线索
return sorted[0]
}
```
---
@@ -43,14 +126,14 @@
- 客户信息卡片
- 近期服务记录(时间+时长)
- AI 区域:
- 维客线索(应用 8 整合线索 + 人工,读取 `member_retention_clue`Emoji 作为二级标签、提供者逗号分隔展示)
- 维客线索(应用 8 整合线索 + 人工,读取 `member_retention_clue`Emoji 作为二级标签、提供者按规则展示)
- 客户分析(应用 7 缓存:运营策略数组 + 总结)
- 关系分析 + 任务建议 + 一句话总结(应用 4 缓存,读取应用 8 最新线索)
- 话术参考(应用 5 缓存)
- 备注分析评分(应用 6 缓存1-10 分)
- 备注入口(提交后触发回访完成判定);备注弹窗含星星评分(再次服务意愿+再来店可能性,各 1-5 星):回访任务默认展开评分区域,其他任务类型默认隐藏通过"展开评价"按钮手动打开
- 备注卡片展示应用 6 的 `score`1-10 分),以打星方式呈现(`星数 = score ÷ 2`5 颗星,支持半星;从 `ai_cache` cache_type=app6_note_analysis 读取)
- 维客线索(应用 8提供者显示规则`source=ai_consumption` 显示"By:系统"`source=ai_note` 显示"By:备注",不显示具体人名
- 维客线索提供者显示规则(见上方"维客线索提供者显示规则"章节)
- "问问助手"按钮 → chat.html
### notes备注管理
@@ -81,5 +164,5 @@
- T4-a细化 P5 应用 4关系分析Prompt JSON 结构,实现 `service_history``assistant_info` 等字段的拼接函数(对应 P5-T7-完整)
- T4-b细化 P5 应用 5话术参考Prompt JSON 结构,实现拼接函数(对应 P5-T8-完整)
- [ ] T5实现备注提交功能集成回访完成判定 + 星星评分:回访任务默认展开,其他任务类型通过"展开评价"按钮手动打开)
- [ ] T6实现 notes 页面(列表 + 删除)
- [ ] T6实现 notes 页面(列表 + 删除 + 分页懒加载
- [ ] T7实现通用组件爱心 icon、喜好标签、跟/弃 icon、预估标记