218 lines
6.9 KiB
Python
218 lines
6.9 KiB
Python
import logging
|
||
from django.conf import settings
|
||
from datetime import datetime
|
||
from apps.gmail.models import GmailConversation, ConversationSummary, UserGoal
|
||
from apps.chat.models import ChatHistory
|
||
from apps.common.services.ai_service import AIService
|
||
import traceback
|
||
from apps.accounts.services.utils import validate_uuid_param
|
||
from apps.gmail.services.gmail_service import GmailService
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
def get_conversation(conversation_id):
|
||
"""
|
||
获取给定对话ID的对话内容
|
||
|
||
参数:
|
||
- conversation_id: 对话ID
|
||
|
||
返回:
|
||
- 对话数据,包含消息列表,如无法获取则返回None
|
||
"""
|
||
try:
|
||
# 验证对话ID参数
|
||
uuid_obj, error = validate_uuid_param(conversation_id)
|
||
if error:
|
||
logger.error(f"无效的对话ID: {conversation_id}")
|
||
return None
|
||
|
||
# 查找对话
|
||
conversation = GmailConversation.objects.filter(conversation_id=conversation_id).first()
|
||
if not conversation:
|
||
logger.warning(f"未找到对话记录: {conversation_id}")
|
||
return None
|
||
|
||
# 获取对话消息
|
||
messages = ChatHistory.objects.filter(
|
||
conversation_id=conversation_id
|
||
).order_by('created_at')
|
||
|
||
if not messages:
|
||
logger.warning(f"对话 {conversation_id} 没有消息记录")
|
||
return None
|
||
|
||
# 构造消息列表
|
||
message_list = []
|
||
for msg in messages:
|
||
message_list.append({
|
||
'id': str(msg.id),
|
||
'content': msg.content,
|
||
'is_user': msg.role == 'user',
|
||
'timestamp': msg.created_at.isoformat(),
|
||
'metadata': msg.metadata or {}
|
||
})
|
||
|
||
return {
|
||
'id': conversation_id,
|
||
'title': conversation.title,
|
||
'user_email': conversation.user_email,
|
||
'influencer_email': conversation.influencer_email,
|
||
'messages': message_list
|
||
}
|
||
|
||
except Exception as e:
|
||
logger.error(f"获取对话时发生错误: {str(e)}")
|
||
logger.error(traceback.format_exc())
|
||
return None
|
||
|
||
def get_conversation_summary(conversation_id):
|
||
"""
|
||
获取对话摘要
|
||
|
||
Args:
|
||
conversation_id: 对话ID
|
||
|
||
Returns:
|
||
str: 摘要内容或None
|
||
"""
|
||
try:
|
||
# 先检查持久化存储的摘要
|
||
try:
|
||
# 不使用UUID验证,直接通过conversation_id查找
|
||
conversation = GmailConversation.objects.filter(conversation_id=conversation_id).first()
|
||
if not conversation:
|
||
logger.warning(f"未找到对话: {conversation_id}")
|
||
return None
|
||
|
||
summary = ConversationSummary.objects.filter(conversation=conversation).first()
|
||
if summary:
|
||
return summary.content
|
||
except Exception as e:
|
||
logger.error(f"获取持久化摘要失败: {str(e)}")
|
||
# 继续尝试生成简单摘要
|
||
|
||
# 如果没有持久化的摘要,尝试生成简单摘要
|
||
chat_history = ChatHistory.objects.filter(conversation_id=conversation_id).order_by('-created_at')[:5]
|
||
if not chat_history:
|
||
return None
|
||
|
||
# 生成简单摘要(最近几条消息)
|
||
messages = []
|
||
for msg in chat_history:
|
||
if len(messages) < 3: # 只取最新的3条
|
||
role = "用户" if msg.role == "user" else "达人"
|
||
content = msg.content
|
||
if len(content) > 100:
|
||
content = content[:100] + "..."
|
||
messages.append(f"{role}: {content}")
|
||
|
||
if messages:
|
||
return "最近对话: " + " | ".join(reversed(messages))
|
||
return None
|
||
except Exception as e:
|
||
logger.error(f"获取对话摘要失败: {str(e)}")
|
||
return None
|
||
|
||
def get_last_message(conversation_id):
|
||
"""
|
||
获取给定对话的最后一条消息
|
||
|
||
参数:
|
||
- conversation_id: 对话ID
|
||
|
||
返回:
|
||
- 最后一条消息文本,如果无法获取则返回None
|
||
"""
|
||
try:
|
||
# 直接通过conversation_id获取最后一条消息,不进行UUID验证
|
||
# 获取对话消息
|
||
chat_messages = ChatHistory.objects.filter(
|
||
conversation_id=conversation_id
|
||
).order_by('created_at')
|
||
|
||
if not chat_messages:
|
||
logger.warning(f"对话 {conversation_id} 没有消息记录")
|
||
return None
|
||
|
||
# 过滤出达人发送的消息
|
||
influencer_messages = [msg for msg in chat_messages if msg.role == 'assistant']
|
||
|
||
if not influencer_messages:
|
||
logger.warning(f"对话 {conversation_id} 中没有达人发送的消息")
|
||
return None
|
||
|
||
# 返回最后一条达人消息
|
||
last_message = influencer_messages[-1].content
|
||
return last_message
|
||
|
||
except Exception as e:
|
||
logger.error(f"获取最后一条消息时发生错误: {str(e)}")
|
||
logger.error(traceback.format_exc())
|
||
return None
|
||
|
||
def generate_recommended_reply(user, goal_description, conversation_summary, last_message):
|
||
"""
|
||
根据用户目标、对话摘要和最后一条消息生成推荐话术
|
||
|
||
Args:
|
||
user: 用户对象
|
||
goal_description: 用户目标描述
|
||
conversation_summary: 对话摘要
|
||
last_message: 达人最后发送的消息内容
|
||
|
||
Returns:
|
||
tuple: (推荐话术内容, 错误信息)
|
||
"""
|
||
# 直接调用AIService生成回复
|
||
return AIService.generate_email_reply(goal_description, conversation_summary, last_message)
|
||
|
||
def get_or_create_goal(user, conversation_id, goal_description=None):
|
||
"""
|
||
获取或创建用户目标
|
||
|
||
Args:
|
||
user: 用户对象
|
||
conversation_id: 对话ID
|
||
goal_description: 目标描述 (可选,如不提供则只获取不创建)
|
||
|
||
Returns:
|
||
tuple: (UserGoal, bool) - 目标对象和是否新创建的标志
|
||
"""
|
||
# 查找对话
|
||
conversation = GmailConversation.objects.filter(
|
||
conversation_id=conversation_id,
|
||
user=user
|
||
).first()
|
||
|
||
if not conversation:
|
||
return None, False
|
||
|
||
# 查找现有目标
|
||
goal = UserGoal.objects.filter(
|
||
user=user,
|
||
conversation=conversation
|
||
).first()
|
||
|
||
# 如果有目标且不需要更新,直接返回
|
||
if goal and not goal_description:
|
||
return goal, False
|
||
|
||
# 如果有目标需要更新
|
||
if goal and goal_description:
|
||
goal.description = goal_description
|
||
goal.save()
|
||
return goal, False
|
||
|
||
# 如果需要创建新目标
|
||
if not goal and goal_description:
|
||
goal = UserGoal.objects.create(
|
||
user=user,
|
||
conversation=conversation,
|
||
description=goal_description
|
||
)
|
||
return goal, True
|
||
|
||
return None, False
|
||
|