operations_project/apps/gmail/services/goal_service.py
2025-05-20 15:57:10 +08:00

218 lines
6.9 KiB
Python
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.

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