Files
FastapiAdmin/backend/app/api/v1/module_ai/chat/controller.py
T
zhangtao f74b5f277e refactor: 重构查询参数处理逻辑,统一搜索参数处理
- 移除各模块查询schema中的自定义model_validator,统一通过search_to_dict处理搜索参数
- 为需要的字段添加json_schema_extra标记查询操作类型
- 重构base_crud的条件解析逻辑,支持直接处理普通字符串、数字类型参数
- 重构base_schema中的公共查询参数校验逻辑,简化时间范围和创建更新人参数处理
- 修复菜单查询的异步懒加载问题,添加多级预加载
- 调整日志打印配置,关闭uvicorn.access重复日志
- 修复前端路由跳转路径错误
- 调整弹窗宽度适配内容
- 修复测试环境限流器未注册问题
- 清理无用的导入和废弃函数
2026-07-16 01:19:03 +08:00

160 lines
7.0 KiB
Python

from typing import Annotated, Any
from fastapi import APIRouter, Body, Depends, Path, Query, Security, status
from fastapi.responses import JSONResponse
from redis.asyncio import Redis
from app.common.response import ResponseSchema, SuccessResponse
from app.core.base_schema import AuthSchema, PaginationQueryParam
from app.core.dependencies import AuthPermission, redis_getter
from app.core.router_class import OperationLogRoute
from .schema import (
AiChatRequestSchema,
AiChatResponseSchema,
AiModelConfigListResponse,
AiModelConfigSchema,
AiModelConfigUpdateSchema,
ChatSessionCreateSchema,
ChatSessionQueryParam,
ChatSessionUpdateSchema,
)
from .service import AiModelConfigService, ChatService
ChatRouter = APIRouter(route_class=OperationLogRoute, prefix="/chat", tags=["AI管理"])
@ChatRouter.get("/detail/{session_id}", summary="获取会话详情", response_model=ResponseSchema[dict[str, Any]])
async def get_session_detail_controller(
auth: Annotated[AuthSchema, Security(AuthPermission(["module_ai:chat:detail"]))],
session_id: Annotated[str, Path(description="会话ID")],
) -> JSONResponse:
service = ChatService(auth)
result = await service.get_session(session_id=session_id)
return SuccessResponse(data=result, msg="获取会话详情成功")
@ChatRouter.get("/list", summary="查询会话列表", response_model=ResponseSchema[dict])
async def get_session_list_controller(
auth: Annotated[AuthSchema, Security(AuthPermission(["module_ai:chat:query"]))],
page: Annotated[PaginationQueryParam, Depends()],
search: Annotated[ChatSessionQueryParam, Query()],
) -> JSONResponse:
service = ChatService(auth)
result_dict = await service.page(
page_no=page.page_no,
page_size=page.page_size,
search=search,
order_by=page.order_by,
)
return SuccessResponse(data=result_dict, msg="查询会话列表成功")
@ChatRouter.post("/create", status_code=status.HTTP_201_CREATED, summary="创建会话", response_model=ResponseSchema[dict[str, Any]])
async def create_session_controller(
auth: Annotated[AuthSchema, Security(AuthPermission(["module_ai:chat:create"]))],
data: Annotated[ChatSessionCreateSchema, Body(description="会话创建参数")],
) -> JSONResponse:
service = ChatService(auth)
result = await service.create(data=data)
return SuccessResponse(data=result, msg="创建会话成功")
@ChatRouter.put("/update/{session_id}", summary="更新会话", response_model=ResponseSchema[None])
async def update_session_controller(
auth: Annotated[AuthSchema, Security(AuthPermission(["module_ai:chat:update"]))],
session_id: Annotated[str, Path(description="会话ID")],
data: Annotated[ChatSessionUpdateSchema, Body(description="会话更新参数")],
) -> JSONResponse:
service = ChatService(auth)
await service.update(session_id=session_id, data=data)
return SuccessResponse(data=None, msg="更新会话成功")
@ChatRouter.delete("/delete", summary="删除会话", response_model=ResponseSchema[None])
async def delete_session_controller(
auth: Annotated[AuthSchema, Security(AuthPermission(["module_ai:chat:delete"]))],
session_ids: Annotated[list[str], Body(description="会话ID列表")],
) -> JSONResponse:
service = ChatService(auth)
await service.delete(session_ids=session_ids)
return SuccessResponse(data=None, msg="删除会话成功")
@ChatRouter.post("/ai-chat", summary="AI 对话(非流式)", response_model=ResponseSchema[AiChatResponseSchema])
async def ai_chat_controller(
auth: Annotated[AuthSchema, Security(AuthPermission(["module_ai:chat:query"]))],
data: Annotated[AiChatRequestSchema, Body(description="对话请求")],
) -> JSONResponse:
service = ChatService(auth)
result = await service.chat_non_stream(
message=data.message,
session_id=data.session_id,
)
return SuccessResponse(
data=AiChatResponseSchema(
response=result["response"],
session_id=result["session_id"],
function_calls=result.get("function_calls"),
action=result.get("action"),
),
msg="对话成功",
)
@ChatRouter.get("/model", summary="获取 AI 模型配置列表", response_model=ResponseSchema[AiModelConfigListResponse])
async def list_model_config_controller(
redis: Annotated[Redis, Depends(redis_getter)],
auth: Annotated[AuthSchema, Security(AuthPermission(["module_ai:chat:query"]))],
) -> JSONResponse:
service = AiModelConfigService(auth, redis)
result = await service.list()
return SuccessResponse(data=result, msg="获取模型配置列表成功")
@ChatRouter.post("/model", status_code=status.HTTP_201_CREATED, summary="新增一个 AI 模型配置", response_model=ResponseSchema[dict[str, Any]])
async def create_model_config_controller(
redis: Annotated[Redis, Depends(redis_getter)],
auth: Annotated[AuthSchema, Security(AuthPermission(["module_ai:chat:update"]))],
data: Annotated[AiModelConfigUpdateSchema, Body(description="模型配置参数")],
) -> JSONResponse:
service = AiModelConfigService(auth, redis)
payload = AiModelConfigSchema(**data.model_dump())
result = await service.create(payload)
return SuccessResponse(data=result, msg="模型配置已新增")
@ChatRouter.put("/model/{config_id}", summary="更新指定 ID 的 AI 模型配置", response_model=ResponseSchema[dict[str, Any]])
async def update_model_config_controller(
redis: Annotated[Redis, Depends(redis_getter)],
auth: Annotated[AuthSchema, Security(AuthPermission(["module_ai:chat:update"]))],
config_id: Annotated[str, Path(description="配置项 ID")],
data: Annotated[AiModelConfigUpdateSchema, Body(description="模型配置参数")],
) -> JSONResponse:
service = AiModelConfigService(auth, redis)
payload = AiModelConfigSchema(**data.model_dump())
result = await service.update(config_id, payload)
return SuccessResponse(data=result, msg="模型配置已更新")
@ChatRouter.delete("/model/{config_id}", summary="删除指定 ID 的 AI 模型配置", response_model=ResponseSchema[None])
async def delete_model_config_controller(
redis: Annotated[Redis, Depends(redis_getter)],
auth: Annotated[AuthSchema, Security(AuthPermission(["module_ai:chat:update"]))],
config_id: Annotated[str, Path(description="配置项 ID")],
) -> JSONResponse:
service = AiModelConfigService(auth, redis)
await service.delete(config_id)
return SuccessResponse(data=None, msg="模型配置已删除")
@ChatRouter.post("/model/{config_id}/activate", summary="切换激活的 AI 模型配置", response_model=ResponseSchema[None])
async def activate_model_config_controller(
redis: Annotated[Redis, Depends(redis_getter)],
auth: Annotated[AuthSchema, Security(AuthPermission(["module_ai:chat:update"]))],
config_id: Annotated[str, Path(description="配置项 ID;传 __default__ 使用系统默认")],
) -> JSONResponse:
service = AiModelConfigService(auth, redis)
await service.set_active(config_id)
return SuccessResponse(data=None, msg="已切换模型")