init
This commit is contained in:
197
app/backend-python/services/chat_history_service.py
Normal file
197
app/backend-python/services/chat_history_service.py
Normal file
@@ -0,0 +1,197 @@
|
||||
"""
|
||||
对话记录服务
|
||||
负责存储和查询用户与管家agent的对话记录
|
||||
"""
|
||||
|
||||
import logging
|
||||
import json
|
||||
from typing import Optional, Dict, Any, List
|
||||
from datetime import datetime
|
||||
|
||||
from database import query, insert
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# 延迟导入以避免循环依赖
|
||||
_conversation_service = None
|
||||
def get_conversation_service():
|
||||
global _conversation_service
|
||||
if _conversation_service is None:
|
||||
from services.conversation_service import conversation_service
|
||||
_conversation_service = conversation_service
|
||||
return _conversation_service
|
||||
|
||||
|
||||
class ChatHistoryService:
|
||||
"""对话记录服务"""
|
||||
|
||||
@staticmethod
|
||||
def generate_id() -> int:
|
||||
"""生成唯一ID(使用时间戳+随机数)"""
|
||||
import time
|
||||
import random
|
||||
return int(time.time() * 1000000) + random.randint(1000, 9999)
|
||||
|
||||
@staticmethod
|
||||
async def save_message(
|
||||
system_user_id: int,
|
||||
context_id: str,
|
||||
role: str,
|
||||
content: str,
|
||||
message_id: Optional[str] = None,
|
||||
task_id: Optional[str] = None,
|
||||
status: str = "success",
|
||||
error_message: Optional[str] = None,
|
||||
metadata: Optional[Dict[str, Any]] = None
|
||||
) -> bool:
|
||||
"""
|
||||
保存对话消息
|
||||
|
||||
Args:
|
||||
system_user_id: 系统用户ID
|
||||
context_id: 会话上下文ID
|
||||
role: 角色 (user, agent, system)
|
||||
content: 消息内容
|
||||
message_id: 消息ID(可选)
|
||||
task_id: 任务ID(可选)
|
||||
status: 状态 (success, failed, error)
|
||||
error_message: 错误信息(如果失败)
|
||||
metadata: 元数据(可选)
|
||||
|
||||
Returns:
|
||||
是否成功保存
|
||||
"""
|
||||
try:
|
||||
msg_id = ChatHistoryService.generate_id()
|
||||
|
||||
# 将元数据转为JSON字符串
|
||||
metadata_json = json.dumps(metadata, ensure_ascii=False) if metadata else None
|
||||
|
||||
sql = """
|
||||
INSERT INTO chat_history
|
||||
(id, system_user_id, context_id, message_id, task_id, role, content,
|
||||
status, error_message, metadata, created_at)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NOW())
|
||||
"""
|
||||
|
||||
params = (
|
||||
msg_id,
|
||||
system_user_id,
|
||||
context_id,
|
||||
message_id,
|
||||
task_id,
|
||||
role,
|
||||
content,
|
||||
status,
|
||||
error_message,
|
||||
metadata_json
|
||||
)
|
||||
|
||||
insert(sql, params)
|
||||
logger.info(f"✅ 保存对话记录成功: user={system_user_id}, role={role}, context={context_id}")
|
||||
|
||||
# 更新对话列表
|
||||
try:
|
||||
conv_service = get_conversation_service()
|
||||
|
||||
# 确保对话列表存在
|
||||
await conv_service.ensure_conversation_exists(
|
||||
system_user_id=system_user_id,
|
||||
context_id=context_id
|
||||
)
|
||||
|
||||
# 如果是用户或agent消息,更新最后一条消息和消息计数
|
||||
if role in ["user", "agent"]:
|
||||
await conv_service.update_conversation(
|
||||
context_id=context_id,
|
||||
last_message=content,
|
||||
increment_message_count=True
|
||||
)
|
||||
except Exception as e:
|
||||
logger.warning(f"⚠️ 更新对话列表失败(不影响消息保存): {e}")
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"❌ 保存对话记录失败: {e}", exc_info=True)
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
async def get_conversation_history(
|
||||
system_user_id: int,
|
||||
context_id: str,
|
||||
limit: int = 50
|
||||
) -> List[Dict[str, Any]]:
|
||||
"""
|
||||
获取会话历史记录
|
||||
|
||||
Args:
|
||||
system_user_id: 系统用户ID
|
||||
context_id: 会话上下文ID
|
||||
limit: 返回记录数量限制
|
||||
|
||||
Returns:
|
||||
对话记录列表
|
||||
"""
|
||||
try:
|
||||
sql = """
|
||||
SELECT id, system_user_id, context_id, message_id, task_id, role,
|
||||
content, status, error_message, metadata, created_at
|
||||
FROM chat_history
|
||||
WHERE system_user_id = %s AND context_id = %s
|
||||
ORDER BY created_at DESC
|
||||
LIMIT %s
|
||||
"""
|
||||
|
||||
results = query(sql, (system_user_id, context_id, limit))
|
||||
|
||||
# 解析metadata JSON字符串
|
||||
for row in results:
|
||||
if row.get('metadata'):
|
||||
try:
|
||||
row['metadata'] = json.loads(row['metadata'])
|
||||
except:
|
||||
pass
|
||||
|
||||
return results
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"❌ 获取会话历史失败: {e}", exc_info=True)
|
||||
return []
|
||||
|
||||
@staticmethod
|
||||
async def get_user_recent_conversations(
|
||||
system_user_id: int,
|
||||
limit: int = 20
|
||||
) -> List[Dict[str, Any]]:
|
||||
"""
|
||||
获取用户最近的对话记录(跨会话)
|
||||
|
||||
Args:
|
||||
system_user_id: 系统用户ID
|
||||
limit: 返回记录数量限制
|
||||
|
||||
Returns:
|
||||
对话记录列表
|
||||
"""
|
||||
try:
|
||||
sql = """
|
||||
SELECT id, system_user_id, context_id, message_id, task_id, role,
|
||||
content, status, error_message, created_at
|
||||
FROM chat_history
|
||||
WHERE system_user_id = %s
|
||||
ORDER BY created_at DESC
|
||||
LIMIT %s
|
||||
"""
|
||||
|
||||
results = query(sql, (system_user_id, limit))
|
||||
return results
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"❌ 获取用户对话历史失败: {e}", exc_info=True)
|
||||
return []
|
||||
|
||||
|
||||
# 创建全局服务实例
|
||||
chat_history_service = ChatHistoryService()
|
||||
|
||||
Reference in New Issue
Block a user