- 从服务器拉取完整代码 - 按框架规范整理项目结构 - 配置 Drone CI 测试环境部署 - 包含后端(FastAPI)、前端(Vue3)、管理端 技术栈: Vue3 + TypeScript + FastAPI + MySQL
242 lines
6.6 KiB
Markdown
242 lines
6.6 KiB
Markdown
# 获取员工未绑定录音信息
|
||
|
||
## 接口信息
|
||
|
||
- **路径**:POST `/api/beauty/v1/audio/infos`
|
||
- **说明**:根据员工手机号获取录音信息(**最关键的接口**)
|
||
|
||
## 请求参数
|
||
|
||
### Body参数(JSON)
|
||
|
||
| 参数 | 必选 | 类型 | 默认值 | 描述 |
|
||
|------|------|------|--------|------|
|
||
| estateId | 是 | integer | - | 项目ID |
|
||
| consultantPhone | 否 | string | - | 员工手机号(三方员工id 必传其一) |
|
||
| externalUserId | 否 | string | - | 三方员工id(员工手机号 必传其一) |
|
||
| audioStartDate | 否 | string | - | 录音时间(例:2025-05-06) |
|
||
|
||
### 请求示例
|
||
|
||
```json
|
||
{
|
||
"estateId": 516799468310364162,
|
||
"consultantPhone": "13800138000",
|
||
"audioStartDate": "2024-10-01"
|
||
}
|
||
```
|
||
|
||
## 响应结果
|
||
|
||
### Body结构
|
||
|
||
| 参数 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| records | list | 录音文件列表 |
|
||
| └─ id | bigint | 录音ID |
|
||
| └─ externalUserId | string | 三方员工ID |
|
||
| └─ consultantPhone | string | 员工手机号 |
|
||
| └─ consultantName | varchar | 销售人员姓名 |
|
||
| └─ fileUrl | varchar | 录音地址,7天有效 |
|
||
| └─ startTime | datetime | 录音开始时间(yyyy-MM-dd HH:mm:ss) |
|
||
| └─ endTime | datetime | 录音结束时间(yyyy-MM-dd HH:mm:ss) |
|
||
| └─ duration | bigint | 文件时长(ms) |
|
||
| └─ fileSize | bigint | 文件大小(bt) |
|
||
|
||
### 响应示例
|
||
|
||
```json
|
||
{
|
||
"code": "0",
|
||
"msg": "success",
|
||
"data": {
|
||
"records": [
|
||
{
|
||
"id": 123456,
|
||
"externalUserId": "EMP001",
|
||
"consultantPhone": "13800138000",
|
||
"consultantName": "张三",
|
||
"fileUrl": "https://example.com/audio/123456.mp3",
|
||
"startTime": "2025-01-15 10:30:00",
|
||
"endTime": "2025-01-15 10:35:00",
|
||
"duration": 300000,
|
||
"fileSize": 2048000
|
||
},
|
||
{
|
||
"id": 123457,
|
||
"externalUserId": "EMP001",
|
||
"consultantPhone": "13800138000",
|
||
"consultantName": "张三",
|
||
"fileUrl": "https://example.com/audio/123457.mp3",
|
||
"startTime": "2025-01-15 14:00:00",
|
||
"endTime": "2025-01-15 14:10:00",
|
||
"duration": 600000,
|
||
"fileSize": 4096000
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
## 业务逻辑
|
||
|
||
1. 通过员工手机号直接查询该员工的录音
|
||
2. 可选:通过时间范围筛选特定日期的录音
|
||
3. 返回录音列表,包含录音ID用于后续获取ASR文本
|
||
4. 录音URL有效期为7天,过期需重新获取
|
||
|
||
## 使用场景
|
||
|
||
**这是获取员工对话记录的核心接口**
|
||
|
||
1. **按手机号查询员工录音** - 最常用的场景
|
||
2. **时间范围筛选** - 获取指定日期的录音
|
||
3. **获取最近N条对话** - 配合时间排序实现
|
||
4. **员工能力评估** - 获取录音后调用ASR分析,传递给Dify工作流
|
||
|
||
## 完整业务流程
|
||
|
||
### 获取员工最近N条对话记录
|
||
|
||
```python
|
||
# 1. 调用此接口获取员工录音列表
|
||
audios = get_employee_audios(
|
||
consultant_phone="13800138000",
|
||
audio_start_date="2024-10-01"
|
||
)
|
||
|
||
# 2. 按时间倒序排序
|
||
audios.sort(key=lambda x: x['startTime'], reverse=True)
|
||
|
||
# 3. 取前N条
|
||
recent_audios = audios[:10]
|
||
|
||
# 4. 对每条录音获取ASR文本
|
||
for audio in recent_audios:
|
||
asr_result = get_audio_asr_result(audio['id'])
|
||
# 组合成完整对话记录
|
||
conversation = {
|
||
'audio_id': audio['id'],
|
||
'consultant_phone': audio['consultantPhone'],
|
||
'consultant_name': audio['consultantName'],
|
||
'start_time': audio['startTime'],
|
||
'duration': audio['duration'],
|
||
'conversation': asr_result.get('result', [])
|
||
}
|
||
```
|
||
|
||
### 传递给Dify工作流
|
||
|
||
```python
|
||
# 5. 转换为Dify陪练工作流格式
|
||
dialogue_history = []
|
||
for msg in conversation['conversation']:
|
||
dialogue_history.append({
|
||
'speaker': 'user' if msg['role'] == 'consultant' else 'ai',
|
||
'content': msg['text'],
|
||
'timestamp': calculate_timestamp(
|
||
conversation['start_time'],
|
||
msg['begin_time']
|
||
)
|
||
})
|
||
|
||
# 6. 调用Dify陪练分析工作流
|
||
analysis_result = await dify_service.analyze_practice_session(
|
||
dialogue_history=dialogue_history
|
||
)
|
||
```
|
||
|
||
## 错误码
|
||
|
||
| code | msg | 说明 |
|
||
|------|-----|------|
|
||
| 0 | success | 成功 |
|
||
| 400 | 顾问手机号和三方员工ID不能同时为空 | 必须传入手机号或员工ID |
|
||
| 1002 | 未授权 | access_token无效或过期 |
|
||
|
||
## 关键优势
|
||
|
||
### vs 其他方案
|
||
|
||
| 方案 | 步骤 | 效率 |
|
||
|-----|------|------|
|
||
| **此接口** | 1步:手机号→录音列表 | ✅ 最优 |
|
||
| 通过来访单ID | 3步:业务系统→来访单ID→录音 | ❌ 需要外部数据 |
|
||
| 通过客户ID | 3步:客户ID→来访单→录音 | ❌ 需要额外维护 |
|
||
|
||
### 为什么是最佳方案
|
||
|
||
1. **✅ 直接查询**:一个接口直接获取员工录音,无需中间步骤
|
||
2. **✅ 手机号匹配**:天然支持手机号匹配,符合业务需求
|
||
3. **✅ 时间筛选**:支持按日期筛选,获取最近对话
|
||
4. **✅ 完整信息**:返回录音ID、员工信息、时间信息
|
||
|
||
## 注意事项
|
||
|
||
1. **手机号和员工ID必传其一**:不能两者都为空
|
||
2. **录音URL有效期7天**:过期需重新调用获取新URL
|
||
3. **时间范围建议**:不建议查询超过30天的数据
|
||
4. **未绑定录音**:此接口获取"未绑定来访单的录音",即员工的所有录音记录
|
||
|
||
## 实施建议
|
||
|
||
### 立即行动
|
||
|
||
1. **获取真实员工手机号**:从贵阳曼尼斐绮门店获取1-2个真实员工手机号
|
||
2. **验证接口调用**:使用真实手机号测试接口,确认能获取录音列表
|
||
3. **检查ASR数据**:确认录音是否有对应的ASR分析结果
|
||
|
||
### 代码实现
|
||
|
||
在`YanjiService`中实现:
|
||
|
||
```python
|
||
async def get_employee_audios_by_phone(
|
||
self,
|
||
consultant_phone: str,
|
||
start_date: str = None,
|
||
limit: int = 10
|
||
) -> List[Dict]:
|
||
"""
|
||
根据员工手机号获取录音信息
|
||
|
||
Args:
|
||
consultant_phone: 员工手机号
|
||
start_date: 起始日期(可选,格式:2024-10-01)
|
||
limit: 返回数量限制
|
||
|
||
Returns:
|
||
录音信息列表,按时间倒序
|
||
"""
|
||
payload = {
|
||
"estateId": self.estate_id,
|
||
"consultantPhone": consultant_phone
|
||
}
|
||
|
||
if start_date:
|
||
payload["audioStartDate"] = start_date
|
||
|
||
data = await self._request(
|
||
method="POST",
|
||
path="/api/beauty/v1/audio/infos",
|
||
json_data=payload
|
||
)
|
||
|
||
if data is None:
|
||
return []
|
||
|
||
records = data.get("records", [])
|
||
|
||
# 按时间倒序排序
|
||
records.sort(key=lambda x: x.get('startTime', ''), reverse=True)
|
||
|
||
# 限制返回数量
|
||
return records[:limit]
|
||
```
|
||
|
||
---
|
||
|
||
**文档版本**:v1.0
|
||
**最后更新**:2025-10-15
|
||
|