Yansen 2 年之前
父節點
當前提交
e629563b64

+ 1
- 0
package.json 查看文件

14
     "antd": "^4.22.3",
14
     "antd": "^4.22.3",
15
     "react": "18.1.0",
15
     "react": "18.1.0",
16
     "react-dom": "18.1.0",
16
     "react-dom": "18.1.0",
17
+    "react-helmet": "^6.1.0",
17
     "react-router-dom": "6",
18
     "react-router-dom": "6",
18
     "react-transition-group": "^4.4.5"
19
     "react-transition-group": "^4.4.5"
19
   },
20
   },

+ 34
- 0
pnpm-lock.yaml 查看文件

10
   less: ^4.1.3
10
   less: ^4.1.3
11
   react: 18.1.0
11
   react: 18.1.0
12
   react-dom: 18.1.0
12
   react-dom: 18.1.0
13
+  react-helmet: ^6.1.0
13
   react-router-dom: '6'
14
   react-router-dom: '6'
14
   react-transition-group: ^4.4.5
15
   react-transition-group: ^4.4.5
15
   vite: ^3.0.0
16
   vite: ^3.0.0
21
   antd: registry.npmmirror.com/antd/4.22.3_ef5jwxihqo6n7gxfmzogljlgcm
22
   antd: registry.npmmirror.com/antd/4.22.3_ef5jwxihqo6n7gxfmzogljlgcm
22
   react: registry.npmmirror.com/react/18.1.0
23
   react: registry.npmmirror.com/react/18.1.0
23
   react-dom: registry.npmmirror.com/react-dom/18.1.0_react@18.1.0
24
   react-dom: registry.npmmirror.com/react-dom/18.1.0_react@18.1.0
25
+  react-helmet: registry.npmmirror.com/react-helmet/6.1.0_react@18.1.0
24
   react-router-dom: registry.npmmirror.com/react-router-dom/6.3.0_ef5jwxihqo6n7gxfmzogljlgcm
26
   react-router-dom: registry.npmmirror.com/react-router-dom/6.3.0_ef5jwxihqo6n7gxfmzogljlgcm
25
   react-transition-group: registry.npmmirror.com/react-transition-group/4.4.5_ef5jwxihqo6n7gxfmzogljlgcm
27
   react-transition-group: registry.npmmirror.com/react-transition-group/4.4.5_ef5jwxihqo6n7gxfmzogljlgcm
26
 
28
 
2089
       scheduler: registry.npmmirror.com/scheduler/0.22.0
2091
       scheduler: registry.npmmirror.com/scheduler/0.22.0
2090
     dev: false
2092
     dev: false
2091
 
2093
 
2094
+  registry.npmmirror.com/react-fast-compare/3.2.0:
2095
+    resolution: {integrity: sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz}
2096
+    name: react-fast-compare
2097
+    version: 3.2.0
2098
+    dev: false
2099
+
2100
+  registry.npmmirror.com/react-helmet/6.1.0_react@18.1.0:
2101
+    resolution: {integrity: sha512-4uMzEY9nlDlgxr61NL3XbKRy1hEkXmKNXhjbAIOVw5vcFrsdYbH2FEwcNyWvWinl103nXgzYNlns9ca+8kFiWw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/react-helmet/-/react-helmet-6.1.0.tgz}
2102
+    id: registry.npmmirror.com/react-helmet/6.1.0
2103
+    name: react-helmet
2104
+    version: 6.1.0
2105
+    peerDependencies:
2106
+      react: '>=16.3.0'
2107
+    dependencies:
2108
+      object-assign: registry.npmmirror.com/object-assign/4.1.1
2109
+      prop-types: registry.npmmirror.com/prop-types/15.8.1
2110
+      react: registry.npmmirror.com/react/18.1.0
2111
+      react-fast-compare: registry.npmmirror.com/react-fast-compare/3.2.0
2112
+      react-side-effect: registry.npmmirror.com/react-side-effect/2.1.2_react@18.1.0
2113
+    dev: false
2114
+
2092
   registry.npmmirror.com/react-is/16.13.1:
2115
   registry.npmmirror.com/react-is/16.13.1:
2093
     resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/react-is/-/react-is-16.13.1.tgz}
2116
     resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/react-is/-/react-is-16.13.1.tgz}
2094
     name: react-is
