operations_project/apps/gmail/services/export_service.py

128 lines
5.4 KiB
Python
Raw Normal View History

2025-05-21 11:14:08 +08:00
import os
import logging
import pandas as pd
from datetime import datetime
from django.db.models import Q, F
from django.utils import timezone
from apps.gmail.models import GmailConversation, GmailAttachment, ConversationSummary
from apps.chat.models import ChatHistory
logger = logging.getLogger(__name__)
class GmailExportService:
"""
Gmail导出服务提供将达人回复导出为Excel的功能
"""
@staticmethod
def export_replied_influencers(user, format='xlsx'):
"""
导出已回复的达人Gmail列表
Args:
user: 用户对象
format: 导出格式, 默认为xlsx
Returns:
tuple: (文件路径, 错误信息)
"""
try:
# 获取用户所有的Gmail对话
conversations = GmailConversation.objects.filter(
user=user,
is_active=True
)
if not conversations.exists():
return None, "未找到任何Gmail对话"
# 准备导出数据
export_data = []
for conversation in conversations:
# 查询达人是否有回复
chat_history = ChatHistory.objects.filter(
user=user,
conversation_id=conversation.conversation_id,
metadata__contains={"from": conversation.influencer_email}
).order_by('created_at')
# 如果达人有回复,则添加到导出列表
if chat_history.exists():
# 获取第一条回复的时间
first_reply = chat_history.first()
first_reply_time = first_reply.created_at.replace(tzinfo=None) if first_reply else None
# 获取最后一条回复的时间
last_reply = chat_history.last()
last_reply_time = last_reply.created_at.replace(tzinfo=None) if last_reply else None
# 获取回复次数
reply_count = chat_history.count()
# 直接从数据库中获取对话摘要不调用外部API
summary = ""
try:
# 先从ConversationSummary模型中查找
conversation_summary = ConversationSummary.objects.filter(
conversation=conversation
).first()
if conversation_summary:
summary = conversation_summary.content
else:
# 如果没有摘要,尝试获取最新的几条消息内容
recent_messages = ChatHistory.objects.filter(
user=user,
conversation_id=conversation.conversation_id
).order_by('-created_at')[:5]
if recent_messages:
summary = "最近消息: " + " | ".join([msg.content[:100] + ("..." if len(msg.content) > 100 else "") for msg in recent_messages])
except Exception as e:
logger.error(f"获取对话摘要失败: {str(e)}")
summary = '无法获取摘要'
# 构建导出记录 - 注意移除时区信息
export_record = {
'用户邮箱': conversation.user_email,
'达人邮箱': conversation.influencer_email,
'对话标题': conversation.title,
'对话开始时间': conversation.created_at.replace(tzinfo=None),
'首次回复时间': first_reply_time,
'最近回复时间': last_reply_time,
'回复次数': reply_count,
'对话摘要': summary,
'对话ID': conversation.conversation_id
}
export_data.append(export_record)
if not export_data:
return None, "没有找到已回复的达人"
# 创建DataFrame
df = pd.DataFrame(export_data)
# 生成文件名和路径
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
file_name = f"influencer_replies_{timestamp}.{format}"
export_dir = os.path.join('media', 'exports')
os.makedirs(export_dir, exist_ok=True)
file_path = os.path.join(export_dir, file_name)
# 根据格式导出
if format == 'xlsx':
df.to_excel(file_path, index=False, engine='openpyxl')
elif format == 'csv':
df.to_csv(file_path, index=False, encoding='utf-8-sig')
else:
return None, f"不支持的导出格式: {format}"
return file_path, None
except Exception as e:
logger.error(f"导出已回复达人失败: {str(e)}")
import traceback
logger.error(traceback.format_exc())
return None, f"导出失败: {str(e)}"