"""Chat engine: message persistence, status tracking, recall.""" from datetime import datetime from app import db from app.models.chat import Conversation, Message, MessageStatus class ChatEngineService: @staticmethod def get_or_create_conversation(user_id, title="新对话"): conv = Conversation.query.filter_by(user_id=user_id).order_by( Conversation.last_message_at.desc() ).first() if conv: return conv conv = Conversation(user_id=user_id, title=title) db.session.add(conv) db.session.commit() return conv @staticmethod def list_conversations(user_id, skip=0, limit=20): return Conversation.query.filter_by(user_id=user_id).order_by( Conversation.last_message_at.desc() ).offset(skip).limit(limit).all() @staticmethod def send_message(conversation_id, sender_id, content, content_type="text", attachment_url=None, attachment_name=None): conv = Conversation.query.get(conversation_id) if not conv or str(conv.user_id) != str(sender_id): return None msg = Message( conversation_id=conversation_id, sender_id=sender_id, content=content, content_type=content_type or "text", attachment_url=attachment_url, attachment_name=attachment_name, status=MessageStatus.SENT, ) db.session.add(msg) conv.last_message_at = datetime.utcnow() db.session.commit() return msg @staticmethod def get_messages(conversation_id, user_id, before_id=None, limit=50): conv = Conversation.query.get(conversation_id) if not conv or str(conv.user_id) != str(user_id): return [] q = Message.query.filter_by(conversation_id=conversation_id).filter( Message.is_recalled == False ) if before_id: before = Message.query.get(before_id) if before: q = q.filter(Message.created_at < before.created_at) return q.order_by(Message.created_at.desc()).limit(limit).all() @staticmethod def recall_message(message_id, user_id): msg = Message.query.get(message_id) if not msg or str(msg.sender_id) != str(user_id): return False msg.is_recalled = True msg.recalled_at = datetime.utcnow() msg.status = MessageStatus.RECALLED db.session.commit() return True @staticmethod def update_message_status(message_id, status): msg = Message.query.get(message_id) if not msg: return False msg.status = status db.session.commit() return True