2117
     name: react-is
2129
       react: registry.npmmirror.com/react/18.1.0
2152
       react: registry.npmmirror.com/react/18.1.0
2130
     dev: false
2153
     dev: false
2131
 
2154
 
2155
+  registry.npmmirror.com/react-side-effect/2.1.2_react@18.1.0:
2156
+    resolution: {integrity: sha512-PVjOcvVOyIILrYoyGEpDN3vmYNLdy1CajSFNt4TDsVQC5KpTijDvWVoR+/7Rz2xT978D8/ZtFceXxzsPwZEDvw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/react-side-effect/-/react-side-effect-2.1.2.tgz}
2157
+    id: registry.npmmirror.com/react-side-effect/2.1.2
2158
+    name: react-side-effect
2159
+    version: 2.1.2
2160
+    peerDependencies:
2161
+      react: ^16.3.0 || ^17.0.0 || ^18.0.0
2162
+    dependencies:
2163
+      react: registry.npmmirror.com/react/18.1.0
2164
+    dev: false
2165
+
2132
   registry.npmmirror.com/react-transition-group/4.4.5_ef5jwxihqo6n7gxfmzogljlgcm:
2166
   registry.npmmirror.com/react-transition-group/4.4.5_ef5jwxihqo6n7gxfmzogljlgcm:
2133
     resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/react-transition-group/-/react-transition-group-4.4.5.tgz}
2167
     resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/react-transition-group/-/react-transition-group-4.4.5.tgz}
2134
     id: registry.npmmirror.com/react-transition-group/4.4.5
2168
     id: registry.npmmirror.com/react-transition-group/4.4.5

+ 110
- 0
public/particles/particles.json 查看文件

1
+{
2
+  "particles": {
3
+    "number": {
4
+      "value": 80,
5
+      "density": {
6
+        "enable": true,
7
+        "value_area": 800
8
+      }
9
+    },
10
+    "color": {
11
+      "value": "#1890ff"
12
+    },
13
+    "shape": {
14
+      "type": "circle",
15
+      "stroke": {
16
+        "width": 0,
17
+        "color": "#000000"
18
+      },
19
+      "polygon": {
20
+        "nb_sides": 5
21
+      },
22
+      "image": {
23
+        "src": "img/github.svg",
24
+        "width": 100,
25
+        "height": 100
26
+      }
27
+    },
28
+    "opacity": {
29
+      "value": 0.5,
30
+      "random": false,
31
+      "anim": {
32
+        "enable": false,
33
+        "speed": 1,
34
+        "opacity_min": 0.1,
35
+        "sync": false
36
+      }
37
+    },
38
+    "size": {
39
+      "value": 3,
40
+      "random": true,
41
+      "anim": {
42
+        "enable": false,
43
+        "speed": 40,
44
+        "size_min": 0.1,
45
+        "sync": false
46
+      }
47
+    },
48
+    "line_linked": {
49
+      "enable": true,
50
+      "distance": 150,
51
+      "color": "#1890ff",
52
+      "opacity": 0.4,
53
+      "width": 1
54
+    },
55
+    "move": {
56
+      "enable": true,
57
+      "speed": 6,
58
+      "direction": "none",
59
+      "random": false,
60
+      "straight": false,
61
+      "out_mode": "out",
62
+      "bounce": false,
63
+      "attract": {
64
+        "enable": false,
65
+        "rotateX": 600,
66
+        "rotateY": 1200
67
+      }
68
+    }
69
+  },
70
+  "interactivity": {
71
+    "detect_on": "canvas",
72
+    "events": {
73
+      "onhover": {
74
+        "enable": false,
75
+        "mode": "repulse"
76
+      },
77
+      "onclick": {
78
+        "enable": false,
79
+        "mode": "push"
80
+      },
81
+      "resize": true
82
+    },
83
+    "modes": {
84
+      "grab": {
85
+        "distance": 400,
86
+        "line_linked": {
87
+          "opacity": 1
88
+        }
89
+      },
90
+      "bubble": {
91
+        "distance": 400,
92
+        "size": 40,
93
+        "duration": 2,
94
+        "opacity": 8,
95
+        "speed": 3
96
+      },
97
+      "repulse": {
98
+        "distance": 200,
99
+        "duration": 0.4
100
+      },
101
+      "push": {
102
+        "particles_nb": 4
103
+      },
104
+      "remove": {
105
+        "particles_nb": 2
106
+      }
107
+    }
108
+  },
109
+  "retina_detect": true
110
+}

