android app
This commit is contained in:
87
saars/backend/app/api/chat.py
Normal file
87
saars/backend/app/api/chat.py
Normal file
@@ -0,0 +1,87 @@
|
||||
"""
|
||||
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/<conversation_id>/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/<conversation_id>/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/<message_id>/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"})
|
||||
Reference in New Issue
Block a user