fix(feedback): 反馈管理跳转无效 + 本地调试角色补齐
Some checks are pending
ci/woodpecker/push/woodpecker Pipeline is pending

问题 1:菜单点「反馈管理」跳到 #/admin/feedback,URL 变了但
AuthGate 只在初始 render 读 location,hashchange 不会重渲染。
修复:AuthGate 用 useState/useEffect 监听 hashchange/popstate,
URL 变化即时切换页面。

问题 2:本地 DEV_BYPASS_AUTH 模式下 roles 没有 BI-ADMIN-FEEDBACK,
菜单看不到入口。前后端 dev bypass 的 roles 都补上:
  ['所有权限', 'BI-SCHEDULE-OPT', 'BI-ADMIN-FEEDBACK']

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
kkfluous
2026-04-30 14:25:30 +08:00
parent 1a3d48b2d1
commit 9bbd11cc86
3 changed files with 26 additions and 13 deletions

View File

@@ -1,4 +1,4 @@
import { useMemo } from 'react';
import { useEffect, useMemo, useState } from 'react';
import { Truck, Route, Activity, Zap } from 'lucide-react';
import { Shell, type ModuleConfig } from './components/Shell';
import AssetsModule from './modules/assets/AssetsModule';
@@ -22,8 +22,29 @@ const SCHEDULING_MODULE: ModuleConfig = {
id: 'scheduling', label: '智能调度', icon: Activity, component: SchedulingModule,
};
function getRouteKey(): string {
if (typeof window === 'undefined') return '';
const path = window.location.pathname;
const hash = window.location.hash;
if (path === '/ele/import' || hash === '#/ele/import' || hash === '#ele/import') return 'ele/import';
if (path === '/admin/feedback' || hash === '#/admin/feedback' || hash === '#admin/feedback') return 'admin/feedback';
return '';
}
function AuthGate() {
const { isLoading, isAuthenticated, error, user } = useAuth();
const [routeKey, setRouteKey] = useState(getRouteKey);
// 监听 hashchange / popstate让 a href="#/..." 跳转能即时生效
useEffect(() => {
const update = () => setRouteKey(getRouteKey());
window.addEventListener('hashchange', update);
window.addEventListener('popstate', update);
return () => {
window.removeEventListener('hashchange', update);
window.removeEventListener('popstate', update);
};
}, []);
const modules = useMemo(() => {
if (canAccessScheduling(user?.roles)) {
@@ -48,16 +69,8 @@ function AuthGate() {
}
// 隐藏后端管理页:通过路径或 hash 直接访问,主导航不出现
if (typeof window !== 'undefined') {
const path = window.location.pathname;
const hash = window.location.hash;
if (path === '/ele/import' || hash === '#/ele/import' || hash === '#ele/import') {
return <EleImportPage />;
}
if (path === '/admin/feedback' || hash === '#/admin/feedback' || hash === '#admin/feedback') {
return <FeedbackAdminPage />;
}
}
if (routeKey === 'ele/import') return <EleImportPage />;
if (routeKey === 'admin/feedback') return <FeedbackAdminPage />;
return <Shell modules={modules} />;
}

View File

@@ -46,7 +46,7 @@ export default function AuthProvider({ children }: { children: ReactNode }) {
userName: '本地开发',
permissionLevel: 'full',
depName: '',
roles: ['所有权限', 'BI-SCHEDULE-OPT'],
roles: ['所有权限', 'BI-SCHEDULE-OPT', 'BI-ADMIN-FEEDBACK'],
},
error: null,
});

View File

@@ -23,7 +23,7 @@ export async function authMiddleware(c: Context, next: Next) {
depCode: '',
depName: '',
permissionLevel: 'full',
roles: ['所有权限', 'BI-SCHEDULE-OPT'],
roles: ['所有权限', 'BI-SCHEDULE-OPT', 'BI-ADMIN-FEEDBACK'],
};
c.set('user', devUser);
return next();