qinglong/src/pages/login/index.tsx
2021-12-05 23:04:26 +08:00

218 lines
6.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { Fragment, useEffect, useState } from 'react';
import {
Button,
Row,
Input,
Form,
message,
notification,
Statistic,
} from 'antd';
import config from '@/utils/config';
import { history, Link } from 'umi';
import styles from './index.less';
import { request } from '@/utils/http';
import { useTheme } from '@/utils/hooks';
import { MobileOutlined } from '@ant-design/icons';
const FormItem = Form.Item;
const { Countdown } = Statistic;
const Login = () => {
const [loading, setLoading] = useState(false);
const [waitTime, setWaitTime] = useState<any>();
const { theme } = useTheme();
const [twoFactor, setTwoFactor] = useState(false);
const [verifying, setVerifying] = useState(false);
const [loginInfo, setLoginInfo] = useState<any>();
const handleOk = (values: any) => {
setLoading(true);
setTwoFactor(false);
setWaitTime(null);
request
.post(`${config.apiPrefix}login`, {
data: {
username: values.username,
password: values.password,
},
})
.then((data) => {
if (data.code === 420) {
setLoginInfo({
username: values.username,
password: values.password,
});
setTwoFactor(true);
} else {
checkResponse(data);
}
setLoading(false);
})
.catch(function (error) {
console.log(error);
setLoading(false);
});
};
const completeTowFactor = (values: any) => {
setVerifying(true);
request
.put(`${config.apiPrefix}user/two-factor/login`, {
data: { ...loginInfo, code: values.code },
})
.then((data: any) => {
if (data.code === 430) {
message.error(data.message);
} else {
checkResponse(data);
}
setVerifying(false);
})
.catch((error: any) => {
console.log(error);
setVerifying(false);
});
};
const checkResponse = (data: any) => {
if (data.code === 200) {
const {
token,
lastip,
lastaddr,
lastlogon,
retries = 0,
platform,
} = data.data;
localStorage.setItem(config.authKey, token);
notification.success({
message: '登录成功!',
description: (
<>
<div>
{lastlogon ? new Date(lastlogon).toLocaleString() : '-'}
</div>
<div>{lastaddr || '-'}</div>
<div>IP{lastip || '-'}</div>
<div>{platform || '-'}</div>
<div>{retries > 0 ? `失败${retries}` : '成功'}</div>
</>
),
duration: 5,
});
history.push('/crontab');
} else if (data.code === 100) {
message.warn(data.message);
} else if (data.code === 410) {
message.error(data.message);
setWaitTime(data.data);
} else {
message.error(data.message);
}
};
useEffect(() => {
const isAuth = localStorage.getItem(config.authKey);
if (isAuth) {
history.push('/crontab');
}
}, []);
return (
<div className={styles.container}>
<div className={styles.top}>
<div className={styles.header}>
<img
alt="logo"
className={styles.logo}
src="https://pic.imgdb.cn/item/61acd0dd2ab3f51d912b1986.png"
/>
<span className={styles.title}>
{twoFactor ? '两步验证' : config.siteName}
</span>
</div>
</div>
<div className={styles.main}>
{twoFactor ? (
<Form layout="vertical" onFinish={completeTowFactor}>
<FormItem
name="code"
label="验证码"
rules={[
{
pattern: /^[0-9]{6}$/,
message: '验证码为6位数字',
validateTrigger: 'onBlur',
},
]}
hasFeedback
>
<Input placeholder="6位数字" autoFocus autoComplete="off" />
</FormItem>
<Button
type="primary"
htmlType="submit"
style={{ width: '100%' }}
loading={verifying}
>
</Button>
</Form>
) : (
<Form layout="vertical" onFinish={handleOk}>
<FormItem name="username" label="用户名" hasFeedback>
<Input placeholder="用户名" autoFocus />
</FormItem>
<FormItem name="password" label="密码" hasFeedback>
<Input type="password" placeholder="密码" />
</FormItem>
<Row>
{waitTime ? (
<Button type="primary" style={{ width: '100%' }} disabled>
<Countdown
valueStyle={{
color:
theme === 'vs'
? 'rgba(0,0,0,.25)'
: 'rgba(232, 230, 227, 0.25)',
}}
className="inline-countdown"
onFinish={() => setWaitTime(null)}
format="ss"
value={Date.now() + 1000 * waitTime}
/>
</Button>
) : (
<Button
type="primary"
htmlType="submit"
style={{ width: '100%' }}
loading={loading}
>
</Button>
)}
</Row>
</Form>
)}
</div>
<div className={styles.extra}>
{twoFactor ? (
<div style={{ paddingLeft: 20, position: 'relative' }}>
<MobileOutlined style={{ position: 'absolute', left: 0, top: 4 }} />
</div>
) : (
''
)}
</div>
</div>
);
};
export default Login;