|
|
import React, { useState, useEffect } from 'react'
|
|
|
import { history, Outlet, useLocation, matchRoutes, useModel } from '@umijs/max'
|
|
|
import { Menu, Tabs, Select } from 'antd'
|
|
|
import './SystemContentList.less'
|
|
|
import { formatRoute, getDefaultRoute } from '@/utils/routeUtils'
|
|
|
import styles from './TopNavBar.less'
|
|
|
import { Row, Col, Avatar, Dropdown, Button } from 'antd'
|
|
|
import { userInfo } from '@/utils/globalCommon'
|
|
|
import { HomeOutlined, LogoutOutlined, AppstoreOutlined, UserOutlined, SettingOutlined, DatabaseOutlined, FileTextOutlined, LockOutlined, AreaChartOutlined, CaretDownOutlined, BellOutlined, SearchOutlined, QuestionCircleOutlined } from '@ant-design/icons'
|
|
|
import { getPageQuery } from '@/utils/utils'
|
|
|
import menuTitle from '@/assets/img/智能管控平台.svg'
|
|
|
import menuTitle1 from '@/assets/img/智能管控平台-1.svg'
|
|
|
import fireHydrant from '@/assets/img/fireHydrant.svg'
|
|
|
import fireHydrant1 from '@/assets/img/fireHydrant1.svg'
|
|
|
import menuicon1 from '@/assets/img/menuicon1.svg'
|
|
|
import menuicon2 from '@/assets/img/menuicon2.svg'
|
|
|
import menuicon3 from '@/assets/img/menuicon1.svg'
|
|
|
import menuicon4 from '@/assets/img/menuicon1.svg'
|
|
|
|
|
|
import book from '@/assets/img/book.svg'
|
|
|
import danger from '@/assets/img/danger.svg'
|
|
|
import danger1 from '@/assets/img/danger1.svg'
|
|
|
import license from '@/assets/img/license.svg'
|
|
|
import people from '@/assets/img/people.svg'
|
|
|
import risk from '@/assets/img/risk.svg'
|
|
|
import { CustomBreadcrumb } from '@/components/GlobalComponent'
|
|
|
|
|
|
|
|
|
// 自定义菜单项渲染组件,支持根据激活状态显示不同图片
|
|
|
const CustomMenuItem = ({ item, selectedKeys }) => {
|
|
|
const isActive = selectedKeys.includes(item.key);
|
|
|
|
|
|
// 为每个菜单项定义激活状态的图片
|
|
|
// 如果没有专门的激活状态图片,则使用默认图片
|
|
|
const getActiveIcon = (baseIcon) => {
|
|
|
// 这里可以根据需要为每个图标定义对应的激活状态图片
|
|
|
// 目前暂时使用相同的图片,用户可以根据实际情况替换
|
|
|
return baseIcon;
|
|
|
};
|
|
|
|
|
|
const renderIcon = () => {
|
|
|
if (item.icon && typeof item.icon === 'object' && item.icon.props && item.icon.props.src) {
|
|
|
const iconSrc = isActive ? getActiveIcon(item.icon.props.src) : item.icon.props.src;
|
|
|
|
|
|
const baseStyle = item.icon.props.style || { width: '16px', height: '16px' };
|
|
|
|
|
|
const dynamicStyle = {
|
|
|
...baseStyle,
|
|
|
opacity: isActive ? 1 : 0.6
|
|
|
};
|
|
|
|
|
|
return <img
|
|
|
src={iconSrc}
|
|
|
alt={item.icon.props.alt || 'menu icon'}
|
|
|
style={dynamicStyle}
|
|
|
/>
|
|
|
}
|
|
|
return item.icon;
|
|
|
};
|
|
|
|
|
|
const renderMenuItem = (menuItem) => ({
|
|
|
...menuItem,
|
|
|
icon: renderIcon(),
|
|
|
children: menuItem.children?.map(child => renderMenuItem(child))
|
|
|
});
|
|
|
|
|
|
return renderMenuItem(item);
|
|
|
};
|
|
|
|
|
|
const SystemContentList = (props) => {
|
|
|
const dynamicRoute = window.dynamicRoute
|
|
|
console.log(dynamicRoute)
|
|
|
const location = useLocation()
|
|
|
const pathName = location.pathname
|
|
|
const [openKey, setOpenKey] = useState([])
|
|
|
const [selectedKey, setSelectedKey] = useState([])
|
|
|
const [menuItems, setMenuItems] = useState([])
|
|
|
const [systemType, setSystemType] = useState('应急管理系统')
|
|
|
const [isMenuCollapsed, setIsMenuCollapsed] = useState(false); // 添加菜单收缩状态
|
|
|
let defaultKey = ''
|
|
|
|
|
|
useEffect(() => {
|
|
|
console.log('dynamicRoute structure:', dynamicRoute)
|
|
|
if (!dynamicRoute || dynamicRoute?.length === 0) return
|
|
|
let newList = []
|
|
|
let routes = []
|
|
|
|
|
|
if (dynamicRoute?.length) {
|
|
|
let tempRoute = dynamicRoute?.filter(item => pathName.indexOf(item.key) !== -1) ?? []
|
|
|
|
|
|
newList = formatRoute(tempRoute[0]?.children)
|
|
|
routes = formatRoute(tempRoute[0]?.children, true)
|
|
|
defaultKey = getDefaultRoute(routes)
|
|
|
const mathRoute = matchRoutes(routes, pathName)
|
|
|
|
|
|
setRouteActive({ key: mathRoute?.length ? pathName : defaultKey }, routes)
|
|
|
}
|
|
|
|
|
|
setMenuItems(newList)
|
|
|
|
|
|
const fixedMenuItems = [
|
|
|
{
|
|
|
"path": "/topnavbar00/business/emergencyResource",
|
|
|
icon: <img src={menuicon1} alt="应急资源管理" style={{ width: '16px', height: '16px' }} />,
|
|
|
"key": "/topnavbar00/business/emergencyResource",
|
|
|
"label": "应急资源管理"
|
|
|
},
|
|
|
// 应急预案管理
|
|
|
{
|
|
|
"path": "/topnavbar00/business/emergencyPlan",
|
|
|
icon: <img src={menuicon2} alt="应急预案管理" style={{ width: '16px', height: '16px' }} />,
|
|
|
"key": "/topnavbar00/business/emergencyPlan",
|
|
|
"label": "应急预案管理"
|
|
|
},
|
|
|
// 应急演练管理
|
|
|
{
|
|
|
"path": "/topnavbar00/business/emergencyDrill",
|
|
|
icon: <img src={menuicon3} alt="应急演练管理" style={{ width: '16px', height: '16px' }} />,
|
|
|
"key": "/topnavbar00/business/emergencyDrill",
|
|
|
"label": "应急演练管理"
|
|
|
},
|
|
|
// 应急值班管理
|
|
|
{
|
|
|
"path": "/topnavbar00/business/emergencyDuty",
|
|
|
icon: <img src={menuicon4} alt="应急值班管理" style={{ width: '16px', height: '16px' }} />,
|
|
|
"key": "/topnavbar00/business/emergencyDuty",
|
|
|
"label": "应急值班管理"
|
|
|
},
|
|
|
// 事故接警单
|
|
|
{
|
|
|
"path": "/topnavbar00/business/emergencyAccident",
|
|
|
icon: <img src={menuicon1} alt="事故接警单" style={{ width: '16px', height: '16px' }} />,
|
|
|
"key": "/topnavbar00/business/emergencyAccident",
|
|
|
"label": "事故接警单"
|
|
|
},
|
|
|
]
|
|
|
setMenuItems(fixedMenuItems)
|
|
|
// 初始化默认路由
|
|
|
const defaultRoute = fixedMenuItems[0]?.key || ''
|
|
|
const mathRoute = matchRoutes(fixedMenuItems, pathName)
|
|
|
setRouteActive({ key: mathRoute?.length ? pathName : defaultRoute }, fixedMenuItems)
|
|
|
}, [pathName])
|
|
|
|
|
|
const setRouteActive = (value, menu) => {
|
|
|
const curKey = value.key
|
|
|
const tempMenu = menu ?? menuItems ?? []
|
|
|
const mathRoute = matchRoutes(tempMenu, curKey)
|
|
|
let openKeys = []
|
|
|
let selectedKeys = []
|
|
|
|
|
|
mathRoute?.map((item, index) => {
|
|
|
mathRoute?.length !== index + 1 && (openKeys = [...openKeys, item.pathname])
|
|
|
mathRoute?.length === index + 1 && (selectedKeys = [...selectedKeys, item.pathname])
|
|
|
})
|
|
|
|
|
|
setOpenKey(openKeys)
|
|
|
setSelectedKey(selectedKeys)
|
|
|
history.replace(curKey)
|
|
|
}
|
|
|
|
|
|
// 切换菜单收缩状态
|
|
|
const toggleMenu = () => {
|
|
|
setIsMenuCollapsed(!isMenuCollapsed);
|
|
|
};
|
|
|
|
|
|
const { initialState: { menu }, setInitialState } = useModel('@@initialState')
|
|
|
|
|
|
const loginOut = async () => {
|
|
|
// await outLogin()
|
|
|
const { redirect } = getPageQuery()
|
|
|
|
|
|
if (window.location.pathname !== '/login/login' && !redirect) {
|
|
|
history.replace({
|
|
|
pathname: '/login',
|
|
|
// search: stringify({
|
|
|
// redirect: window.location.href,
|
|
|
// }),
|
|
|
})
|
|
|
|
|
|
setInitialState({ currentUser: null, menu: null, menuMap: null })
|
|
|
window.dynamicRoute = null
|
|
|
localStorage.clear()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
const handleMenuClick = (e) => {
|
|
|
switch (e.key) {
|
|
|
case 'logout':
|
|
|
loginOut()
|
|
|
break
|
|
|
default:
|
|
|
break
|
|
|
}
|
|
|
}
|
|
|
|
|
|
const dropDownMenuItems = [
|
|
|
{
|
|
|
label: <><LogoutOutlined style={{ marginRight: '8px' }} />退出登录</>,
|
|
|
key: 'logout'
|
|
|
}
|
|
|
]
|
|
|
|
|
|
const dropDownMenu = () => (
|
|
|
<Menu items={dropDownMenuItems} onClick={handleMenuClick} selectedKeys={[]} className={styles.tabBarMenu} />
|
|
|
)
|
|
|
|
|
|
return (
|
|
|
<div className='pageContainer systemContent'>
|
|
|
<div
|
|
|
className='leftMenu'
|
|
|
style={{
|
|
|
width: isMenuCollapsed ? '80px' : '230px',
|
|
|
transition: 'width 0.3s ease',
|
|
|
position: 'relative', // 添加相对定位,使按钮可以相对于菜单定位
|
|
|
overflow: 'unset'
|
|
|
}}
|
|
|
>
|
|
|
<div className='menuTitle' style={{
|
|
|
marginBottom: '10px',
|
|
|
display: isMenuCollapsed ? 'none' : 'flex'
|
|
|
}}>
|
|
|
<img src={menuTitle} alt='menuTitle' style={{ marginTop: '20px', marginBottom: '2px', width: '172.44px', height: '51.28px' }} />
|
|
|
<img src={menuTitle1} alt='menuTitle1' style={{ width: '172.44px', height: '51.28px' }} />
|
|
|
</div>
|
|
|
<div style={{
|
|
|
textAlign: 'center',
|
|
|
marginBottom: 16,
|
|
|
borderRadius: "10px !important",
|
|
|
display: isMenuCollapsed ? 'none' : 'block'
|
|
|
}}>
|
|
|
<Select
|
|
|
value={systemType}
|
|
|
onChange={setSystemType}
|
|
|
style={{
|
|
|
width: 192,
|
|
|
height: 42
|
|
|
}}
|
|
|
options={[
|
|
|
{ value: '安全管理系统', label: '安全管理系统' },
|
|
|
{ value: '环保管理系统', label: '环保管理系统' },
|
|
|
{ value: '消防管理系统', label: '消防管理系统' },
|
|
|
{ value: '智能巡检系统', label: '智能巡检系统' },
|
|
|
{ value: '应急管理系统', label: '应急管理系统' }
|
|
|
]}
|
|
|
dropdownStyle={{
|
|
|
backgroundColor: '#003AA7',
|
|
|
borderColor: '#3D81FF'
|
|
|
}}
|
|
|
popupClassName="custom-select-dropdown"
|
|
|
className="custom-select"
|
|
|
suffixIcon={<CaretDownOutlined style={{ color: '#fff', fontSize: '16px' }} />}
|
|
|
/>
|
|
|
</div>
|
|
|
<style jsx>{`
|
|
|
.custom-select .ant-select-selector {
|
|
|
height: 42px !important;
|
|
|
border-radius: 8px !important;
|
|
|
border-color: #3D81FF !important;
|
|
|
background-color: #003AA7 !important;
|
|
|
color: #fff !important;
|
|
|
fontSize: 22px !important;
|
|
|
fontWeight: 600 !important;
|
|
|
}
|
|
|
.custom-select .ant-select-selection-item {
|
|
|
color: #fff !important;
|
|
|
fontSize: 22px !important;
|
|
|
fontWeight: 600 !important;
|
|
|
display: flex !important;
|
|
|
align-items: center !important;
|
|
|
justify-content: center !important;
|
|
|
padding: 0 !important;
|
|
|
padding-right: 50px !important;
|
|
|
font-size: 16px !important;
|
|
|
font-weight: 500 !important;
|
|
|
}
|
|
|
.custom-select .ant-select-arrow {
|
|
|
opacity: 0.66 !important;
|
|
|
color: #fff !important;
|
|
|
}
|
|
|
.custom-select-dropdown .ant-select-item-option-selected {
|
|
|
background-color: #3D81FF !important;
|
|
|
color: #fff !important;
|
|
|
}
|
|
|
.custom-select-dropdown .ant-select-item-option-active:not(.ant-select-item-option-selected) {
|
|
|
background-color: rgba(61, 129, 255, 0.1) !important;
|
|
|
color: #fff !important;
|
|
|
}
|
|
|
.custom-select-dropdown .ant-select-item-option-content {
|
|
|
color: #fff !important;
|
|
|
font-size: 16px !important;
|
|
|
font-weight: 600 !important;
|
|
|
}
|
|
|
.menuToggleBtn {
|
|
|
position: absolute;
|
|
|
right: -15px;
|
|
|
top: 50%;
|
|
|
width: 30px;
|
|
|
height: 30px;
|
|
|
background: #FDFDFF;
|
|
|
color: #5C5C5C;
|
|
|
border: 1px solid #FFFFFF;
|
|
|
border-radius: 50%;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
cursor: pointer;
|
|
|
z-index: 9999; /* 增加z-index确保按钮在最上层 */
|
|
|
font-size: 16px;
|
|
|
font-weight: bold;
|
|
|
outline: none;
|
|
|
transition: all 0.3s ease;
|
|
|
box-shadow: 0 0 5px 3px rgba(169, 185, 255, 0.33);
|
|
|
}
|
|
|
.menuToggleBtn:hover {
|
|
|
border: 1px solid #3D81FF;
|
|
|
background: #3D81FF;
|
|
|
color: white;
|
|
|
transform: scale(1.1);
|
|
|
}
|
|
|
`}</style>
|
|
|
{/* 菜单收缩按钮 */}
|
|
|
<button
|
|
|
className="menuToggleBtn"
|
|
|
onClick={toggleMenu}
|
|
|
aria-label={isMenuCollapsed ? "展开菜单" : "收缩菜单"}
|
|
|
>
|
|
|
{isMenuCollapsed ? ">" : "<"}
|
|
|
</button>
|
|
|
|
|
|
<Menu
|
|
|
openKeys={openKey}
|
|
|
selectedKeys={selectedKey}
|
|
|
// 使用自定义的itemRender方法处理激活状态的图标切换
|
|
|
items={menuItems.map(item => {
|
|
|
const isActive = selectedKey.includes(item.key);
|
|
|
|
|
|
// 处理当前项的图标
|
|
|
let icon = item.icon;
|
|
|
if (icon && typeof icon === 'object' && icon.props && icon.props.src) {
|
|
|
let iconSrc = icon.props.src;
|
|
|
|
|
|
// 根据激活状态切换不同的图片
|
|
|
if (isActive) {
|
|
|
// 工时仪表盘:激活态使用fireHydrant1
|
|
|
if (item.key === '/topnavbar00/business/timesheet' && typeof fireHydrant !== 'undefined') {
|
|
|
iconSrc = fireHydrant;
|
|
|
}
|
|
|
// 隐患排查:激活态使用danger1
|
|
|
else if (item.key === '/topnavbar00/business/hiddentrouble' && typeof danger1 !== 'undefined') {
|
|
|
iconSrc = danger1;
|
|
|
}
|
|
|
// 激活态使用danger1
|
|
|
else if (item.key === '/topnavbar00/business/staffsheet' && typeof danger1 !== 'undefined') {
|
|
|
iconSrc = danger1;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
const baseStyle = icon.props.style || { width: '16px', height: '16px' };
|
|
|
const dynamicStyle = {
|
|
|
...baseStyle,
|
|
|
opacity: isActive ? 1 : 0.6
|
|
|
};
|
|
|
|
|
|
icon = <img
|
|
|
src={iconSrc}
|
|
|
alt={icon.props.alt}
|
|
|
style={dynamicStyle}
|
|
|
/>;
|
|
|
}
|
|
|
|
|
|
// 递归处理子项
|
|
|
const children = item.children?.map(child => {
|
|
|
const childIsActive = selectedKey.includes(child.key);
|
|
|
return { ...child };
|
|
|
});
|
|
|
|
|
|
return {
|
|
|
...item,
|
|
|
icon,
|
|
|
children,
|
|
|
// 根据菜单收缩状态决定是否显示标签文本
|
|
|
label: isMenuCollapsed ? null : item.label
|
|
|
};
|
|
|
})}
|
|
|
onClick={value => setRouteActive(value)}
|
|
|
onOpenChange={value => setOpenKey(value)}
|
|
|
mode={isMenuCollapsed ? 'vertical' : 'inline'}
|
|
|
/>
|
|
|
</div>
|
|
|
|
|
|
<div
|
|
|
className='rightContent'
|
|
|
style={{
|
|
|
width: isMenuCollapsed ? 'calc(100% - 80px)' : 'calc(100% - 230px)',
|
|
|
transition: 'width 0.3s ease'
|
|
|
}}
|
|
|
>
|
|
|
{/* <div style={{ width: '100%', backgroundColor: '#fff', marginBottom: '10px' }}> */}
|
|
|
<div className='tabBarHeader'>
|
|
|
<Row className='tabBarRow'>
|
|
|
{/* <Col xs={16} sm={16} md={16} lg={16} xl={16} className='tabBarLeft'>
|
|
|
<img src={Logo} alt='logo' className='leftLogo' />
|
|
|
|
|
|
<Menu mode='horizontal' className='leftMenu' selectedKeys={[activeKey]} items={menuItems} onClick={value => setRouteActive(value)} />
|
|
|
</Col> */}
|
|
|
|
|
|
<Col xs={20} sm={20} md={20} lg={20} xl={20} className='tabBarLeft'>
|
|
|
<CustomBreadcrumb />
|
|
|
</Col>
|
|
|
<Col xs={4} sm={4} md={4} lg={4} xl={4} className='tabBarRight'>
|
|
|
<Button type='text' className='tabBarRightBtn'><BellOutlined /></Button>
|
|
|
<Button type='text' className='tabBarRightBtn'><SearchOutlined /></Button>
|
|
|
<Button type='text' className='tabBarRightBtn'><QuestionCircleOutlined /></Button>
|
|
|
<Avatar className='tabBarRightAvaTor' src='https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201707%2F31%2F20170731021444_2YUfe.jpeg&refer=http%3A%2F%2Fb-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1669779871&t=ec025ed48a1668dee9cfa0e803b6f787' />
|
|
|
|
|
|
<span className='tabBarRightName'>{userInfo?.user_name_cn ? userInfo.user_name_cn : (userInfo?.user_name || '')}</span>
|
|
|
|
|
|
<Dropdown dropdownRender={dropDownMenu}>
|
|
|
<Button type='text' className='tabBarRightBtn'><SettingOutlined /></Button>
|
|
|
</Dropdown>
|
|
|
</Col>
|
|
|
</Row>
|
|
|
</div>
|
|
|
{/* </div> */}
|
|
|
<div style={{ padding: '12px', height: '100%' }}>
|
|
|
<div className='rightContentMain'>
|
|
|
<Outlet />
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
</div>
|
|
|
)
|
|
|
}
|
|
|
|
|
|
export default SystemContentList
|
|
|
|
|
|
|