kn-cli 1.0.44 → 1.0.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/package.json +2 -1
  2. package/readme.md +6 -0
  3. package/src/utils/index.js +1 -1
  4. package/templates/template_admin/.gitignore +6 -0
  5. package/templates/template_admin/build.sh +2 -0
  6. package/templates/template_admin/cli.config.js +21 -0
  7. package/templates/template_admin/dev.sh +89 -0
  8. package/templates/template_admin/frontend_build.sh +83 -0
  9. package/templates/template_admin/init/prepare-commit-msg +5 -0
  10. package/templates/template_admin/init.sh +33 -0
  11. package/templates/template_admin/jsconfig.json +10 -0
  12. package/templates/template_admin/package.json +23 -0
  13. package/templates/template_admin/public/404.html +26 -0
  14. package/templates/template_admin/public/favicon.ico +0 -0
  15. package/templates/template_admin/public/favicon.png +0 -0
  16. package/templates/template_admin/public/index.html +43 -0
  17. package/templates/template_admin/public/src/_antd.less +4 -0
  18. package/templates/template_admin/public/src/_reset.less +128 -0
  19. package/templates/template_admin/public/src/_variable.less +80 -0
  20. package/templates/template_admin/public/src/assets/iconfont/iconfont.eot +0 -0
  21. package/templates/template_admin/public/src/assets/iconfont/iconfont.less +57 -0
  22. package/templates/template_admin/public/src/assets/iconfont/iconfont.svg +36 -0
  23. package/templates/template_admin/public/src/assets/iconfont/iconfont.ttf +0 -0
  24. package/templates/template_admin/public/src/assets/iconfont/iconfont.woff +0 -0
  25. package/templates/template_admin/public/src/assets/iconfont/iconfont.woff2 +0 -0
  26. package/templates/template_admin/public/src/assets/images/avatar.png +0 -0
  27. package/templates/template_admin/public/src/assets/images/loading.svg +40 -0
  28. package/templates/template_admin/public/src/components/Alert/index.jsx +0 -0
  29. package/templates/template_admin/public/src/components/Alert/index.less +0 -0
  30. package/templates/template_admin/public/src/components/Auth/index.jsx +44 -0
  31. package/templates/template_admin/public/src/components/Header/index.jsx +57 -0
  32. package/templates/template_admin/public/src/components/Header/index.less +57 -0
  33. package/templates/template_admin/public/src/components/IconFont/index.jsx +10 -0
  34. package/templates/template_admin/public/src/components/IconFont/index.less +5 -0
  35. package/templates/template_admin/public/src/components/Layout/Basic/index.jsx +26 -0
  36. package/templates/template_admin/public/src/components/Layout/Basic/index.less +37 -0
  37. package/templates/template_admin/public/src/components/Layout/CenterBody/index.jsx +15 -0
  38. package/templates/template_admin/public/src/components/Layout/CenterBody/index.less +30 -0
  39. package/templates/template_admin/public/src/components/Layout/Provider/index.jsx +12 -0
  40. package/templates/template_admin/public/src/components/Layout/index.jsx +27 -0
  41. package/templates/template_admin/public/src/components/Layout/index.less +63 -0
  42. package/templates/template_admin/public/src/components/Link/index.jsx +24 -0
  43. package/templates/template_admin/public/src/components/Link/index.less +11 -0
  44. package/templates/template_admin/public/src/components/Loading/index.jsx +14 -0
  45. package/templates/template_admin/public/src/components/Loading/index.less +85 -0
  46. package/templates/template_admin/public/src/components/Menu/index.jsx +126 -0
  47. package/templates/template_admin/public/src/components/Menu/index.less +19 -0
  48. package/templates/template_admin/public/src/components/Page/PageLoading/index.jsx +30 -0
  49. package/templates/template_admin/public/src/components/Page/PageLoading/index.less +29 -0
  50. package/templates/template_admin/public/src/components/Popup/index.jsx +22 -0
  51. package/templates/template_admin/public/src/components/Popup/index.less +18 -0
  52. package/templates/template_admin/public/src/components/Toast/index.jsx +60 -0
  53. package/templates/template_admin/public/src/components/Toast/index.less +43 -0
  54. package/templates/template_admin/public/src/components/TopMenu/index.jsx +228 -0
  55. package/templates/template_admin/public/src/components/TopMenu/index.less +105 -0
  56. package/templates/template_admin/public/src/components/mask/index.jsx +47 -0
  57. package/templates/template_admin/public/src/components/mask/index.less +32 -0
  58. package/templates/template_admin/public/src/dictionary/index.js +103 -0
  59. package/templates/template_admin/public/src/hooks/index.jsx +18 -0
  60. package/templates/template_admin/public/src/hooks/useDelay.jsx +29 -0
  61. package/templates/template_admin/public/src/hooks/useImageLoader.jsx +27 -0
  62. package/templates/template_admin/public/src/hooks/useLoading.jsx +42 -0
  63. package/templates/template_admin/public/src/hooks/useLogin.jsx +33 -0
  64. package/templates/template_admin/public/src/hooks/useNextPage.jsx +89 -0
  65. package/templates/template_admin/public/src/hooks/usePreload.jsx +66 -0
  66. package/templates/template_admin/public/src/hooks/useScrollTop.jsx +32 -0
  67. package/templates/template_admin/public/src/hooks/useSearch.jsx +137 -0
  68. package/templates/template_admin/public/src/hooks/useUpdate.jsx +11 -0
  69. package/templates/template_admin/public/src/index.jsx +50 -0
  70. package/templates/template_admin/public/src/mock/auth.js +91 -0
  71. package/templates/template_admin/public/src/mock/index.js +63 -0
  72. package/templates/template_admin/public/src/mock/user.js +70 -0
  73. package/templates/template_admin/public/src/mock/utils.js +33 -0
  74. package/templates/template_admin/public/src/pages/checkLogin/index.jsx +13 -0
  75. package/templates/template_admin/public/src/pages/index.jsx +23 -0
  76. package/templates/template_admin/public/src/pages/index.less +22 -0
  77. package/templates/template_admin/public/src/pages/login/index.jsx +27 -0
  78. package/templates/template_admin/public/src/pages/login/index.less +44 -0
  79. package/templates/template_admin/public/src/pages/material/index.jsx +12 -0
  80. package/templates/template_admin/public/src/pages/order/index.jsx +12 -0
  81. package/templates/template_admin/public/src/pages/permission/index.jsx +12 -0
  82. package/templates/template_admin/public/src/pages/subHome/index.jsx +12 -0
  83. package/templates/template_admin/public/src/pages/subHome2/index.jsx +12 -0
  84. package/templates/template_admin/public/src/pages/subHome3/index.jsx +12 -0
  85. package/templates/template_admin/public/src/pages/suggest/index.jsx +12 -0
  86. package/templates/template_admin/public/src/pages/superAdminLogin/index.jsx +57 -0
  87. package/templates/template_admin/public/src/pages/superAdminLogin/index.less +44 -0
  88. package/templates/template_admin/public/src/pages/user/index.jsx +13 -0
  89. package/templates/template_admin/public/src/pages/userData/index.jsx +12 -0
  90. package/templates/template_admin/public/src/pages/video/index.jsx +12 -0
  91. package/templates/template_admin/public/src/provider/app.jsx +119 -0
  92. package/templates/template_admin/public/src/provider/menu.jsx +20 -0
  93. package/templates/template_admin/public/src/route.jsx +77 -0
  94. package/templates/template_admin/public/src/services/auth.js +28 -0
  95. package/templates/template_admin/public/src/services/index.js +181 -0
  96. package/templates/template_admin/public/src/services/user.js +26 -0
  97. package/templates/template_admin/public/src/utils/index.js +38 -0
  98. package/templates/template_admin/public/static/about.html +1 -0
  99. package/templates/template_admin/public/static/kssoLogin.html +22 -0
  100. package/templates/template_admin/readme.md +55 -0
  101. package/templates/template_admin/report.sh +68 -0
  102. package/templates/template_admin/tools/iconfont/gulpfile.js +70 -0
  103. package/templates/template_admin/tools/iconfont/package.json +20 -0
  104. package/templates/template_admin/tools/iconfont/run.sh +39 -0
  105. package/templates/template_admin/tools/iconfont/svg/arrowBack.svg +1 -0
  106. package/templates/template_admin/tools/iconfont/svg/check.svg +1 -0
  107. package/templates/template_admin/tools/iconfont/svg/close.svg +1 -0
  108. package/templates/template_admin/tools/iconfont/svg/down.svg +1 -0
  109. package/templates/template_admin/tools/iconfont/svg/image.svg +1 -0
  110. package/templates/template_admin/tools/iconfont/svg/play.svg +1 -0
  111. package/templates/template_admin/tools/iconfont/svg/refresh.svg +1 -0
  112. package/templates/template_admin/tools/iconfont/svg/warn.svg +1 -0
  113. package/templates/template_admin/tools/iconfont/templates/_icons.css +26 -0
  114. package/templates/template_admin/tools/iconfont/templates/_icons.less +29 -0
  115. package/templates/template_admin/tools/iconfont/templates/index.html +56 -0
  116. package/templates/template_admin/tools/tinypng/package.json +11 -0
  117. package/templates/template_admin/tools/tinypng/run.sh +15 -0
  118. package/templates/template_admin/webpack.api.js +33 -0
  119. package/templates/template_app/jsconfig.json +10 -0
