登录注册:优化协议弹窗与PM后台落点

授权项目负责人登录后,若当前项目具备项目成员、中心管理或审计导出读取权限,优先进入对应管理后台页面,避免仍停留在我的工作台。

抽取登录协议为共享内容模块,注册页新增服务条款和隐私政策弹窗,并在注册成功后展示待管理员审核提示。

补充路由、登录页和注册页静态回归测试,覆盖 PM 管理后台默认落点和协议弹窗行为。
This commit is contained in:
Cheng Zhou
2026-05-13 11:03:46 +08:00
parent 89cecce6b5
commit ab1975d3c6
8 changed files with 392 additions and 57 deletions
+29
View File
@@ -472,6 +472,25 @@ const router = createRouter({
routes,
});
const pmAdminLandingModules: Array<{ module: string; path: (studyId: string) => string }> = [
{ module: "project_members", path: (studyId) => `/admin/projects/${studyId}/members` },
{ module: "sites", path: (studyId) => `/admin/projects/${studyId}/sites` },
{ module: "audit_export", path: () => "/admin/audit-logs" },
];
const findPmAdminLandingPath = async () => {
const studyStore = useStudyStore();
const studyId = studyStore.currentStudy?.id;
if (!studyId) return null;
if (!studyStore.currentPermissions) {
await studyStore.loadCurrentStudyPermissions();
}
const role = studyStore.currentStudyRole || (studyStore.currentStudy as any)?.role_in_study || "";
if (role !== "PM") return null;
const matched = pmAdminLandingModules.find((item) => !!studyStore.currentPermissions?.roles?.PM?.[item.module]?.read);
return matched ? matched.path(studyId) : null;
};
const ensureAdminProjectAccess = async (to: any, isAdmin: boolean) => {
if (isAdmin) return true;
const studyStore = useStudyStore();
@@ -530,13 +549,23 @@ router.beforeEach(async (to, _from, next) => {
next({ path: studyStore.currentStudy ? "/project/overview" : "/admin/users" });
return;
}
if (!isAdmin && token && (to.path === "/" || to.path === "/workbench")) {
const pmAdminLanding = await findPmAdminLandingPath().catch(() => null);
if (pmAdminLanding) {
next({ path: pmAdminLanding });
return;
}
}
if ((to.path === "/login" || to.path === "/register") && token) {
if (!auth.forceLogin) {
const pmAdminLanding = isAdmin ? null : await findPmAdminLandingPath().catch(() => null);
next({
path: isAdmin
? studyStore.currentStudy
? "/project/overview"
: "/admin/users"
: pmAdminLanding
? pmAdminLanding
: studyStore.currentStudy
? "/project/overview"
: "/workbench",