128 lines
5.4 KiB
Python
128 lines
5.4 KiB
Python
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)}" |