@@ -0,0 +1,126 @@
1
+
2
+ import { Menu } from 'antd';
3
+ import React, { useEffect, useRef, useState } from 'react';
4
+ import {matchPath,useLocation,useNavigate,} from 'react-router-dom';
5
+ import { AppstoreOutlined, MailOutlined, SettingOutlined } from '@ant-design/icons';
6
+ import {useDelay,useLoading} from '@/hooks';
7
+ import ProviderMenu from '@/provider/menu';
8
+
9
+
10
+ import styles from './index.less';
11
+
12
+ const ICON_NAME={
13
+ 'AppstoreOutlined':<AppstoreOutlined />,
14
+ 'MailOutlined':<MailOutlined />,
15
+ 'SettingOutlined':<SettingOutlined />,
16
+ }
17
+
18
+
19
+
20
+
21
+ const LeftMenu=(props)=>{
22
+
23
+ const providerMenu = ProviderMenu.useContainer();
24
+ const delay = useDelay();
25
+ const loader = useLoading();
26
+ const [menus,setMenus] = useState([]);
27
+ const [openKeys,setOpenKeys] = useState([]);
28
+ const [selectedKeys,setSelectKeys] = useState([]);
29
+ const curRoute = useLocation();
30
+ const nav = useNavigate();
31
+
32
+ const MENU_KEY_COUNTER=useRef(1);
33
+ const MENU_KEY=useRef({});
34
+ const translateMenu=(data={},parent)=>{
35
+ const {label,icon,children,path}= data;
36
+ let myKey = `${MENU_KEY_COUNTER.current}`
37
+ let item ={
38
+ key:myKey,
39
+ label:`${label}`,
40
+ source:data,
41
+ path,
42
+ routepath:parent?`${parent.key}-${myKey}`:myKey
43
+ }
44
+ MENU_KEY.current[myKey] = item;
45
+ MENU_KEY_COUNTER.current++;
46
+ if(icon){
47
+ item.icon= ICON_NAME[icon];
48
+ }
49
+ if(children){
50
+ item.children = children.map(childData=>{
51
+ return translateMenu(childData,item)
52
+ })
53
+ }
54
+ return item;
55
+ }
56
+
57
+
58
+ window.matchPath=matchPath;
59
+
60
+
61
+ const GET_ROUTE_MENU=(menuList)=>{
62
+ let groupKeys=[];
63
+ for(let key in menuList){
64
+ const menuItem = menuList[key];
65
+ const {path,routeTemplate}= menuItem.source;
66
+ if(path){
67
+ let fn = matchPath;
68
+ let match= fn(routeTemplate||path,curRoute.pathname);
69
+ if(match){
70
+ groupKeys = menuItem.routepath?menuItem.routepath.split('-'):'';
71
+ }
72
+ }
73
+ }
74
+ return groupKeys;
75
+ }
76
+
77
+ const loadMenu= ()=>{
78
+ loader.setLoading(true);
79
+ if(providerMenu.menus){
80
+ const menuList= providerMenu.menus.map(menu=>{
81
+ return translateMenu(menu)
82
+ })
83
+ setMenus(menuList);
84
+ }else{
85
+ setMenus([]);
86
+ }
87
+ loader.setLoading(false);
88
+ }
89
+
90
+ useEffect(()=>{
91
+ loadMenu();
92
+ },[providerMenu])
93
+
94
+ useEffect(()=>{
95
+ let groupKeys= GET_ROUTE_MENU(MENU_KEY.current);
96
+ setOpenKeys(groupKeys);
97
+ let selectKey =groupKeys[groupKeys.length-1];
98
+ setSelectKeys([selectKey])
99
+ },[curRoute,menus]);
100
+
101
+ const onClickMenuItem=(e)=>{
102
+ const { item, key, keyPath, domEvent } = e;
103
+ const menuData = MENU_KEY.current[key];
104
+ if(menuData.path){
105
+ nav(menuData.path);
106
+ }
107
+ }
108
+ const onOpenChange=(keys)=>{
109
+ setOpenKeys(keys);
110
+ }
111
+ return (
112
+ <section className={styles.nav}>
113
+ <Menu
114
+ theme='dark'
115
+ selectedKeys={selectedKeys}
116
+ openKeys={openKeys}
117
+ onOpenChange={onOpenChange}
118
+ onClick={onClickMenuItem}
119
+ mode="inline"
120
+ items={loader.loading?[]:menus}
121
+ />
122
+ </section>
123
+ )
124
+ }
125
+
126
+ export default LeftMenu;
@@ -0,0 +1,19 @@
1
+ @import '~@/_variable.less';
2
+
3
+
4
+ .nav{
5
+ width: var(--nav-width);
6
+ height:100%;
7
+ background-color: var(--color-primary-dark);
8
+ transition: all .2s;
9
+ z-index: var(--z-nav-mobile);
10
+ overflow-y: auto;
11
+ &[data-nav-hide='true']{
12
+ display: none;
13
+ }
14
+ &[data-nav-mode='mobile']{
15
+ position: fixed;
16
+ z-index: var(--z-nav-mobile);
17
+ box-shadow: 0 0 20px #444;
18
+ }
19
+ }
@@ -0,0 +1,30 @@
1
+ import React,{useEffect, useState} from 'react';
2
+ import ReactDOM from 'react-dom';
3
+ import CSS from './index.less';
4
+ import Popup from '@/components/Popup';
5
+ import imgLoading from '@/assets/images/loading.svg';
6
+
7
+ const PageLoading = (props) => {
8
+ const {visible=true} = props;
9
+ if(!visible){
10
+ return '';
11
+ }
12
+ return (
13
+ <div className={CSS.wrap } >
14
+ <div className={CSS.box} data-show={visible}>
15
+ <img src={imgLoading} />
16
+ </div>
17
+ </div>
18
+ );
19
+ };
20
+
21
+ export const ShowPageLoading=(props={canTouch:false})=>{
22
+ let popup = Popup(()=>{},{cantouch:props.canTouch});
23
+ ReactDOM.render(
24
+ <PageLoading visible={true} />,
25
+ popup.dom
26
+ );
27
+ return popup.destory;
28
+ }
29
+
30
+ export default React.memo(PageLoading);
@@ -0,0 +1,29 @@
1
+ .wrap {
2
+ position: fixed;
3
+ width: 100%;
4
+ height: 100%;
5
+ left: 0;
6
+ top: 0;
7
+ z-index: 99;
8
+ display: flex;
9
+ justify-content: center;
10
+ align-items: center;
11
+ }
12
+
13
+ .box {
14
+
15
+ width: 80px;
16
+ height: 80px;
17
+ background: rgba(0,0,0,.3);
18
+ border-radius: 12px;
19
+ display: flex;
20
+ justify-content: center;
21
+ align-items: center;
22
+ img{
23
+ display: block;
24
+ width:80%;
25
+ }
26
+ &[data-show=false]{
27
+ opacity: 0;
28
+ }
29
+ }
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+ import ReactDOM from 'react-dom';
3
+ import styles from './index.less';
4
+ styles;
5
+
6
+ const Popup = (reslove,options) => {
7
+ let rootDom = document.createElement('div');
8
+ rootDom.className='popup-box';
9
+ if(options&&options.cantouch)rootDom.setAttribute('data-can-touch','1');
10
+ if(options&&options.transparent)rootDom.setAttribute('data-transparent','1');
11
+
12
+ let destory = (result) => {
13
+ ReactDOM.unmountComponentAtNode(rootDom);
14
+ rootDom.parentNode.removeChild(rootDom);
15
+ if (reslove) reslove(result);
16
+ };
17
+ document.body.appendChild(rootDom);
18
+ return { dom: rootDom, destory };
19
+ };
20
+
21
+
22
+ export default Popup;
@@ -0,0 +1,18 @@
1
+
2
+
3
+ :global{
4
+ .popup-box{
5
+ position: absolute;
6
+ left:0;
7
+ top:0;
8
+ width:100%;
9
+ height:100%;
10
+ z-index: 99;
11
+ &[data-transparent]{
12
+ height:auto;
13
+ }
14
+ &[data-can-touch]{
15
+ pointer-events: none;
16
+ }
17
+ }
18
+ }
@@ -0,0 +1,60 @@
1
+ import React,{useEffect} from 'react';
2
+ import ReactDOM from 'react-dom';
3
+ import styles from './index.less';
4
+ import Popup from '@/components/Popup/index.jsx';
5
+
6
+ const toastList=[];
7
+ const runNext=()=>{
8
+ let props = toastList[0];
9
+ if(props){
10
+ const {message,delay,resolve,position}=props;
11
+ let popup = Popup(resolve,{cantouch:true});
12
+ ReactDOM.render(
13
+ <Toast destory={popup.destory} message={message} delay={delay} position={position}/>,
14
+ popup.dom
15
+ );
16
+ }
17
+ }
18
+
19
+ const Toast=props=>{
20
+ const {
21
+ message,
22
+ delay=1000*2,
23
+ destory,
24
+ position='top'
25
+ }=props;
26
+ useEffect(()=>{
27
+ setTimeout(()=>{
28
+ destory();
29
+ toastList.shift();
30
+ runNext();
31
+ },delay);
32
+ },[])
33
+ const ANITYPE={
34
+ 'center':'animate__slideInDown',
35
+ 'top':'animate__slideInDown',
36
+ 'bottom':'animate__slideInUp'
37
+ }
38
+ return (
39
+ <section className={styles.wrap} data-position={position}>
40
+ <div className={styles.content+ ` ${ANITYPE[position]} animate__animated animate__fast`} dangerouslySetInnerHTML={{ __html:message }}>
41
+ </div>
42
+ </section>
43
+ )
44
+ }
45
+
46
+
47
+ const ShowToast=props=>{
48
+ if(typeof props === 'string'){
49
+ props = {message:props}
50
+ }
51
+ return new Promise((resolve) => {
52
+ props.resolve = resolve;
53
+ toastList.push(props);
54
+ if(toastList.length===1){
55
+ runNext();
56
+ }
57
+ });
58
+ }
59
+
60
+ export default ShowToast;
@@ -0,0 +1,43 @@
1
+ @import '~@/_variable.less';
2
+
3
+ .wrap{
4
+ position: fixed;
5
+ left:0;
6
+ top:0;
7
+ width:100%;
8
+ height:100%;
9
+ pointer-events: none;
10
+ display: flex;
11
+ justify-content: center;
12
+ align-items: center;
13
+ flex-direction: column;
14
+ z-index:var(--z-toast);
15
+ &[data-position=top]{
16
+ justify-content: flex-start;
17
+ padding-top:80px;
18
+ }
19
+ &[data-position=bottom]{
20
+ justify-content: flex-end;
21
+ padding-bottom:80px;
22
+ }
23
+ .content{
24
+ min-height:30px;
25
+ min-width:60px;
26
+
27
+ background: rgba(0,0,0,.8);
28
+ opacity:.8;
29
+ border-radius: var(--radius-default);
30
+ padding:var(--padding-default);
31
+
32
+ display: flex;
33
+ flex-direction: column;
34
+ justify-content: center;
35
+ align-items: center;
36
+
37
+ font-size: 14px;
38
+ color: #FFFFFF;
39
+ text-shadow: 2px 2px 0px rgba(0, 0, 0, 0.24);
40
+
41
+
42
+ }
43
+ }
@@ -0,0 +1,228 @@
1
+ import React, { useState,useEffect, useRef} from 'react';
2
+ import { matchPath,useLocation,useNavigate } from 'react-router-dom';
3
+
4
+
5
+ import { LogoutOutlined, UserOutlined } from '@ant-design/icons';
6
+ import imgAvatar from '@/assets/images/avatar.png';
7
+ import { Menu,Dropdown } from 'antd'
8
+ import ProviderApp from '@/provider/app';
9
+ import ProviderMenu from '@/provider/menu';
10
+ import styles from './index.less';
11
+ import {GET_MENU} from '@/services/auth';
12
+
13
+
14
+
15
+
16
+ /**
17
+ * 顶部导航栏
18
+ * 左侧导航栏的路由也继顶部导航栏来控制
19
+ * 路由数据结构:
20
+ * const MenuRoute=[
21
+ {
22
+ label:'顶部菜单A',
23
+ path:'/home/sub/1',
24
+ menus:[
25
+ {
26
+ label:'菜单组A-1',
27
+ icon:'MailOutlined',
28
+ children:[
29
+ {label:'菜单组A-1-home',path:'/',},
30
+ {label:'菜单组A-1-sub:id',path:'/home/sub/1',routeTemplate:'/home/sub/:id'},
31
+ {label:'菜单组A-1-sub3:id',path:'/home/sub3/2',routeTemplate:'/home/sub3/:id'},
32
+ ]
33
+ },
34
+ ]
35
+ }
36
+ ]
37
+ 顶部的导航栏结构为{label,path,menus}
38
+ 左侧导航栏数据为顶部导航栏数据的menus内子项{label,icon,children}组成
39
+ routeTemplate用来识别动态参数的路由,同前端本地路由配置同步即可
40
+ 当顶部导航栏只有一项时,将自动隐藏顶部导航菜单
41
+ * @returns
42
+ */
43
+ const TopMenu=(props)=>{
44
+ const app = ProviderApp.useContainer();
45
+ const providerMenu = ProviderMenu.useContainer();
46
+ const curRoute = useLocation();
47
+
48
+ const [menus,setMenus]=useState([]);
49
+ const navigate = useNavigate();
50
+ const [selectedKeys,setSelectedKeys] = useState([]);
51
+
52
+
53
+ const MENU_KEY_COUNTER=useRef(1);
54
+ const MENU_KEY=useRef({})
55
+ const translateMenu=(data={})=>{
56
+ const {label,path}= data;
57
+ let myKey = `${MENU_KEY_COUNTER.current}`
58
+ let item ={
59
+ key:myKey,
60
+ label:`${label}`,
61
+ path,
62
+ source:data,
63
+ }
64
+ MENU_KEY.current[myKey] = item;
65
+ MENU_KEY_COUNTER.current++;
66
+ return item;
67
+ }
68
+
69
+ const transServicesMenuChildren=(menu)=>{
70
+ let req=[];
71
+ for(let i=0;i<menu.length;i++){
72
+ let item= menu[i];
73
+ const {url:path,name:label,icon,children:menus}= item;
74
+ let children;
75
+ if(menus&&menus.length>0){
76
+ children= transServicesMenuChildren(menus);
77
+ }
78
+ req.push({
79
+ path,label,icon,children
80
+ })
81
+ }
82
+ return req;
83
+ }
84
+ const loadMenu=async ()=>{
85
+ const isLogin= await app.isLogin();
86
+ if(!isLogin){
87
+ navigate('/login')
88
+ return;
89
+ }
90
+ let reqMenu = await GET_MENU();
91
+ if(reqMenu?.code==0){
92
+ let originMenu= reqMenu.data;
93
+ reqMenu=[];
94
+ for(let i=0;i<originMenu.length;i++){
95
+ let topMenu= originMenu[i];
96
+ const {url:path,children,name:label}=topMenu;
97
+ const menus = transServicesMenuChildren(children);
98
+ reqMenu.push({
99
+ path,menus,label
100
+ })
101
+ }
102
+ }
103
+ if(!reqMenu){
104
+ setMenus([]);
105
+ return;
106
+ }
107
+ const data = reqMenu.map(topMenu=>{
108
+ return translateMenu(topMenu);
109
+ })
110
+ setMenus(data);
111
+ }
112
+
113
+ const GET_ROUTE_MENU=(menu)=>{
114
+ const {routeTemplate,path} = menu;
115
+ const children = menu.children||menu.menus||null;
116
+ if(routeTemplate||path){
117
+ let match= matchPath(routeTemplate||path,curRoute.pathname);
118
+ if(match){
119
+ console.log(`match route: ${routeTemplate||path} -> ${curRoute.pathname}` )
120
+ return true;
121
+ }
122
+ }
123
+ if(children){
124
+ for(let subMenu of children){
125
+ let match = GET_ROUTE_MENU(subMenu);
126
+ if(match){
127
+ return true;
128
+ }
129
+ }
130
+ }
131
+ return false;
132
+ }
133
+
134
+ const reloadOpenMenu=()=>{
135
+ for(let menuKey in MENU_KEY.current){
136
+ const topMenu = MENU_KEY.current[menuKey];
137
+ const match= GET_ROUTE_MENU(topMenu.source);
138
+ if(match){
139
+ let changeLeftMenu=false;//是否重新设置左侧导航菜单数据
140
+ if(selectedKeys[0] != menuKey){
141
+ changeLeftMenu= true;
142
+ }
143
+ if(!providerMenu.menus||providerMenu.menus.length<=0){
144
+ changeLeftMenu= true;
145
+ }
146
+ setSelectedKeys([menuKey]);
147
+ if(changeLeftMenu){
148
+ providerMenu.setMenus(topMenu.source.menus);
149
+ }
150
+ return;
151
+ }
152
+ }
153
+ setSelectedKeys([]);
154
+ providerMenu.setMenus([]);
155
+ }
156
+ useEffect(loadMenu,[]);
157
+
158
+ useEffect(()=>{
159
+ reloadOpenMenu();
160
+ },[curRoute,menus]);
161
+
162
+
163
+
164
+ // 推出登录
165
+ const onAvatarClick = (e)=>{
166
+ if (e?.key === 'logout') {
167
+ app.logout();
168
+ }
169
+ }
170
+ const onHome=()=>{
171
+ navigate('/');
172
+ }
173
+ const onClickMenuItem=(e)=>{
174
+ const { item, key, keyPath, domEvent } = e;
175
+ const menuData = MENU_KEY.current[key];
176
+ const {path,source:{menus}} = menuData;
177
+ providerMenu.setMenus(menus);
178
+ if(path){
179
+ navigate(path)
180
+ }
181
+ setSelectedKeys([key])
182
+ }
183
+
184
+ return (
185
+ <section className={styles.topMenu}>
186
+ <div className={styles.left}>
187
+ <span className={styles.title} onClick={onHome}>后管系统</span>
188
+ </div>
189
+
190
+ <div className={styles.center}>
191
+ {
192
+ menus&&menus.length>1&&
193
+ <Menu
194
+ items={menus}
195
+ mode="horizontal"
196
+ onClick={onClickMenuItem}
197
+
198
+ selectedKeys={selectedKeys}
199
+ className={styles.menu}
200
+ />
201
+ }
202
+ </div>
203
+ <div className={styles.right}>
204
+
205
+ <span className={styles.username}>Hi,{app?.user?.username||''}!</span>
206
+ <Dropdown overlay={(
207
+ <Menu onClick={onAvatarClick} className={styles.avatarMenu}>
208
+ <Menu.Item key="user">
209
+ <UserOutlined />
210
+ 用户名
211
+ </Menu.Item>
212
+
213
+ <Menu.Item key="logout">
214
+ <LogoutOutlined />
215
+ 退出登录
216
+ </Menu.Item>
217
+ </Menu>
218
+ )}>
219
+ <img className={styles.avatar} src={imgAvatar}/>
220
+ </Dropdown>
221
+
222
+ </div>
223
+
224
+ </section>
225
+ )
226
+ }
227
+
228
+ export default TopMenu;
@@ -0,0 +1,105 @@
1
+ @import '~@/_variable.less';
2
+
3
+
4
+ .topMenu{
5
+ display: flex;
6
+ align-items: center;
7
+ justify-content: space-between;
8
+ height: var(--topMenu-height);
9
+ width:100%;
10
+ z-index:var(--z-top-menu);
11
+ background-color: var(--color-primary-dark);
12
+ .left{
13
+ padding-left: 16px;
14
+ display: flex;
15
+ align-items: center;
16
+ width: var(--nav-width);
17
+ .logo{
18
+ cursor: pointer;
19
+ width: 110px;
20
+ height: 32px;
21
+ margin-right: 7px;
22
+ color:white;
23
+ display: flex;
24
+ align-items: center;
25
+ font-size: 32px;
26
+ }
27
+ .title {
28
+ cursor: pointer;
29
+ color: #fff;
30
+ font-size: 16px;
31
+ padding: 0 55px 0 7px;
32
+ font-weight: var(--weight-Light);
33
+ }
34
+ }
35
+ .center{
36
+ height: 100%;
37
+ display: flex;
38
+ align-items: center;
39
+ flex:1;
40
+ }
41
+ .right{
42
+ display: flex;
43
+ align-items: center;
44
+ flex:1;
45
+ justify-content: flex-end;
46
+ .username{
47
+ color:white;
48
+ }
49
+ .avatar{
50
+ width: 40px;
51
+ height: 40px;
52
+ border-radius: 50%;
53
+ margin: 0 24px 0 24px;
54
+ }
55
+ }
56
+
57
+ .menu:global(.ant-menu){
58
+ line-height: var(--topMenu-height);
59
+ background-color: inherit;
60
+ border-bottom: none;
61
+ flex:1;
62
+ // min-width: 100px;
63
+
64
+ :global{
65
+ .ant-menu-item,
66
+ .ant-menu-item a{
67
+ color:rgba(104,114,126,1);
68
+ font-weight: var(--weight-Medium);
69
+ }
70
+ .ant-menu-item:hover a,
71
+ .ant-menu-item:hover,
72
+ .ant-menu-item-selected a{
73
+ color: rgba(255,255,255,.8);
74
+ }
75
+ .ant-menu-item-selected{
76
+ color: white;
77
+ }
78
+ .ant-menu-item:hover:after,
79
+ .ant-menu-item-selected:after{
80
+ border-bottom: 2px solid #fff;
81
+ }
82
+ .ant-menu-item{
83
+ padding: 0 24px;
84
+ }
85
+ }
86
+ }
87
+ }
88
+ .avatarMenu{
89
+ min-width: 100px;
90
+ :global(.anticon) {
91
+ margin-right: 8px;
92
+ }
93
+
94
+ :global(.ant-dropdown-menu-item) {
95
+ min-width: 100px;
96
+ }
97
+ }
98
+
99
+ .navShow{
100
+ font-size: 26px;
101
+ cursor: pointer;
102
+ &:hover{
103
+ color: var(--color-text-hover);
104
+ }
105
+ }