edit | blame | history | raw

Design Document: AI调解通话记录查看功能

上下文

背景

云小调系统通过AI调解员自动拨打当事人电话进行初步沟通,调解员需要在实时看板中了解通话详情以便进行后续人工调解。当前系统缺少通话记录的详细展示功能。

约束条件

  • 前端项目使用React + Ant Design 4.24.12
  • 数据来源为 OutboundBotAPIService.getConversationLog API
  • 需要兼容多种外呼状态(已接通、未接通等)
  • 录音文件为.wav格式

相关利益相关者

  • 调解员:需要快速查看通话记录了解沟通情况
  • 产品经理:关注用户体验和功能完整性

目标与非目标

目标

  • 提供直观的通话记录查看入口
  • 展示清晰的双方对话内容
  • 支持录音文件播放
  • 正确处理各种外呼状态

非目标

  • 不实现通话记录的编辑功能
  • 不实现通话记录的导出功能
  • 不实现录音文件的下载功能(本期暂不实现)

技术决策

1. UI组件结构

决策:使用Ant Design Modal作为弹窗容器,自定义内部组件

理由
- Modal组件与系统其他弹窗风格一致
- 内部需要高度自定义的聊天界面样式
- 便于后续扩展其他功能

组件层级
MediationBoard └── BoardItem (调解记录卡片) └── CallRecordButton (通话记录按钮) └── CallRecordModal (通话记录弹窗) ├── AudioPlayer (录音播放器) └── ConversationList (对话记录列表) └── ConversationItem (单条对话)

2. 数据获取策略

决策:按需加载,点击按钮时调用API

理由
- 避免列表加载时请求数量过多
- 减少不必要的API调用
- 提升页面初始加载速度

API调用流程
用户点击按钮 → 获取caseId(URL参数 > localStorage) → 获取person_id和job_id(调解记录数据) → 调用getConversationLog API → 处理返回数据(取最后一条) → 渲染弹窗内容

3. 外呼状态处理

决策:根据callStatus字段区分展示内容

状态分类
| 状态类型 | callStatus值 | 展示内容 |
|---------|-------------|---------|
| 已接通 | 1, 20-31 | 录音播放器 + 对话记录 |
| 未接通 | 0, 2-19, 32 | 提示"未接通,无通话记录" |

4. 对话记录展示设计

决策:采用类似微信聊天的左右布局

设计规范
- AI调解员消息
- 位置:左侧
- 头像:机器人图标
- 背景:浅蓝色(#e3f2fd)
- 名称显示:"AI调解员"

  • 当事人消息
  • 位置:右侧
  • 头像:显示名字首字
  • 背景:浅绿色(#e8f5e9)
  • 名称显示:调解记录中的creator字段值

时间戳格式YYYY-MM-DD HH:mm

5. 录音播放器设计

决策:使用HTML5原生audio标签

理由
- 原生支持.wav格式
- 无需额外依赖
- 浏览器兼容性好

样式设计
- 位置:弹窗顶部固定
- 背景:浅灰色(#f5f5f5)
- 高度:50px
- 宽度:100%

替代方案

方案1:使用第三方聊天UI库

  • 优点:开箱即用,功能完善
  • 缺点:引入额外依赖,样式可能不一致
  • 决策:不采用,保持项目简洁

方案2:在卡片内直接展示对话

  • 优点:无需弹窗,操作更直接
  • 缺点:占用空间大,影响列表展示
  • 决策:不采用,使用弹窗更合理

风险与权衡

风险1:录音文件URL无效

  • 概率:中
  • 影响:用户无法播放录音
  • 缓解措施
  • 提供明确的错误提示
  • 支持用户手动重试
  • 记录错误日志便于排查

风险2:API响应缓慢

  • 概率:低
  • 影响:用户体验下降
  • 缓解措施
  • 显示加载状态
  • 设置合理的超时时间(30秒)
  • 提供取消操作选项

风险3:对话内容过长

  • 概率:高
  • 影响:弹窗内容溢出
  • 缓解措施
  • 弹窗设置最大高度
  • 内部区域支持滚动
  • 对话列表虚拟化(如内容过多)

迁移计划

实施步骤

  1. 创建通话记录弹窗组件
  2. 在MediationBoard组件中添加按钮和弹窗触发逻辑
  3. 实现API调用和数据转换
  4. 添加样式和交互效果
  5. 处理各种边界情况

回滚方案

  • 功能通过feature flag控制,出问题可直接禁用
  • 按钮点击事件独立封装,不影响现有调解记录展示

开放问题

  1. 录音文件存储周期:需要确认录音文件的保存时长,避免播放失败
  2. 并发限制:是否需要限制同时打开的弹窗数量
  3. 权限控制:是否所有调解员都能查看通话记录

参考设计

对话记录UI设计稿

┌─────────────────────────────────────────────────────────────┐
│  AI调解员与申请人(刘树杰)的通话              任务ID: xxx  │
├─────────────────────────────────────────────────────────────┤
│  ┌─────────────────────────────────────────────────────┐    │
│  │  🔊 录音播放器  [▶播放] ━━━━━━━●─────── 03:45/10:20 │    │
│  └─────────────────────────────────────────────────────┘    │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  ┌──────┐  你好,刘树杰先生吗?我是白云区...               │
│  │  AI  │  2026-03-12 16:30                                │
│  └──────┘                                                   │
│                                                              │
│        呃,你刚才前面说你是谁?                    ┌──────┐ │
│        2026-03-12 16:33                          │  刘  │ │
│                                                   └──────┘ │
│                                                              │
│  ┌──────┐  哦,不好意思,我是白云区人和镇...                │
│  │  AI  │  2026-03-12 16:33                                │
│  └──────┘                                                   │
│                                                              │
└─────────────────────────────────────────────────────────────┘