""" Chat REST API: conversations, messages, recall. """ from flask import Blueprint, request, jsonify from flask_jwt_extended import jwt_required, get_jwt_identity from app.services.chat_engine import ChatEngineService from app.socket_events import broadcast_new_message chat_bp = Blueprint("chat", __name__) @chat_bp.route("/conversations", methods=["GET"]) @jwt_required() def list_conversations(): skip = request.args.get("skip", 0, type=int) limit = min(request.args.get("limit", 20, type=int), 100) user_id = get_jwt_identity() convs = ChatEngineService.list_conversations(user_id, skip=skip, limit=limit) return jsonify({ "items": [ { "id": c.id, "title": c.title, "last_message_at": c.last_message_at.isoformat() if c.last_message_at else None, "created_at": c.created_at.isoformat() if c.created_at else None, } for c in convs ] }) @chat_bp.route("/conversations", methods=["POST"]) @jwt_required() def create_conversation(): data = request.get_json() or {} title = (data.get("title") or "新对话").strip() or "新对话" user_id = get_jwt_identity() conv = ChatEngineService.get_or_create_conversation(user_id, title=title) return jsonify({ "id": conv.id, "title": conv.title, "last_message_at": conv.last_message_at.isoformat() if conv.last_message_at else None, "created_at": conv.created_at.isoformat() if conv.created_at else None, }), 201 @chat_bp.route("/conversations//messages", methods=["GET"]) @jwt_required() def get_messages(conversation_id): before_id = request.args.get("before_id") limit = min(request.args.get("limit", 50, type=int), 100) user_id = get_jwt_identity() messages = ChatEngineService.get_messages(conversation_id, user_id, before_id=before_id, limit=limit) return jsonify({"items": [m.to_dict() for m in reversed(messages)]}) @chat_bp.route("/conversations//messages", methods=["POST"]) @jwt_required() def send_message(conversation_id): data = request.get_json() or {} content = (data.get("content") or "").strip() content_type = data.get("content_type") or "text" attachment_url = data.get("attachment_url") attachment_name = data.get("attachment_name") if not content and not attachment_url: return jsonify({"error": "content or attachment required"}), 400 user_id = get_jwt_identity() msg = ChatEngineService.send_message( conversation_id, user_id, content or "(附件)", content_type=content_type, attachment_url=attachment_url, attachment_name=attachment_name, ) if not msg: return jsonify({"error": "Conversation not found or access denied"}), 404 broadcast_new_message(msg) return jsonify(msg.to_dict()), 201 @chat_bp.route("/messages//recall", methods=["POST"]) @jwt_required() def recall_message(message_id): user_id = get_jwt_identity() ok = ChatEngineService.recall_message(message_id, user_id) if not ok: return jsonify({"error": "Message not found or recall not allowed"}), 400 return jsonify({"status": "recalled"})