+ 9
- 0
public/particles/particles.min.js
文件差異過大導致無法顯示
查看文件


+ 2
- 6
src/components/page/index.jsx 查看文件

1
 import React from 'react';
1
 import React from 'react';
2
 import { PageHeader } from 'antd';
2
 import { PageHeader } from 'antd';
3
-import { useLocation } from "react-router-dom";
4
-import { getRouteArr } from '@/routes/menus';
3
+import useRoute from '@/routes/useRoute';
5
 import './style.less'
4
 import './style.less'
6
 
5
 
7
 export default (props) => {
6
 export default (props) => {
8
   const { children, ...headerProps } = props;
7
   const { children, ...headerProps } = props;
9
 
8
 
10
-  const location = useLocation();
11
-  const routeArr = getRouteArr();
12
-
13
-  const currentRoute = routeArr.filter(x => x.path === location.pathname)[0] || {};
9
+  const currentRoute = useRoute() || {};
14
   const { title } = currentRoute.meta || {};
10
   const { title } = currentRoute.meta || {};
15
 
11
 
16
   return (
12
   return (

+ 1
- 1
src/layouts/AuthLayout/components/Header/Logo.jsx 查看文件

8
   return (
8
   return (
9
     <div className='logo'>
9
     <div className='logo'>
10
       <img src="./logo.png" alt="" />
10
       <img src="./logo.png" alt="" />
11
-      <h3>{config.appName}</h3>
11
+      <h3>{config.shorName}</h3>
12
     </div>
12
     </div>
13
   )
13
   )
14
 }
14
 }

+ 10
- 1
src/layouts/AuthLayout/index.jsx 查看文件

1
 import React, { useEffect, useRef, useMemo, useState } from 'react';
1
 import React, { useEffect, useRef, useMemo, useState } from 'react';
2
 import { Layout, Spin } from 'antd';
2
 import { Layout, Spin } from 'antd';
3
-import { useModel } from '@/store'
3
+import { Helmet } from "react-helmet";
4
+import { useModel } from '@/store';
5
+import useRoute from '@/routes/useRoute';
4
 import RequireLogin from './components/RequireLogin';
6
 import RequireLogin from './components/RequireLogin';
5
 import SiderBar from './components/SiderBar';
7
 import SiderBar from './components/SiderBar';
6
 import Header from './components/Header';
8
 import Header from './components/Header';
10
 import './style.less';
12
 import './style.less';
11
 
13
 
12
 export default (props) => {
14
 export default (props) => {
15
+  const { config } = useModel('system');
13
   const { user, getCurrent } = useModel('user');
16
   const { user, getCurrent } = useModel('user');
14
   // const isReady = useReady(user)
17
   // const isReady = useReady(user)
15
   // const isReady = true
18
   // const isReady = true
16
 
19
 
20
+  const currentRoute = useRoute();
21
+  const pageTitle = currentRoute && currentRoute.meta ? currentRoute.meta.title : undefined;
22
+  const fullTitle = pageTitle ? `${pageTitle} | ${config.appName}` : config.appName;
17
 
23
 
18
   useEffect(() => {
24
   useEffect(() => {
19
     if (!user) {
25
     if (!user) {
23
 
29
 
24
   return (
30
   return (
25
     <Spin spinning={!user} size="large">
31
     <Spin spinning={!user} size="large">
32
+      <Helmet>
33
+        <title>{fullTitle}</title>
34
+      </Helmet>
26
       <RequireLogin>
35
       <RequireLogin>
27
         <div className='main-layout'>
36
         <div className='main-layout'>
28
           <Header />
37
           <Header />

+ 7
- 0
src/pages/404/index.jsx 查看文件

1
 import React from 'react';
1
 import React from 'react';
2
 import { Button, Result } from 'antd';
2
 import { Button, Result } from 'antd';
3
+import { Helmet } from "react-helmet";
3
 import { NavLink } from "react-router-dom";
4
 import { NavLink } from "react-router-dom";
5
+import { useModel } from '@/store';
4
 
6
 
5
 const style = {
7
 const style = {
6
   display: 'grid',
8
   display: 'grid',
9
 }
11
 }
10
 
12
 
11
 export default (props) => {
13
 export default (props) => {
14
+  const { config } = useModel('system');
15
+
12
   return (
16
   return (
13
     <div style={style}>
17
     <div style={style}>
18
+      <Helmet>
19
+        <title>{config.appName}</title>
20
+      </Helmet>
14
       <Result
21
       <Result
15
         status="404"
22
         status="404"
16
         title="404"
23
         title="404"

+ 12
- 2
src/pages/login/index.jsx 查看文件

1
 import React from 'react';
1
 import React from 'react';
2
+import { Helmet } from "react-helmet";
3
+import { useModel } from '@/store';
2
 import LoginForm from './LoginForm';
4
 import LoginForm from './LoginForm';
3
 import LoginEffect from './Effect';
5
 import LoginEffect from './Effect';
4
 import './style.less'
6
 import './style.less'
6
 const year = new Date().getFullYear();
8
 const year = new Date().getFullYear();
7
 
9
 
8
 export default (props) => {
10
 export default (props) => {
11
+  const { config } = useModel('system');
12
+
13
+  const title = `欢迎使用${config.appName}`
14
+  const copyright = `${config.company} @ ${year}`
15
+
9
   return (
16
   return (
10
     <div className='login-page'>
17
     <div className='login-page'>
18
+      <Helmet>
19
+        <title>{config.appName}</title>
20
+      </Helmet>
11
       <div className="login-card">
21
       <div className="login-card">
12
         <div className="login-card-left">
22
         <div className="login-card-left">
13
           <div className="login-form-box">
23
           <div className="login-form-box">
14
             <div className="login-form">
24
             <div className="login-form">
15
               <h2>登录系统</h2>
25
               <h2>登录系统</h2>
16
-              <div className="login-subtitle">欢迎使用云致管理系统</div>
26
+              <div className="login-subtitle">{title}</div>
17
               <LoginForm />
27
               <LoginForm />
18
             </div>
28
             </div>
19
           </div>
29
           </div>
20
           <div className="login-copyright">
30
           <div className="login-copyright">
21
-          南京云致 @ {year}
31
+            {copyright}
22
           </div>
32
           </div>
23
         </div>
33
         </div>
24
         <div className="login-card-right">
34
         <div className="login-card-right">

+ 7
- 2
src/pages/login/style.less 查看文件

28
     display: grid;
28
     display: grid;
29
     place-items: center;
29
     place-items: center;
30
 
30
 
31
+    .login-form {
32
+      min-width: 280px;
33
+    }
34
+
31
     .login-subtitle {
35
     .login-subtitle {
32
       font-size: .9em;
36
       font-size: .9em;
33
       color: #666;
37
       color: #666;
34
       margin-bottom: 24px;
38
       margin-bottom: 24px;
39
+      letter-spacing: 2px;
35
     }
40
     }
36
   }
41
   }
37
 
42
 
41
     place-items: center;
46
     place-items: center;
42
 
47
 
43
     .login-effect {
48
     .login-effect {
44
-      width: 120px;
45
-      height: 120px;
49
+      width: 180px;
50
+      height: 180px;
46
       position: relative;
51
       position: relative;
47
     }
52
     }
48
 
53
 

+ 11
- 0
src/routes/useRoute.jsx 查看文件

1
+import { useLocation } from "react-router-dom";
2
+import { getRouteArr } from './menus';
3
+
4
+export default function useRoute() {
5
+  const location = useLocation();
6
+  const routeArr = getRouteArr();
7
+
8
+  const currentRoute = routeArr.filter(x => x.path === location.pathname)[0];
9
+
10
+  return currentRoute;
11
+}

+ 3
- 1
src/store/models/system.js 查看文件

8
 export default function useSystem() {
8
 export default function useSystem() {
9
   const [theme, setTheme] = useState('light');
9
   const [theme, setTheme] = useState('light');
10
   const [config, setConfig] = useState({
10
   const [config, setConfig] = useState({
11
-    appName: '云致科技',
11
+    appName: '云致科技信息管理系统',
12
+    shorName: '云致科技',
13
+    company: '云致科技'
12
   });
14
   });
13
 
15
 
14
   const updateTheme = useCallback((t) => {
16
   const updateTheme = useCallback((t) => {