style: align Taro H5 with legacy question bank UI

This commit is contained in:
Codex
2026-07-02 01:22:48 +08:00
parent 25338be748
commit 7d629843b7
16 changed files with 974 additions and 494 deletions

View File

@@ -0,0 +1,94 @@
import Taro from '@tarojs/taro';
import { appEnv, ensureRuntimeConfigLoaded, isH5Runtime } from '@/env';
import type { ApiEnvelope, CurrentUser } from '@/types';
import { getTenantContext, resolveTenant } from './api';
import { loadCurrentUser } from './auth';
let pendingGuardPath = '';
function hostFromRuntime() {
if (isH5Runtime() && typeof window !== 'undefined') return window.location.host;
return '';
}
function safeRedirectPath(path: string) {
return path.startsWith('/pages/') && !path.startsWith('/pages/student/login/') ? path : '/pages/student/home/index';
}
function loginUrl(redirectPath: string) {
return `/pages/student/login/index?redirect=${encodeURIComponent(safeRedirectPath(redirectPath))}`;
}
function currentPagePath() {
const instance = Taro.getCurrentInstance();
const path = instance.router?.path || '';
return path.startsWith('/') ? path : `/${path}`;
}
function isPublicPath(path: string) {
return path === '/pages/bootstrap/index' || path === '/pages/student/login/index';
}
function shouldGuardPath(path: string) {
if (isPublicPath(path)) return false;
if (appEnv.portal === 'tenant-admin') return path.startsWith('/pages/tenant-admin/');
if (appEnv.portal === 'platform-admin') return path.startsWith('/pages/platform-admin/');
return path.startsWith('/pages/student/') && ![
'/pages/student/region/index',
'/pages/student/catalog/index',
'/pages/student/scoreline/index',
].includes(path);
}
export function landingPath() {
if (appEnv.portal === 'tenant-admin') return '/pages/tenant-admin/workbench/index';
if (appEnv.portal === 'platform-admin') return '/pages/platform-admin/workbench/index';
return '/pages/student/home/index';
}
export async function ensureTenantResolved() {
await ensureRuntimeConfigLoaded();
const current = getTenantContext();
if (current?.tenantId) return current;
return resolveTenant({ host: hostFromRuntime() });
}
export async function requireSignedIn(redirectPath: string): Promise<ApiEnvelope<CurrentUser> | null> {
await ensureTenantResolved();
try {
return await loadCurrentUser();
} catch {
Taro.redirectTo({ url: loginUrl(redirectPath) });
return null;
}
}
export async function requirePlatformAdmin(redirectPath: string) {
const payload = await requireSignedIn(redirectPath);
if (!payload) return null;
const user = payload.user || payload.item;
const roles = user?.roles || [];
if (user?.primaryRole === 'platform_admin' || roles.includes('platform_admin')) return payload;
throw new Error('当前账号不是平台管理员。');
}
export async function guardCurrentRoute() {
await ensureRuntimeConfigLoaded();
const path = currentPagePath();
if (!path || !shouldGuardPath(path) || pendingGuardPath === path) return;
pendingGuardPath = path;
try {
if (appEnv.portal === 'platform-admin') {
await requirePlatformAdmin(path);
return;
}
await requireSignedIn(path);
} finally {
pendingGuardPath = '';
}
}
export function redirectAfterLogin(rawRedirect?: string) {
const redirectPath = rawRedirect ? decodeURIComponent(rawRedirect) : landingPath();
Taro.redirectTo({ url: safeRedirectPath(redirectPath) });
}