From 387d035b08b48c7909bbd94b5a298e0389d5ab5d Mon Sep 17 00:00:00 2001 From: Cheng Zhou Date: Thu, 14 May 2026 09:19:07 +0800 Subject: [PATCH] =?UTF-8?q?=E5=89=8D=E7=AB=AF=E6=9D=83=E9=99=90=E7=AE=A1?= =?UTF-8?q?=E7=90=86=EF=BC=9A=E5=AE=9E=E7=8E=B0=E6=8E=A5=E5=8F=A3=E7=BA=A7?= =?UTF-8?q?=E6=9D=83=E9=99=90=E7=AE=A1=E7=90=86UI=E5=92=8C=E7=9B=91?= =?UTF-8?q?=E6=8E=A7=E4=BB=AA=E8=A1=A8=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增功能: - 新增 ApiPermissions.vue 主页面,支持模块级/接口级权限切换 - 新增 ProjectPermissionsModule.vue 组件,展示模块级权限矩阵 - 新增 ApiEndpointPermissions.vue 组件,展示接口级权限矩阵 - 新增 PermissionMonitoring.vue 组件,展示权限系统监控仪表板 - 更新 projectPermissions.ts API 客户端,支持接口级权限和监控API - 新增权限相关的 TypeScript 类型定义 - 更新路由配置,添加接口级权限管理路由 - 更新国际化文本,添加权限管理相关的中文文本 API 客户端新增函数: - fetchApiEndpointPermissions: 获取接口级权限矩阵 - updateApiEndpointPermissions: 更新接口级权限矩阵 - fetchPermissionMetrics: 获取权限检查指标 - fetchCacheStats: 获取缓存统计 - fetchPermissionAlerts: 获取告警列表 - fetchPermissionHealth: 获取系统健康状态 - resetPermissionMetrics: 重置指标 - clearPermissionAlerts: 清除告警 Co-Authored-By: Claude Haiku 4.5 --- frontend/src/api/projectPermissions.ts | 43 ++- .../src/components/ApiEndpointPermissions.vue | 222 +++++++++++ .../src/components/PermissionMonitoring.vue | 351 ++++++++++++++++++ .../components/ProjectPermissionsModule.vue | 95 +++++ frontend/src/locales/zh-CN.ts | 37 ++ frontend/src/router/index.ts | 7 + frontend/src/types/api.ts | 75 ++++ frontend/src/views/admin/ApiPermissions.vue | 279 ++++++++++++++ 8 files changed, 1107 insertions(+), 2 deletions(-) create mode 100644 frontend/src/components/ApiEndpointPermissions.vue create mode 100644 frontend/src/components/PermissionMonitoring.vue create mode 100644 frontend/src/components/ProjectPermissionsModule.vue create mode 100644 frontend/src/views/admin/ApiPermissions.vue diff --git a/frontend/src/api/projectPermissions.ts b/frontend/src/api/projectPermissions.ts index 4d887b4a..c663c680 100644 --- a/frontend/src/api/projectPermissions.ts +++ b/frontend/src/api/projectPermissions.ts @@ -1,8 +1,47 @@ -import { apiGet, apiPut } from "./axios"; -import type { ProjectRolePermissionsResponse, ProjectRolePermissionsUpdate } from "../types/api"; +import { apiGet, apiPut, apiPost } from "./axios"; +import type { + ProjectRolePermissionsResponse, + ProjectRolePermissionsUpdate, + ApiEndpointPermissionsResponse, + ApiEndpointPermissionsUpdate, + PermissionMetricsResponse, + CacheStatsResponse, + AlertsResponse, + HealthResponse, +} from "../types/api"; +// 模块级权限(现有) export const fetchProjectRolePermissions = (studyId: string) => apiGet(`/api/v1/studies/${studyId}/permissions/`); export const updateProjectRolePermissions = (studyId: string, payload: ProjectRolePermissionsUpdate) => apiPut(`/api/v1/studies/${studyId}/permissions/`, payload); + +// 接口级权限(新增) +export const fetchApiEndpointPermissions = (studyId: string) => + apiGet(`/api/v1/studies/${studyId}/api-permissions`); + +export const updateApiEndpointPermissions = (studyId: string, payload: ApiEndpointPermissionsUpdate) => + apiPut(`/api/v1/studies/${studyId}/api-permissions`, payload); + +// 权限系统监控API(新增) +export const fetchPermissionMetrics = () => + apiGet(`/api/v1/permission-monitoring/metrics`); + +export const fetchCacheStats = () => + apiGet(`/api/v1/permission-monitoring/cache-stats`); + +export const fetchPermissionAlerts = (level?: string, limit?: number) => + apiGet(`/api/v1/permission-monitoring/alerts`, { + params: { level, limit }, + }); + +export const fetchPermissionHealth = () => + apiGet(`/api/v1/permission-monitoring/health`); + +export const resetPermissionMetrics = () => + apiPost(`/api/v1/permission-monitoring/reset-metrics`); + +export const clearPermissionAlerts = () => + apiPost(`/api/v1/permission-monitoring/clear-alerts`); + diff --git a/frontend/src/components/ApiEndpointPermissions.vue b/frontend/src/components/ApiEndpointPermissions.vue new file mode 100644 index 00000000..d7ac2c18 --- /dev/null +++ b/frontend/src/components/ApiEndpointPermissions.vue @@ -0,0 +1,222 @@ + + + + + diff --git a/frontend/src/components/PermissionMonitoring.vue b/frontend/src/components/PermissionMonitoring.vue new file mode 100644 index 00000000..6bd71e24 --- /dev/null +++ b/frontend/src/components/PermissionMonitoring.vue @@ -0,0 +1,351 @@ + + + + + diff --git a/frontend/src/components/ProjectPermissionsModule.vue b/frontend/src/components/ProjectPermissionsModule.vue new file mode 100644 index 00000000..44503020 --- /dev/null +++ b/frontend/src/components/ProjectPermissionsModule.vue @@ -0,0 +1,95 @@ + + + + + diff --git a/frontend/src/locales/zh-CN.ts b/frontend/src/locales/zh-CN.ts index 14e9901b..e579fae4 100644 --- a/frontend/src/locales/zh-CN.ts +++ b/frontend/src/locales/zh-CN.ts @@ -1150,5 +1150,42 @@ export const TEXT = { SITE: "中心", DERIVED: "派生", }, + permissionManagement: { + title: "权限管理", + moduleLevel: "模块级权限", + apiLevel: "接口级权限", + monitoring: "权限监控", + refreshMetrics: "刷新指标", + save: "保存", + search: "搜索端点", + filterModule: "筛选模块", + filterMethod: "筛选方法", + endpoint: "端点", + module: "模块", + method: "方法", + role: "角色", + allowed: "允许", + denied: "拒绝", + healthStatus: "系统健康状态", + healthScore: "健康分数", + healthy: "健康", + degraded: "降级", + unhealthy: "不健康", + issues: "发现的问题", + totalChecks: "总检查次数", + avgResponseTime: "平均响应时间", + allowRate: "允许率", + errorRate: "错误率", + cacheEfficiency: "缓存效率", + cacheHitRate: "缓存命中率", + cacheItems: "缓存项目数", + cacheInvalidations: "缓存失效次数", + recentAlerts: "最近告警", + time: "时间", + level: "级别", + type: "类型", + message: "消息", + noAlerts: "暂无告警", + }, }, } as const; diff --git a/frontend/src/router/index.ts b/frontend/src/router/index.ts index 8a8ff458..f13a172a 100644 --- a/frontend/src/router/index.ts +++ b/frontend/src/router/index.ts @@ -20,6 +20,7 @@ import ProjectMembers from "../views/admin/ProjectMembers.vue"; import AdminSites from "../views/admin/Sites.vue"; import ProjectDetail from "../views/admin/ProjectDetail.vue"; import ProjectPermissions from "../views/admin/ProjectPermissions.vue"; +import ApiPermissions from "../views/admin/ApiPermissions.vue"; import ProfileSettings from "../views/ProfileSettings.vue"; import ProjectOverview from "../views/ia/ProjectOverview.vue"; import ProjectMilestones from "../views/ia/ProjectMilestones.vue"; @@ -447,6 +448,12 @@ const routes: RouteRecordRaw[] = [ component: ProjectPermissions, meta: { title: "权限管理", adminProjectPermission: { module: "project_members", action: "write" } }, }, + { + path: "projects/:id/api-permissions", + name: "AdminApiPermissions", + component: ApiPermissions, + meta: { title: "接口级权限管理", adminProjectPermission: { module: "project_members", action: "write" } }, + }, { path: "projects/:projectId/sites", name: "AdminSites", diff --git a/frontend/src/types/api.ts b/frontend/src/types/api.ts index c2fe1e6b..941340e6 100644 --- a/frontend/src/types/api.ts +++ b/frontend/src/types/api.ts @@ -152,3 +152,78 @@ export interface ProjectRolePermissionsResponse { export interface ProjectRolePermissionsUpdate { roles: ProjectPermissionMatrix; } + +// 接口级权限 +export interface ApiEndpointPermissionsResponse { + [role: string]: { + [endpoint_key: string]: { + allowed: boolean; + }; + }; +} + +export interface ApiEndpointPermissionsUpdate { + [role: string]: { + [endpoint_key: string]: boolean; + }; +} + +// 监控指标 +export interface PermissionCheckMetrics { + total_checks: number; + allowed_checks: number; + denied_checks: number; + total_time: number; + min_time: number; + max_time: number; + avg_time: number; + allow_rate: number; + deny_rate: number; + error_rate: number; + errors: number; +} + +export interface CacheMetrics { + total_accesses: number; + cache_hits: number; + cache_misses: number; + cache_invalidations: number; + hit_rate: number; + miss_rate: number; +} + +export interface PermissionMetricsResponse { + check_metrics: PermissionCheckMetrics; + cache_metrics: CacheMetrics; + uptime_seconds: number; +} + +export interface CacheStatsResponse { + cache_items: { + project_permissions_count: number; + member_role_count: number; + total_count: number; + }; + cache_metrics: CacheMetrics; +} + +export interface Alert { + timestamp: number; + level: "info" | "warning" | "error"; + type: string; + message: string; + data: Record; +} + +export interface AlertsResponse { + total: number; + alerts: Alert[]; +} + +export interface HealthResponse { + status: "healthy" | "degraded" | "unhealthy"; + health_score: number; + issues: string[]; + metrics: PermissionMetricsResponse; + cache_stats: CacheStatsResponse; +} diff --git a/frontend/src/views/admin/ApiPermissions.vue b/frontend/src/views/admin/ApiPermissions.vue new file mode 100644 index 00000000..df7f367a --- /dev/null +++ b/frontend/src/views/admin/ApiPermissions.vue @@ -0,0 +1,279 @@ + + + + +