from django.db import models from apps.accounts.models import User import json import os from django.utils import timezone import uuid class GmailCredential(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='gmail_credentials') email = models.EmailField(unique=True, help_text="Gmail email address") credentials = models.TextField(help_text="Serialized OAuth2 credentials (JSON)") is_default = models.BooleanField(default=False, help_text="Default Gmail account for user") created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) is_valid = models.BooleanField(default=True, help_text="Whether the credential is valid") last_history_id = models.CharField(max_length=50, blank=True, null=True, help_text="Last processed Gmail history ID") class Meta: unique_together = ('user', 'email') def set_credentials(self, credentials): self.credentials = json.dumps({ 'token': credentials.token, 'refresh_token': credentials.refresh_token, 'token_uri': credentials.token_uri, 'client_id': credentials.client_id, 'client_secret': credentials.client_secret, 'scopes': credentials.scopes }) self.is_valid = True def get_credentials(self): from google.oauth2.credentials import Credentials creds_data = json.loads(self.credentials) return Credentials( token=creds_data['token'], refresh_token=creds_data['refresh_token'], token_uri=creds_data['token_uri'], client_id=creds_data['client_id'], client_secret=creds_data['client_secret'], scopes=creds_data['scopes'] ) def __str__(self): return f"{self.user.username} - {self.email}" class GmailConversation(models.Model): """Gmail对话记录,跟踪用户和达人之间的邮件交互""" user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='gmail_conversations') user_email = models.EmailField(help_text="用户Gmail邮箱") influencer_email = models.EmailField(help_text="达人Gmail邮箱") conversation_id = models.CharField(max_length=100, unique=True, help_text="关联到chat_history的会话ID") title = models.CharField(max_length=100, default="Gmail对话", help_text="对话标题") last_sync_time = models.DateTimeField(default=timezone.now, help_text="最后同步时间") created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) is_active = models.BooleanField(default=True) metadata = models.JSONField(default=dict, blank=True, null=True, help_text="存储额外信息,如已处理的消息ID等") def __str__(self): return f"{self.user.username}: {self.user_email} - {self.influencer_email}" class Meta: ordering = ['-updated_at'] unique_together = ('user', 'user_email', 'influencer_email') class GmailAttachment(models.Model): """Gmail附件记录""" conversation = models.ForeignKey(GmailConversation, on_delete=models.CASCADE, related_name='attachments') email_message_id = models.CharField(max_length=100, help_text="Gmail邮件ID") attachment_id = models.CharField(max_length=100, help_text="Gmail附件ID") filename = models.CharField(max_length=255, help_text="原始文件名") file_path = models.CharField(max_length=255, help_text="保存在服务器上的路径") content_type = models.CharField(max_length=100, help_text="MIME类型") size = models.IntegerField(default=0, help_text="文件大小(字节)") sender_email = models.EmailField(help_text="发送者邮箱") chat_message_id = models.CharField(max_length=100, blank=True, null=True, help_text="关联到ChatHistory的消息ID") created_at = models.DateTimeField(auto_now_add=True) def __str__(self): return f"{self.filename} ({self.size} bytes)" def get_file_extension(self): """获取文件扩展名""" _, ext = os.path.splitext(self.filename) return ext.lower() def get_absolute_url(self): """获取文件URL""" return f"/media/gmail_attachments/{os.path.basename(self.file_path)}" class Meta: ordering = ['-created_at'] class ConversationSummary(models.Model): """Gmail对话摘要模型,用于持久化存储对话摘要""" id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) conversation = models.OneToOneField('GmailConversation', on_delete=models.CASCADE, related_name='summary') content = models.TextField(verbose_name='摘要内容') last_message_id = models.CharField(max_length=255, verbose_name='最后处理的消息ID或ChatHistory的ID', null=True, blank=True) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) class Meta: db_table = 'gmail_conversation_summaries' verbose_name = 'Gmail对话摘要' verbose_name_plural = 'Gmail对话摘要' def __str__(self): return f"对话 {self.conversation.id} 摘要"