import { useState, useEffect, useMemo, type ComponentType } from 'react'; import { useAuth } from '../auth/useAuth'; import { DemoModeProvider } from './Blur'; import FeedbackFab from './FeedbackFab'; export interface ModuleConfig { id: string; label: string; icon: ComponentType<{ size?: number; className?: string }>; component: ComponentType; } /** path 到模块 id 的映射 */ const PATH_MAP: Record = { '/vehicle': 'assets', '/assets': 'assets', '/mileage': 'mileage', '/scheduling': 'scheduling', '/energy': 'energy', }; function getInitialModule(modules: ModuleConfig[]): string { // 优先看 hash const hash = window.location.hash.slice(1); if (modules.some((m) => m.id === hash)) return hash; // 再看 pathname const pathModule = PATH_MAP[window.location.pathname]; if (pathModule && modules.some((m) => m.id === pathModule)) return pathModule; // 默认第一个 return modules[0]?.id ?? ''; } function getHashModule(modules: ModuleConfig[]): string { const hash = window.location.hash.slice(1); return modules.some((m) => m.id === hash) ? hash : ''; } export function Shell({ modules }: { modules: ModuleConfig[] }) { const [activeModule, setActiveModule] = useState(() => getInitialModule(modules)); useEffect(() => { const onHashChange = () => { const h = getHashModule(modules); if (h) setActiveModule(h); }; window.addEventListener('hashchange', onHashChange); return () => window.removeEventListener('hashchange', onHashChange); }, [modules]); useEffect(() => { // 同步 hash 到当前模块:使用 replaceState 避免产生多余的 history 记录, // 否则在小程序/webview 环境下首次进入需要点两次返回才能退出 if (window.location.hash.slice(1) !== activeModule) { const { pathname, search } = window.location; window.history.replaceState(null, '', `${pathname}${search}#${activeModule}`); } }, [activeModule]); const switchModule = (id: string) => { if (window.location.hash.slice(1) === id) return; const { pathname, search } = window.location; window.history.replaceState(null, '', `${pathname}${search}#${id}`); setActiveModule(id); }; const ActiveComponent = modules.find((m) => m.id === activeModule)?.component ?? modules[0]?.component; const { user } = useAuth(); const watermarkText = useMemo(() => { const name = user?.userName || '未登录'; const time = new Date().toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }).replace(/\//g, '-'); return `${name}-${time}`; }, [user]); return (
{/* 全局水印 */}
${watermarkText}`)}")`, backgroundRepeat: 'repeat', }} />
{/* Web 侧边栏 (md 及以上) */} {/* 内容区 */}
{ActiveComponent && }
{/* 移动端底部导航 (md 以下) */}
); }