修正项目访问与角色排序体验

- 登录成功后按用户恢复上次项目,管理员优先选择启用项目\n- 项目详情路由增加 setup_config:read 权限校验,未授权时回到可访问页面\n- 项目管理操作按当前项目行角色读取权限,避免误用首个角色权限\n- 角色模板排序中固定 PM 优先,保持角色列表、生效管理和权限编辑器顺序一致\n- 补充登录、路由、项目管理和角色排序相关测试
This commit is contained in:
Cheng Zhou
2026-06-04 16:31:56 +08:00
parent 0b3a4d4d31
commit e78bb04c4b
8 changed files with 60 additions and 17 deletions
+22 -1
View File
@@ -350,7 +350,7 @@ const routes: RouteRecordRaw[] = [
path: "projects/:projectId",
name: "AdminProjectDetail",
component: ProjectDetail,
meta: { title: TEXT.modules.adminProjects.detailTitle, requiresProjectMember: true },
meta: { title: TEXT.modules.adminProjects.detailTitle, requiresProjectMember: true, projectPermission: "setup_config:read" },
},
{
path: "projects/:projectId/members",
@@ -466,6 +466,20 @@ const ensureRouteProjectMember = async (to: any, studyStore: ReturnType<typeof u
return true;
};
const ensureProjectPermissionAccess = async (
operationKey: string,
isAdmin: boolean,
studyStore: ReturnType<typeof useStudyStore>,
) => {
if (isAdmin) return true;
if (!operationKey || !studyStore.currentStudy) return false;
if (!studyStore.currentPermissions) {
await studyStore.loadCurrentStudyPermissions();
}
const role = studyStore.currentStudyRole || (studyStore.currentStudy as any)?.role_in_study || "";
return isApiPermissionAllowed(studyStore.currentPermissions?.[role]?.[operationKey]);
};
router.beforeEach(async (to, _from, next) => {
const auth = useAuthStore();
const studyStore = useStudyStore();
@@ -533,6 +547,13 @@ router.beforeEach(async (to, _from, next) => {
return;
}
}
if (to.meta.projectPermission) {
const allowed = await ensureProjectPermissionAccess(to.meta.projectPermission as string, isAdmin, studyStore).catch(() => false);
if (!allowed) {
next({ path: isAdmin ? "/admin/users" : "/admin/projects" });
return;
}
}
if (to.meta.systemPermission) {
const allowed = await hasSystemPermissionAccess(to.meta.systemPermission as string, isAdmin);
if (!allowed) {