Kaynağa Gözat

添加菜单左侧图标 增加菜单展开收起功能 增加只展开一个子菜单功能

xueqin 3 yıl önce
ebeveyn
işleme
3c395395c5

+ 26 - 23
src/components/AHeader/index.js

@@ -4,7 +4,7 @@ import { useState, useEffect } from 'react';
 import { useSelector, useDispatch } from 'react-redux';
 import MyMessage from "../MyMessage";
 import { panesNow } from '@reducers/tabPanes.js';
-import { getTimeDetail,getCookie,setCookie } from '@utils/index';
+import { getTimeDetail, getCookie, setCookie } from '@utils/index';
 import logo from '@images/logo.png';
 import msg from '@images/msg.png';
 import me from '@images/me.png';
@@ -12,7 +12,7 @@ import down from '@images/down.png';
 import './index.less'
 import { message } from "antd/lib/index";
 import { add, active } from '@reducers/tabPanes'
-import { setSys, setUser} from '@reducers/userInfo.js';
+import { setSys, setUser } from '@reducers/userInfo.js';
 import apiObj from '@api/index';
 
 const { post, api, xPost } = apiObj;
@@ -24,14 +24,14 @@ const { Header } = Layout;
 
 function AHeader({ history, hideName }) {
     const dispatch = useDispatch();//当前选中的菜单
-    const { panes } = useSelector(state => {
+    const { panes, collapsed } = useSelector(state => {
         return state.tabPanes;
     });
     const [form] = Form.useForm();
     const [dateTime, setDateTime] = useState('');
     const [visible, setVisible] = useState(false);
     //const [socket,setSocket] = useState(null);
-    const [unReadNum,setUnReadNum] = useState(0);
+    const [unReadNum, setUnReadNum] = useState(0);
     const { user, sysName } = useSelector((state) => {
         return state.userInfo;
     });
@@ -48,12 +48,12 @@ function AHeader({ history, hideName }) {
         history.push('/login');
     }
     //获取未读消息数量
-    function getNotNoticeCount(){
+    function getNotNoticeCount() {
         xPost(api.getNotNoticeCount).then((res) => {
             if (res.data.code === 200) {
-                const data = res.data.data||{};
+                const data = res.data.data || {};
                 let count = data.count;
-                count = count>99?'99+':count;
+                count = count > 99 ? '99+' : count;
                 setUnReadNum(count)
                 initWebsocket(count);
                 //dispatch(setUnReadNum(count));
@@ -63,40 +63,40 @@ function AHeader({ history, hideName }) {
         })
     }
     //未读消息页面显示并带入未读筛选条件
-    function showMyMsgPage(){
+    function showMyMsgPage() {
         const pageKey = 'ZNTZ-WDTZ&我的通知';
         const item = panes.find((it) => it.key === pageKey);
         if (item) {   //已存在当前tab,则定位即可不增加
-            dispatch(active({idName:pageKey,isUnRead:true}));
+            dispatch(active({ idName: pageKey, isUnRead: true }));
             return;
         }
         dispatch(
-            add({ title: '我的通知', content: <MyMessage />, key: pageKey,isUnRead:true})
+            add({ title: '我的通知', content: <MyMessage />, key: pageKey, isUnRead: true })
         )
     }
-    async function initWebsocket(num){
+    async function initWebsocket(num) {
         const mqtt = require('mqtt');
-        const client  = mqtt.connect('ws://192.168.2.237:15675/ws');
+        const client = mqtt.connect('ws://192.168.2.237:15675/ws');
         //const userInfo = await getUserHos();
         //const userdata = userInfo.data.data;
         //handleUserInfo(userdata);
         const hisId = getCookie("hospitalId");
         //setSocket(client)
         client.on('connect', function () {
-            client.subscribe(hisId+"-"+user.id, function (err) {
+            client.subscribe(hisId + "-" + user.id, function (err) {
                 if (!err) {
-                    console.log(hisId+"-"+user.id+"订阅成功")
+                    console.log(hisId + "-" + user.id + "订阅成功")
                 }
             })
         })
 
         client.on('message', function (topic, message) {
-            let n = num>unReadNum?num:unReadNum;
-            setUnReadNum(+n+1)
-            console.log('收到消息+1:',message.toString())
+            let n = num > unReadNum ? num : unReadNum;
+            setUnReadNum(+n + 1)
+            console.log('收到消息+1:', message.toString())
         })
     }
-    function handleUserInfo(data){
+    function handleUserInfo(data) {
         const { userInfo, software } = data;
         const sysId = getCookie("systemId");
         const hisId = getCookie("hospitalId");
@@ -108,8 +108,8 @@ function AHeader({ history, hideName }) {
     }
     //获取组织列表
     function getUserHos() {
-        return new Promise((resolve)=>{
-            xPost(api.getUserHospitals).then((res)=>{
+        return new Promise((resolve) => {
+            xPost(api.getUserHospitals).then((res) => {
                 resolve(res);
             });
         });
@@ -160,15 +160,18 @@ function AHeader({ history, hideName }) {
     );
     return (
         <Header className='page-header'>
-            <img className='logo' src={logo} alt="" />
+            {!collapsed ? <img className='logo' src={logo} alt="" /> : <span className='smallname'>朗通</span>
+
+            }
+
             {hideName ? '' : <><span className='break-line'>|</span>
                 <span className='sys-name'>{sysName}</span></>}
             <div className='infos'>
                 <span className='time'>{dateTime}</span>
                 <span className='break-line'>|</span>
                 <div className="unRead-msg-cont" onClick={showMyMsgPage}>
-                    <img className='msg-icon' src={msg} alt="未读消息"/>
-                    {unReadNum?<span className='unRead-msg'>{unReadNum}</span>:''}
+                    <img className='msg-icon' src={msg} alt="未读消息" />
+                    {unReadNum ? <span className='unRead-msg'>{unReadNum}</span> : ''}
                 </div>
                 <div className="user">
                     <Dropdown overlay={menu} trigger={['click']}>

+ 10 - 0
src/components/AHeader/index.less

@@ -4,6 +4,16 @@
 .logo{
   margin: -6px 26px 0 0;
 }
+.smallname{
+  color: #fff;
+  font-size: 16px;
+font-family: PingFangSC-Medium, PingFang SC;
+font-weight: 500;
+color: #FFFFFF;
+margin-left: -25px;
+padding-right: 20px;
+vertical-align: middle;
+}
 .break-line{
   color: #fff;
   margin-right: 18px;

+ 137 - 19
src/components/AMenu/index.js

@@ -1,7 +1,8 @@
-import { Menu, message } from 'antd';
+import { Menu, message, Button } from 'antd';
 import { useState, useEffect } from 'react';
-import { useDispatch, useSelector } from 'react-redux'
+import { useDispatch, useSelector, setstate } from 'react-redux'
 import { add, active } from '@reducers/tabPanes'
+import { toglecollapsed } from '@reducers/tabPanes.js';
 import OrgManager from "../OrgManager";
 import RoleManager from "../RoleManager";
 import UserManager from "../UserManager";
@@ -15,11 +16,59 @@ import ExceptionLog from "../ExceptionLog";
 import MyMessage from "../MyMessage";
 import MsgManage from "../MsgManage";
 import apiObj from '@api/index';
+import './index.less'
+import iconLt from '@images/lt.png';
+import QXGL from '@images/icon-key.png';
+import QXGL1 from '@images/icon-key1.png';
+import XTSZ from '@images/icon-set.png';
+import XTSZ1 from '@images/icon-set1.png';
+import RZGL from '@images/icon-note.png';
+import RZGL1 from '@images/icon-note1.png';
+import ZNTZ from '@images/icon-tip.png';
+import ZNTZ1 from '@images/icon-tip1.png';
+import BAZK from '@images/icon-add.png';
+import BAZK1 from '@images/icon-add1.png';
+
+import { createFromIconfontCN, MenuUnfoldOutlined, MenuFoldOutlined } from '@ant-design/icons';
+// import right from "@images/icon-right.png";
+// import chart from '../../../src/images/icon-chart.png';
+
+// import right from '../../../src/images/icon-right.png';
 
 const { post, api } = apiObj;
 const { SubMenu } = Menu;
 const propTypes = {};
 const defaultProps = {};
+const icon = [{
+    icon: QXGL,
+    icon1: QXGL1,
+    name: 'QXGL',
+},
+{
+    icon: XTSZ,
+    icon1: XTSZ1,
+    name: 'XTSZ',
+},
+{
+    icon: RZGL,
+    icon1: RZGL1,
+    name: 'RZGL',
+},
+{
+    icon: ZNTZ,
+    icon1: ZNTZ1,
+    name: 'ZNTZ',
+},
+{
+    icon: BAZK,
+    icon1: BAZK1,
+    name: 'BAZK',
+},
+]
+const MyIcon = createFromIconfontCN({
+    scriptUrl: '//at.alicdn.com/t/font_2938689_8eruev6ldqw.js', // 在 iconfont.cn 上生成
+    type: 'icon-paobu',
+});
 
 const pageMap = {
     'QXGL-ZZGL': <OrgManager />,
@@ -34,24 +83,30 @@ const pageMap = {
     'ZNTZ-WDTZ': <MyMessage />,
     'ZNTZ-TZGL': <MsgManage />,
 }
+const menuiocn =
+    [{ icon: require('@images/logo.png') }]
+const rootSubmenuKeys = [];
+
 
 let firstMenuPage = {};         //第一个菜单,自动激活时用
 function AMenu() {
     const [menuList, setMenuList] = useState([]);        //菜单列表数据
     const dispatch = useDispatch();
     //当前选中的菜单
-    const { activeTab, panes } = useSelector(state => {
+    const { activeTab, panes, collapsed } = useSelector(state => {
         return state.tabPanes;
     });
-    
-    
+    // const {collapsed}
+
+    // let collapsed = false
     //切换菜单、增加tab
     function changeMenu(val) {
+        console.log('我是切换菜单的val=========', val)
         const idName = val.key.split("&");
         const item = panes.find((it) => it.key === val.key);
         //console.log(item);
         if (item) {   //已存在当前tab,则定位即可不增加
-            dispatch(active({idName:val.key}));
+            dispatch(active({ idName: val.key }));
             return;
         }
         dispatch(
@@ -66,49 +121,94 @@ function AMenu() {
                 const menuData = data.showMenuInfo;
                 setMenuList(menuData);
                 firstMenuPage = findFirstPage(menuData);
-                const {menuName,code}=firstMenuPage;
+                const { menuName, code } = firstMenuPage;
                 dispatch(
-                    add({ title: menuName, content: pageMap[code] || <NullPage />, key: code+"&"+menuName })
+                    add({ title: menuName, content: pageMap[code] || <NullPage />, key: code + "&" + menuName })
                 );
             } else {
                 message.error(res.data.msg || '获取菜单失败');
             }
         })
     }
-    function findFirstPage(menuData){
+    function findFirstPage(menuData) {
         //获取第一个菜单页面,默认选中
-        if(!menuData) return null;
-        let page1=null;
-        menuData.find((it)=>{
-            if(it.menuType==='1'){
-                page1=it;
+        if (!menuData) return null;
+        let page1 = null;
+        menuData.find((it) => {
+            if (it.menuType === '1') {
+                page1 = it;
                 return true;
-            }else if(it.menuType==='0'&&it.children){
-                page1=findFirstPage(it.children);
-                if(page1) return true
+            } else if (it.menuType === '0' && it.children) {
+                page1 = findFirstPage(it.children);
+                if (page1) return true
             }
         });
         return page1;
     }
+
+
+    const rootSubmenuKeys = [] //所有包含子集的一级菜单
+    const [openKeys, setOpenKeys] = useState([]);
+
+    function onOpenChange(keys) {
+        console.log('我是选中的一级标签====', openKeys)
+        const latestOpenKey = keys.find(key => openKeys.indexOf(key) === -1);
+        if (rootSubmenuKeys.indexOf(latestOpenKey) === -1) {
+            setOpenKeys(latestOpenKey ? [latestOpenKey] : []);
+        } else {
+            setOpenKeys(keys);
+        }
+    }
     function getSubMenu(data) {     //menuType=0目录,1页面,2按钮
+
         return data.map((it) => {
+            var iconitem
+            var openkey
+            if (it.menuType == 0) {
+                let item = it.code + it.menuName
+                rootSubmenuKeys.push(item)
+            }
+
+            icon.find((value) => {
+                let checked
+                if (it.code == value.name) {
+
+                    console.log('我是activetab=====', activeTab)
+                    if (activeTab.indexOf(it.code) === -1) {
+                        checked = true
+                        iconitem = value.icon
+                    } else {
+                        checked = false
+                        iconitem = value.icon1
+                    }
+
+
+                }
+
+            })
             if (it.menuType === '1') {
                 return (
-                    <Menu.Item key={it.code+"&"+it.menuName}>{it.menuName}</Menu.Item>
+                    <Menu.Item key={it.code + "&" + it.menuName} icon={<img src={iconitem} />}>{it.menuName}</Menu.Item>
+
                 )
             } else if (it.menuType === '0') {
                 return (
-                    <SubMenu key={it.code+"&"+it.menuName} title={it.menuName}>
+                    <SubMenu key={it.code + "&" + it.menuName} title={it.menuName} icon={<img src={iconitem} />}>
                         {it.children ? getSubMenu(it.children) : ''}
                     </SubMenu>
+
                 )
             } else {
                 return ''
             }
         })
     }
+    function toggleCollapsed() {
+        dispatch(toglecollapsed([]))
+    }
     useEffect(() => {
         getUserMenus();
+
         /*const timeO = setTimeout(() => {
             dispatch(
                 add({ title: firstMenuPage.menuName, content: pageMap[firstMenuPage.menuName] || <NullPage />, key: firstMenuPage.code })
@@ -119,18 +219,36 @@ function AMenu() {
         }*/
 
     }, []);
+
     return (
+        <div className='menu'>
+
             <Menu
                 /*defaultSelectedKeys={[menuList[0].menuName]}
                 defaultOpenKeys={[menuList[0].menuId]}*/
                 selectedKeys={activeTab}
                 mode="inline"
                 onClick={changeMenu}
+                openKeys={openKeys}
+                onOpenChange={onOpenChange}
             >
                 {
                     getSubMenu(menuList)
                 }
+
             </Menu>
+            <div className='pstcollaps'>
+                <div className='collaps'> {collapsed ? <MenuUnfoldOutlined className='trigger'
+                    onClick={toggleCollapsed}></MenuUnfoldOutlined> : <MenuFoldOutlined className='trigger'
+                        onClick={toggleCollapsed}></MenuFoldOutlined>}</div>
+                {
+                    !collapsed ? <div className='compomentname'> ©杭州朗通信息技术有限公司 </div> : <div className='compomentname' />
+                }
+
+            </div>
+
+
+        </div>
     )
 }
 AMenu.propTypes = propTypes;

+ 49 - 0
src/components/AMenu/index.less

@@ -0,0 +1,49 @@
+// @import '~antd/dist/antd.less';
+// @import "../../common/common.less";
+
+.page-sider{
+    .ant-layout-sider-children{
+        position: relative;
+        .menu{
+      
+        .test{
+           
+        }
+       
+        
+        }
+        .pstcollaps{
+            width: 100%;
+            position: absolute;
+            bottom: 16px;
+            left: 0px;
+            .trigger{
+                padding-left: 24px;
+                color: #1890ff!important;
+                text-align: center;
+                svg{
+                    width: 24px!important;
+                    height: 17px!important;
+                }
+            }
+            .trigger:hover {
+                color: #1890ff!important;
+              }
+              .compomentname{
+                width: 100%;
+                height: 17px;
+                font-size: 12px;
+                font-family: PingFangSC-Regular, PingFang SC;
+                font-weight: 400;
+                color: #333333!important;
+                line-height: 17px;
+                text-align: center;
+                // padding: 16px 0px;
+              }
+        }
+        }
+}
+
+
+
+  

+ 22 - 11
src/components/PageLayout/index.js

@@ -1,24 +1,33 @@
-import {useEffect,useState} from 'react';
-import { useDispatch,useSelector } from 'react-redux'
+import { useEffect, useState } from 'react';
+import { useDispatch, useSelector } from 'react-redux'
 import { Layout } from 'antd';
 import AHeader from '../AHeader'
 import AMenu from '../AMenu'
 import ATabs from '../ATabs'
 import apiObj from '@api/index';
-import { setStatusList, setHisTypeList, setTitleList, setDataList,setMsgTypeList, setMsgStatusList} from '@reducers/staticInfo';
+import { setStatusList, setHisTypeList, setTitleList, setDataList, setMsgTypeList, setMsgStatusList } from '@reducers/staticInfo';
 
-const {  Content, Sider } = Layout;
-const {post,api,xPost} = apiObj;
+const { Content, Sider } = Layout;
+const { post, api, xPost } = apiObj;
 const propTypes = {
 
 }
 const defaultProps = {};
 
-function PageLayout(){
+//当前选中的菜单
+// const {  collapsed } = useSelector(state => {
+//     return state.collapsed;
+// });
+function PageLayout() {
     const dispatch = useDispatch();
-    const staticInfo =useSelector(state => {
+    const staticInfo = useSelector(state => {
         return state.staticInfo;
     });
+    const collapsed = useSelector(state => {
+        // 刚才打印的状态变了  但是显示隐藏没变   那么大概率就是这里的有问题被  打印一下 这里确实undefined
+        console.log(123123123, state.tabPanes.collapsed)
+        return state.tabPanes.collapsed;
+    });
     function getStaticInfos() {
         const { hisTypeList, statusList, titleList, dataList } = staticInfo;
         // if ([...hisTypeList, ...statusList, ...titleList, ...dataList].length > 0) {
@@ -27,7 +36,7 @@ function PageLayout(){
         post(api.getManagerBoxInfo).then((res) => {
             if (res.data.code === 200) {
                 const data = res.data.data;
-                dispatch(setHisTypeList(data[43]||data[45]));       //非单家医院为医院类型43,单家医院为病区45
+                dispatch(setHisTypeList(data[43] || data[45]));       //非单家医院为医院类型43,单家医院为病区45
                 dispatch(setStatusList(data[47]));
                 dispatch(setTitleList(data[40]));
                 dispatch(setDataList(data[48]));
@@ -36,15 +45,17 @@ function PageLayout(){
             }
         })
     }
-    useEffect(()=>{
+    useEffect(() => {
         getStaticInfos()
-    },[]);
+    }, []);
     return (
         <Layout>
             <AHeader></AHeader>
             <Layout>
-                <Sider className='page-sider'>
+                <Sider className='page-sider' trigger={null} collapsible collapsed={collapsed}>
                     <AMenu></AMenu>
+                {/* {collapsed}
+                    杭州朗通信息技术公司 */}
                 </Sider>
                 <Content className='page-content'>
                     <ATabs></ATabs>

BIN
src/images/case_menu.png


BIN
src/images/case_menu1.png


BIN
src/images/chart_menu.png


BIN
src/images/chart_menu1.png


BIN
src/images/control_menu.png


BIN
src/images/control_menu1.png


BIN
src/images/examine_menu.png


BIN
src/images/examine_menu1.png


BIN
src/images/home_menu.png


BIN
src/images/home_menu1.png


BIN
src/images/limit_menu.png


BIN
src/images/limit_menu1.png


BIN
src/images/new_menu.png


BIN
src/images/new_menu1.png


BIN
src/images/notebook_menu.png


BIN
src/images/notebook_menu1.png


BIN
src/images/setting_menu.png


BIN
src/images/setting_menu1.png


BIN
src/images/table_menu.png


BIN
src/images/table_menu1.png


+ 7 - 2
src/store/reducers/tabPanes.js

@@ -5,7 +5,9 @@ export const slice = createSlice({
     initialState: {
         activeTab: '',
         panes:[],
-        toUnRead:false
+        toUnRead:false,
+        collapsed:false,
+        
     },
     reducers: {
         close: (state,action) => {        //关闭tab
@@ -32,9 +34,12 @@ export const slice = createSlice({
         panesNow: (state, action) => {       //切换tab
             state.panes = [];
         },
+        toglecollapsed: (state,action) => {
+            state.collapsed = !state.collapsed
+        }
     },
 });
 
-export const { close, closeOther, active, add, panesNow } = slice.actions;
+export const { close, closeOther, active, add, panesNow, toglecollapsed } = slice.actions;
 
 export default slice.reducer;