306 lines
9.0 KiB
TypeScript
306 lines
9.0 KiB
TypeScript
|
|
import { HomeOutlined } from '@ant-design/icons';
|
|||
|
|
import { PageContainer, PageContainerProps } from '@ant-design/pro-components';
|
|||
|
|
import { useLocation, useNavigate } from '@umijs/max';
|
|||
|
|
import { Breadcrumb, Space } from 'antd';
|
|||
|
|
import { useEffect, useState } from 'react';
|
|||
|
|
// import './MyPageContainer.scss';
|
|||
|
|
|
|||
|
|
export interface TabItem {
|
|||
|
|
key: string;
|
|||
|
|
label: string;
|
|||
|
|
path: string;
|
|||
|
|
closable?: boolean;
|
|||
|
|
}
|
|||
|
|
interface BreadcrumbItem {
|
|||
|
|
title: string;
|
|||
|
|
path: string;
|
|||
|
|
onClick?: () => void;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export interface MyPageContainerProps extends PageContainerProps {
|
|||
|
|
enableTabs?: boolean;
|
|||
|
|
tabKey?: string;
|
|||
|
|
tabLabel?: string;
|
|||
|
|
onTabChange?: (activeKey: string) => void;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 注释掉标签页管理相关代码,不再使用
|
|||
|
|
// // 全局标签页状态管理
|
|||
|
|
// class TabsManager {
|
|||
|
|
// private tabs: TabItem[] = [];
|
|||
|
|
// private activeKey: string = '';
|
|||
|
|
// private listeners: Set<() => void> = new Set();
|
|||
|
|
|
|||
|
|
// subscribe(listener: () => void) {
|
|||
|
|
// this.listeners.add(listener);
|
|||
|
|
// return () => this.listeners.delete(listener);
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
// private notify() {
|
|||
|
|
// this.listeners.forEach((listener) => listener());
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
// getTabs() {
|
|||
|
|
// return this.tabs;
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
// getActiveKey() {
|
|||
|
|
// return this.activeKey;
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
// addTab(tab: TabItem) {
|
|||
|
|
// const existingIndex = this.tabs.findIndex((t) => t.key === tab.key);
|
|||
|
|
// if (existingIndex === -1) {
|
|||
|
|
// // 如果是新标签页,插入到当前激活标签页的右边
|
|||
|
|
// const currentActiveIndex = this.tabs.findIndex(
|
|||
|
|
// (t) => t.key === this.activeKey,
|
|||
|
|
// );
|
|||
|
|
// if (currentActiveIndex !== -1) {
|
|||
|
|
// // 在当前激活标签页的右边插入新标签页
|
|||
|
|
// this.tabs.splice(currentActiveIndex + 1, 0, tab);
|
|||
|
|
// } else {
|
|||
|
|
// // 如果没有当前激活标签页,添加到末尾
|
|||
|
|
// this.tabs.push(tab);
|
|||
|
|
// }
|
|||
|
|
// } else {
|
|||
|
|
// // 如果标签页已存在,更新其信息
|
|||
|
|
// this.tabs[existingIndex] = { ...this.tabs[existingIndex], ...tab };
|
|||
|
|
// }
|
|||
|
|
// this.activeKey = tab.key;
|
|||
|
|
// this.notify();
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
// addTabNext(tab: TabItem) {
|
|||
|
|
// const existingIndex = this.tabs.findIndex((t) => t.key === tab.key);
|
|||
|
|
// if (existingIndex === -1) {
|
|||
|
|
// // 强制在当前激活标签页的右边插入新标签页
|
|||
|
|
// const currentActiveIndex = this.tabs.findIndex(
|
|||
|
|
// (t) => t.key === this.activeKey,
|
|||
|
|
// );
|
|||
|
|
// if (currentActiveIndex !== -1) {
|
|||
|
|
// this.tabs.splice(currentActiveIndex + 1, 0, tab);
|
|||
|
|
// } else {
|
|||
|
|
// this.tabs.push(tab);
|
|||
|
|
// }
|
|||
|
|
// } else {
|
|||
|
|
// // 如果标签页已存在,移动到当前激活标签页的右边
|
|||
|
|
// const existingTab = this.tabs[existingIndex];
|
|||
|
|
// this.tabs.splice(existingIndex, 1); // 先移除原位置的标签页
|
|||
|
|
// const currentActiveIndex = this.tabs.findIndex(
|
|||
|
|
// (t) => t.key === this.activeKey,
|
|||
|
|
// );
|
|||
|
|
// if (currentActiveIndex !== -1) {
|
|||
|
|
// this.tabs.splice(currentActiveIndex + 1, 0, { ...existingTab, ...tab });
|
|||
|
|
// } else {
|
|||
|
|
// this.tabs.push({ ...existingTab, ...tab });
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
// this.activeKey = tab.key;
|
|||
|
|
// this.notify();
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
// removeTab(targetKey: string) {
|
|||
|
|
// const targetIndex = this.tabs.findIndex((tab) => tab.key === targetKey);
|
|||
|
|
// if (targetIndex === -1) return;
|
|||
|
|
|
|||
|
|
// const newTabs = this.tabs.filter((tab) => tab.key !== targetKey);
|
|||
|
|
|
|||
|
|
// if (newTabs.length === 0) {
|
|||
|
|
// this.tabs = [];
|
|||
|
|
// this.activeKey = '';
|
|||
|
|
// history.push('/');
|
|||
|
|
// } else {
|
|||
|
|
// this.tabs = newTabs;
|
|||
|
|
// if (this.activeKey === targetKey) {
|
|||
|
|
// // 如果关闭的是当前激活的标签,激活相邻的标签
|
|||
|
|
// const newActiveKey =
|
|||
|
|
// targetIndex > 0 ? newTabs[targetIndex - 1].key : newTabs[0].key;
|
|||
|
|
// this.activeKey = newActiveKey;
|
|||
|
|
// const targetTab = newTabs.find((tab) => tab.key === newActiveKey);
|
|||
|
|
// if (targetTab) {
|
|||
|
|
// history.push(targetTab.path);
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
// this.notify();
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
// setActiveKey(key: string) {
|
|||
|
|
// this.activeKey = key;
|
|||
|
|
// const targetTab = this.tabs.find((tab) => tab.key === key);
|
|||
|
|
// if (targetTab) {
|
|||
|
|
// history.push(targetTab.path);
|
|||
|
|
// }
|
|||
|
|
// this.notify();
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
// closeOtherTabs(currentKey: string) {
|
|||
|
|
// const currentTab = this.tabs.find((tab) => tab.key === currentKey);
|
|||
|
|
// if (currentTab) {
|
|||
|
|
// this.tabs = [currentTab];
|
|||
|
|
// this.activeKey = currentKey;
|
|||
|
|
// this.notify();
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
// closeLeftTabs(currentKey: string) {
|
|||
|
|
// const currentIndex = this.tabs.findIndex((tab) => tab.key === currentKey);
|
|||
|
|
// if (currentIndex > 0) {
|
|||
|
|
// this.tabs = this.tabs.slice(currentIndex);
|
|||
|
|
// this.notify();
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
// closeRightTabs(currentKey: string) {
|
|||
|
|
// const currentIndex = this.tabs.findIndex((tab) => tab.key === currentKey);
|
|||
|
|
// if (currentIndex !== -1) {
|
|||
|
|
// this.tabs = this.tabs.slice(0, currentIndex + 1);
|
|||
|
|
// this.notify();
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
// refreshTab(key: string) {
|
|||
|
|
// // 通过路由跳转的方式刷新当前标签页,避免整个页面刷新导致标签页状态丢失
|
|||
|
|
// const targetTab = this.tabs.find((tab) => tab.key === key);
|
|||
|
|
// if (targetTab) {
|
|||
|
|
// const originalPath = targetTab.path;
|
|||
|
|
// // 移除可能存在的刷新参数,确保获取干净的原始路径
|
|||
|
|
// const cleanPath = originalPath
|
|||
|
|
// .replace(/[?&]_refresh=\d+/g, '')
|
|||
|
|
// .replace(/\?$/, '');
|
|||
|
|
|
|||
|
|
// // 添加时间戳参数强制刷新
|
|||
|
|
// const refreshPath = cleanPath.includes('?')
|
|||
|
|
// ? `${cleanPath}&_refresh=${Date.now()}`
|
|||
|
|
// : `${cleanPath}?_refresh=${Date.now()}`;
|
|||
|
|
|
|||
|
|
// // 先更新为带刷新参数的路径并跳转
|
|||
|
|
// targetTab.path = refreshPath;
|
|||
|
|
// this.setActiveKey(key);
|
|||
|
|
|
|||
|
|
// // 延迟恢复原始路径,确保路由跳转完成
|
|||
|
|
// setTimeout(() => {
|
|||
|
|
// // 恢复为干净的原始路径
|
|||
|
|
// targetTab.path = cleanPath;
|
|||
|
|
// // 再次跳转到干净路径,移除URL中的刷新参数
|
|||
|
|
// history.push(cleanPath);
|
|||
|
|
// this.notify();
|
|||
|
|
// }, 300);
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
// // 全局标签页管理器实例
|
|||
|
|
// const tabsManager = new TabsManager();
|
|||
|
|
|
|||
|
|
export function MyPageContainer({
|
|||
|
|
title,
|
|||
|
|
children,
|
|||
|
|
enableTabs = false, // 默认关闭多标签页功能
|
|||
|
|
tabKey,
|
|||
|
|
tabLabel,
|
|||
|
|
onTabChange,
|
|||
|
|
...rest
|
|||
|
|
}: MyPageContainerProps) {
|
|||
|
|
const navigate = useNavigate();
|
|||
|
|
const location = useLocation(); // 使用useLocation钩子
|
|||
|
|
const [dataBre, setDataBre] = useState<any>(
|
|||
|
|
JSON.parse(sessionStorage.getItem('breadcrumbs') || '[]'),
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
// 简化的面包屑更新逻辑
|
|||
|
|
const updateBreadcrumbs = () => {
|
|||
|
|
try {
|
|||
|
|
// 获取当前路径和标题
|
|||
|
|
const currentPath = location.pathname + location.search;
|
|||
|
|
const currentTitle =
|
|||
|
|
typeof title === 'string'
|
|||
|
|
? title
|
|||
|
|
: String(title?.props?.children || '');
|
|||
|
|
|
|||
|
|
// 清空无效的面包屑数据(重置逻辑)
|
|||
|
|
const newBreadcrumbs: BreadcrumbItem[] = [];
|
|||
|
|
|
|||
|
|
// 只添加当前页面的面包屑
|
|||
|
|
if (currentPath && currentTitle) {
|
|||
|
|
newBreadcrumbs.push({
|
|||
|
|
title: currentTitle,
|
|||
|
|
path: currentPath,
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 更新sessionStorage
|
|||
|
|
try {
|
|||
|
|
sessionStorage.setItem('breadcrumbs', JSON.stringify(newBreadcrumbs));
|
|||
|
|
} catch (storageError) {
|
|||
|
|
console.error('存储到sessionStorage失败:', storageError);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 更新状态
|
|||
|
|
setDataBre(newBreadcrumbs);
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('更新面包屑时出错:', error);
|
|||
|
|
// 出错时重置面包屑
|
|||
|
|
setDataBre([]);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
useEffect(() => {
|
|||
|
|
console.log('title', title);
|
|||
|
|
setTimeout(() => {
|
|||
|
|
updateBreadcrumbs();
|
|||
|
|
}, 250);
|
|||
|
|
}, [location.pathname, location.search, title]);
|
|||
|
|
// 不再需要标签页相关的状态和逻辑
|
|||
|
|
// 直接返回简化版的PageContainer
|
|||
|
|
return (
|
|||
|
|
<PageContainer
|
|||
|
|
fixedHeader
|
|||
|
|
header={{
|
|||
|
|
title: (
|
|||
|
|
<Space style={{ fontSize: '12px', cursor: 'pointer', color: '#999' }}>
|
|||
|
|
<Breadcrumb
|
|||
|
|
items={[
|
|||
|
|
{
|
|||
|
|
title: <HomeOutlined />,
|
|||
|
|
onClick: () => {
|
|||
|
|
navigate('/');
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
...dataBre?.map((res: any) => ({
|
|||
|
|
title: res.title || '',
|
|||
|
|
onClick: () => {
|
|||
|
|
navigate(res.path);
|
|||
|
|
},
|
|||
|
|
})),
|
|||
|
|
]}
|
|||
|
|
/>
|
|||
|
|
</Space>
|
|||
|
|
),
|
|||
|
|
style: {
|
|||
|
|
backgroundColor: '#FFF',
|
|||
|
|
boxShadow: '10px 2px 10px 0 rgba(0, 0, 0, 0.1)',
|
|||
|
|
},
|
|||
|
|
}}
|
|||
|
|
token={{
|
|||
|
|
paddingBlockPageContainerContent: 0,
|
|||
|
|
paddingInlinePageContainerContent: 0,
|
|||
|
|
}}
|
|||
|
|
{...rest}
|
|||
|
|
>
|
|||
|
|
<Space
|
|||
|
|
direction="vertical"
|
|||
|
|
size="middle"
|
|||
|
|
style={{
|
|||
|
|
width: '100%',
|
|||
|
|
}}
|
|||
|
|
>
|
|||
|
|
{children}
|
|||
|
|
</Space>
|
|||
|
|
</PageContainer>
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 不再导出标签页管理器
|
|||
|
|
// export { tabsManager };
|