Files
wecom_it_smart_desk/docs/03-技术架构/会话存档功能-技术方案.md
T

261 lines
8.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 会话存档功能 - 技术方案
> **版本**: v1.0 | **日期**: 2026-07-15 | **状态**: 已完成
---
## 1. 架构设计
### 1.1 整体架构
```
┌─────────────────────────────────────────────────────────────┐
│ IT 智能服务台架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ H5 员工端 │ │ 坐席端 │ │ 管理后台 │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │
│ └──────────────┼──────────────┘ │
│ │ │
│ ┌───────▼───────┐ │
│ │ Nginx 入口 │ │
│ └───────┬───────┘ │
│ │ │
│ ┌───────▼───────┐ │
│ │ FastAPI 后端 │ │
│ └───────┬───────┘ │
│ │ │
│ ┌────────────┼────────────┐ │
│ │ │ │ │
│ ┌──────▼──────┐ ┌──▼──┐ ┌──────▼──────┐ │
│ │ 会话管理 API │ │ Dify │ │ 企微 API │ │
│ └──────┬──────┘ └─────┘ └────────────┘ │
│ │ │
│ ┌──────▼──────────────────────────────────┐ │
│ │ PostgreSQL 数据库 │ │
│ │ ┌────────────┐ ┌──────────────────┐ │ │
│ │ │ conversations│ │ messages │ │ │
│ │ │ - is_archived│ │ │ │ │
│ │ │ - archived_at │ │ │ │ │
│ │ └────────────┘ └──────────────────┘ │ │
│ └─────────────────────────────────────────┘ │
│ │ │
│ ┌──────▼──────────────────────────────────┐ │
│ │ 定时任务 (crontab) │ │
│ │ archive_sessions.py │ │
│ └─────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
```
---
## 2. 数据库设计
### 2.1 Conversation 表扩展
```python
# backend/app/models/conversation.py
# 是否已归档(会话结束超过90天后自动标记)
is_archived: Mapped[bool] = mapped_column(
Boolean,
nullable=False,
default=False,
comment="是否已归档",
)
# 归档时间
archived_at: Mapped[Optional[datetime]] = mapped_column(
DateTime(timezone=True),
nullable=True,
comment="归档时间",
)
```
### 2.2 索引设计
```python
__table_args__ = (
# ... 其他索引
Index("idx_conversations_is_archived", "is_archived"),
Index("idx_conversations_archived_at", "archived_at"),
)
```
### 2.3 索引说明
| 索引名 | 字段 | 用途 |
|--------|-----|------|
| idx_conversations_is_archived | is_archived | 按归档状态筛选 |
| idx_conversations_archived_at | archived_at | 按归档时间排序 |
---
## 3. API 设计
### 3.1 管理后台 API
#### 获取会话审计列表
```
GET /api/admin/audit/conversations
```
**请求参数**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| status | string | 否 | 状态筛选 |
| is_archived | bool | 否 | 归档状态筛选 |
| keyword | string | 否 | 关键词搜索 |
| date_from | string | 否 | 开始日期 |
| date_to | string | 否 | 结束日期 |
| page | int | 否 | 页码,默认1 |
| page_size | int | 否 | 每页条数,默认20 |
**响应示例**
```json
{
"code": 0,
"data": {
"items": [
{
"id": "conv-xxx",
"employee_name": "张三",
"status": "resolved",
"is_archived": true,
"archived_at": "2026-07-01T03:00:00Z",
"created_at": "2026-03-01T10:00:00Z",
"updated_at": "2026-03-15T15:30:00Z"
}
],
"total": 100,
"page": 1,
"page_size": 20
}
}
```
---
## 4. 定时归档脚本
### 4.1 脚本设计
**文件位置**`backend/scripts/archive_sessions.py`
**核心逻辑**
```python
# 归档阈值(天)
ARCHIVE_DAYS = 90
# 计算归档截止时间
cutoff_date = datetime.now(timezone.utc) - timedelta(days=ARCHIVE_DAYS)
# 查找需要归档的会话
stmt = select(Conversation).where(
Conversation.status == "resolved",
Conversation.is_archived == False,
Conversation.updated_at < cutoff_date
)
```
### 4.2 定时任务配置
```bash
# crontab 配置
# 每天凌晨3点执行
0 3 * * * cd /opt/wecom-it-desk/backend && python scripts/archive_sessions.py >> /var/log/itdesk-archive.log 2>&1
```
### 4.3 日志输出
```
[2026-07-15 03:00:00] 开始执行会话归档任务...
[2026-07-15 03:00:00] 归档阈值: 90 天
[2026-07-15 03:00:00] 找到 15 个需要归档的会话
[2026-07-15 03:00:01] 成功归档 15 个会话
[2026-07-15 03:00:01] 归档时间: 2026-07-15T03:00:01+00:00
```
---
## 5. 前端设计
### 5.1 坐席端 - 历史会话过滤
**文件**`frontend-agent/src/stores/conversation.ts`
```typescript
// 历史会话仅显示 90 天内的已结单会话
const HISTORY_DAYS = 90
const historyConversations = computed(() => {
const cutoffDate = new Date()
cutoffDate.setDate(cutoffDate.getDate() - HISTORY_DAYS)
const cutoffTime = cutoffDate.getTime()
return sortedConversations.value.filter(c => {
if (c.status !== 'resolved') return false
const createdTime = c.created_at ? new Date(c.created_at).getTime() : 0
return createdTime >= cutoffTime
})
})
```
### 5.2 管理后台 - 归档状态筛选
**文件**`frontend-admin/src/views/SessionAudit.vue`
```typescript
// 过滤条件
const filters = reactive({
keyword: '',
status: '',
is_archived: '', // 新增归档状态筛选
})
// 表格列
<el-table-column prop="is_archived" label="归档" width="80">
<template #default="{ row }">
<el-tag v-if="row.is_archived" type="info"></el-tag>
<span v-else></span>
</template>
</el-table-column>
```
---
## 6. 部署配置
### 6.1 数据库迁移
```bash
# 使用 Alembic 创建迁移
cd backend
alembic revision --autogenerate -m "add archive fields"
alembic upgrade head
```
### 6.2 定时任务部署
```bash
# 复制脚本到服务器
scp backend/scripts/archive_sessions.py sxn@10.212.189.210:/opt/wecom-it-desk/backend/scripts/
# 添加 crontab 任务
crontab -e
# 添加: 0 3 * * * cd /opt/wecom-it-desk/backend && python scripts/archive_sessions.py >> /var/log/itdesk-archive.log 2>&1
```
---
## 7. 版本历史
| 版本 | 日期 | 变更 |
|------|------|------|
| v1.0 | 2026-07-15 | 初始版本 |