Files
fe_portal_manage_frontend/src/layouts/BasicLayout.tsx
2025-07-14 10:13:56 +08:00

154 lines
4.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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);