feat: 1. 完善全局路由的访问权限的验证。 2. 完善接口返回的树形路由结构 3.优化评查点列表的查询,改用表连接的方式,废弃使用数据库的rpc函数,同时进行地区隔离和权限隔离。

4. 删除冗余的评查文件列表。      5.完善上传文档 页面初始化查询数据的时候 查询文件类型(改成动态指定)  6. 添加获取入口模块的查询接口。    7.完善服务端中判断token的有效性,失效则跳转到登录页。
8. 重构layout和sidebar的页面,改成由动态权限路由来渲染对应的菜单栏。       9.重构入口页面,通过动态查询根据不同地区的人返回不同的入口。
This commit is contained in:
2025-11-20 01:35:30 +08:00
parent adfb84a31d
commit 2edde8a8ab
23 changed files with 1201 additions and 2154 deletions
+36 -26
View File
@@ -126,33 +126,47 @@ export async function loader({ request }: LoaderFunctionArgs) {
try {
const { getUserSession } = await import("~/api/login/auth.server");
const session = await getUserSession(request);
userRole = session.userRole || 'common';
userRole = session.userRole;
frontendJWT = session.frontendJWT || null;
// console.log("🔑 [Root Loader] 用户角色:", userRole);
// 🔑 检查用户角色和JWT是否为空
if (!userRole || userRole === '') {
console.error("❌ [Root Loader] 用户角色为空,session数据异常");
// 保存当前路径,登录后可以跳转回来
const redirectTo = pathname !== '/login' ? pathname : '/';
return redirect(`/login?redirect=${encodeURIComponent(redirectTo)}&error=no_role`);
}
if (!frontendJWT) {
console.error("❌ [Root Loader] JWT token为空,session数据异常");
// 保存当前路径,登录后可以跳转回来
const redirectTo = pathname !== '/login' ? pathname : '/';
return redirect(`/login?redirect=${encodeURIComponent(redirectTo)}&error=no_token`);
}
// console.log("🔑 [Root Loader] 用户角色:", userRole, "JWT前20字符:", frontendJWT.substring(0, 20));
// 🔒 RBAC 路由权限检查
if (frontendJWT) {
const { getUserRoutesByRole } = await import("~/api/auth/user-routes");
// 权限校验需要包含隐藏路由,确保用户可以访问隐藏的功能页面
const routesResult = await getUserRoutesByRole(userRole, frontendJWT, true);
const { getUserRoutesByRole } = await import("~/api/auth/user-routes");
// 权限校验需要包含隐藏路由,确保用户可以访问隐藏的功能页面
const routesResult = await getUserRoutesByRole(userRole, frontendJWT, true);
if (routesResult.success && routesResult.data) {
// 从菜单数据中提取所有允许的路径
allowedPaths = extractAllPaths(routesResult.data);
// console.log("🔑 [Root Loader] 用户允许的路由:", allowedPaths);
if (routesResult.success && routesResult.data) {
// 从菜单数据中提取所有允许的路径
allowedPaths = extractAllPaths(routesResult.data);
// console.log("🔑 [Root Loader] 用户允许的路由:", allowedPaths);
// 检查当前路径是否在允许列表中
const isAllowedPath = isPathAllowed(pathname, allowedPaths);
// 检查当前路径是否在允许列表中
const isAllowedPath = isPathAllowed(pathname, allowedPaths);
if (!isAllowedPath) {
console.warn(`⚠️ [Root Loader] 用户尝试访问未授权路由: ${pathname}`);
// 返回 403 错误,而不是 redirect(避免循环)
throw new Response("无权访问此页面", { status: 403 });
}
} else {
// 获取路由权限失败,只记录警告,不阻止访问(避免影响正常使用)
console.warn("⚠️ [Root Loader] 获取用户路由权限失败,跳过权限检查");
if (!isAllowedPath) {
console.warn(`⚠️ [Root Loader] 用户尝试访问未授权路由: ${pathname}`);
// 返回 403 错误,而不是 redirect(避免循环)
throw new Response("无权访问此页面", { status: 403 });
}
} else {
// 获取路由权限失败,只记录警告,不阻止访问(避免影响正常使用)
console.warn("⚠️ [Root Loader] 获取用户路由权限失败,跳过权限检查");
}
} catch (error) {
// 如果是 Response 对象(403 错误),直接抛出
@@ -171,13 +185,9 @@ export async function loader({ request }: LoaderFunctionArgs) {
console.warn("⚠️ [Root Loader] 获取用户会话失败:", error);
// 保持默认值 'common'
}
}
// ⚠️ 重要:现在使用客户端 localStorage 存储 token,服务端不再检查 session
// 认证检查改为在客户端进行(通过 ClientAuthGuard 组件)
if (!frontendJWT) {
frontendJWT = getAccessToken();
// 注意:认证检查和重定向已在 getUserSession() 中统一处理
// 如果执行到这里,说明已通过认证或是公共路径
}
// 检查51707端口访问控制