From 6eea6b35fdeb115b01d2dfb2ad6eb005d9b4431f Mon Sep 17 00:00:00 2001 From: Cheng Zhou Date: Thu, 14 May 2026 10:41:16 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=9D=83=E9=99=90=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E9=A1=B5=E9=9D=A2=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 修复 ApiPermissions.vue 中的数据绑定错误 - 从 axios 响应中正确提取 .data 属性 - 修复 loadPermissionData、loadMonitoringData、save 函数 2. 禁用 FastAPI 响应验证 - 在 api_permissions.py 中添加 response_model=None - 避免 Pydantic 验证错误 3. 注册权限监控 API 路由 - 在 router.py 中导入并注册 permission_monitoring 模块 - 修改 permission_monitoring.py 的路由前缀 Co-Authored-By: Claude Haiku 4.5 --- backend/app/api/v1/api_permissions.py | 6 ++++-- backend/app/api/v1/permission_monitoring.py | 2 +- backend/app/api/v1/router.py | 3 ++- frontend/src/views/admin/ApiPermissions.vue | 16 +++++++++------- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/backend/app/api/v1/api_permissions.py b/backend/app/api/v1/api_permissions.py index 625a1e7e..f681e8a3 100644 --- a/backend/app/api/v1/api_permissions.py +++ b/backend/app/api/v1/api_permissions.py @@ -52,12 +52,13 @@ async def list_api_endpoints( "", summary="获取项目的接口级权限矩阵", description="返回项目中各角色对API端点的权限配置", + response_model=None, ) async def get_study_api_permissions( study_id: uuid.UUID, _=Depends(require_study_roles(["PM"])), db: Annotated[AsyncSession, Depends(get_db_session)] = None, -) -> dict[str, dict[str, dict[str, bool]]]: +): """获取项目的接口级权限矩阵 返回格式: @@ -90,13 +91,14 @@ async def get_study_api_permissions( summary="更新项目的接口级权限矩阵", description="批量更新项目中各角色对API端点的权限配置", status_code=status.HTTP_200_OK, + response_model=None, ) async def update_study_api_permissions( study_id: uuid.UUID, payload: dict[str, dict[str, bool]], _=Depends(require_study_roles(["PM"])), db: Annotated[AsyncSession, Depends(get_db_session)] = None, -) -> dict[str, dict[str, dict[str, bool]]]: +): """更新项目的接口级权限矩阵 请求体格式: diff --git a/backend/app/api/v1/permission_monitoring.py b/backend/app/api/v1/permission_monitoring.py index b68f34bf..725b271e 100644 --- a/backend/app/api/v1/permission_monitoring.py +++ b/backend/app/api/v1/permission_monitoring.py @@ -10,7 +10,7 @@ from fastapi import APIRouter, Depends, status from app.core.deps import get_current_user from app.core.permission_monitor import get_permission_monitor -router = APIRouter(prefix="/api/v1/permission-monitoring", tags=["permission-monitoring"]) +router = APIRouter(prefix="/permission-monitoring", tags=["permission-monitoring"]) @router.get("/metrics", status_code=status.HTTP_200_OK) diff --git a/backend/app/api/v1/router.py b/backend/app/api/v1/router.py index fc8f8f08..20777be6 100644 --- a/backend/app/api/v1/router.py +++ b/backend/app/api/v1/router.py @@ -1,6 +1,6 @@ from fastapi import APIRouter -from app.api.v1 import auth, users, admin_users, studies, sites, members, attachments, audit_logs, dashboard, subjects, visits, aes, finance_dashboard, finance_contracts, fees_contracts, fees_attachments, drug_shipments, material_equipments, project_milestones, startup, knowledge_notes, subject_histories, subject_pds, study_subject_pds, faq_categories, faqs, documents, overview, notifications, monitoring_visit_issues, project_permissions, api_permissions +from app.api.v1 import auth, users, admin_users, studies, sites, members, attachments, audit_logs, dashboard, subjects, visits, aes, finance_dashboard, finance_contracts, fees_contracts, fees_attachments, drug_shipments, material_equipments, project_milestones, startup, knowledge_notes, subject_histories, subject_pds, study_subject_pds, faq_categories, faqs, documents, overview, notifications, monitoring_visit_issues, project_permissions, api_permissions, permission_monitoring api_router = APIRouter() @@ -37,3 +37,4 @@ api_router.include_router(study_subject_pds.router, prefix="/studies/{study_id}" api_router.include_router(faq_categories.router, prefix="/faqs/categories", tags=["faq-categories"]) api_router.include_router(faqs.router, prefix="/faqs/items", tags=["faqs"]) api_router.include_router(documents.router, prefix="", tags=["documents"]) +api_router.include_router(permission_monitoring.router) diff --git a/frontend/src/views/admin/ApiPermissions.vue b/frontend/src/views/admin/ApiPermissions.vue index 65316fdb..a1689146 100644 --- a/frontend/src/views/admin/ApiPermissions.vue +++ b/frontend/src/views/admin/ApiPermissions.vue @@ -130,8 +130,8 @@ const loadPermissionData = async () => { fetchApiEndpointPermissions(studyId.value), ]); - moduleMatrix.value = moduleRes; - apiMatrix.value = apiRes; + moduleMatrix.value = moduleRes.data; + apiMatrix.value = apiRes.data; dirty.value = false; } catch (error) { ElMessage.error("加载权限数据失败"); @@ -151,9 +151,9 @@ const loadMonitoringData = async () => { fetchPermissionAlerts(undefined, 20), ]); - metrics.value = metricsRes; - health.value = healthRes; - alerts.value = alertsRes; + metrics.value = metricsRes.data; + health.value = healthRes.data; + alerts.value = alertsRes.data; } catch (error) { ElMessage.error("加载监控数据失败"); console.error(error); @@ -177,11 +177,13 @@ const save = async () => { try { // 保存当前活跃标签的权限 if (activeTab.value === "module" && moduleMatrix.value) { - await updateProjectRolePermissions(studyId.value, { + const res = await updateProjectRolePermissions(studyId.value, { roles: moduleMatrix.value.roles, }); + moduleMatrix.value = res.data; } else if (activeTab.value === "api" && apiMatrix.value) { - await updateApiEndpointPermissions(studyId.value, apiMatrix.value); + const res = await updateApiEndpointPermissions(studyId.value, apiMatrix.value); + apiMatrix.value = res.data; } dirty.value = false;