from __future__ import annotations from typing import Any import json from fastapi import Depends, File, Form, Query, UploadFile from fastapi.responses import JSONResponse, StreamingResponse from fastapi_common.fastapi_common_security.security import verify_access_token from fastapi_common.fastapi_common_web.controller import BaseController from fastapi_common.fastapi_common_web.domain.responses import Result from fastapi_modules.fastapi_leaudit.domian.Dto.ragChatDto import ( RagConversationRenameDTO, RagChatSendMessageDTO, RagMessageFeedbackDTO, RagStopMessageDTO, ) from fastapi_modules.fastapi_leaudit.domian.Dto.ragDatasetDto import ( RagDatasetBatchDocumentDeleteDTO, RagDatasetUpdateDTO, ) from fastapi_modules.fastapi_leaudit.domian.vo.ragChatVo import ( RagAppParametersVO, RagChatAppListVO, RagChatAppVO, RagConversationPageVO, RagConversationRenameVO, RagMessagePageVO, RagOperationResultVO, ) from fastapi_modules.fastapi_leaudit.domian.vo.ragDatasetVo import ( RagDatasetBatchDeleteResultVO, RagDatasetDetailVO, RagDatasetDocumentItemVO, RagDatasetDocumentPageVO, RagDatasetPageVO, RagDatasetRetrieveResponseVO, RagDatasetSegmentItemVO, RagDatasetSegmentPageVO, RagDatasetUploadDocumentVO, ) from fastapi_modules.fastapi_leaudit.services.impl.permissionServiceImpl import PermissionServiceImpl from fastapi_modules.fastapi_leaudit.services.impl.ragChatServiceImpl import RagChatServiceImpl from fastapi_modules.fastapi_leaudit.services.impl.ragDatasetServiceImpl import RagDatasetServiceImpl from fastapi_modules.fastapi_leaudit.services.permissionService import IPermissionService from fastapi_modules.fastapi_leaudit.services.ragChatService import IRagChatService from fastapi_modules.fastapi_leaudit.services.ragDatasetService import IRagDatasetService class RagChatController(BaseController): _PERMISSIONS = { "chat_use": "rag:chat:use", "conversation_read": "rag:conversation:read", "conversation_update": "rag:conversation:update", "conversation_delete": "rag:conversation:delete", "message_feedback": "rag:message:feedback", "app_read": "rag:app:read", "dataset_read": "rag:dataset:read", "dataset_manage": "rag:dataset:manage", "dataset_create": "rag:dataset:create", "dataset_update": "rag:dataset:update", "dataset_delete": "rag:dataset:delete", } @staticmethod def _tenant_context(payload: dict[str, Any]) -> dict[str, str | None]: return { "UserArea": payload.get("area"), "UserRole": payload.get("user_role"), "TenantCode": payload.get("tenant_code"), "TenantName": payload.get("tenant_name"), } def __init__(self): super().__init__(prefix="/v3/rag", tags=["RAG 聊天"]) self.RagChatService: IRagChatService = RagChatServiceImpl() self.RagDatasetService: IRagDatasetService = RagDatasetServiceImpl() self.PermissionService: IPermissionService = PermissionServiceImpl() @self.router.get("/apps", response_model=Result[RagChatAppListVO]) async def GetApps(payload: dict[str, Any] = Depends(verify_access_token)): if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["app_read"]]): return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有查看聊天应用权限", "data": None}) tenant_context = self._tenant_context(payload) data = await self.RagChatService.GetApps( CurrentUserId=int(payload["user_id"]), **tenant_context, ) return Result.success(data=data) @self.router.get("/apps/default", response_model=Result[RagChatAppVO | None]) async def GetDefaultApp(payload: dict[str, Any] = Depends(verify_access_token)): if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["app_read"]]): return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有查看默认聊天应用权限", "data": None}) tenant_context = self._tenant_context(payload) data = await self.RagChatService.GetDefaultApp( CurrentUserId=int(payload["user_id"]), **tenant_context, ) return Result.success(data=data) @self.router.get("/datasets/my", response_model=Result[RagDatasetPageVO]) async def GetMyDatasets(payload: dict[str, Any] = Depends(verify_access_token)): if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["dataset_read"]]): return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有查看知识库权限", "data": None}) tenant_context = self._tenant_context(payload) data = await self.RagDatasetService.GetMyDatasets( CurrentUserId=int(payload["user_id"]), **tenant_context, ) return Result.success(data=data) @self.router.get("/datasets/admin", response_model=Result[RagDatasetPageVO]) async def GetAdminDatasets( area: str | None = Query(None), tenant_code: str | None = Query(None, description="租户编码,支持逗号分隔"), onlyEnabled: bool | None = Query(None), page: int = Query(1, ge=1), pageSize: int = Query(20, ge=1, le=200), payload: dict[str, Any] = Depends(verify_access_token), ): if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["dataset_manage"]]): return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有管理知识库权限", "data": None}) tenant_context = self._tenant_context(payload) data = await self.RagDatasetService.GetAdminDatasets( CurrentUserId=int(payload["user_id"]), **tenant_context, Area=area, TenantFilterCode=tenant_code, OnlyEnabled=onlyEnabled, Page=page, PageSize=pageSize, ) return Result.success(data=data) @self.router.post("/datasets/admin", response_model=Result[RagDatasetDetailVO]) async def CreateAdminDataset(Body: dict[str, Any], payload: dict[str, Any] = Depends(verify_access_token)): if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["dataset_create"]]): return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有创建知识库权限", "data": None}) tenant_context = self._tenant_context(payload) data = await self.RagDatasetService.CreateAdminDataset( CurrentUserId=int(payload["user_id"]), **tenant_context, Body=Body, ) return Result.success(data=data) @self.router.put("/datasets/admin/{DatasetId}", response_model=Result[RagDatasetDetailVO | None]) async def UpdateAdminDataset(DatasetId: int, Body: dict[str, Any], payload: dict[str, Any] = Depends(verify_access_token)): if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["dataset_update"]]): return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有更新知识库权限", "data": None}) tenant_context = self._tenant_context(payload) data = await self.RagDatasetService.UpdateAdminDataset( CurrentUserId=int(payload["user_id"]), **tenant_context, DatasetId=DatasetId, Body=Body, ) return Result.success(data=data) @self.router.delete("/datasets/admin/{DatasetId}", response_model=Result[RagOperationResultVO]) async def DeleteAdminDataset(DatasetId: int, payload: dict[str, Any] = Depends(verify_access_token)): if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["dataset_delete"]]): return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有删除知识库权限", "data": None}) tenant_context = self._tenant_context(payload) data = await self.RagDatasetService.DeleteAdminDataset( CurrentUserId=int(payload["user_id"]), **tenant_context, DatasetId=DatasetId, ) return Result.success(data=data) @self.router.get("/datasets/{DatasetId}", response_model=Result[RagDatasetDetailVO | None]) async def GetDatasetDetail(DatasetId: int, payload: dict[str, Any] = Depends(verify_access_token)): if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["dataset_read"]]): return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有查看知识库权限", "data": None}) tenant_context = self._tenant_context(payload) data = await self.RagDatasetService.GetDatasetDetail( CurrentUserId=int(payload["user_id"]), **tenant_context, DatasetId=DatasetId, ) return Result.success(data=data) @self.router.patch("/datasets/{DatasetId}", response_model=Result[RagDatasetDetailVO | None]) async def UpdateDataset(DatasetId: int, Body: RagDatasetUpdateDTO, payload: dict[str, Any] = Depends(verify_access_token)): if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["dataset_update"]]): return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有修改知识库权限", "data": None}) tenant_context = self._tenant_context(payload) data = await self.RagDatasetService.UpdateDataset( CurrentUserId=int(payload["user_id"]), **tenant_context, DatasetId=DatasetId, Body=Body, ) return Result.success(data=data) @self.router.get("/datasets/{DatasetId}/documents", response_model=Result[RagDatasetDocumentPageVO]) async def GetDatasetDocuments( DatasetId: int, page: int = Query(1, ge=1), limit: int = Query(20, ge=1, le=100), keyword: str | None = Query(None), payload: dict[str, Any] = Depends(verify_access_token), ): if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["dataset_read"]]): return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有查看知识库文档权限", "data": None}) tenant_context = self._tenant_context(payload) data = await self.RagDatasetService.GetDatasetDocuments( CurrentUserId=int(payload["user_id"]), **tenant_context, DatasetId=DatasetId, Page=page, Limit=limit, Keyword=keyword, ) return Result.success(data=data) @self.router.get("/datasets/{DatasetId}/documents/{DocumentId}", response_model=Result[RagDatasetDocumentItemVO | None]) async def GetDatasetDocumentDetail( DatasetId: int, DocumentId: int, payload: dict[str, Any] = Depends(verify_access_token), ): if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["dataset_read"]]): return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有查看知识库文档权限", "data": None}) tenant_context = self._tenant_context(payload) data = await self.RagDatasetService.GetDatasetDocumentDetail( CurrentUserId=int(payload["user_id"]), **tenant_context, DatasetId=DatasetId, DocumentId=DocumentId, ) return Result.success(data=data) @self.router.post("/datasets/{DatasetId}/documents", response_model=Result[RagDatasetUploadDocumentVO]) async def UploadDatasetDocument( DatasetId: int, file: UploadFile = File(...), data: str | None = Form(None), payload: dict[str, Any] = Depends(verify_access_token), ): if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["dataset_update"]]): return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有上传知识库文档权限", "data": None}) process_config = json.loads(data) if data else None file_bytes = await file.read() tenant_context = self._tenant_context(payload) result = await self.RagDatasetService.UploadDatasetDocument( CurrentUserId=int(payload["user_id"]), **tenant_context, DatasetId=DatasetId, FileName=file.filename or "document", ContentType=file.content_type, Content=file_bytes, ProcessConfig=process_config, ) return Result.success(data=result) @self.router.post("/datasets/{DatasetId}/documents/{DocumentId}/update-by-file", response_model=Result[RagDatasetUploadDocumentVO]) async def UpdateDatasetDocumentByFile( DatasetId: int, DocumentId: int, file: UploadFile = File(...), data: str | None = Form(None), payload: dict[str, Any] = Depends(verify_access_token), ): if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["dataset_update"]]): return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有重处理知识库文档权限", "data": None}) process_config = json.loads(data) if data else None file_bytes = await file.read() tenant_context = self._tenant_context(payload) result = await self.RagDatasetService.UpdateDatasetDocumentByFile( CurrentUserId=int(payload["user_id"]), **tenant_context, DatasetId=DatasetId, DocumentId=DocumentId, FileName=file.filename or "document", ContentType=file.content_type, Content=file_bytes, ProcessConfig=process_config, ) return Result.success(data=result) @self.router.get("/datasets/{DatasetId}/documents/{DocumentId}/indexing-status") async def GetDatasetDocumentIndexingStatus( DatasetId: int, DocumentId: int, payload: dict[str, Any] = Depends(verify_access_token), ): if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["dataset_read"]]): return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有查看知识库处理进度权限", "data": None}) tenant_context = self._tenant_context(payload) result = await self.RagDatasetService.GetDatasetDocumentIndexingStatus( CurrentUserId=int(payload["user_id"]), **tenant_context, DatasetId=DatasetId, DocumentId=DocumentId, ) return Result.success(data=result["data"]) @self.router.patch("/datasets/{DatasetId}/documents/status/{Action}", response_model=Result[RagOperationResultVO]) async def BatchUpdateDatasetDocumentStatus( DatasetId: int, Action: str, Body: dict[str, Any], payload: dict[str, Any] = Depends(verify_access_token), ): if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["dataset_update"]]): return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有修改知识库文档状态权限", "data": None}) enabled = Action == "enable" if Action not in {"enable", "disable"}: return JSONResponse(status_code=400, content={"code": 400, "msg": "当前仅支持启用和禁用", "data": None}) document_ids = Body.get("document_ids") or [] tenant_context = self._tenant_context(payload) result = await self.RagDatasetService.BatchUpdateDatasetDocumentStatus( CurrentUserId=int(payload["user_id"]), **tenant_context, DatasetId=DatasetId, DocumentIds=[int(item) for item in document_ids], Enabled=enabled, ) return Result.success(data=result) @self.router.get("/datasets/{DatasetId}/documents/{DocumentId}/segments", response_model=Result[RagDatasetSegmentPageVO]) async def GetDatasetDocumentSegments( DatasetId: int, DocumentId: int, page: int = Query(1, ge=1), limit: int = Query(20, ge=1, le=200), keyword: str | None = Query(None), payload: dict[str, Any] = Depends(verify_access_token), ): if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["dataset_read"]]): return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有查看知识库分段权限", "data": None}) tenant_context = self._tenant_context(payload) result = await self.RagDatasetService.GetDatasetDocumentSegments( CurrentUserId=int(payload["user_id"]), **tenant_context, DatasetId=DatasetId, DocumentId=DocumentId, Page=page, Limit=limit, Keyword=keyword, ) return Result.success(data=result) @self.router.delete("/datasets/{DatasetId}/documents/{DocumentId}", response_model=Result[RagOperationResultVO]) async def DeleteDatasetDocument( DatasetId: int, DocumentId: int, payload: dict[str, Any] = Depends(verify_access_token), ): if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["dataset_delete"]]): return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有删除知识库文档权限", "data": None}) tenant_context = self._tenant_context(payload) result = await self.RagDatasetService.DeleteDatasetDocument( CurrentUserId=int(payload["user_id"]), **tenant_context, DatasetId=DatasetId, DocumentId=DocumentId, ) return Result.success(data=result) @self.router.post("/datasets/{DatasetId}/documents/batch-delete", response_model=Result[RagDatasetBatchDeleteResultVO]) async def BatchDeleteDatasetDocuments( DatasetId: int, Body: RagDatasetBatchDocumentDeleteDTO, payload: dict[str, Any] = Depends(verify_access_token), ): if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["dataset_delete"]]): return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有删除知识库文档权限", "data": None}) tenant_context = self._tenant_context(payload) result = await self.RagDatasetService.BatchDeleteDatasetDocuments( CurrentUserId=int(payload["user_id"]), **tenant_context, DatasetId=DatasetId, DocumentIds=Body.document_ids, ) return Result.success(data=result) @self.router.post("/datasets/{DatasetId}/retrieve", response_model=Result[RagDatasetRetrieveResponseVO]) async def RetrieveDataset( DatasetId: int, Body: dict[str, Any], payload: dict[str, Any] = Depends(verify_access_token), ): if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["dataset_read"]]): return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有检索知识库权限", "data": None}) tenant_context = self._tenant_context(payload) result = await self.RagDatasetService.RetrieveDataset( CurrentUserId=int(payload["user_id"]), **tenant_context, DatasetId=DatasetId, Query=str(Body.get("query") or ""), RetrievalModel=Body.get("retrieval_model") if isinstance(Body.get("retrieval_model"), dict) else None, ) return Result.success(data=result) @self.router.get("/datasets/{DatasetId}/documents/{DocumentId}/segments/{SegmentId}", response_model=Result[RagDatasetSegmentItemVO | None]) async def GetDatasetDocumentSegmentDetail( DatasetId: int, DocumentId: int, SegmentId: str, payload: dict[str, Any] = Depends(verify_access_token), ): if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["dataset_read"]]): return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有查看知识库分段权限", "data": None}) tenant_context = self._tenant_context(payload) result = await self.RagDatasetService.GetDatasetDocumentSegmentDetail( CurrentUserId=int(payload["user_id"]), **tenant_context, DatasetId=DatasetId, DocumentId=DocumentId, SegmentId=SegmentId, ) return Result.success(data=result) @self.router.post("/datasets/{DatasetId}/documents/{DocumentId}/segments/{SegmentId}", response_model=Result[RagDatasetSegmentItemVO | None]) async def UpdateDatasetDocumentSegment( DatasetId: int, DocumentId: int, SegmentId: str, Body: dict[str, Any], payload: dict[str, Any] = Depends(verify_access_token), ): if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["dataset_update"]]): return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有修改知识库分段权限", "data": None}) tenant_context = self._tenant_context(payload) result = await self.RagDatasetService.UpdateDatasetDocumentSegment( CurrentUserId=int(payload["user_id"]), **tenant_context, DatasetId=DatasetId, DocumentId=DocumentId, SegmentId=SegmentId, Body=Body, ) return Result.success(data=result) @self.router.delete("/datasets/{DatasetId}/documents/{DocumentId}/segments/{SegmentId}", response_model=Result[RagOperationResultVO]) async def DeleteDatasetDocumentSegment( DatasetId: int, DocumentId: int, SegmentId: str, payload: dict[str, Any] = Depends(verify_access_token), ): if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["dataset_delete"]]): return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有删除知识库分段权限", "data": None}) tenant_context = self._tenant_context(payload) result = await self.RagDatasetService.DeleteDatasetDocumentSegment( CurrentUserId=int(payload["user_id"]), **tenant_context, DatasetId=DatasetId, DocumentId=DocumentId, SegmentId=SegmentId, ) return Result.success(data=result) @self.router.get("/chat/parameters", response_model=Result[RagAppParametersVO]) async def GetAppParameters( appId: int | None = Query(None, description="聊天应用ID"), payload: dict[str, Any] = Depends(verify_access_token), ): if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["chat_use"], self._PERMISSIONS["app_read"]]): return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有查看聊天配置权限", "data": None}) tenant_context = self._tenant_context(payload) data = await self.RagChatService.GetAppParameters( CurrentUserId=int(payload["user_id"]), **tenant_context, AppId=appId, ) return Result.success(data=data) @self.router.post("/chat/messages") async def SendMessage(Body: RagChatSendMessageDTO, payload: dict[str, Any] = Depends(verify_access_token)): if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["chat_use"]]): return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有使用 RAG 对话权限", "data": None}) tenant_context = self._tenant_context(payload) stream = self.RagChatService.SendMessage( CurrentUserId=int(payload["user_id"]), UserName=payload.get("username") or str(payload.get("user_id")), **tenant_context, Query=Body.query, ConversationId=Body.conversationId, AppId=Body.appId, ) return StreamingResponse( stream, media_type="text/event-stream", headers={"Cache-Control": "no-cache", "X-Accel-Buffering": "no", "Connection": "keep-alive"}, ) @self.router.post("/chat/messages/{MessageId}/stop", response_model=Result[RagOperationResultVO]) async def StopMessage( MessageId: str, Body: RagStopMessageDTO | None = None, payload: dict[str, Any] = Depends(verify_access_token), ): if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["chat_use"]]): return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有停止 RAG 对话权限", "data": None}) tenant_context = self._tenant_context(payload) data = await self.RagChatService.StopMessage( CurrentUserId=int(payload["user_id"]), **tenant_context, MessageId=MessageId, Body=Body, ) return Result.success(data=data) @self.router.get("/chat/conversations", response_model=Result[RagConversationPageVO]) async def GetConversations( appId: int | None = Query(None, description="聊天应用ID"), page: int = Query(1, ge=1), pageSize: int = Query(20, ge=1, le=100), payload: dict[str, Any] = Depends(verify_access_token), ): if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["conversation_read"]]): return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有查看聊天会话权限", "data": None}) tenant_context = self._tenant_context(payload) data = await self.RagChatService.GetConversations( CurrentUserId=int(payload["user_id"]), **tenant_context, AppId=appId, Page=page, PageSize=pageSize, ) return Result.success(data=data) @self.router.get("/chat/conversations/{ConversationId}/messages", response_model=Result[RagMessagePageVO]) async def GetConversationMessages( ConversationId: str, page: int = Query(1, ge=1), pageSize: int = Query(20, ge=1, le=100), payload: dict[str, Any] = Depends(verify_access_token), ): if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["conversation_read"]]): return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有查看聊天消息权限", "data": None}) tenant_context = self._tenant_context(payload) data = await self.RagChatService.GetConversationMessages( CurrentUserId=int(payload["user_id"]), **tenant_context, ConversationId=ConversationId, Page=page, PageSize=pageSize, ) return Result.success(data=data) @self.router.patch("/chat/conversations/{ConversationId}", response_model=Result[RagConversationRenameVO]) async def RenameConversation( ConversationId: str, Body: RagConversationRenameDTO, payload: dict[str, Any] = Depends(verify_access_token), ): if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["conversation_update"]]): return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有修改聊天会话权限", "data": None}) tenant_context = self._tenant_context(payload) data = await self.RagChatService.RenameConversation( CurrentUserId=int(payload["user_id"]), **tenant_context, ConversationId=ConversationId, Body=Body, ) return Result.success(data=data) @self.router.delete("/chat/conversations/{ConversationId}", response_model=Result[RagOperationResultVO]) async def DeleteConversation(ConversationId: str, payload: dict[str, Any] = Depends(verify_access_token)): if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["conversation_delete"]]): return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有删除聊天会话权限", "data": None}) tenant_context = self._tenant_context(payload) data = await self.RagChatService.DeleteConversation( CurrentUserId=int(payload["user_id"]), **tenant_context, ConversationId=ConversationId, ) return Result.success(data=data) @self.router.post("/chat/messages/{MessageId}/feedback", response_model=Result[RagOperationResultVO]) async def UpdateFeedback( MessageId: str, Body: RagMessageFeedbackDTO, payload: dict[str, Any] = Depends(verify_access_token), ): if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["message_feedback"]]): return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有反馈聊天消息权限", "data": None}) tenant_context = self._tenant_context(payload) data = await self.RagChatService.UpdateFeedback( CurrentUserId=int(payload["user_id"]), **tenant_context, MessageId=MessageId, Body=Body, ) return Result.success(data=data) async def _check_permission(self, user_id: int, permission_keys: list[str]) -> bool: return await self.PermissionService.HasAnyPermission(UserId=user_id, PermissionKeys=permission_keys)