154 lines
4.6 KiB
TypeScript
154 lines
4.6 KiB
TypeScript
// src/layouts/BasicLayout.tsx
|
||
import React from 'react';
|
||
import ProLayout, { PageContainer } from '@ant-design/pro-layout';
|
||
import { Link, useLocation, useIntl, useHistory } from 'umi';
|
||
import { connect } from 'dva';
|
||
import defaultSettings from '../../config/defaultSettings';
|
||
import routes from '../../config/router.config'; // 引入你的自定义路由结构
|
||
import { ConfigProvider, Breadcrumb } from 'antd';
|
||
import HeaderComponent from './Header';
|
||
import IconFont from '@/components/IconFont/IconFont';
|
||
import type { BreadcrumbState } from '@/models/breadcrumb';
|
||
import type { TabModelState, TabItem } from '@/models/tab';
|
||
|
||
const MenuRender = (item: any, isSubMenu: boolean) => {
|
||
const intl = useIntl();
|
||
return (
|
||
<>
|
||
{isSubMenu ? (
|
||
<span className="ant-pro-menu-item">
|
||
<IconFont type={item.icon as string} />
|
||
<span className="ant-pro-menu-item-title">
|
||
{intl.formatMessage({ id: `menu.${item.name}` || '' })}
|
||
</span>
|
||
</span>
|
||
) : (
|
||
<Link className="ant-pro-menu-item" key={item.path} to={item.path || '/'} innerRef={null}>
|
||
<IconFont type={item.icon as string} />
|
||
<span className="ant-pro-menu-item-title">
|
||
{intl.formatMessage({ id: `menu.${item.name}` || '' })}
|
||
</span>
|
||
</Link>
|
||
)}
|
||
</>
|
||
);
|
||
};
|
||
|
||
const BreadcrumbRender = (
|
||
routeBreadcrumb: any,
|
||
intl: any,
|
||
history: any,
|
||
dynamicBreadcrumbName: string | null,
|
||
) => {
|
||
const breadcrumbRoutes = routeBreadcrumb?.routes;
|
||
return (
|
||
<Breadcrumb>
|
||
<Breadcrumb.Item
|
||
onClick={() => {
|
||
history.push('/');
|
||
}}
|
||
>
|
||
<span style={{ cursor: 'pointer' }}>{intl.formatMessage({ id: 'menu.首页' })}</span>
|
||
</Breadcrumb.Item>
|
||
{breadcrumbRoutes?.map((item: any, index: number) => {
|
||
// 判断是否是最后一个面包屑项且存在动态名称
|
||
const isLastItem = index === breadcrumbRoutes.length - 1;
|
||
const displayName =
|
||
isLastItem && dynamicBreadcrumbName
|
||
? dynamicBreadcrumbName
|
||
: intl.formatMessage({ id: `menu.${item.breadcrumbName}` || '' });
|
||
|
||
return <Breadcrumb.Item key={item.path}>{displayName}</Breadcrumb.Item>;
|
||
})}
|
||
</Breadcrumb>
|
||
);
|
||
};
|
||
|
||
interface BasicLayoutProps {
|
||
children: React.ReactNode;
|
||
breadcrumb: BreadcrumbState;
|
||
tab: TabModelState;
|
||
dispatch: any;
|
||
}
|
||
|
||
const BasicLayout: React.FC<BasicLayoutProps> = (props) => {
|
||
const { children, breadcrumb, tab, dispatch } = props;
|
||
const location = useLocation();
|
||
const intl = useIntl();
|
||
const history = useHistory();
|
||
|
||
console.log('tab model state:', tab);
|
||
|
||
const handleTabChange = (key: string) => {
|
||
dispatch({
|
||
type: 'tab/switchTab',
|
||
payload: { key },
|
||
});
|
||
};
|
||
|
||
const handleTabEdit = (targetKey: any, action: string) => {
|
||
if (action === 'remove') {
|
||
dispatch({
|
||
type: 'tab/closeTab',
|
||
payload: { key: targetKey },
|
||
});
|
||
}
|
||
};
|
||
|
||
return (
|
||
<ConfigProvider>
|
||
<ProLayout
|
||
{...defaultSettings}
|
||
route={{ routes }}
|
||
subMenuItemRender={(menuItemProps, defaultDom) => {
|
||
return MenuRender(menuItemProps, true);
|
||
}}
|
||
menuItemRender={(item, dom) => {
|
||
return MenuRender(item, false);
|
||
}}
|
||
location={location}
|
||
fixSiderbar
|
||
layout="mix"
|
||
headerRender={() => {
|
||
return <HeaderComponent />;
|
||
}}
|
||
>
|
||
<PageContainer
|
||
ghost={true}
|
||
header={{
|
||
title: false,
|
||
// breadcrumbRender: ({ breadcrumb: routeBreadcrumb }) =>
|
||
// BreadcrumbRender(routeBreadcrumb, intl, history, breadcrumb.breadcrumbName),
|
||
}}
|
||
// 将tab.tabList转换为需要的格式,添加国际化处理
|
||
tabList={tab.tabList.map(item => ({
|
||
...item,
|
||
tab: typeof item.tab === 'string' ? intl.formatMessage({ id: `menu.${item.tab}` }) : item.tab
|
||
}))}
|
||
tabProps={{
|
||
type: 'editable-card',
|
||
hideAdd: true,
|
||
activeKey: tab.activeKey,
|
||
onChange: handleTabChange,
|
||
onEdit: handleTabEdit,
|
||
size: 'small',
|
||
tabBarGutter: 6,
|
||
renderTabBar: (propsTab, DefaultTabBar) => (
|
||
<DefaultTabBar {...propsTab} className="custom-tab-bar" />
|
||
),
|
||
}}
|
||
>
|
||
{children}
|
||
</PageContainer>
|
||
</ProLayout>
|
||
</ConfigProvider>
|
||
);
|
||
};
|
||
|
||
export default connect(
|
||
({ breadcrumb, tab }: { breadcrumb: BreadcrumbState; tab: TabModelState }) => ({
|
||
breadcrumb,
|
||
tab,
|
||
}),
|
||
)(BasicLayout);
|