Yansen пре 2 година
родитељ
комит
65985af3ef

+ 3
- 5
config/defaultSettings.js Прегледај датотеку

@@ -3,18 +3,16 @@ const Settings = {
3 3
   navTheme: 'dark',
4 4
   // 拂晓蓝
5 5
   primaryColor: '#1890ff',
6
-  layout: 'side',
7 6
   contentWidth: 'Fluid',
8 7
   fixedHeader: false,
9 8
   fixSiderbar: true,
10 9
   colorWeak: false,
11
-  title: '海安军供',
10
+  title: '', // 必须为空
12 11
   pwa: false,
13
-  logo: '/w2/logo.png',
14 12
   iconfontUrl: '',
15
-  splitMenus: false,
16
-  headerRender: false,
17 13
   footerRender: false,
14
+  layout: 'mix',
15
+  splitMenus: true,
18 16
 };
19 17
 
20 18
 export default Settings;

+ 14
- 14
config/routes.js Прегледај датотеку

@@ -1,18 +1,18 @@
1 1
 export default [
2
-  // {
3
-  //   path: '/user',
4
-  //   layout: false,
5
-  //   routes: [
6
-  //     {
7
-  //       name: 'login',
8
-  //       path: '/user/login',
9
-  //       component: './User/Login',
10
-  //     },
11
-  //     {
12
-  //       component: './404',
13
-  //     },
14
-  //   ],
15
-  // },
2
+  {
3
+    path: '/user',
4
+    layout: false,
5
+    routes: [
6
+      {
7
+        name: 'login',
8
+        path: '/user/login',
9
+        component: './User/Login',
10
+      },
11
+      {
12
+        component: './404',
13
+      },
14
+    ],
15
+  },
16 16
   // {
17 17
   //   path: '/welcome',
18 18
   //   name: 'welcome',

+ 1
- 0
package.json Прегледај датотеку

@@ -50,6 +50,7 @@
50 50
     "antd": "^4.20.0",
51 51
     "classnames": "^2.3.0",
52 52
     "lodash": "^4.17.0",
53
+    "md5": "^2.3.0",
53 54
     "moment": "^2.29.0",
54 55
     "omit.js": "^2.0.2",
55 56
     "rc-menu": "^9.1.0",

+ 42
- 40
src/app.jsx Прегледај датотеку

@@ -1,36 +1,41 @@
1 1
 import { requestConfig } from '@/utils/request';
2
+import { Link } from 'umi';
2 3
 import { history } from '@umijs/max';
4
+import RightContent from '@/components/RightContent';
3 5
 import { SettingDrawer } from '@ant-design/pro-components';
6
+import { queryCurrentUser } from '@/services/api/user';
7
+import logoImg from '@/assets/images/logo.png';
4 8
 import defaultSettings from '../config/defaultSettings';
5 9
 
6 10
 const isDev = process.env.NODE_ENV === 'development';
7
-// const loginPath = '/user/login';
11
+const loginPath = '/user/login';
8 12
 
9 13
 /**
10 14
  * @see  https://umijs.org/zh-CN/plugins/plugin-initial-state
11 15
  * */
12 16
 
13 17
 export async function getInitialState() {
14
-  // const fetchUserInfo = async () => {
15
-  //   try {
16
-  //     const msg = await queryCurrentUser();
17
-  //     return msg.data;
18
-  //   } catch (error) {
19
-  //     history.push(loginPath);
20
-  //   }
21
-  //   return undefined;
22
-  // };
23
-  // // 如果不是登录页面,执行
24
-  // if (history.location.pathname !== loginPath) {
25
-  //   const currentUser = await fetchUserInfo();
26
-  //   return {
27
-  //     fetchUserInfo,
28
-  //     currentUser,
29
-  //     settings: defaultSettings,
30
-  //   };
31
-  // }
18
+  const fetchUserInfo = async () => {
19
+    try {
20
+      const msg = await queryCurrentUser();
21
+      return msg;
22
+    } catch (error) {
23
+      history.push(loginPath);
24
+    }
25
+    return undefined;
26
+  };
27
+
28
+  // 如果不是登录页面,执行
29
+  if (history.location.pathname !== loginPath) {
30
+    const currentUser = await fetchUserInfo();
31
+    return {
32
+      fetchUserInfo,
33
+      currentUser,
34
+      settings: defaultSettings,
35
+    };
36
+  }
32 37
   return {
33
-    // fetchUserInfo,
38
+    fetchUserInfo,
34 39
     settings: defaultSettings,
35 40
   };
36 41
 }
@@ -38,7 +43,7 @@ export async function getInitialState() {
38 43
 // ProLayout 支持的api https://procomponents.ant.design/components/layout
39 44
 export const layout = ({ initialState, setInitialState }) => {
40 45
   const cfg = {
41
-    // rightContentRender: () => <RightContent />,
46
+    rightContentRender: () => <RightContent />,
42 47
     disableContentMargin: false,
43 48
     token: {
44 49
       sider: {
@@ -49,36 +54,33 @@ export const layout = ({ initialState, setInitialState }) => {
49 54
         colorTextMenuSelected: '#fff',
50 55
         colorTextMenuTitle: '#fff',
51 56
         colorTextMenu: 'hsla(0,0%,100%,.65);',
52
-        
53
-        // colorTextMenuTitle: string,
54
-        // colorTextCollapsedButtonHover: string,
55
-        // colorTextCollapsedButton: string,
56
-        // colorTextMenuSecondary: string,
57
-        // colorTextSubMenuSelected: string,
58
-        // colorBgMenuItemCollapsedHover: string,
59
-        // colorBgMenuItemCollapsedSelected: string,
57
+
60 58
       },
59
+      header: {
60
+        colorBgHeader: '#0D267C',
61
+        colorHeaderTitle: '#fff',
62
+        colorTextMenuActive: '#fff',
63
+        colorTextMenu: '#fff',
64
+        colorTextMenuSelected: '#fff',
65
+        colorBgMenuItemHover: '#4276F5',
66
+        colorBgMenuItemSelected: '#4276F5',
67
+        colorTextRightActionsItem: '#fff',
68
+        heightLayoutHeader: 64,
69
+      }
61 70
     },
62 71
     // waterMarkProps: {
63 72
     //   content: initialState?.currentUser?.name,
64 73
     // },
65 74
     // footerRender: () => <Footer />,
75
+    headerTitleRender: () => <Link to="/"><img src={logoImg} style={{ height: '42px' }} alt="" /></Link>,
66 76
     onPageChange: () => {
67 77
       const { location } = history;
68 78
 
69 79
       // 如果没有登录,重定向到 login
70
-      // if (!initialState?.currentUser && location.pathname !== loginPath) {
71
-      //   history.push(loginPath);
72
-      // }
80
+      if (!initialState?.currentUser && location.pathname !== loginPath) {
81
+        history.push(loginPath);
82
+      }
73 83
     },
74
-    // links: isDev
75
-    //   ? [
76
-    //       <Link key="openapi" to="/umi/plugin/openapi" target="_blank">
77
-    //         <LinkOutlined />
78
-    //         <span>OpenAPI 文档</span>
79
-    //       </Link>,
80
-    //     ]
81
-    //   : [],
82 84
     menuHeaderRender: undefined,
83 85
     // 自定义 403 页面
84 86
     // unAccessible: <div>unAccessible</div>,

BIN
src/assets/images/login/background.png Прегледај датотеку


BIN
src/assets/images/login/小背景.png Прегледај датотеку


BIN
src/assets/images/login/装饰右.png Прегледај датотеку


BIN
src/assets/images/login/装饰左.png Прегледај датотеку


BIN
src/assets/images/logo.png Прегледај датотеку


+ 4
- 2
src/components/RightContent/index.less Прегледај датотеку

@@ -1,6 +1,6 @@
1 1
 @import (reference) '~antd/es/style/themes/index';
2 2
 
3
-@pro-header-hover-bg: rgba(0, 0, 0, 0.025);
3
+@pro-header-hover-bg: rgba(255, 255, 255, 0.025);
4 4
 
5 5
 .menu {
6 6
   :global(.anticon) {
@@ -41,11 +41,13 @@
41 41
     }
42 42
   }
43 43
   .account {
44
+    color: #fff;
45
+
44 46
     .avatar {
45 47
       margin-right: 8px;
46 48
       color: @primary-color;
47 49
       vertical-align: top;
48
-      background: rgba(255, 255, 255, 0.85);
50
+      // background: rgba(255, 255, 255, 0.85);
49 51
     }
50 52
   }
51 53
 }

+ 13
- 0
src/global.less Прегледај датотеку

@@ -17,6 +17,19 @@ body,
17 17
 .ant-layout {
18 18
   min-height: 100vh;
19 19
 }
20
+
21
+.ant-pro .ant-layout-header.ant-pro-layout-header {
22
+  padding: 0;
23
+}
24
+
25
+.ant-pro-top-nav-header-menu {
26
+  line-height: 64px !important;
27
+}
28
+
29
+.ant-pro-layout .ant-pro-top-nav-header-base-menu.ant-menu-light .ant-menu-item-selected {
30
+  border-radius: 0;
31
+}
32
+
20 33
 .ant-pro-sider.ant-layout-sider.ant-pro-sider-fixed {
21 34
   left: unset;
22 35
 }

+ 47
- 92
src/pages/User/Login/index.jsx Прегледај датотеку

@@ -1,116 +1,71 @@
1 1
 import Footer from '@/components/Footer';
2
-import { login } from '@/services/api/login';
2
+import { login } from '@/services/api/user';
3 3
 import { LockOutlined, UserOutlined } from '@ant-design/icons';
4 4
 import { LoginForm, ProFormText } from '@ant-design/pro-components';
5 5
 import { history, useModel } from '@umijs/max';
6
-import { Alert, message, Tabs } from 'antd';
6
+import { Alert, message, Form, Button, Input } from 'antd';
7 7
 import { useState } from 'react';
8
-import styles from './index.less';
8
+import md5 from 'md5';
9
+import Logo from '@/assets/images/logo.png';
10
+import decorateLeft from '@/assets/images/login/装饰左.png';
11
+import decorateRight from '@/assets/images/login/装饰右.png';
12
+import './index.less';
9 13
 
10
-const LoginMessage = ({ content }) => {
11
-  return (
12
-    <Alert
13
-      style={{
14
-        marginBottom: 24,
15
-      }}
16
-      message={content}
17
-      type="error"
18
-      showIcon
19
-    />
20
-  );
21
-};
14
+const errStyle = {color: 'red', paddingBottom: '10px'}
22 15
 
23 16
 const Login = () => {
24
-  const [userLoginState, setUserLoginState] = useState({});
25 17
   const [type, setType] = useState('account');
26 18
   const { initialState, setInitialState } = useModel('@@initialState');
27
-
28
-  const fetchUserInfo = async () => {
29
-    const userInfo = await initialState?.fetchUserInfo?.();
30
-    if (userInfo) {
31
-      await setInitialState((s) => ({
32
-        ...s,
33
-        currentUser: userInfo,
34
-      }));
35
-    }
36
-  };
19
+  const [errMsg, setErrMsg] = useState()
37 20
 
38 21
   const handleSubmit = async (values) => {
39 22
     try {
40 23
       // 登录
41
-      const msg = await login({ params: values });
42
-      console.log(msg);
43
-      if (msg.success === 'true') {
44
-        const defaultLoginSuccessMessage = '登录成功!';
45
-        message.success(defaultLoginSuccessMessage);
46
-        await fetchUserInfo();
47
-        const urlParams = new URL(window.location.href).searchParams;
48
-        history.push(urlParams.get('redirect') || '/');
49
-        return;
50
-      }
24
+      const res = await login({ ...values, password: md5(values.password) });
25
+      console.log(res);
26
+
27
+      const defaultLoginSuccessMessage = '登录成功!';
28
+      message.success(defaultLoginSuccessMessage);
29
+      
30
+      setInitialState({
31
+        currentUser: res.user,
32
+      });
33
+      
34
+      const urlParams = new URL(window.location.href).searchParams;
35
+      history.push(urlParams.get('redirect') || '/');
36
+      return;
51 37
 
52
-      // 如果失败去设置用户错误信息
53
-      setUserLoginState(msg);
38
+      
54 39
     } catch (error) {
55
-      const defaultLoginFailureMessage = '登录失败,请重试!';
56 40
       console.log(error);
57
-      message.error(defaultLoginFailureMessage);
58 41
     }
59 42
   };
60 43
 
61 44
   return (
62
-    <div className={styles.container}>
63
-      <div className={styles.content}>
64
-        <LoginForm
65
-          // logo={<img alt="logo" src="/logo.svg" />}
66
-          title="军供"
67
-          onFinish={async (values) => {
68
-            await handleSubmit(values);
69
-          }}
70
-        >
71
-          <Tabs activeKey={type} onChange={setType}>
72
-            <Tabs.TabPane key="account" tab="账户密码登录" />
73
-          </Tabs>
74
-
75
-          {userLoginState.success === 'false' && (
76
-            <LoginMessage content={userLoginState.errorMessage} />
77
-          )}
78
-
79
-          <>
80
-            <ProFormText
81
-              name="account"
82
-              fieldProps={{
83
-                size: 'large',
84
-                prefix: <UserOutlined className={styles.prefixIcon} />,
85
-              }}
86
-              placeholder="admin"
87
-              // placeholder="请输入用户名"
88
-              rules={[
89
-                {
90
-                  required: true,
91
-                  message: '请输入用户名!',
92
-                },
93
-              ]}
94
-            />
95
-            <ProFormText.Password
96
-              name="password"
97
-              fieldProps={{
98
-                size: 'large',
99
-                prefix: <LockOutlined className={styles.prefixIcon} />,
100
-              }}
101
-              placeholder="123456"
102
-              // placeholder="请输入密码!"
103
-              rules={[
104
-                {
105
-                  required: true,
106
-                  message: '请输入密码!',
107
-                },
108
-              ]}
109
-            />
110
-          </>
111
-        </LoginForm>
112
-      </div>
113
-      <Footer />
45
+    <div className="page-container">
46
+      <Form name="login" id="login" onFinish={handleSubmit}>
47
+        <div className="form-left">
48
+          <img src={Logo} />
49
+        </div>
50
+        <div className="form-right">
51
+          <h2>用户登录</h2>
52
+          <div className="sub-title">
53
+            <img src={decorateLeft} alt="" />
54
+            <span>Welcome</span>
55
+            <img src={decorateRight} alt="" />
56
+          </div>
57
+          <div id="msg" style={errStyle}>{errMsg}</div>
58
+          <Form.Item className="input-control" name="userName" required>
59
+            <Input type="text" prefix={<UserOutlined />} className="form-control cust-input" placeholder="用户名" />
60
+          </Form.Item>
61
+          <Form.Item className="input-control" name="password" required>
62
+            <Input type="password" prefix={<LockOutlined />} className="form-control cust-input" placeholder="密码" />
63
+          </Form.Item>
64
+          <Form.Item className="form-group" style={{ marginBottom: '60px' }}>
65
+            <Button type="primary" className="btn-primary" htmlType="submit">登 录</Button>
66
+          </Form.Item>
67
+        </div>
68
+      </Form>
114 69
     </div>
115 70
   );
116 71
 };

+ 100
- 38
src/pages/User/Login/index.less Прегледај датотеку

@@ -1,48 +1,110 @@
1
-@import (reference) '~antd/es/style/themes/index';
2 1
 
3
-.container {
4
-  display: flex;
5
-  flex-direction: column;
6
-  height: 100vh;
7
-  overflow: auto;
8
-  background: @layout-body-background;
2
+html, body {
3
+  height: 100%;
4
+  margin: 0;
9 5
 }
10 6
 
11
-.lang {
7
+.page-container {
12 8
   width: 100%;
13
-  height: 40px;
14
-  line-height: 44px;
15
-  text-align: right;
16
-  :global(.ant-dropdown-trigger) {
17
-    margin-right: 24px;
18
-  }
19
-}
9
+  height: 100%;
10
+  background-image: url(~@/assets/images/login/background.png);
11
+  background-repeat: no-repeat;
12
+  background-size: cover;
13
+  display: flex;
14
+  justify-content: center;
15
+  align-items: center;
20 16
 
21
-.content {
22
-  flex: 1;
23
-  padding: 32px 0;
24
-}
17
+  form {
18
+    flex: none;
19
+    width: 720px;
20
+    margin: 0 auto;
21
+    border-radius: 20px;
22
+    overflow: hidden;
23
+    background: transparent;
24
+    display: flex;
25 25
 
26
-@media (min-width: @screen-md-min) {
27
-  .container {
28
-    background-image: url('https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/V-_oS6r-i7wAAAAAAAAAAAAAFl94AQBr');
29
-    background-size: cover;
30
-  }
26
+    .form-left {
27
+      flex: 2;
28
+      height: 480px;
29
+      background-image: url(~@/assets/images/login/小背景.png);
30
+      background-color: transparent;
31
+      background-repeat: no-repeat;
32
+      background-size: cover;
33
+      display: flex;
34
+      align-items: center;
31 35
 
32
-  .content {
33
-    padding: 32px 0 24px;
34
-  }
35
-}
36
+      img {
37
+        background: rgba(5,33,59,0.5);
38
+        padding: 16px 40px;
39
+      }
40
+    }
41
+
42
+    .form-right {
43
+      flex: 1;
44
+      background: #fff;
45
+      box-sizing: border-box;
46
+      padding: 0 1em;
47
+      padding-top: 40px;
48
+      overflow: hidden;
36 49
 
37
-.icon {
38
-  margin-left: 8px;
39
-  color: rgba(0, 0, 0, 0.2);
40
-  font-size: 24px;
41
-  vertical-align: middle;
42
-  cursor: pointer;
43
-  transition: color 0.3s;
50
+      h2 {
51
+        text-align: center;
52
+        font-size: 24px;
53
+        color: #0D267C;
54
+        line-height: 36px;
55
+      }
44 56
 
45
-  &:hover {
46
-    color: @primary-color;
57
+      .sub-title {
58
+        box-sizing: border-box;
59
+        padding: 0 1em;
60
+        font-size: 18px;
61
+        color: #0D267C;
62
+        display: flex;
63
+        align-items: center;
64
+        justify-content: space-between;
65
+
66
+        img {
67
+          width: 60px;
68
+          display: block;
69
+          box-sizing: border-box;
70
+          flex: none;
71
+        }
72
+        
73
+      }
74
+
75
+      .input-control {
76
+        margin-top: 2em;
77
+      }
78
+
79
+      .form-control.cust-input {
80
+        border-radius: 0;
81
+        border: none;
82
+        border-bottom: 1px solid #0D267C;
83
+        box-shadow: none;
84
+      }
85
+
86
+      .btn-primary {
87
+        display: inline-block;
88
+        margin-bottom: 0;
89
+        user-select: none;
90
+        border: 1px solid transparent;
91
+        border-radius: 4px;
92
+        transition: .4s cubic-bezier(.175, .885, .32, 1);
93
+
94
+        padding: 10px 16px;
95
+        font-size: 17px;
96
+        line-height: 1.25;
97
+        border-radius: 4px;
98
+
99
+        color: #fff;
100
+        background-color: #0D267C;
101
+        border-color: #0D267C;
102
+
103
+        margin-top: 4em;
104
+        width: 100%;
105
+        height: auto;
106
+      }
107
+    }
47 108
   }
48
-}
109
+  
110
+}

+ 19
- 0
src/services/api/user.js Прегледај датотеку

@@ -0,0 +1,19 @@
1
+import { request } from '@umijs/max';
2
+
3
+/**
4
+ * 获取当前人员
5
+ * 
6
+ * showType 是 umi 封装的 request 参数, 0 代表不显示错误
7
+ * 
8
+ * @param {*} 
9
+ * @returns
10
+ */
11
+ export const queryCurrentUser = () => request('/users/current', { showType: 0 });
12
+
13
+ /**
14
+  * 登录
15
+  * @param {*} 
16
+  * @returns
17
+  */
18
+  export const login = (data) => request('/login', { data, method: 'post' });
19
+

+ 14
- 9
src/utils/request.js Прегледај датотеку

@@ -2,9 +2,7 @@ import { message } from 'antd';
2 2
 
3 3
 function requestInterceptor(url, options) {
4 4
   const headers = options.headers || {};
5
-  // const token = sessionStorage.getItem('token')
6
-  //   ? { Authorization: `Bearer ${sessionStorage.getItem('token')}` }
7
-  //   : {};
5
+  const token = sessionStorage.getItem('token') || '';
8 6
 
9 7
   return {
10 8
     // url,
@@ -13,27 +11,34 @@ function requestInterceptor(url, options) {
13 11
       ...options,
14 12
       headers: {
15 13
         ...headers,
16
-        // ...token,
14
+        Authorization: token,
17 15
       },
18 16
     },
19 17
   };
20 18
 }
21 19
 
22 20
 async function responseInterceptor(response) {
23
-  console.log(response, 'responseresponse');
24
-
25 21
   if (response.headers['content-type'] === 'application/vnd.ms-excel;charset=utf-8') {
26
-    console.log(response.data, 'data');
27 22
     return response;
28 23
   }
29 24
 
30 25
   const { data } = response;
31 26
   if (data.code === 1000) {
27
+    if (data.data.token) {
28
+      sessionStorage.setItem('token', data.data.token);
29
+    }
30
+
32 31
     return data;
33 32
   } else {
34
-    message.error(data.message || '系统错误');
33
+    if (response.config.showType !== 0) {
34
+      const errMsg = data.message || '系统错误';
35
+      message.error(errMsg.indexOf('exception') > -1 ? '服务异常' : errMsg);
36
+    }
35 37
   }
36
-  return Promise.reject(data);
38
+
39
+  console.error(response);
40
+
41
+  return Promise.reject(data.message || '系统错误');
37 42
 }
38 43
 
39 44
 export const requestConfig = {