318 lines
8.2 KiB
Markdown
318 lines
8.2 KiB
Markdown
# 联系记录接口文档
|
||
|
||
## 1. 查询联系记录列表
|
||
|
||
### 接口信息
|
||
- **URL**: `/api/contacts`
|
||
- **方法**: `GET`
|
||
- **认证**: 需要登录(Header 携带 Authorization)
|
||
|
||
### 请求参数
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|
||
|--------|------|------|------|------|
|
||
| page | integer | 否 | 页码,默认 1 | 1 |
|
||
| page_size | integer | 否 | 每页数量,默认 10 | 20 |
|
||
| search | string | 否 | 搜索关键词(姓名/岗位/联系方式) | 张三 |
|
||
| reply_status | string | 否 | 回复状态筛选 | 已回复 |
|
||
| wechat_exchanged | boolean | 否 | 是否交换微信 | true |
|
||
| start_date | string | 否 | 开始日期(YYYY-MM-DD) | 2024-01-01 |
|
||
| end_date | string | 否 | 结束日期(YYYY-MM-DD) | 2024-12-31 |
|
||
|
||
### 请求示例
|
||
|
||
```bash
|
||
# 基础查询
|
||
GET /api/contacts?page=1&page_size=20
|
||
|
||
# 关键词搜索
|
||
GET /api/contacts?search=张三
|
||
|
||
# 按回复状态筛选
|
||
GET /api/contacts?reply_status=已回复
|
||
|
||
# 按时间范围筛选
|
||
GET /api/contacts?start_date=2024-01-01&end_date=2024-12-31
|
||
|
||
# 组合筛选
|
||
GET /api/contacts?search=产品经理&reply_status=已回复&wechat_exchanged=true&start_date=2024-01-01&end_date=2024-12-31
|
||
```
|
||
|
||
### 响应示例
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "success",
|
||
"data": {
|
||
"total": 150,
|
||
"page": 1,
|
||
"page_size": 20,
|
||
"results": [
|
||
{
|
||
"id": 1,
|
||
"name": "张三",
|
||
"position": "产品经理",
|
||
"contact": "13800138000",
|
||
"reply_status": "已回复",
|
||
"wechat_exchanged": true,
|
||
"account_id": 1,
|
||
"worker_id": "worker-001",
|
||
"notes": "沟通顺畅,有意向",
|
||
"contacted_at": "2024-03-01T10:30:00",
|
||
"created_at": "2024-03-01T10:00:00"
|
||
},
|
||
{
|
||
"id": 2,
|
||
"name": "李四",
|
||
"position": "前端工程师",
|
||
"contact": "wechat:lisi123",
|
||
"reply_status": "未回复",
|
||
"wechat_exchanged": false,
|
||
"account_id": 2,
|
||
"worker_id": "worker-002",
|
||
"notes": "",
|
||
"contacted_at": "2024-03-02T14:20:00",
|
||
"created_at": "2024-03-02T14:00:00"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 2. 导出联系记录为 Excel
|
||
|
||
### 接口信息
|
||
- **URL**: `/api/contacts/export`
|
||
- **方法**: `GET`
|
||
- **认证**: 需要登录(Header 携带 Authorization)
|
||
- **响应类型**: `application/json`(返回下载链接)
|
||
|
||
### 请求参数
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|
||
|--------|------|------|------|------|
|
||
| search | string | 否 | 搜索关键词(姓名/岗位/联系方式) | 张三 |
|
||
| reply_status | string | 否 | 回复状态筛选 | 已回复 |
|
||
| wechat_exchanged | boolean | 否 | 是否交换微信 | true |
|
||
| start_date | string | 否 | 开始日期(YYYY-MM-DD) | 2024-01-01 |
|
||
| end_date | string | 否 | 结束日期(YYYY-MM-DD) | 2024-12-31 |
|
||
|
||
### 请求示例
|
||
|
||
```bash
|
||
# 导出所有联系记录
|
||
GET /api/contacts/export
|
||
|
||
# 导出指定时间段的记录
|
||
GET /api/contacts/export?start_date=2024-01-01&end_date=2024-12-31
|
||
|
||
# 导出已回复且交换微信的记录
|
||
GET /api/contacts/export?reply_status=已回复&wechat_exchanged=true
|
||
|
||
# 导出组合筛选结果
|
||
GET /api/contacts/export?search=产品经理&start_date=2024-01-01&end_date=2024-03-31&reply_status=已回复
|
||
```
|
||
|
||
### 响应示例
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "success",
|
||
"data": {
|
||
"download_url": "http://127.0.0.1:8000/media/exports/contacts_export_20240304_153045_a1b2c3d4.xlsx",
|
||
"filename": "contacts_export_20240304_153045_a1b2c3d4.xlsx",
|
||
"total_records": 150,
|
||
"generated_at": "2024-03-04 15:30:45"
|
||
}
|
||
}
|
||
```
|
||
|
||
### 响应字段说明
|
||
|
||
| 字段名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| download_url | string | 文件下载链接(完整 URL) |
|
||
| filename | string | 生成的文件名 |
|
||
| total_records | integer | 导出的记录总数 |
|
||
| generated_at | string | 文件生成时间 |
|
||
|
||
### Excel 文件格式
|
||
|
||
**表头**(蓝色背景,白色粗体文字):
|
||
|
||
| 列名 | 说明 | 示例 |
|
||
|------|------|------|
|
||
| ID | 记录 ID | 1 |
|
||
| 姓名 | 联系人姓名 | 张三 |
|
||
| 岗位 | 应聘岗位 | 产品经理 |
|
||
| 联系方式 | 电话或微信 | 13800138000 |
|
||
| 回复状态 | 回复状态 | 已回复 |
|
||
| 是否交换微信 | 是/否 | 是 |
|
||
| Worker ID | Worker 标识 | worker-001 |
|
||
| 备注 | 备注信息 | 沟通顺畅,有意向 |
|
||
| 联系时间 | 联系时间 | 2024-03-01 10:30:00 |
|
||
| 创建时间 | 创建时间 | 2024-03-01 10:00:00 |
|
||
|
||
### 前端调用示例
|
||
|
||
```javascript
|
||
// 使用 axios
|
||
const exportContacts = async (params) => {
|
||
try {
|
||
const response = await axios.get('/api/contacts/export', {
|
||
params: params,
|
||
headers: {
|
||
'Authorization': `Bearer ${token}`
|
||
}
|
||
});
|
||
|
||
if (response.data.code === 200) {
|
||
const { download_url, filename, total_records } = response.data.data;
|
||
|
||
// 方式1:直接打开下载链接
|
||
window.open(download_url, '_blank');
|
||
|
||
// 方式2:使用 a 标签下载
|
||
const link = document.createElement('a');
|
||
link.href = download_url;
|
||
link.download = filename;
|
||
document.body.appendChild(link);
|
||
link.click();
|
||
document.body.removeChild(link);
|
||
|
||
// 提示用户
|
||
console.log(`成功导出 ${total_records} 条记录`);
|
||
}
|
||
} catch (error) {
|
||
console.error('导出失败:', error);
|
||
}
|
||
};
|
||
|
||
// 调用示例
|
||
exportContacts({
|
||
start_date: '2024-01-01',
|
||
end_date: '2024-12-31',
|
||
reply_status: '已回复'
|
||
});
|
||
```
|
||
|
||
```javascript
|
||
// 使用 fetch
|
||
const exportContacts = async (params) => {
|
||
const queryString = new URLSearchParams(params).toString();
|
||
|
||
try {
|
||
const response = await fetch(`/api/contacts/export?${queryString}`, {
|
||
headers: {
|
||
'Authorization': `Bearer ${token}`
|
||
}
|
||
});
|
||
|
||
const result = await response.json();
|
||
|
||
if (result.code === 200) {
|
||
const { download_url, filename, total_records } = result.data;
|
||
|
||
// 直接下载文件
|
||
const link = document.createElement('a');
|
||
link.href = download_url;
|
||
link.download = filename;
|
||
link.click();
|
||
|
||
alert(`成功导出 ${total_records} 条记录`);
|
||
}
|
||
} catch (error) {
|
||
console.error('导出失败:', error);
|
||
}
|
||
};
|
||
```
|
||
|
||
```vue
|
||
<!-- Vue 3 组件示例 -->
|
||
<template>
|
||
<button @click="handleExport" :loading="exporting">
|
||
导出 Excel
|
||
</button>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref } from 'vue';
|
||
import axios from 'axios';
|
||
|
||
const exporting = ref(false);
|
||
|
||
const handleExport = async () => {
|
||
exporting.value = true;
|
||
|
||
try {
|
||
const response = await axios.get('/api/contacts/export', {
|
||
params: {
|
||
start_date: '2024-01-01',
|
||
end_date: '2024-12-31'
|
||
}
|
||
});
|
||
|
||
if (response.data.code === 200) {
|
||
const { download_url, total_records } = response.data.data;
|
||
|
||
// 下载文件
|
||
window.open(download_url, '_blank');
|
||
|
||
// 显示成功提示
|
||
ElMessage.success(`成功导出 ${total_records} 条记录`);
|
||
}
|
||
} catch (error) {
|
||
ElMessage.error('导出失败,请重试');
|
||
} finally {
|
||
exporting.value = false;
|
||
}
|
||
};
|
||
</script>
|
||
```
|
||
|
||
---
|
||
|
||
## 错误码说明
|
||
|
||
| 错误码 | 说明 |
|
||
|--------|------|
|
||
| 200 | 成功 |
|
||
| 400 | 请求参数错误 |
|
||
| 401 | 未登录或 token 无效 |
|
||
| 500 | 服务器内部错误 |
|
||
|
||
## 注意事项
|
||
|
||
1. **时间筛选**:
|
||
- `start_date` 从当天 00:00:00 开始
|
||
- `end_date` 到当天 23:59:59 结束
|
||
- 时间筛选基于 `created_at` 字段(创建时间)
|
||
|
||
2. **搜索功能**:
|
||
- `search` 参数支持模糊匹配
|
||
- 同时搜索姓名、岗位、联系方式三个字段
|
||
|
||
3. **导出机制**:
|
||
- 导出接口返回下载链接,不直接返回文件流
|
||
- 文件保存在服务器 `media/exports/` 目录
|
||
- 文件名格式:`contacts_export_{时间戳}_{随机ID}.xlsx`
|
||
- 导出接口不分页,会导出所有符合条件的记录
|
||
- 建议在导出大量数据时添加时间范围限制
|
||
|
||
4. **文件管理**:
|
||
- 导出的文件会保存在服务器上
|
||
- 建议定期清理过期的导出文件
|
||
- 可以通过定时任务删除超过一定时间的文件
|
||
|
||
5. **认证要求**:
|
||
- 所有接口都需要在 Header 中携带 `Authorization` token
|
||
- token 格式:`Bearer <token>`
|
||
|
||
6. **下载链接**:
|
||
- 返回的 `download_url` 是可直接访问的完整下载 URL
|
||
- 前端可直接 `window.open(download_url)` 或 `a.href = download_url` 下载
|