Browse Source

feat: 保留一份原有的登录

pull/141/head
cp3hnu 1 year ago
parent
commit
c3763d1a42
1 changed files with 221 additions and 0 deletions
  1. +221
    -0
      react-ui/src/pages/User/Login/login.tsx

+ 221
- 0
react-ui/src/pages/User/Login/login.tsx View File

@@ -0,0 +1,221 @@
import { clearSessionToken, setSessionToken } from '@/access';
import { getCaptchaImg, login } from '@/services/system/auth';
import { parseJsonText } from '@/utils';
import { safeInvoke } from '@/utils/functional';
import LocalStorage from '@/utils/localStorage';
import { to } from '@/utils/promise';
import { history, useModel } from '@umijs/max';
import { Button, Checkbox, Flex, Form, Image, Input, message, type InputRef } from 'antd';
import CryptoJS from 'crypto-js';
import { useEffect, useRef, useState } from 'react';
import { flushSync } from 'react-dom';
import styles from './login.less';

const VERSION = 1;
const AESKEY = 'OPENSOURCETECHNOLOGYCENTER';

const LoginInputPrefix = ({ icon }: { icon: string }) => {
return (
<div className={styles['login-input-prefix']}>
<img className={styles['login-input-prefix__icon']} src={icon} alt="" draggable={false} />
<div className={styles['login-input-prefix__line']}></div>
</div>
);
};

const Login = () => {
const { initialState, setInitialState } = useModel('@@initialState');
const [captchaCode, setCaptchaCode] = useState<string>('');
const [uuid, setUuid] = useState<string>('');
const [form] = Form.useForm();
const captchaInputRef = useRef<InputRef>(null);

useEffect(() => {
getCaptchaCode();
const autoLogin = LocalStorage.getItem(LocalStorage.rememberPasswordKey) ?? 'false';
if (autoLogin === 'true') {
const userStorage = LocalStorage.getItem(LocalStorage.loginUserKey);
const userJson = safeInvoke((text: string) =>
CryptoJS.AES.decrypt(text, AESKEY).toString(CryptoJS.enc.Utf8),
)(userStorage);
const user = safeInvoke(parseJsonText)(userJson);
if (user && typeof user === 'object' && user.version === VERSION) {
const { username, password } = user;
form.setFieldsValue({ username: username, password: password, autoLogin: true });
} else {
form.setFieldsValue({ username: '', password: '', autoLogin: true });
LocalStorage.removeItem(LocalStorage.loginUserKey);
}
} else {
form.setFieldsValue({ username: '', password: '', autoLogin: false });
}
}, []);
const getCaptchaCode = async () => {
const [res] = await to(getCaptchaImg());
if (res) {
const imgdata = `data:image/png;base64,${res.img}`;
setCaptchaCode(imgdata);
setUuid(res.uuid);
}
};

const fetchUserInfo = async () => {
const userInfo = await initialState?.fetchUserInfo?.();
if (userInfo) {
flushSync(() => {
setInitialState((s) => ({
...s,
currentUser: userInfo,
}));
});
}
};

// 登录
const handleSubmit = async (values: API.LoginParams) => {
const [res, error] = await to(login({ ...values, uuid }));
if (res && res.data) {
const current = new Date();
const expireTime = current.setTime(current.getTime() + 1000 * 12 * 60 * 60);
const { access_token } = res.data;
setSessionToken(access_token, access_token, expireTime);
message.success('登录成功!');

LocalStorage.setItem(LocalStorage.rememberPasswordKey, values.autoLogin ? 'true' : 'false');
if (values.autoLogin) {
const user = {
username: values.username,
password: values.password,
version: VERSION,
};
const encrypted = CryptoJS.AES.encrypt(JSON.stringify(user), AESKEY).toString();
LocalStorage.setItem(LocalStorage.loginUserKey, encrypted);
} else {
LocalStorage.removeItem(LocalStorage.loginUserKey);
}

await fetchUserInfo();
const urlParams = new URL(window.location.href).searchParams;
history.push(urlParams.get('redirect') || '/');
} else {
if (error?.data?.code === 500 && error?.data?.msg === '验证码错误') {
captchaInputRef.current?.focus({
cursor: 'all',
});
}

clearSessionToken();
getCaptchaCode();
}
};

return (
<div className={styles['user-login']}>
<div className={styles['user-login__left']}>
<div className={styles['user-login__left__top']}>
<img
src={require('@/assets/img/logo.png')}
style={{ width: '32px', marginRight: '12px' }}
draggable={false}
alt=""
/>
智能材料科研平台
</div>
<div className={styles['user-login__left__title']}>
<span>智能材料科研平台</span>
<img
src={require('@/assets/img/login-ai-logo.png')}
className={styles['user-login__left__title__img']}
draggable={false}
alt=""
/>
</div>
<div className={styles['user-login__left__message']}>
<span>大语言模型运维 统一管理平台</span>
</div>
<img
className={styles['user-login__left__bottom-img']}
src={require('@/assets/img/login-left-image.png')}
draggable={false}
alt=""
/>
</div>
<div className={styles['user-login__right']}>
<div>
<div className={styles['user-login__right__title']}>
<span style={{ color: '#111111' }}>欢迎登录</span>
<span>智能材料科研平台</span>
</div>
<div className={styles['user-login__right__content']}>
<div className={styles['user-login__right__content__title']}>账号登录</div>
<div className={styles['user-login__right__content__form']}>
<Form
labelCol={{ span: 0 }}
wrapperCol={{ span: 24 }}
initialValues={{ autoLogin: true }}
onFinish={handleSubmit}
autoComplete="off"
form={form}
>
<Form.Item name="username" rules={[{ required: true, message: '请输入用户名' }]}>
<Input
placeholder="请输入用户名"
prefix={<LoginInputPrefix icon={require('@/assets/img/login-user.png')} />}
allowClear
/>
</Form.Item>

<Form.Item name="password" rules={[{ required: true, message: '请输入密码' }]}>
<Input.Password
placeholder="请输入密码"
prefix={<LoginInputPrefix icon={require('@/assets/img/login-password.png')} />}
allowClear
/>
</Form.Item>

<Flex align="start" style={{ height: '98px' }}>
<div style={{ flex: 1 }}>
<Form.Item name="code" rules={[{ required: true, message: '请输入验证码' }]}>
<Input
placeholder="请输入验证码"
prefix={
<LoginInputPrefix icon={require('@/assets/img/login-captcha.png')} />
}
ref={captchaInputRef}
allowClear
/>
</Form.Item>
</div>
<Image
className={styles['user-login__right__content__form__captcha']}
src={captchaCode}
alt="验证码"
preview={false}
onClick={() => getCaptchaCode()}
/>
</Flex>

<Form.Item
name="autoLogin"
valuePropName="checked"
labelCol={{ span: 0 }}
wrapperCol={{ span: 16 }}
>
<Checkbox>记住密码</Checkbox>
</Form.Item>

<Form.Item labelCol={{ span: 0 }} wrapperCol={{ span: 24 }}>
<Button type="primary" htmlType="submit">
登录
</Button>
</Form.Item>
</Form>
</div>
</div>
</div>
</div>
</div>
);
};

export default Login;

Loading…
Cancel
Save