Commit 312df31cf00709b19f1d098a8423b8b46e3be29a

Authored by sanmu
1 parent 73fd7ef2

feat: add login

.umirc.ts
... ... @@ -12,11 +12,11 @@ export default defineConfig({
12 12 title: '订单管理系统',
13 13 },
14 14 proxy: {
15   - '/service/': {
16   - target: 'http://localhost:8085/',
17   - // target: 'http://39.108.227.113:8085/',
  15 + '/api/': {
  16 + // target: 'http://localhost:8085/',
  17 + target: 'http://39.108.227.113:8085/',
18 18 changeOrigin: true,
19   - // pathRewrite: { '^/api': '' },
  19 + pathRewrite: { '^/api': '' },
20 20 },
21 21 },
22 22 routes: [
... ...
README.md
... ... @@ -29,4 +29,6 @@
29 29  
30 30 # 校验没生效
31 31  
32   -chmod +x .husky/commit-msg chmod +x .husky/pre-commit
  32 +chmod +x .husky/commit-msg
  33 +
  34 +chmod +x .husky/pre-commit
... ...
src/app.ts
1 1 // 运行时配置
2 2  
3   -import { RequestConfig } from '@umijs/max';
  3 +import { RequestConfig, history } from '@umijs/max';
4 4  
5 5 import '@inspir/assembly-css/dist/special.css';
6 6 import { message } from 'antd';
... ... @@ -34,10 +34,11 @@ export const request: RequestConfig = {
34 34 if (response && response.status) {
35 35 // 401重定向
36 36 if (response.status === 401) {
37   - if (!location.pathname.includes(loginPath)) {
  37 + if (!location.pathname.includes('login')) {
38 38 localStorage.removeItem('token');
  39 + localStorage.removeItem('userInfo');
39 40 message.error('token失效,请重新登录!');
40   - // history.push(loginPath);
  41 + history.push('/login');
41 42 return null;
42 43 }
43 44 }
... ... @@ -74,7 +75,7 @@ export const request: RequestConfig = {
74 75 }
75 76  
76 77 return {
77   - url,
  78 + url: '/api' + url,
78 79 options: {
79 80 ...options,
80 81 signal,
... ... @@ -93,6 +94,7 @@ export const request: RequestConfig = {
93 94 if (data.result !== RESPONSE_CODE.SUCCESS) {
94 95 message.error(data.message);
95 96 }
  97 +
96 98 // do something
97 99 return response;
98 100 },
... ...
src/models/user.ts
... ... @@ -2,7 +2,28 @@ import { useState } from 'react';
2 2  
3 3 // src/models/userModel.ts
4 4 export default function Page() {
5   - const { token, setToken } = useState('');
  5 + const [token, setToken] = useState('');
  6 + const [userInfo, setUserInfo] = useState({});
6 7  
7   - return { token, setToken };
  8 + const setUserToken = (token: string) => {
  9 + localStorage.setItem('token', token);
  10 + setToken(token);
  11 + };
  12 +
  13 + const setUserLocalInfo = (token: string, userInfo: any) => {
  14 + localStorage.setItem('token', token);
  15 + setToken(token);
  16 +
  17 + localStorage.setItem('userInfo', JSON.stringify(userInfo));
  18 + setUserInfo(userInfo);
  19 + };
  20 +
  21 + return {
  22 + token,
  23 + setToken,
  24 + userInfo,
  25 + setUserInfo,
  26 + setUserToken,
  27 + setUserLocalInfo,
  28 + };
8 29 }
... ...
src/pages/Login/index.tsx
1   -import { LockOutlined, MobileOutlined, UserOutlined } from '@ant-design/icons';
  1 +import { RESPONSE_CODE } from '@/constants/enum';
  2 +import {
  3 + postOrderErpAuthLoginByPwd,
  4 + postOrderErpCaptchaGetImgCaptchaCode,
  5 +} from '@/services';
  6 +import { LockOutlined, UserOutlined } from '@ant-design/icons';
2 7 import {
3 8 LoginForm,
4 9 ProConfigProvider,
5   - ProFormCaptcha,
6   - ProFormCheckbox,
7 10 ProFormText,
8 11 } from '@ant-design/pro-components';
9   -import { history } from '@umijs/max';
10   -import { Tabs, message, theme } from 'antd';
11   -import { useState } from 'react';
12   -
13   -type LoginType = 'phone' | 'account';
  12 +import { history, useModel } from '@umijs/max';
  13 +import { theme } from 'antd';
  14 +import { useEffect, useState } from 'react';
14 15  
15 16 export default () => {
  17 + const { setUserLocalInfo } = useModel('user');
16 18 const { token } = theme.useToken();
17   - const [loginType, setLoginType] = useState<LoginType>('phone');
  19 + const [code, setCode] = useState('');
  20 + const [uuid, setUuid] = useState('');
18 21  
  22 + const fetchCode = async () => {
  23 + const res = await postOrderErpCaptchaGetImgCaptchaCode();
  24 + setCode(res.data.img);
  25 + setUuid(res.data.uuid);
  26 + };
  27 + useEffect(() => {
  28 + fetchCode();
  29 + }, []);
19 30 return (
20 31 <ProConfigProvider hashed={false}>
21 32 <div
... ... @@ -25,114 +36,69 @@ export default () =&gt; {
25 36 <div className="flex items-center justify-center">
26 37 <LoginForm
27 38 title="订单管理"
28   - onFinish={async () => {
29   - history.push('/order');
  39 + onFinish={async (values) => {
  40 + const res = await postOrderErpAuthLoginByPwd({
  41 + data: { ...values, imgCaptchaUuid: uuid },
  42 + });
  43 +
  44 + setUserLocalInfo(res.data.token, res.data?.user);
  45 + if (res.result === RESPONSE_CODE.SUCCESS) {
  46 + history.push('/order');
  47 + }
30 48 }}
31 49 >
32   - <Tabs
33   - centered
34   - activeKey={loginType}
35   - onChange={(activeKey) => setLoginType(activeKey as LoginType)}
36   - >
37   - <Tabs.TabPane key={'account'} tab={'账号密码登录'} />
38   - <Tabs.TabPane key={'phone'} tab={'手机号登录'} />
39   - </Tabs>
40   - {loginType === 'account' && (
41   - <>
42   - <ProFormText
43   - name="username"
44   - fieldProps={{
45   - size: 'large',
46   - prefix: <UserOutlined className={'prefixIcon'} />,
47   - }}
48   - placeholder={'用户名'}
49   - rules={[
50   - {
51   - required: true,
52   - message: '请输入用户名!',
53   - },
54   - ]}
55   - />
56   - <ProFormText.Password
57   - name="password"
58   - fieldProps={{
59   - size: 'large',
60   - prefix: <LockOutlined className={'prefixIcon'} />,
61   - }}
62   - placeholder={'密码'}
63   - rules={[
64   - {
65   - required: true,
66   - message: '请输入密码!',
67   - },
68   - ]}
69   - />
70   - </>
71   - )}
72   - {loginType === 'phone' && (
73   - <>
74   - <ProFormText
75   - fieldProps={{
76   - size: 'large',
77   - prefix: <MobileOutlined className={'prefixIcon'} />,
78   - }}
79   - name="mobile"
80   - placeholder={'手机号'}
81   - rules={[
82   - {
83   - required: true,
84   - message: '请输入手机号!',
85   - },
86   - {
87   - pattern: /^1\d{10}$/,
88   - message: '手机号格式错误!',
89   - },
90   - ]}
91   - />
92   - <ProFormCaptcha
93   - fieldProps={{
94   - size: 'large',
95   - prefix: <LockOutlined className={'prefixIcon'} />,
96   - }}
97   - captchaProps={{
98   - size: 'large',
99   - }}
100   - placeholder={'请输入验证码'}
101   - captchaTextRender={(timing, count) => {
102   - if (timing) {
103   - return `${count} ${'获取验证码'}`;
104   - }
105   - return '获取验证码';
106   - }}
107   - name="captcha"
108   - rules={[
109   - {
110   - required: true,
111   - message: '请输入验证码!',
112   - },
113   - ]}
114   - onGetCaptcha={async () => {
115   - message.success('获取验证码成功!验证码为:1234');
116   - }}
117   - />
118   - </>
119   - )}
120   - <div
121   - style={{
122   - marginBlockEnd: 24,
  50 + <div className="my-8"></div>
  51 + <ProFormText
  52 + name="userName"
  53 + fieldProps={{
  54 + size: 'large',
  55 + prefix: <UserOutlined className={'prefixIcon'} />,
  56 + }}
  57 + placeholder={'用户名'}
  58 + rules={[
  59 + {
  60 + required: true,
  61 + message: '请输入用户名!',
  62 + },
  63 + ]}
  64 + />
  65 + <ProFormText.Password
  66 + name="password"
  67 + fieldProps={{
  68 + size: 'large',
  69 + prefix: <LockOutlined className={'prefixIcon'} />,
  70 + }}
  71 + placeholder={'密码'}
  72 + rules={[
  73 + {
  74 + required: true,
  75 + message: '请输入密码!',
  76 + },
  77 + ]}
  78 + />
  79 + <ProFormText
  80 + name="imgCaptchaCode"
  81 + fieldProps={{
  82 + size: 'large',
  83 + }}
  84 + placeholder={'验证码'}
  85 + rules={[
  86 + {
  87 + required: true,
  88 + message: '请输入验证码!',
  89 + },
  90 + ]}
  91 + />
  92 + <img
  93 + src={code}
  94 + className="mb-4 cursor-pointer"
  95 + onClick={() => {
  96 + fetchCode();
123 97 }}
124   - >
125   - <ProFormCheckbox noStyle name="autoLogin">
126   - 自动登录
127   - </ProFormCheckbox>
128   - {/* <a
129   - style={{
130   - float: 'right',
131   - }}
132   - >
133   - 忘记密码
134   - </a> */}
135   - </div>
  98 + />
  99 + {/* <ProFormCheckbox noStyle name="autoLogin">
  100 + 自动登录
  101 + </ProFormCheckbox> */}
136 102 </LoginForm>
137 103 </div>
138 104 </div>
... ...