import React, { ReactNode, useMemo, useEffect, useCallback, /* useState, */ ReactText, } from 'react'; import qs from 'qs'; import { env, navRedirectDiscope, redirctToLogin } from '@jy-fe/business'; import { ElementType } from '@jy-fe/business/es/authority'; import { unicodeToChar, useDeepEqualIdentifier } from '@jy-fe/utils'; import classnames from 'classnames'; import locale from 'antd/es/locale/zh_CN'; import ConfigProvider from 'antd/es/config-provider'; import Avatar from 'antd/es/avatar'; import 'antd/es/avatar/style/index'; import Menu from 'antd/es/menu'; import 'antd/es/menu/style/index'; import { /* MenuInfo, */ SelectInfo } from 'rc-menu/es/interface'; import Popover from 'antd/es/popover'; import 'antd/es/popover/style/index'; import message from 'antd/es/message'; import 'antd/es/message/style/index'; import 'antd/es/tooltip/style/index'; import { XuiReactDownloadIcon } from '@jy-fe/icons'; import { XuiXladminThemeLayoutInfoDataType, XuiXladminThemeLayoutProps, } from './xui-xladmin-theme-layout.d'; import XuiRoleMenu from '../xui-role-menu'; const XuiThemeLayout: React.FC = ({ systemType, admType, logoImg, logoutImg, portraitImg, personalSetImg, ownModule, Link, history, children, initialState, onDownload, mode, onModeChange, horizontalSelectedUrl, onSelectedHorizontalMenuCallback, openedKeys, selectedKeys, onSelectedSubMenu, onSelectedMenuItem, positionVisible, onPositionVisible, roleVisible, onRoleVisible, roleDataDiscope, effectCallback, }) => { const iconfontClassName = useMemo(() => { const iconMap = new Map([ [6, 'recruit-admin'], [7, 'xl-admin'], [8, 'dd-admin'], ]); return `iconfont icon-${iconMap.get(admType)}`; }, [admType]); /** 获取当前路由地址 */ const { pathname } = location; const className = 'xui-ant__xladmin-theme-layout'; const headerClassName = 'xui-ant__xladmin-theme-layout--header'; const contentClassName = 'xui-ant__xladmin-theme-layout--content'; /** 纵向导航栏类名 */ const verticalPopupMenuClassName = 'xui-ant__xladmin-theme-layout--verticalPopupMenu'; /** 个人信息浮块类名 */ const userPopoverClassName = 'xui-ant__xladmin-theme-layout--userPopover'; /** * 以下为权限部分 */ /** 解析浏览器?后的参数对 */ const urlParams = useMemo(() => qs.parse(location.search, { ignoreQueryPrefix: true }), []); const { code } = urlParams; if (code) { delete urlParams.code; const searchStr = qs.stringify(urlParams, { addQueryPrefix: true }); history.replace(`${location.pathname}${searchStr}`); } const { roleData = [], redirectPathMap = {}, verticalNav = [], access = [], aidMap = {}, highlightIdMap = {}, } = initialState || {}; const accessEqual = useDeepEqualIdentifier(access); const aidMapEqual = useDeepEqualIdentifier(aidMap); /** 重定向判断 */ navRedirectDiscope(systemType, redirectPathMap, pathname, redirectPath => { history.replace(redirectPath); }); /** 退出登录 */ const logout = useCallback(() => { localStorage.removeItem('token'); message.success('退出成功'); location.href = env.ssoLogoutHREF; }, []); /** 点击横向滚动条后的调用 */ const selectedHorizontalMenuCallback = useCallback( (currentPathname: string, currentRedirectPath: string) => { onSelectedHorizontalMenuCallback(currentPathname); history.push(currentRedirectPath); }, [history, onSelectedHorizontalMenuCallback], ); /** 获取横向导航栏选中块的相关属性 */ const selectedHorizontalMenuItem = useCallback( (item: any) => { if (item.mstyle === '/') { selectedHorizontalMenuCallback('/', '/'); } else { navRedirectDiscope(systemType, redirectPathMap, item.mstyle, redirectPath => { selectedHorizontalMenuCallback(item.mstyle, redirectPath); }); } }, [systemType, redirectPathMap, selectedHorizontalMenuCallback], ); /** 生成横向导航栏 */ const HorizontalMenu = useMemo(() => { const menus = roleData.map((element: ElementType) => { if (element.newTabType === 1) { return (
{element.mlabel}
); } if (ownModule.includes(element.mstyle || '')) { return (
selectedHorizontalMenuItem(element)} > {element.mlabel}
); } return (
{element.mlabel}
); }); menus.unshift(
selectedHorizontalMenuItem({ mstyle: '/', }) } > 工作台
, ); return menus; }, [ownModule, horizontalSelectedUrl, roleData, selectedHorizontalMenuItem]); /** 判断纵向导航栏跳转 */ const checkVerticalMenu = useCallback( (data: any) => { if (data.newTabType === 1) { return ( {data.mlabel} ); } if (data.urlType === systemType) { return {data.mlabel}; } return {data.mlabel}; }, [Link, systemType], ); /** 生成纵向导航栏 */ const VerticalMenu = useMemo(() => { const verticalMenuArray: ReactNode[] = []; if (horizontalSelectedUrl !== '/') { verticalNav.forEach((element: any) => { if (element.pmystyle === horizontalSelectedUrl) { if (element.children && element.children.length > 0) { verticalMenuArray.push(
{unicodeToChar(element.micon || '')}
{element.mlabel}
} > {element.children.map((child: any) => { return {checkVerticalMenu(child)}; })}
, ); } else { verticalMenuArray.push(
{unicodeToChar(element.micon || '')}
{checkVerticalMenu(element)}
, ); } } }); } return verticalMenuArray; }, [horizontalSelectedUrl, mode, verticalNav, iconfontClassName, checkVerticalMenu]); /** 用户信息 */ const info = useMemo(() => { let currentInfo = {} as XuiXladminThemeLayoutInfoDataType; const infoStr = localStorage.getItem('info'); if (infoStr) { currentInfo = JSON.parse(infoStr); } return currentInfo; }, []); /** 用户名 */ const userName = useMemo(() => { if (info.userInfo && info.userInfo.realName) { const { userInfo: { realName }, } = info; return realName; } return ''; }, [info]); /** 公司/部门/职位 信息 */ const positionInfo = useMemo<{ positionIds: string[]; positionNames: string[] }>(() => { const { tenancies, rootOrgId, orgId, postId } = info; const positionIds = [rootOrgId, orgId, postId]; const positionNames = [] as string[]; tenancies?.forEach(tenancy => { if (tenancy.tenancyId === rootOrgId) { positionNames.push(tenancy.tenancyName); tenancy.tenancyDetps?.forEach(dept => { if (dept.deptId === orgId) { positionNames?.push(dept.deptKey); dept.postList?.forEach(post => { if (post.postId === postId) { positionNames.push(post.postTitle); } }); } }); } }); return { positionIds, positionNames }; }, [info]); const changeParams = useMemo(() => { const { tenancyInfo: { tenancyId }, } = info; return { tenancyId, }; }, [info]); const onRoleMenuChange = useCallback( (params: { postId?: ReactText; roleId: ReactText; orgId?: ReactText }) => { redirctToLogin({ admType, redirect_url: location.origin, ...params, ...changeParams, }); }, [admType, changeParams], ); const roleMenuData = useMemo(() => { const { postRoleResList = [] } = info; return postRoleResList; }, [info]); useEffect(() => { const hKey = `/${pathname.split('/')[1]}`; /** 锁定横向导航栏高亮 */ onSelectedHorizontalMenuCallback(hKey); // /** 锁定纵向导航栏高亮 */ let highlightIdMapKey = ''; for (let i = 0; i < access.length; i++) { const accessValue = access[i]; if (pathname.includes(accessValue)) { highlightIdMapKey = accessValue; break; } } const highlightIds = highlightIdMap[highlightIdMapKey]; if (highlightIds) { onSelectedSubMenu(highlightIds); onSelectedMenuItem([highlightIds[highlightIds.length - 1]]); } }, [ pathname, accessEqual, highlightIdMap, onSelectedHorizontalMenuCallback, onSelectedSubMenu, onSelectedMenuItem, ]); useEffect(() => { roleDataDiscope({ roleId: info.roleId, aidMap, userName, ...positionInfo, }); }, [userName, roleDataDiscope, info.roleId, aidMapEqual, positionInfo]); useEffect(() => { effectCallback(); }, [effectCallback]); return (
logo
{HorizontalMenu}
{onDownload && (
)}
{userName}
个人设置 个人设置
退出登录 退出登录
} >
{userName}
{VerticalMenu.length > 0 && (
onSelectedMenuItem(e.selectedKeys || [])} className={`${contentClassName}--nav--verticalMenu`} > {VerticalMenu}
{mode === 'vertical' ? (
) : (
)}
)}
{children}
); }; export default XuiThemeLayout;