diff --git a/src/pages/Container/Layout/index.jsx b/src/pages/Container/Layout/index.jsx index 49e82ce..7e0fe5e 100644 --- a/src/pages/Container/Layout/index.jsx +++ b/src/pages/Container/Layout/index.jsx @@ -26,12 +26,26 @@ const { Text } = Typography; const TABS_KEY = "sim_layout_tabs"; const ACTIVE_KEY = "sim_layout_active"; +/* ---- 路径规范化:统一补全 /safetyEval 前缀,避免同一路由生成多个标签 ---- */ +const normalizePath = (path) => { + if (!path) return path; + return path.startsWith("/safetyEval") ? path : `/safetyEval${path}`; +}; + /* ---- sessionStorage 持久化 ---- */ function loadState() { try { - const tabs = JSON.parse(sessionStorage.getItem(TABS_KEY) || "[]"); - const activeKey = sessionStorage.getItem(ACTIVE_KEY) || ""; - return { tabs, activeKey }; + const rawTabs = JSON.parse(sessionStorage.getItem(TABS_KEY) || "[]"); + const tabs = rawTabs.map((t) => ({ ...t, key: normalizePath(t.key) })); + // 路由去重:相同路由只保留一个标签 + const seen = new Set(); + const deduped = tabs.filter((t) => { + if (seen.has(t.key)) return false; + seen.add(t.key); + return true; + }); + const activeKey = normalizePath(sessionStorage.getItem(ACTIVE_KEY) || ""); + return { tabs: deduped, activeKey }; } catch { return { tabs: [], activeKey: "" }; } @@ -45,12 +59,12 @@ function saveState(tabs, activeKey) { export default function SimulatedLayout({ children, history }) { const [collapsed, setCollapsed] = useState(false); const [state, setState] = useState(loadState); - const [currentPath, setCurrentPath] = useState(window.location.pathname); + const [currentPath, setCurrentPath] = useState(() => normalizePath(window.location.pathname)); // 监听路由变化,更新 currentPath useEffect(() => { const unlisten = history?.listen?.((location) => { - setCurrentPath(location.pathname || window.location.pathname); + setCurrentPath(normalizePath(location.pathname || window.location.pathname)); }); return () => unlisten?.(); }, [history]); @@ -80,10 +94,10 @@ export default function SimulatedLayout({ children, history }) { }, []); const navigateTo = useCallback((path) => { - if (path !== currentPath) { - history.replace(path.replace(/^\/safetyEval/, "")); - // history.listen 可能不存在,手动同步 currentPath - setCurrentPath(window.location.pathname); + const normalized = normalizePath(path); + if (normalized !== currentPath) { + history.replace(normalized.replace(/^\/safetyEval/, "")); + setCurrentPath(normalized); } }, [currentPath, history]);