86 lines
2.7 KiB
Python
86 lines
2.7 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
会话归档脚本
|
|
|
|
功能:将会话结束超过90天的会话标记为已归档
|
|
|
|
运行方式:
|
|
cd backend
|
|
python scripts/archive_sessions.py
|
|
|
|
定时任务配置(crontab):
|
|
# 每天凌晨3点执行
|
|
0 3 * * * cd /opt/wecom-it-desk/backend && python scripts/archive_sessions.py >> /var/log/itdesk-archive.log 2>&1
|
|
"""
|
|
|
|
import sys
|
|
import os
|
|
from datetime import datetime, timedelta, timezone
|
|
|
|
# 添加 backend 目录到 Python 路径
|
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
|
|
from sqlalchemy import create_engine, select, update
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.config import settings
|
|
from app.models.conversation import Conversation
|
|
|
|
|
|
# 归档阈值:会话结束后多少天开始归档(可配置)
|
|
ARCHIVE_DAYS = 90
|
|
|
|
|
|
def archive_sessions():
|
|
"""将会话结束超过 ARCHIVE_DAYS 天的会话标记为已归档"""
|
|
|
|
print(f"[{datetime.now()}] 开始执行会话归档任务...")
|
|
print(f"归档阈值: {ARCHIVE_DAYS} 天")
|
|
|
|
# 使用配置中的数据库 URL
|
|
# 注意:本地开发使用 aiosqlite 异步驱动,但脚本是同步的
|
|
# 需要将 sqlite+aiosqlite:// 替换为 sqlite://
|
|
db_url = settings.database_url.replace("sqlite+aiosqlite://", "sqlite://")
|
|
engine = create_engine(db_url)
|
|
|
|
# 计算归档截止时间:当前时间 - ARCHIVE_DAYS 天
|
|
# 只有 resolved_at 早于此时间的会话才会被归档
|
|
cutoff_date = datetime.now(timezone.utc) - timedelta(days=ARCHIVE_DAYS)
|
|
|
|
with Session(engine) as session:
|
|
# 查找需要归档的会话:
|
|
# 1. 状态为 resolved(已结单)
|
|
# 2. 已结单时间(resolved_at 或 updated_at)早于截止时间
|
|
# 3. 尚未被归档
|
|
stmt = select(Conversation).where(
|
|
Conversation.status == "resolved",
|
|
Conversation.is_archived == False,
|
|
# 使用 updated_at 作为参考(resolved 状态的会话 updated_at 即为结单时间)
|
|
Conversation.updated_at < cutoff_date
|
|
)
|
|
|
|
sessions_to_archive = session.execute(stmt).scalars().all()
|
|
count = len(sessions_to_archive)
|
|
|
|
if count == 0:
|
|
print(f"[{datetime.now()}] 没有需要归档的会话")
|
|
return
|
|
|
|
print(f"[{datetime.now()}] 找到 {count} 个需要归档的会话")
|
|
|
|
# 标记为已归档
|
|
now = datetime.now(timezone.utc)
|
|
for session_obj in sessions_to_archive:
|
|
session_obj.is_archived = True
|
|
session_obj.archived_at = now
|
|
|
|
# 提交更改
|
|
session.commit()
|
|
|
|
print(f"[{datetime.now()}] 成功归档 {count} 个会话")
|
|
print(f"归档时间: {now.isoformat()}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
archive_sessions()
|