import React, { useState, useEffect } from 'react'; import { Sidebar } from './Sidebar'; // import { Header } from './Header'; import { Breadcrumb } from './Breadcrumb'; import { useMatches, useLocation } from '@remix-run/react'; import type { UserRole } from '~/root'; interface LayoutProps { children: React.ReactNode; userRole?: UserRole; frontendJWT?: string; isMobile?: boolean; // 是否为移动端设备(服务端通过 User-Agent 检测) } // 添加一个接口表示路由handle可能包含的属性 interface RouteHandle { hideBreadcrumb?: boolean; [key: string]: unknown; } interface Match { handle?: RouteHandle; pathname: string; data: unknown; } export function Layout({ children, userRole = 'developer' as UserRole, frontendJWT = '', isMobile = false }: LayoutProps) { const [sidebarCollapsed, setSidebarCollapsed] = useState(false); const [effectiveUserRole, setEffectiveUserRole] = useState(userRole); const [effectiveFrontendJWT, setEffectiveFrontendJWT] = useState(frontendJWT); const matches = useMatches() as Match[]; const location = useLocation(); // 检查当前路径是否应该隐藏侧边栏 const noLayoutPaths = ['/login', '/']; // 移动端设备强制隐藏侧边栏 const shouldHideSidebar = isMobile || noLayoutPaths.includes(location.pathname); // 检查当前路由是否应该隐藏默认面包屑 // 移动端设备强制隐藏面包屑(避免显示首页链接) const shouldHideBreadcrumb = isMobile || shouldHideSidebar || matches.some(match => match.handle && match.handle.hideBreadcrumb === true ); // 从 localStorage 读取用户信息和 JWT 作为备用方案 useEffect(() => { if (typeof window === 'undefined') return; try { // 如果服务端没有传递 userRole,从 localStorage 读取 if (!userRole || userRole === '') { const storedUserInfoStr = localStorage.getItem('user_info'); if (storedUserInfoStr) { const storedUserInfo = JSON.parse(storedUserInfoStr); const storedUserRole = storedUserInfo.user_role || 'common'; console.log('📖 [Layout] 从 localStorage 读取用户角色:', storedUserRole); setEffectiveUserRole(storedUserRole as UserRole); } } else { setEffectiveUserRole(userRole); } // 如果服务端没有传递 frontendJWT,从 localStorage 读取 if (!frontendJWT || frontendJWT === '') { const storedToken = localStorage.getItem('access_token'); if (storedToken) { console.log('📖 [Layout] 从 localStorage 读取 JWT token'); setEffectiveFrontendJWT(storedToken); } } else { setEffectiveFrontendJWT(frontendJWT); } } catch (error) { console.error('❌ [Layout] 读取 localStorage 失败:', error); } }, [userRole, frontendJWT]); // 从localStorage中获取侧边栏状态 useEffect(() => { // 检查是否为移动端 const isMobile = window.innerWidth <= 768; // 从localStorage获取侧边栏状态 const savedState = localStorage.getItem('sidebarCollapsed'); // 移动端默认收起,桌面端使用保存的状态 if (isMobile) { setSidebarCollapsed(true); } else if (savedState) { setSidebarCollapsed(savedState === 'true'); } }, []); const toggleSidebar = () => { const newState = !sidebarCollapsed; setSidebarCollapsed(newState); localStorage.setItem('sidebarCollapsed', String(newState)); }; // 切换应用模块 // const changeAppModule = (appId: AppModule) => { // setSelectedApp(appId); // localStorage.setItem('selectedApp', appId); // }; // 如果是无布局页面,只渲染内容 if (shouldHideSidebar) { return <>{children}; } return (
{/* 侧边栏始终保留,不再使用条件渲染 */}
{/* 应用模块选择器 */} {/*
{APP_MODULES.map(app => ( ))}
*/}
{!shouldHideBreadcrumb && } {children}
); }