Yansen 2 年 前
コミット
2198c06951
共有9 個のファイルを変更した102 個の追加99 個の削除を含む
  1. 2
    2
      package.json
  2. 0
    42
      src/App.css
  3. 16
    4
      src/App.jsx
  4. 32
    2
      src/layouts/AuthLayout/components/Menus.jsx
  5. 1
    1
      src/layouts/AuthLayout/components/SiderBar.jsx
  6. 3
    8
      src/main.jsx
  7. 10
    10
      src/routes/menus.jsx
  8. 32
    29
      src/routes/routes.jsx
  9. 6
    1
      src/store/models/system.js

+ 2
- 2
package.json ファイルの表示

@@ -10,11 +10,11 @@
10 10
   },
11 11
   "dependencies": {
12 12
     "@ant-design/icons": "^4.8.0",
13
-    "@ant-design/pro-components": "^2.3.46",
13
+    "@ant-design/pro-components": "^2.3.51",
14 14
     "@wangeditor/editor": "^5.1.23",
15 15
     "@wangeditor/editor-for-react": "^1.0.6",
16 16
     "@zjxpcyc/react-tiny-store": "^2.0.1",
17
-    "antd": "^5.0.5",
17
+    "antd": "^5.1.2",
18 18
     "axios": "^1.2.0",
19 19
     "classnames": "^2.3.2",
20 20
     "dayjs": "^1.11.7",

+ 0
- 42
src/App.css ファイルの表示

@@ -1,42 +0,0 @@
1
-#root {
2
-  max-width: 1280px;
3
-  margin: 0 auto;
4
-  padding: 2rem;
5
-  text-align: center;
6
-}
7
-
8
-.logo {
9
-  height: 6em;
10
-  padding: 1.5em;
11
-  will-change: filter;
12
-}
13
-.logo:hover {
14
-  filter: drop-shadow(0 0 2em #646cffaa);
15
-}
16
-.logo.react:hover {
17
-  filter: drop-shadow(0 0 2em #61dafbaa);
18
-}
19
-
20
-
21
-@keyframes logo-spin {
22
-  from {
23
-    transform: rotate(0deg);
24
-  }
25
-  to {
26
-    transform: rotate(360deg);
27
-  }
28
-}
29
-
30
-@media (prefers-reduced-motion: no-preference) {
31
-  a:nth-of-type(2) .logo {
32
-    animation: logo-spin infinite 20s linear;
33
-  }
34
-}
35
-
36
-.card {
37
-  padding: 2em;
38
-}
39
-
40
-.read-the-docs {
41
-  color: #888;
42
-}

+ 16
- 4
src/App.jsx ファイルの表示

@@ -1,10 +1,22 @@
1
-import { useState } from 'react'
2
-
1
+import React from 'react';
2
+import 'dayjs/locale/zh-cn';
3
+import locale from 'antd/locale/zh_CN';
4
+import { ConfigProvider } from 'antd';
5
+import Router from './routes/Router'
6
+import { useModel } from './store';
3 7
 
4 8
 function App() {
5
-  const [count, setCount] = useState(0)
6 9
 
7
-  return null;
10
+  const { antThemeData } = useModel('system');
11
+  const theme = React.useMemo(() => ({token: antThemeData}), [antThemeData]);
12
+
13
+  console.log(theme)
14
+
15
+  return (
16
+    <ConfigProvider locale={locale} theme={theme}>
17
+      <Router />
18
+    </ConfigProvider>
19
+  );
8 20
 }
9 21
 
10 22
 export default App

+ 32
- 2
src/layouts/AuthLayout/components/Menus.jsx ファイルの表示

@@ -1,10 +1,14 @@
1 1
 import React from 'react';
2 2
 import { Menu } from 'antd';
3
+import { useNavigate } from 'react-router-dom';
4
+import useRoute from '@/utils/hooks/useRoute';
3 5
 
4
-const menuStyle = { height: '100%' };
6
+const menuStyle = { height: '100%', borderRight: 0 };
5 7
 
6 8
 export default (props) => {
7 9
   const { theme, items, location } = props;
10
+  const navigate = useNavigate();
11
+  const { meta } = useRoute() || {};
8 12
 
9 13
   // const selectedKeys = React.useMemo(() => {
10 14
   //   const parts = location.pathname.split('/').filter(Boolean);
@@ -20,7 +24,33 @@ export default (props) => {
20 24
 
21 25
   const selectedKeys = [location.pathname];
22 26
 
27
+  const onClick = ({key}) => {
28
+    const path = key
29
+    if (path.indexOf('http') > -1) {
30
+      document.createElement('a');
31
+      a.href = path;
32
+      a.target = '_blank';
33
+      a.click();
34
+    } else {
35
+      if (meta?.target === '_blank') {
36
+        document.createElement('a');
37
+        a.href = `${window.location.pathname}#${path}`
38
+        a.target = '_blank';
39
+        a.click();
40
+      } else {
41
+        navigate(path);
42
+      }
43
+    }
44
+  }
45
+
23 46
   return (
24
-    <Menu style={menuStyle} theme={theme} items={items} selectedKeys={selectedKeys} />
47
+    <Menu
48
+      mode="inline"
49
+      style={menuStyle}
50
+      theme={theme}
51
+      items={items}
52
+      selectedKeys={selectedKeys}
53
+      onClick={onClick}
54
+    />
25 55
   )
26 56
 }

+ 1
- 1
src/layouts/AuthLayout/components/SiderBar.jsx ファイルの表示

@@ -15,7 +15,7 @@ export default (props) => {
15 15
 
16 16
 
17 17
   return (
18
-    <Sider className='layout-sidebar' theme={theme} defaultCollapsed collapsible width={width}>
18
+    <Sider className='layout-sidebar' theme={theme} collapsible width={width}>
19 19
       <Menus theme={theme} items={menus} location={location} />
20 20
     </Sider>
21 21
   );

+ 3
- 8
src/main.jsx ファイルの表示

@@ -1,16 +1,11 @@
1 1
 import React from 'react'
2 2
 import ReactDOM from 'react-dom/client'
3
-import 'dayjs/locale/zh-cn';
4
-import locale from 'antd/locale/zh_CN';
5
-import { ConfigProvider } from 'antd';
6
-import Router from './routes/Router'
7 3
 import './index.less'
8
-import { Provider } from './store'
4
+import { Provider } from './store';
5
+import App from './App';
9 6
 
10 7
 ReactDOM.createRoot(document.getElementById('root')).render(
11 8
   <Provider>
12
-    <ConfigProvider locale={locale}>
13
-      <Router />
14
-    </ConfigProvider>
9
+    <App />
15 10
   </Provider>
16 11
 )

+ 10
- 10
src/routes/menus.jsx ファイルの表示

@@ -25,22 +25,22 @@ export const getMenuItems = (routes = [], fullPath = '/') => {
25 25
     
26 26
     const children = hasChildren(route.children) ? getMenuItems(route.children, path) : false;
27 27
 
28
-    const { target, title, icon } = route.meta || {}
28
+    const { target = '', title, icon, menuType } = route.meta || {}
29 29
 
30
-    // 坑爹 react-router v6 不支持 hash 路由的 target 跳转
31
-    const label = target === '_blank' ?
32
-      <a href={`${window.location.pathname}#${path}`} target={target}>{title}</a>
33
-      : (
34
-        path.indexOf('http') === 0  ? <a href={path} target="_blank">{title}</a>
35
-        : <Link to={path} target={target}>{title}</Link>
36
-      );
30
+    // // 坑爹 react-router v6 不支持 hash 路由的 target 跳转
31
+    // const label = target === '_blank' ?
32
+    //   <a href={`${window.location.pathname}#${path}`} target={target}>{title}</a>
33
+    //   : (
34
+    //     path.indexOf('http') === 0  ? <a href={path} target="_blank">{title}</a>
35
+    //     : <Link to={path} target={target}>{title}</Link>
36
+    //   );
37 37
 
38 38
     return Object.assign(
39 39
       {
40 40
         key: path,
41
-        label,
42
-        title,
41
+        label: title,
43 42
         icon,
43
+        type: menuType,
44 44
       },
45 45
       children && { children },
46 46
     )

+ 32
- 29
src/routes/routes.jsx ファイルの表示

@@ -42,6 +42,7 @@ import QuestionList from "@/pages/question/list";
42 42
  *    noFooter: 布尔值, 如果为 true, 将没有底部 footer
43 43
  *    target: 字符串, 如果为 _blank, 将在新窗口打开
44 44
  *    permission: 对应服务器端权限名称
45
+ *    menuType: ANTD 的 menuItem 的 type 属性,
45 46
  * }
46 47
  */
47 48
 
@@ -50,12 +51,43 @@ export const authRoutes = [
50 51
     path: 'index',
51 52
     element: <Index />,
52 53
   },
54
+  {
55
+    path: "check",
56
+    element: <Outlet />,
57
+    meta: {
58
+      title: '模拟测评',
59
+      icon: <ProjectOutlined />,
60
+      menuType: 'group',
61
+      // permission: 'form',
62
+    },
63
+    children: [
64
+      {
65
+        index: true,
66
+        element: <CheckList />,
67
+      },
68
+      {
69
+        path: "list",
70
+        element: <CheckList />,
71
+        meta: {
72
+          title: '测评列表',
73
+        }
74
+      },
75
+      {
76
+        path: "edit",
77
+        element: <CheckEdit />,
78
+        meta: {
79
+          title: '测评维护',
80
+        }
81
+      }
82
+    ]
83
+  },
53 84
   {
54 85
     path: "system",
55 86
     element: <Outlet />,
56 87
     meta: {
57 88
       title: '系统管理',
58 89
       icon: <SettingOutlined />,
90
+      menuType: 'group',
59 91
       // permission: 'form',
60 92
     },
61 93
     children: [
@@ -166,35 +198,6 @@ export const authRoutes = [
166 198
 
167 199
     ]
168 200
   },
169
-  {
170
-    path: "check",
171
-    element: <Outlet />,
172
-    meta: {
173
-      title: '模拟测评',
174
-      icon: <ProjectOutlined />,
175
-      // permission: 'form',
176
-    },
177
-    children: [
178
-      {
179
-        index: true,
180
-        element: <CheckList />,
181
-      },
182
-      {
183
-        path: "list",
184
-        element: <CheckList />,
185
-        meta: {
186
-          title: '测评列表',
187
-        }
188
-      },
189
-      {
190
-        path: "edit",
191
-        element: <CheckEdit />,
192
-        meta: {
193
-          title: '测评维护',
194
-        }
195
-      }
196
-    ]
197
-  }
198 201
 
199 202
   // {
200 203
   //   path: "form",

+ 6
- 1
src/store/models/system.js ファイルの表示

@@ -1,8 +1,12 @@
1
-import { useState, useCallback } from "react";
1
+import { useState } from "react";
2 2
 
3 3
 export default function useSystem() {
4 4
   // 主题
5 5
   const [theme, updateTheme] = useState('light');
6
+  const [antThemeData] = useState({
7
+    borderRadius: 6,
8
+    colorPrimary: '#1677ff',
9
+  });
6 10
 
7 11
   // 其他配置
8 12
   const [app, setApp] = useState({
@@ -13,6 +17,7 @@ export default function useSystem() {
13 17
 
14 18
   return {
15 19
     theme,
20
+    antThemeData,
16 21
     updateTheme,
17 22
     app,
18 23
     hashRoute: true,