Files
aiagent/saars/backend/app/services/chat_engine.py
2026-03-07 09:01:00 +08:00

79 lines
2.7 KiB
Python

"""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