"use client"; import dynamic from "next/dynamic"; import { ExclamationCircleFilled, FullscreenExitOutlined, FullscreenOutlined, HomeOutlined, LogoutOutlined, MenuOutlined, SearchOutlined, UserOutlined, } from "@ant-design/icons"; import {ProConfigProvider} from "@ant-design/pro-components"; import type {SelectProps} from "antd"; import {App, Dropdown, MenuProps, Modal, Select} from "antd"; import {deleteCookie, getCookie} from "cookies-next"; import Link from "next/link"; import {usePathname, useRouter} from "next/navigation"; import {useEffect, useRef, useState} from "react"; import {IconMap, RouteInfo, UserInfo} from "../_modules/definies"; import "./styles.css"; import "../globals.css"; import {displayModeIsDark, fetchApi, watchDarkModeChange,} from "../_modules/func"; //动态引入 ProLayout,禁用 SSR const ProLayout = dynamic( () => import("@ant-design/pro-components").then((mod) => mod.ProLayout), { ssr: false } ); export default function RootLayout({ children, }: { children: React.ReactNode; }) { const { push } = useRouter(); const redirectToLogin = () => { push("/login"); }; const [isDark, setIsDark] = useState(false); useEffect(() => { const token = getCookie("token"); if (!token) { redirectToLogin(); return; } getProfile(); setIsDark(displayModeIsDark()); const unsubscribe = watchDarkModeChange((matches: boolean) => { setIsDark(matches); }); document.addEventListener("click", hideSearchInput); return () => { unsubscribe(); document.removeEventListener("click", hideSearchInput); }; }, []); const searchRef = useRef(null); const hideSearchInput = (e: any) => { if (searchRef.current && !searchRef.current.contains(e.target)) { setShowSearch(false); setSearchListData([]); } }; const [showSearch, setShowSearch] = useState(false); const [isLogoutShow, setIsLogoutShow] = useState(false); const [confirmLoading, setConfirmLoading] = useState(false); const onActionClick: MenuProps["onClick"] = ({ key }) => { if (key === "logout") { setIsLogoutShow(true); } else if (key === "profile") { push("/user/profile"); } }; const [userInfo, setUserInfo] = useState({ nickName: "Monrtnon", avatar: "/avatar1.jpeg", }); const getProfile = async () => { const data = await fetchApi("/api/getInfo", push); if (data) { setUserInfo({ nickName: data.user.nickName, avatar: data.user.avatar === "" ? data.user.sex === "1" ? "/avatar1.jpeg" : "/avatar0.jpeg" : "/api" + data.user.avatar, }); } }; const [menuData, setMenuData] = useState([]); const getRoutes = async () => { const body = await fetchApi("/api/getRouters", push); const rootChildren: Array = []; const searchMenuList: any[] = []; const indexRoute: RouteInfo = { path: "/home", name: "首页", icon: , }; searchMenuList.push({ value: indexRoute.path, text: indexRoute.name }); rootChildren.push(indexRoute); if (body.data?.length > 0) { body.data.forEach((menu: any) => { const route: RouteInfo = { path: menu.path, name: menu.meta.title, icon: menu.meta.icon !== null ? ( IconMap[menu.meta.icon.replace(/-/g, "") as "system"] ) : ( ), }; if (menu.children?.length > 0) { if (route.name != null) { getSubMenu(route, menu.children, route.name, route.path, searchMenuList); } } rootChildren.push(route); }); } setMenuData(searchMenuList); return rootChildren; }; const getSubMenu = ( parent: RouteInfo, menuChildren: any[], parentName: string, parentPath: string, searchMenuList: any[] ) => { const routeChildren: Array = []; menuChildren.forEach((menu: any) => { const route: RouteInfo = { path: menu.path, name: menu.meta.title, icon: menu.meta.icon !== null ? ( IconMap[menu.meta.icon.replace(/-/g, "") as "system"] ) : ( ), }; routeChildren.push(route); if (menu.children?.length > 0) { getSubMenu( route, menu.children, parentName + " > " + route.name, parentPath + "/" + route.path, searchMenuList ); } else { searchMenuList.push({ text: parentName + " > " + menu.meta.title, value: parentPath + "/" + route.path, }); } }); parent.routes = routeChildren; }; const logout = async () => { setConfirmLoading(true); const data = await fetchApi("/api/logout", push, { method: "POST" }); if (data.code === 200) { deleteCookie("token"); redirectToLogin(); setIsLogoutShow(false); setConfirmLoading(false); } }; const pathName = usePathname(); const [pathname, setPathname] = useState(pathName); const [searchListData, setSearchListData] = useState([]); const handleSearch = (newValue: string) => { if (!newValue) return; setSearchListData(menuData.filter((item) => item.text.includes(newValue))); }; const handleSearchChange = (path: string) => { setPathname(path || "/index"); push(path); }; const [isFullscreen, setIsFullscreen] = useState(false); const openFullscreen = () => { document.documentElement.requestFullscreen?.(); setIsFullscreen(true); }; const closeFullscreen = () => { document.exitFullscreen?.(); setIsFullscreen(false); }; return ( console.log(e)} menuItemRender={(item, dom) => (
setPathname(item.path || "/index")}> {dom}
)} subMenuItemRender={(item, dom) => dom} avatarProps={{ src: userInfo.avatar, size: "small", title: userInfo.nickName, render: (_, dom) => ( , label: "个人中心" }, { type: "divider" }, { key: "logout", icon: , label: "退出登录" }, ], onClick: onActionClick, }} > {dom} ), }} actionsRender={(props) => { if (props.isMobile) return []; return [
setShowSearch(!showSearch)} /> {showSearch && (