import Footer from '@/components/Footer';
import { getCaptchaImg, login } from '@/services/system/auth';
import { getFakeCaptcha, sancGenerateQrcode, sancAuthCheck } from '@/services/ant-design-pro/login';
import {
AlipayCircleOutlined,
LockOutlined,
MobileOutlined,
TaobaoCircleOutlined,
UserOutlined,
WeiboCircleOutlined,
} from '@ant-design/icons';
import {
LoginForm,
ProFormCaptcha,
ProFormCheckbox,
ProFormText,
} from '@ant-design/pro-components';
import { useEmotionCss } from '@ant-design/use-emotion-css';
import { FormattedMessage, Helmet, history, SelectLang, useIntl, useModel } from '@umijs/max';
import { Alert, Col, Image, message, Row, Tabs, QRCode } from 'antd';
import Settings from '../../../../config/defaultSettings';
import React, { useEffect, useState } from 'react';
import { flushSync } from 'react-dom';
// flushSync 允许你强制 React 同步刷新提供的回调中的任何更新。这确保了 DOM 立即更新
import { clearSessionToken, setSessionToken } from '@/access';
import logoImg from '@/assets/logo.svg';
import login_imge2b033b1 from '@/assets/login_img.e2b033b1.png';
import { use } from 'echarts';
let timer: any = null;
const ActionIcons = () => {
const langClassName = useEmotionCss(({ token }) => {
return {
marginLeft: '8px',
color: 'rgba(0, 0, 0, 0.2)',
fontSize: '24px',
verticalAlign: 'middle',
cursor: 'pointer',
transition: 'color 0.3s',
'&:hover': {
color: token.colorPrimaryActive,
},
};
});
return (
<>
>
);
};
const Lang = () => {
const langClassName = useEmotionCss(({ token }) => {
return {
width: 42,
height: 42,
lineHeight: '42px',
position: 'fixed',
right: 16,
borderRadius: token.borderRadius,
':hover': {
backgroundColor: token.colorBgTextHover,
},
};
});
return (
{SelectLang && }
);
};
const LoginMessage: React.FC<{
content: string;
}> = ({ content }) => {
return (
);
};
const Login: React.FC = () => {
const [userLoginState, setUserLoginState] = useState({ code: 200 });
const [type, setType] = useState('account');
const { initialState, setInitialState } = useModel('@@initialState');
const [captchaCode, setCaptchaCode] = useState('');
const [uuid, setUuid] = useState('');
const [qrcodeVal, setQrcodeVal] = useState('');
const [qrcodeTime, setQrcodeTime] = useState('');
const [qrcodeStatus, setQrcodeStatus] = useState('loading');
const containerClassName = useEmotionCss(() => {
return {
display: 'flex',
flexDirection: 'column',
height: '100vh',
overflow: 'auto',
backgroundImage:
"url('https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/V-_oS6r-i7wAAAAAAAAAAAAAFl94AQBr')",
backgroundSize: '100% 100%',
};
});
const intl = useIntl();
const getCaptchaCode = async () => {
const response = await getCaptchaImg();
const imgdata = `data:image/png;base64,${response.img}`;
setCaptchaCode(imgdata);
setUuid(response.uuid);
};
const fetchUserInfo = async () => {
const userInfo = await initialState?.fetchUserInfo?.();
if (userInfo) {
flushSync(() => {
setInitialState((s) => ({
...s,
currentUser: userInfo,
}));
});
}
};
const handleSubmit = async (values: API.LoginParams) => {
try {
// 登录
const response = await login({ ...values, uuid });
if (response.code === 200) {
const defaultLoginSuccessMessage = intl.formatMessage({
id: 'pages.login.success',
defaultMessage: '登录成功!',
});
const current = new Date();
const expireTime = current.setTime(current.getTime() + 1000 * 12 * 60 * 60);
setSessionToken(response?.token, response?.token, expireTime);
message.success(defaultLoginSuccessMessage);
await fetchUserInfo();
console.log('login ok');
const urlParams = new URL(window.location.href).searchParams;
history.push(urlParams.get('redirect') || '/');
setTimeout(() => history.go(0), 0);
return;
} else {
message.error(response.msg);
clearSessionToken();
// 如果失败去设置用户错误信息
setUserLoginState({ ...response, type });
getCaptchaCode();
}
} catch (error) {
const defaultLoginFailureMessage = intl.formatMessage({
id: 'pages.login.failure',
defaultMessage: '登录失败,请重试!',
});
message.error(defaultLoginFailureMessage);
}
};
const generateQrcode = async () => {
setQrcodeStatus('loading');
const response = await sancGenerateQrcode();
if (response.code === 200) {
const { qrCode, validDate } = response.data;
setQrcodeStatus('active');
setQrcodeVal(qrCode);
setQrcodeTime(validDate);
if (timer) {
clearInterval(timer);
}
timer = setInterval(() => {
const timeDiff = getTimeDiff(validDate);
if (timeDiff > 0) {
clearInterval(timer);
setQrcodeStatus('expired');
return;
}
checkQrcode(qrCode as string);
}, 2000);
}
};
const checkQrcode = async (text: string) => {
const response = await sancAuthCheck(text);
if (response.code === 200) {
const { authStatus } = response.data;
switch (authStatus) {
case 'success':
setQrcodeStatus('scanned');
message.success('扫码成功');
const defaultLoginSuccessMessage = intl.formatMessage({
id: 'pages.login.success',
defaultMessage: '登录成功!',
});
const current = new Date();
const expireTime = current.setTime(current.getTime() + 1000 * 12 * 60 * 60);
setSessionToken(response.data?.token, response.data?.token, expireTime);
message.success(defaultLoginSuccessMessage);
await fetchUserInfo();
const urlParams = new URL(window.location.href).searchParams;
history.push(urlParams.get('redirect') || '/');
setTimeout(() => history.go(0), 0);
break;
case 'failed':
setQrcodeStatus('expired');
message.error(response.data.errCode + ':' + response.data.errMsg);
break;
case 'pending':
break;
}
} else {
clearInterval(timer);
setQrcodeStatus('expired');
}
};
function getTimeDiff(validTimeStr: string): number {
const now = new Date();
const [h, m, s] = validTimeStr.split(':').map(Number);
const target = new Date();
target.setHours(h, m, s, 0);
return now.getTime() - target.getTime();
}
const { code } = userLoginState;
const loginType = type;
useEffect(() => {
getCaptchaCode();
}, []);
return (
{intl.formatMessage({
id: 'menu.login',
defaultMessage: '登录页',
})}
- {Settings.title}
}
title="石河子智慧就业服务系统"
// subTitle={intl.formatMessage({ id: 'pages.layouts.userLayout.title' })}
initialValues={{
autoLogin: true,
}}
// actions={[
//
,
//
,
// ]}
onFinish={async (values) => {
await handleSubmit(values as API.LoginParams);
}}
>
{
setType(type);
if (timer) {
clearInterval(timer);
}
if (type === 'scanQode') {
generateQrcode();
}
}}
centered
items={[
{
key: 'account',
label: intl.formatMessage({
id: 'pages.login.accountLogin.tab',
defaultMessage: '账户密码登录',
}),
},
{
key: 'scanQode',
label: '社保卡扫码登录',
},
// {
// key: 'mobile',
// label: intl.formatMessage({
// id: 'pages.login.phoneLogin.tab',
// defaultMessage: '手机号登录',
// }),
// },
]}
/>
{/* {code !== 200 && loginType === 'account' && ( */}
{/* */}
{/*)}*/}
{type === 'scanQode' && (
<>
generateQrcode()}
value={qrcodeVal}
icon={login_imge2b033b1}
/>
>
)}
{type === 'account' && (
<>
,
}}
placeholder={intl.formatMessage({
id: 'pages.login.username.placeholder',
defaultMessage: '用户名: admin',
})}
rules={[
{
required: true,
message: (
),
},
]}
/>
,
}}
placeholder={intl.formatMessage({
id: 'pages.login.password.placeholder',
defaultMessage: '密码: admin123',
})}
rules={[
{
required: true,
message: (
),
},
]}
/>
),
},
]}
/>
getCaptchaCode()}
/>
>
)}
{code !== 200 && loginType === 'mobile' && }
{type === 'mobile' && (
<>
,
}}
name="mobile"
placeholder={intl.formatMessage({
id: 'pages.login.phoneNumber.placeholder',
defaultMessage: '手机号',
})}
rules={[
{
required: true,
message: (
),
},
{
pattern: /^1\d{10}$/,
message: (
),
},
]}
/>
,
}}
captchaProps={{
size: 'large',
}}
placeholder={intl.formatMessage({
id: 'pages.login.captcha.placeholder',
defaultMessage: '请输入验证码',
})}
captchaTextRender={(timing, count) => {
if (timing) {
return `${count} ${intl.formatMessage({
id: 'pages.getCaptchaSecondText',
defaultMessage: '获取验证码',
})}`;
}
return intl.formatMessage({
id: 'pages.login.phoneLogin.getVerificationCode',
defaultMessage: '获取验证码',
});
}}
name="captcha"
rules={[
{
required: true,
message: (
),
},
]}
onGetCaptcha={async (phone) => {
const result = await getFakeCaptcha({
phone,
});
if (!result) {
return;
}
message.success('获取验证码成功!验证码为:1234');
}}
/>
>
)}
{type !== 'scanQode' && (
)}
);
};
export default Login;