/* * @Author: cclu 1106109051@qq.com * @Date: 2025-02-27 15:55:46 * @LastEditors: cclu 1106109051@qq.com * @LastEditTime: 2025-03-10 17:46:55 * @FilePath: \umi4-admin-main\src\layouts\index.tsx * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE */ import type { FC } from 'react'; import { useState, useEffect } from 'react'; import { Dropdown, Layout, Menu, Tabs, Tooltip } from 'antd'; import type { MenuProps } from 'antd'; import { Outlet, Link, useLocation, connect, history } from 'umi'; import PageAccess from '@/components/PageAccess'; import type { UserConnectedProps, UserModelState } from '@/models/user'; import LayoutWrapper from '@/components/LayoutWrapper'; import Nav from '@/components/Nav'; import Page404 from '@/pages/404'; import handleRecursiveNestedData from '@/utils/handleRecursiveNestedData'; import { MenuDataItem, ProLayout } from '@ant-design/pro-components'; import './index.less' import logo from '../assets/logo.svg'; import upMenu from '@/assets/upMenu.svg' import Icon, { DoubleRightOutlined, SmileOutlined } from '@ant-design/icons'; import { ProfileModelState } from '@/models/global'; import React from 'react'; const { Header, Content } = Layout; const { TabPane } = Tabs; /** * 获取openKeys的方法 * @param currentLocation 当前位置, 由handleGetCurrentLocation方法返回 * @returns openKeys */ const handleGetOpenKeys = (currentLocation: API.MenuItem[] | []): string[] => { //currentLocation为空 if (!currentLocation.length) return ['']; //currentLocation只有一项 if (currentLocation.length === 1) { return currentLocation.map((item: API.MenuItem) => `${item.key}`); } const res = []; //currentLocation有多项, 只要前n-1项 for (let i = 0; i < currentLocation.length - 1; i++) { res.push(`${currentLocation[i].key}`); } return res; }; //自定义的layout页面, 顶部导航通栏+侧边栏(菜单)布局, 可根据需要做调整 const BasicLayout: FC<{ user: UserModelState, global: ProfileModelState, dispatch: any, location: any }> = (props) => { const [collapsed, setCollapsed] = useState(false); const { pathname } = useLocation(); const { dispatch, user: { menu, rootSubmenuKeys, indexAllMenuItemById, indexValidMenuItemByPath }, global: { tabsRoutes } } = props; console.log('props', props); console.log('pathname', pathname); console.log('indexValidMenuItemByPath', indexValidMenuItemByPath); const validMenuItem = indexValidMenuItemByPath[pathname]; // const selectedKeys = validMenuItem?.key; const [activeKey, setActiveKey] = useState(validMenuItem?.path || '/') //Menu中的selectedKeys和openKeys不是一回事: //openKeys: //当前展开的SubMenu菜单项key数组, 有子菜单的父菜单, 当selectedKeys为没子菜单的父菜单时该值应该设为[''], //也就是关闭所有有子菜单的父菜单; //selectedKeys: //当前选中的菜单项key数组, 有子菜单则是子菜单(叶子节点), 没有子菜单则是父菜单(一级菜单), 始终是可选中的 //点击有子菜单的父菜单的回调 // const onOpenChange: MenuProps['onOpenChange'] = (keys) => { // setOpenKeys(keys) // dispatch({ // namespace: "global/setProfileData", // payload: { // keys // } // }) // }; //所有MenuItem: //有children的: 一定都有path, lable不动, children下的label修改为 //无children的: 有path的label修改为, 没path的label不动 const consumableMenu = handleRecursiveNestedData( menu, (item: API.MenuItem) => ({ ...item, name: item.path ? ( {item.name} ) : item.name, }), ); // const consumableMenu: MenuDataItem[] = [ // { // path: '/', // name: 'Dashboard', // icon: , // }, // { // path: '/about', // name: 'Users', // icon: , // children: [ // { // path: '/about/u', // name: 'User List', // }, // { // path: '/about/m', // name: 'User Profile', // }, // ], // }, // ]; const location = useLocation(); // 改变panes const handleTabsPanes = (payload: any): void => { dispatch({ type: 'global/changeTabsRoutes', payload: { data: payload, action: 'add' }, }); }; // 关闭当前标签 const handleEdit = (targetKey: string | React.MouseEvent | React.KeyboardEvent, action: "add" | "remove"): void => { if (action === 'remove' && dispatch) { const index = tabsRoutes.findIndex((n: { path: string }) => n.path === targetKey) // 定位关闭当前标签后,需要选中的下一个标签 // eslint-disable-next-line no-nested-ternary const nextkey = tabsRoutes[index + 1] ? tabsRoutes[index + 1].path : (tabsRoutes[index - 1] ? tabsRoutes[index - 1].path : '') history.push(nextkey || '/') setActiveKey(nextkey) // 缓存路由栈数据 dispatch({ type: 'global/changeTabsRoutes', payload: { data: [targetKey], action }, }) } } // 全部菜单一层的数组 const oneFloorList = [ { SYSTEMMODULE_DESC: "", guid: "1", hideInMenu: false, name: "生成标准页面", path: "/standard/index", }, { SYSTEMMODULE_DESC: "", guid: "2", hideInMenu: false, name: "考评分类管理", path: "/examine/index", }, { SYSTEMMODULE_DESC: "", guid: "3", hideInMenu: false, name: "考核问题管理", path: "/examine/question", }, { SYSTEMMODULE_DESC: "", guid: "4", hideInMenu: false, name: "考核点位管理", path: "/examine/modal", }, { SYSTEMMODULE_DESC: "", guid: "5", hideInMenu: false, name: "考核记录管理", path: "/examine/record", }, { SYSTEMMODULE_DESC: "", guid: "6", hideInMenu: false, name: "菜单管理", path: "/setting/menu", } ] console.log('tabsRoutes', tabsRoutes); console.log('location', location); console.log('consumableMenu', consumableMenu); return ( consumableMenu} menuItemRender={(menuItemProps, defaultDom) => { if (menuItemProps.isUrl || !menuItemProps.path) { return defaultDom; } return ( {defaultDom} ); }} subMenuItemRender={(menuItemProps) => { if (menuItemProps.icon && typeof menuItemProps.icon === 'string') { const ele = React.createElement(Icon[menuItemProps.icon]) return
{ele} {menuItemProps.name}
; } return
{menuItemProps.name}
; }} menuItemRender={(menuItemProps, defaultDom) => { if ( menuItemProps.isUrl || !menuItemProps.path || location.pathname === menuItemProps.path ) { return defaultDom; } return { }}> {defaultDom} {/* {menuItemProps.name} */} ; }} breadcrumbRender={false} itemRender={(route, params, routes, paths) => { const first = routes.indexOf(route) === 0; return first ? ( {route.breadcrumbName} ) : ( {route.breadcrumbName} ); }} actionsRender={() =>