修复(权限管理):统一 PM 系统导航与权限校验

This commit is contained in:
Cheng Zhou
2026-07-10 22:12:59 +08:00
parent f11a5c84d9
commit f2fa10c178
47 changed files with 4071 additions and 1555 deletions
+25 -12
View File
@@ -32,8 +32,8 @@
</div>
</div>
<!-- 管理后台/项目管理控制卡片 - 常驻左侧底部 -->
<div class="sidebar-admin">
<!-- ADMIN / PM 可进入系统管理,其他角色仅可选择项目 -->
<div v-if="canEnterManagement" class="sidebar-admin">
<button class="admin-action-card" type="button" @click="enterManagement">
<span class="admin-glow-layer" aria-hidden="true"></span>
<div class="admin-card-head">
@@ -41,8 +41,8 @@
<el-icon><Monitor /></el-icon>
</div>
<div class="admin-text-box">
<span class="admin-kicker">{{ isAdmin ? "ADMIN SYSTEM" : "STUDY PORTAL" }}</span>
<strong>{{ isAdmin ? "管理后台" : "项目管理" }}</strong>
<span class="admin-kicker">{{ isAdmin ? "ADMIN SYSTEM" : "SYSTEM MANAGEMENT" }}</span>
<strong>系统管理</strong>
</div>
</div>
<p class="admin-desc">
@@ -206,18 +206,22 @@ const loading = ref(false);
const loggingOut = ref(false);
const isTransitioning = ref(false);
const isAdmin = computed(() => isSystemAdmin(auth.user));
const canEnterManagement = computed(() =>
isAdmin.value || projects.value.some((project) => project.role_in_study === "PM"),
);
const userDisplayName = computed(
() => auth.user?.full_name || auth.user?.username || auth.user?.email || TEXT.common.labels.userFallback,
);
const userInitial = computed(() => userDisplayName.value.charAt(0).toUpperCase() || TEXT.common.labels.userInitialFallback);
const entryDescription = computed(() =>
isAdmin.value
? "进入管理后台处理账号、授权 and 系统配置,或选择项目进入项目工作区。"
: "选择本次要进入的项目,或进入项目管理查看您已授权的项目范围。",
);
const managementActionLabel = computed(() => isAdmin.value ? "进入管理后台" : "进入项目管理");
const entryDescription = computed(() => {
if (!canEnterManagement.value) return "选择本次要进入的项目进入项目工作区。";
return isAdmin.value
? "进入系统管理处理账号、授权及系统配置,或选择项目进入项目工作区。"
: "进入系统管理查看您已授权的项目范围,或选择项目进入项目工作区。";
});
const managementActionLabel = computed(() => canEnterManagement.value ? "进入系统管理" : "");
const statusLabel = (status: string | undefined) =>
status ? TEXT.enums.projectStatus[status as keyof typeof TEXT.enums.projectStatus] || status : "未知";
@@ -235,9 +239,18 @@ const loadProjects = async () => {
};
const enterManagement = async () => {
if (!canEnterManagement.value) return;
isTransitioning.value = true;
window.setTimeout(async () => {
studyStore.clearCurrentStudy();
if (isAdmin.value) {
studyStore.clearCurrentStudy();
} else {
const pmProject = projects.value.find((project) => project.role_in_study === "PM");
if (pmProject) {
studyStore.setCurrentStudy(pmProject);
await studyStore.loadCurrentStudyPermissions().catch(() => {});
}
}
await router.push(isAdmin.value ? "/admin/users" : "/admin/projects").catch(() => {});
isTransitioning.value = false;
}, 300);
@@ -461,7 +474,7 @@ onMounted(() => {
color: #ef4444;
}
/* 常驻管理后台卡片(精致浅色流光) */
/* 常驻系统管理卡片(精致浅色流光) */
.sidebar-admin {
width: 100%;
}