import { SetStateAction, useCallback, useEffect, useState } from 'react' import { Layout, Menu, Space, ConfigProvider, Watermark, App, message } from 'antd'; import { DesktopOutlined, MessageOutlined, SendOutlined, CloudOutlined, TeamOutlined, HomeOutlined, PaperClipOutlined, ContainerOutlined, AlipayCircleOutlined, StopOutlined, QrcodeOutlined, DatabaseOutlined, ReadOutlined, MobileOutlined, FundViewOutlined, RadarChartOutlined, BarChartOutlined, WechatOutlined, BookOutlined, FileImageOutlined, EyeOutlined, UserOutlined, AlertOutlined } from '@ant-design/icons'; import { ReactComponent as LaunchSvg } from '../public/svg/launch.svg' import { ReactComponent as AdLaunchSvg } from '../public/svg/adLaunch.svg' import { ReactComponent as MaterialSvg } from '../public/svg/material.svg' import { ReactComponent as GameSvg } from '../public/svg/game.svg' import { ReactComponent as OrdrtListSvg } from '../public/svg/ordrtList.svg' import { ReactComponent as PosSvg } from '../public/svg/pos.svg' import { ReactComponent as PayInstallSvg } from '../public/svg/payInstall.svg' import { ReactComponent as UseSvg } from '../public/svg/use.svg' import { ReactComponent as PayBoxSvg } from '../public/svg/payBox.svg' import { ReactComponent as ExtensionSvg } from '../public/svg/extension.svg' import { ReactComponent as ExtensionListSvg } from '../public/svg/extensionList.svg' import { ReactComponent as MediaSvg } from '../public/svg/media.svg' import { ReactComponent as PositionSvg } from '../public/svg/position.svg' import { ReactComponent as GameListSvg } from '../public/svg/gameList.svg' import { ReactComponent as RoleListSvg } from '../public/svg/roleList.svg' import { ReactComponent as RealNameSvg } from '../public/svg/realName.svg' import { ReactComponent as CorpWechatSvg } from '../public/svg/corpWechat.svg' import { ReactComponent as MsgSvg } from '../public/svg/msg.svg' import { ReactComponent as WeComSvg } from '../public/svg/weCom.svg' import { ReactComponent as BusinessPlanSvg } from '../public/svg/businessPlan.svg' import { ReactComponent as ImageSvg } from '../public/svg/image.svg' import { ReactComponent as BooKSvg } from '../public/svg/book.svg' import { ReactComponent as PaSvg } from '../public/svg/pa.svg' import { ReactComponent as GroupChatSendSvg } from '../public/svg/groupChatSend.svg' import { ReactComponent as MomentsSvg } from '../public/svg/moments.svg' import Avatar from './AvatarDropdown'; import styles from './index.less' import { useLocation, useNavigate } from 'react-router-dom'; import globaStore from '../store'; import { getItem } from '@/utils/utils'; import zhCN from 'antd/locale/zh_CN'; import moment from 'dayjs'; import 'dayjs/locale/zh-cn'; import useNewToken from '@/Hook/useNewToken'; import React from 'react'; import { useInterval, useLocalStorageState, useUpdateEffect } from 'ahooks'; import versions from '@/utils/versions'; moment.locale('zh-cn'); const { Header, Content, Sider } = Layout; type Props = { data: any,//路由数据 name: string,//当前路由名称对应data的key children: any,//渲染的数据 } // =====================枚举转译服务端菜单icon===================== const IconMap = { desktop: , message: , send: , team: , database: , qrcode: , read: , mobile: , fundView: , radarChart: , barChart: , wechat: , // book: , peoples: , 'file-image': , pay: , cloud: , link: , dashboard: , launch: , adLaunch: , material: , game: , order: , pos: , payInstall: , use: , payBox: , extension: , extensionList: , media: , position: , gameList: , roleList: , realName: , corpWechat: , msg: , weCom: , businessPlan: , image: , book: , pa: , groupChatSend: , moments: , interdiction: , eye: , alert: , log: }; export const DispatchContext = React.createContext<{ config: any } | null>(null); /** * 菜单路由 * @param data 路由数据 clientele * @param name 当前路由名称对应data的key * */ function MainLayout(props: Props) { let { data, name } = props const [topKey] = useState([name]) const [letKey, setLetKey] = useState([]) const [topMenu, setTopMenu] = useState([]) const [leftMenu, setLeftMenu] = useState([]) const [jump, setJump] = useLocalStorageState('JUMP'); const { themeConfig } = useNewToken(); const [config] = useState(themeConfig); const navigate = useNavigate();//跳转 // =====================顶部菜单点击事件===================== const getParentKeys = (path) => { const keys = []; path.split('/').reduce((prev, curr) => { const key = `${prev}/${curr}`.replace('//', '/'); if (key !== '/') keys.push(key); return key; }); keys.shift() return keys; }; const location1 = useLocation(); const [openKeys, setOpenKeys] = useState(getParentKeys(location1.pathname)); const handleTopKey = useCallback((menu: { pData: any; key: string; }) => { let topOpen = localStorage.getItem('topOpen') data = menu?.pData || data sessionStorage.setItem('name', menu.key) if (topOpen == '1') {//打开新页面 window.open(window.location.origin + data[menu.key][0].path) } else {//当前页面 if (name !== menu.key) { window.location.href = window.location.origin + data[menu.key][0].path let oldPath = sessionStorage.getItem('oldPath') if (!oldPath || oldPath?.split('/')?.length <= 2 || oldPath?.split('/')[1] !== menu.key) {//不存在路径或者路径的长度小于2或者主路径对不上 sessionStorage.setItem('oldPath', data[menu.key][0].path) } } } }, [data]) //=====================左侧菜单点击事件===================== const handleLetKey = useCallback((menu: { domEvent: { target: { innerText: string; }; }; key: string; keyPath: SetStateAction; }) => { handleTitle(menu?.domEvent?.target?.innerText)//设置title setLetKey([menu.key]) setOpenKeys(menu.keyPath)//在这可以关闭上次展开的菜单 let path = menu.key if (path) { navigate(path) sessionStorage.setItem('oldPath', path) } }, [data]) // =====================首次默认跳转第一个菜单===================== useEffect(() => { let clickName = sessionStorage.getItem('name') if (clickName === 'imChat') { clickName = '' sessionStorage.removeItem('name') } let oldPath = sessionStorage.getItem('oldPath') let thatName = name // 当前菜单刷新 if (jump) { setTimeout(() => { setLetKey([jump]) sessionStorage.setItem('oldPath', jump) setJump() }, 200) } else { if (clickName && data[clickName]) { if (thatName !== clickName) {//更换一级菜单 handleTopKey({ key: clickName, pData: data }) } } if (data[name]) { let item = data[thatName][0].children[0] if (!data[thatName][0].children[0]) { message.error('没有下级菜单,请联系管理员,确认是否开通了系统及菜单') return } let path = '' if (oldPath && oldPath?.split('/').length > 2) {//刷新页面时 path = oldPath } else if (item?.children?.length > 0) {//假如有子菜单 path = item?.children[0]?.path } else {//没有子菜单 path = item?.path } navigate(path)//跳转到指定页面 setLetKey([path])//指定页面名称选中样式 } } if (data) { // 顶部菜单 let TopMenu = Object.values(data).sort((a: any, b: any) => { return a[0]?.orderNum - b[0]?.orderNum }).map((r: any) => { return getItem(r[0]?.title, r[0]?.belongPlatform, IconMap[r[0]?.icon as keyof typeof IconMap]) }) if (!sessionStorage.getItem('name') && TopMenu?.length > 0) { sessionStorage.setItem('name', TopMenu[0]?.key as string) } setTopMenu(TopMenu) } }, [data]) useUpdateEffect(() => { const newKey = location.hash.replace('#', '').split('?')?.[0] if (newKey !== letKey?.[0]) { // sessionStorage.setItem('oldPath', newKey); setLetKey([newKey]) } }, [location.href]) // ================后期items================= useEffect(() => { if (topKey && data[topKey[0]]) { const LeftMenu = data[topKey[0]][0].children.map((item: any, i: number) => { if (item.children?.length > 0) { return getItem(item?.title, item?.path, IconMap[item?.icon as keyof typeof IconMap], item.children) } return getItem(item?.title, item?.path, IconMap[item?.icon as keyof typeof IconMap]) }) setLeftMenu(() => LeftMenu) } }, [topKey, data]) const handleTitle = useCallback((str: string) => { if (str) { let title = document.head.getElementsByTagName('title')[0] let text = '趣程企微管理后台' + '-' + str title.innerText = text } }, []) // 版本 useEffect(() => { versions() }, []) useInterval(versions, 1000 * 60); return
{/* 顶部 */}
{/* logo */}
{(!globaStore.data.isMobile && !globaStore.data.collapsed) &&

企微运营系统

}
{ handleTopKey(menu) }} selectedKeys={topKey} style={{ width: '55%', borderBottom: 0, background: 'transparent' }} /> {/* 右侧操作 */}
{/* 左侧菜单 */} { globaStore.menuCollapsed(c) }} trigger={!globaStore.data.isMobile && null} > { handleLetKey(menu) }} onOpenChange={setOpenKeys} selectedKeys={letKey} items={leftMenu} theme="dark" /> {/* 内容 */}
{props.children}
} export default MainLayout