330 lines
8.9 KiB
TypeScript
330 lines
8.9 KiB
TypeScript
import React, { useEffect, useState } from "react";
|
|
import { Menu } from "antd";
|
|
// import { useSelector } from "react-redux";
|
|
import { useNavigate, useLocation } from "react-router-dom";
|
|
// import styles from "./index.module.less";
|
|
// import logo from "../../assets/logo.png";
|
|
|
|
function getItem(
|
|
label: any,
|
|
key: any,
|
|
icon: any,
|
|
children: any,
|
|
type: any,
|
|
// permission: any
|
|
) {
|
|
return {
|
|
key,
|
|
icon,
|
|
children,
|
|
label,
|
|
type,
|
|
// permission,
|
|
};
|
|
}
|
|
const items = [
|
|
getItem(
|
|
"首页概览",
|
|
"/",
|
|
<i className={`iconfont icon-icon-home`} />,
|
|
null,
|
|
null,
|
|
),
|
|
getItem(
|
|
"人员总览",
|
|
"/staff",
|
|
<i className="iconfont icon-icon-category" />,
|
|
null,
|
|
null,
|
|
),
|
|
getItem(
|
|
"训练计划",
|
|
"/plan",
|
|
<i className="iconfont icon-icon-user" />,
|
|
[
|
|
getItem("周训练计划", "/plan/weekplan", null, null, null),
|
|
getItem("月训练计划", "/plan/monthplan", null, null, null),
|
|
],
|
|
null,
|
|
),
|
|
getItem(
|
|
"每日填报",
|
|
"/daily",
|
|
<i className="iconfont icon-icon-user" />,
|
|
null,
|
|
null,
|
|
),
|
|
getItem(
|
|
"考核成绩",
|
|
"/assessment",
|
|
<i className="iconfont icon-icon-user" />,
|
|
[
|
|
getItem("岗位", "/assessment/positionassessment", null, null, null),
|
|
getItem("共同", "/assessment/commonassessment", null, null, null),
|
|
getItem("体育", "/assessment/sportsassessment", null, null, null),
|
|
],
|
|
null,
|
|
),
|
|
getItem(
|
|
"系统设置",
|
|
"/admin",
|
|
<i className="iconfont icon-icon-user" />,
|
|
[
|
|
getItem("基本设置", "/admin/base-setting", null, null, null),
|
|
getItem("用户管理", "/admin/user", null, null, null),
|
|
getItem("组织架构", "/admin/department", null, null, null),
|
|
getItem("角色管理", "/admin/role", null, null, null),
|
|
getItem("考核标准管理", "/admin/assessment-standard", null, null, null),
|
|
],
|
|
null,
|
|
),
|
|
];
|
|
|
|
const NavigationMenu: React.FC = () => {
|
|
const location = useLocation();
|
|
const navigate = useNavigate();
|
|
const children2Parent: any = {
|
|
"^/plan/weekplan": ["/plan"],
|
|
"^/plan/monthplan": ["/plan"],
|
|
// 添加考核成绩子路径的匹配规则
|
|
"^/assessment/positionassessment": ["/assessment"],
|
|
"^/assessment/commonassessment": ["/assessment"],
|
|
"^/assessment/sportsassessment": ["/assessment"],
|
|
"^/admin/base-setting": ["/admin"],
|
|
"^/admin/department": ["/admin"],
|
|
"^/admin/role": ["/admin"],
|
|
"^/admin/assessment-standard": ["/admin"],
|
|
"^/admin/user": ["/admin"],
|
|
};
|
|
|
|
// 同时在 useEffect 中更新路径判断逻辑
|
|
useEffect(() => {
|
|
if (location.pathname.indexOf("/staff") !== -1) {
|
|
setSelectedKeys(["/staff"]);
|
|
setOpenKeys(openKeyMerge("/staff"));
|
|
} else if (
|
|
// 添加考核成绩路径的判断
|
|
location.pathname.startsWith("/assessment/") ||
|
|
location.pathname === "/plan/weekplan" ||
|
|
location.pathname === "/plan/monthplan"
|
|
) {
|
|
setSelectedKeys([location.pathname]);
|
|
setOpenKeys([location.pathname.split('/').slice(0, 2).join('/')]);
|
|
} else if (
|
|
location.pathname.startsWith("/admin/")
|
|
) {
|
|
setSelectedKeys([location.pathname]);
|
|
setOpenKeys([location.pathname.split('/').slice(0, 2).join('/')]);
|
|
} else {
|
|
setSelectedKeys([location.pathname]);
|
|
setOpenKeys(openKeyMerge(location.pathname));
|
|
}
|
|
}, [location.pathname]);
|
|
|
|
const hit = (pathname: string): string[] => {
|
|
for (const p in children2Parent) {
|
|
if (pathname.search(p) >= 0) {
|
|
return children2Parent[p];
|
|
}
|
|
}
|
|
return [];
|
|
};
|
|
|
|
const openKeyMerge = (pathname: string): string[] => {
|
|
const newOpenKeys = hit(pathname);
|
|
for (let i = 0; i < openKeys.length; i++) {
|
|
let isIn = false;
|
|
for (let j = 0; j < newOpenKeys.length; j++) {
|
|
if (newOpenKeys[j] === openKeys[i]) {
|
|
isIn = true;
|
|
break;
|
|
}
|
|
}
|
|
if (isIn) {
|
|
continue;
|
|
}
|
|
newOpenKeys.push(openKeys[i]);
|
|
}
|
|
return newOpenKeys;
|
|
};
|
|
|
|
// 选中的菜单
|
|
const [selectedKeys, setSelectedKeys] = useState<string[]>([
|
|
location.pathname,
|
|
]);
|
|
// 展开菜单
|
|
const [openKeys, setOpenKeys] = useState<string[]>(hit(location.pathname));
|
|
// const permissions = useSelector(
|
|
// (state: any) => state.loginUser.value.permissions
|
|
// );
|
|
const [activeMenus, setActiveMenus] = useState<any>(items);
|
|
|
|
const onClick = (e: any) => {
|
|
navigate(e.key);
|
|
};
|
|
// console.log(items)
|
|
useEffect(() => {
|
|
setActiveMenus(items);
|
|
// console.log(activeMenus)
|
|
}, [items])
|
|
// useEffect(() => {
|
|
// checkMenuPermissions(items, permissions);
|
|
// }, [items, permissions]);
|
|
|
|
// const checkMenuPermissions = (items: any, permissions: any) => {
|
|
// const menus: any = [];
|
|
// if (permissions.length === 0) {
|
|
// setActiveMenus(menus);
|
|
// return;
|
|
// }
|
|
|
|
// for (const i in items) {
|
|
// const menuItem = items[i];
|
|
// // 一级菜单=>没有子菜单&配置了权限
|
|
// if (menuItem.children === null) {
|
|
// if (
|
|
// menuItem.permission !== null &&
|
|
// typeof permissions[menuItem.permission] === "undefined"
|
|
// ) {
|
|
// continue;
|
|
// }
|
|
// menus.push(menuItem);
|
|
// continue;
|
|
// }
|
|
// const children = [];
|
|
|
|
// for (const j in menuItem.children) {
|
|
// const childrenItem = menuItem.children[j];
|
|
|
|
// if (
|
|
// typeof permissions[childrenItem.permission] !== "undefined" ||
|
|
// !childrenItem.permission
|
|
// ) {
|
|
// // 存在权限
|
|
// children.push(childrenItem);
|
|
// }
|
|
// }
|
|
|
|
// if (children.length > 0) {
|
|
// menus.push(Object.assign({}, menuItem, { children: children }));
|
|
// }
|
|
// }
|
|
// setActiveMenus(menus);
|
|
// };
|
|
|
|
useEffect(() => {
|
|
if (location.pathname.indexOf("/staff") !== -1) {
|
|
setSelectedKeys(["/staff"]);
|
|
setOpenKeys(openKeyMerge("/staff")); // 修正为当前路径的父级
|
|
} else if (
|
|
location.pathname === "/weekplan" ||
|
|
location.pathname === "/monthplan"
|
|
) {
|
|
setSelectedKeys([location.pathname]);
|
|
setOpenKeys(["/plan"]); // 直接展开训练计划父菜单
|
|
} else {
|
|
setSelectedKeys([location.pathname]);
|
|
setOpenKeys(openKeyMerge(location.pathname));
|
|
}
|
|
}, [location.pathname]);
|
|
|
|
return (
|
|
<div className='w-[200px] h-full bg-#fff'>
|
|
<div
|
|
style={{
|
|
textDecoration: "none",
|
|
cursor: "pointer",
|
|
position: "sticky",
|
|
top: 0,
|
|
zIndex: 10,
|
|
background: "#fff",
|
|
}}
|
|
onClick={() => {
|
|
window.location.href = "/";
|
|
}}
|
|
>
|
|
{/* 此处为版权标识,严禁删改
|
|
<img src={logo} className="w-[124px] h-[40px]"/> */}
|
|
</div>
|
|
<div className='w-[200px] h-[calc(100%-74px)] overflow-y-auto overflow-x-hidden'>
|
|
<Menu
|
|
onClick={onClick}
|
|
style={{
|
|
width: 200,
|
|
background: "#ffffff",
|
|
}}
|
|
selectedKeys={selectedKeys}
|
|
openKeys={openKeys}
|
|
mode="inline"
|
|
items={activeMenus}
|
|
onSelect={(data: any) => {
|
|
setSelectedKeys(data.selectedKeys);
|
|
}}
|
|
onOpenChange={(keys: any) => {
|
|
setOpenKeys(keys);
|
|
}}
|
|
/>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default NavigationMenu;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// import { Menu } from "antd";
|
|
// import { useNavigate, useLocation } from "react-router-dom";
|
|
|
|
// export default function NavigationMenu() {
|
|
// const navigate = useNavigate();
|
|
// const location = useLocation();
|
|
// console.log(location.pathname);
|
|
// // 导航菜单项配置
|
|
// const menuItems = [
|
|
// { key: 'staff', label: '人员总览', path: '/' }, // 将path改为根路径
|
|
// { key: 'plan', label: '培训计划', path: '/plan' },
|
|
// { key: 'day', label: '每日填报', path: '/daily' },
|
|
// { key: 'exam', label: '考核成绩', path: '/exam' },
|
|
// ];
|
|
|
|
// return (
|
|
// <>
|
|
// <Menu
|
|
// theme="dark"
|
|
// mode="inline"
|
|
// className="!bg-transparent !border-0 pt-4 [&_.ant-menu-item]:!mt-2"
|
|
// selectedKeys={[ // 改用selectedKeys替代defaultSelectedKeys
|
|
// menuItems.find((item) => location.pathname.startsWith(item.path))?.key,
|
|
// ]}
|
|
// >
|
|
// {menuItems.map((item) => (
|
|
// <Menu.Item
|
|
// key={item.key}
|
|
// className="!h-14 !flex !items-center !text-gray-300 hover:!text-white group !rounded-lg mx-4"
|
|
// onClick={() => navigate(item.path)}
|
|
// >
|
|
// <div className="flex items-center justify-center w-full px-4 transition-all duration-300 h-full rounded-lg">
|
|
// <span className="text-xl font-medium">{item.label}</span>
|
|
// </div>
|
|
// </Menu.Item>
|
|
// ))}
|
|
// </Menu>
|
|
// </>
|
|
// );
|
|
// }
|