权限监控与管理界面全面美化
重新设计权限系统所有 UI 组件的视觉风格,统一配色、圆角、阴影和交互动效: - 实时概览:统计卡片加图标和渐变色条,健康评分改为环形进度,告警改为卡片式 - 趋势分析:图表卡片加彩色图标标识,ECharts 配色升级为渐变面积填充 - 访问日志:指标卡片带图标,日志审计改为卡片式入口,IP排行前三高亮 - IP属地:工具栏重设计,排行列表前三渐变高亮,指标卡片统一新风格 - 系统级权限:从 el-table 改为自定义卡片列表,模块块独立圆角卡片 - 项目权限配置:空状态引导优化,成员表格加头像,工具栏加背景容器 - 角色概览卡片:加进度条可视化,hover 微动效 - 接口权限矩阵:工具栏分离布局,表格圆角包裹 - 角色管理抽屉:侧边栏选中态渐变,操作行 hover 高亮 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@ import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router";
|
||||
import { useAuthStore } from "../store/auth";
|
||||
import { useStudyStore } from "../store/study";
|
||||
import { isSystemAdmin } from "../utils/roles";
|
||||
import { isApiPermissionAllowed } from "../utils/apiPermissionValue";
|
||||
import { findFirstAccessibleProjectPath, getProjectRoutePermission, hasProjectPermission } from "../utils/projectRoutePermissions";
|
||||
import { fetchStudyDetail } from "../api/studies";
|
||||
import { fetchApiEndpointPermissions } from "../api/projectPermissions";
|
||||
@@ -489,6 +490,12 @@ const router = createRouter({
|
||||
routes,
|
||||
});
|
||||
|
||||
const ADMIN_PROJECT_OPERATION_KEYS: Record<string, Record<"read" | "write", string>> = {
|
||||
audit_export: { read: "audit_logs:read", write: "audit_logs:read" },
|
||||
project_members: { read: "project_members:list", write: "project_members:update" },
|
||||
sites: { read: "sites:read", write: "sites:update" },
|
||||
};
|
||||
|
||||
const ensureAdminProjectAccess = async (to: any, isAdmin: boolean) => {
|
||||
if (isAdmin) return true;
|
||||
const studyStore = useStudyStore();
|
||||
@@ -509,8 +516,9 @@ const ensureAdminProjectAccess = async (to: any, isAdmin: boolean) => {
|
||||
|
||||
const role = studyStore.currentStudyRole || (studyStore.currentStudy as any)?.role_in_study || "";
|
||||
if (role !== "PM") return false;
|
||||
// 管理员项目权限检查:PM 角色默认有访问权限
|
||||
return true;
|
||||
const operationKey = ADMIN_PROJECT_OPERATION_KEYS[permission.module]?.[permission.action];
|
||||
if (!operationKey) return false;
|
||||
return isApiPermissionAllowed(studyStore.currentPermissions?.[role]?.[operationKey]);
|
||||
};
|
||||
|
||||
router.beforeEach(async (to, _from, next) => {
|
||||
@@ -578,7 +586,7 @@ router.beforeEach(async (to, _from, next) => {
|
||||
await studyStore.loadCurrentStudyPermissions().catch(() => {});
|
||||
}
|
||||
const role = studyStore.currentStudyRole || (studyStore.currentStudy as any)?.role_in_study || "";
|
||||
const canReadAudit = !!studyStore.currentPermissions?.[role]?.["audit_logs:read"]?.allowed;
|
||||
const canReadAudit = isApiPermissionAllowed(studyStore.currentPermissions?.[role]?.["audit_logs:read"]);
|
||||
if (!(isAdmin || (role === "PM" && canReadAudit))) {
|
||||
next({ path: "/project/overview" });
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user