98 lines
3.3 KiB
Python
98 lines
3.3 KiB
Python
"""会话创建与历史查询接口"""
|
|
|
|
from typing import Annotated
|
|
|
|
from fastapi import APIRouter, Depends, Query, Request
|
|
|
|
from app.common.response import ApiResponse, success_response
|
|
from app.core.auth import get_current_user
|
|
from app.core.exceptions import BizException
|
|
from app.schemas.conversation import (
|
|
ConversationCreate,
|
|
ConversationCreated,
|
|
ConversationDetail,
|
|
ConversationList,
|
|
ConversationRename,
|
|
)
|
|
from app.schemas.user import CurrentUser
|
|
|
|
MAX_OFFSET = 10000
|
|
|
|
router = APIRouter(prefix="/conversations", tags=["Conversation"])
|
|
|
|
|
|
@router.post("")
|
|
async def create_conversation(
|
|
request: Request,
|
|
user: CurrentUser = Depends(get_current_user),
|
|
body: ConversationCreate | None = None,
|
|
) -> ApiResponse[ConversationCreated]:
|
|
store = request.app.state.conversation_store
|
|
screen_id = body.screen_id if body else None
|
|
# 会话挂到大屏上,大屏必须是自己的;没配 MongoDB(没有大屏服务)时无从校验,直接放过
|
|
screens = getattr(request.app.state, "screen_service", None)
|
|
if screen_id is not None and screens is not None:
|
|
if not await screens.exists(screen_id, user.id):
|
|
raise BizException(404, "大屏不存在或已删除")
|
|
return success_response(
|
|
ConversationCreated(conversation_id=await store.create(user.id, screen_id))
|
|
)
|
|
|
|
|
|
@router.get("")
|
|
async def list_conversations(
|
|
request: Request,
|
|
user: Annotated[CurrentUser, Depends(get_current_user)],
|
|
limit: Annotated[int, Query(ge=1, le=100)] = 20,
|
|
offset: Annotated[int, Query(ge=0, le=MAX_OFFSET)] = 0,
|
|
screen_id: Annotated[str | None, Query(min_length=1)] = None,
|
|
) -> ApiResponse[ConversationList]:
|
|
store = request.app.state.conversation_store
|
|
return success_response(
|
|
ConversationList(
|
|
conversations=await store.list_by_user(user.id, limit, offset, screen_id),
|
|
total=await store.count_by_user(user.id, screen_id),
|
|
)
|
|
)
|
|
|
|
|
|
@router.get("/{conversation_id}")
|
|
async def get_conversation(
|
|
conversation_id: str,
|
|
request: Request,
|
|
user: CurrentUser = Depends(get_current_user),
|
|
) -> ApiResponse[ConversationDetail]:
|
|
store = request.app.state.conversation_store
|
|
# 他人的会话与不存在同样返回 404
|
|
if not await store.exists(conversation_id, user.id):
|
|
raise BizException(404, "会话不存在或已过期")
|
|
turns = await store.load_turns(conversation_id, None)
|
|
return success_response(
|
|
ConversationDetail(conversation_id=conversation_id, turns=turns)
|
|
)
|
|
|
|
|
|
@router.patch("/{conversation_id}")
|
|
async def rename_conversation(
|
|
conversation_id: str,
|
|
body: ConversationRename,
|
|
request: Request,
|
|
user: CurrentUser = Depends(get_current_user),
|
|
) -> ApiResponse[dict]:
|
|
store = request.app.state.conversation_store
|
|
if not await store.rename(conversation_id, user.id, body.title):
|
|
raise BizException(404, "会话不存在或已过期")
|
|
return success_response()
|
|
|
|
|
|
@router.delete("/{conversation_id}")
|
|
async def delete_conversation(
|
|
conversation_id: str,
|
|
request: Request,
|
|
user: CurrentUser = Depends(get_current_user),
|
|
) -> ApiResponse[dict]:
|
|
store = request.app.state.conversation_store
|
|
if not await store.delete(conversation_id, user.id):
|
|
raise BizException(404, "会话不存在或已过期")
|
|
return success_response()
|