123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302 |
- import {
- AlipayCircleOutlined,
- LockTwoTone,
- MailTwoTone,
- MobileTwoTone,
- TaobaoCircleOutlined,
- UserOutlined,
- WeiboCircleOutlined,
- } from '@ant-design/icons';
- import { Alert, Space, message, Tabs } from 'antd';
- import React, { useState } from 'react';
- import ProForm, { ProFormCaptcha, ProFormCheckbox, ProFormText } from '@ant-design/pro-form';
- import { useIntl, Link, history, FormattedMessage, SelectLang, useModel } from 'umi';
- import Footer from '@/components/Footer';
- import { fakeAccountLogin, getFakeCaptcha, LoginParamsType } from '@/services/login';
- import styles from './index.less';
- import { selectNavList } from '@/services/user';
- const LoginMessage: React.FC<{
- content: string;
- }> = ({ content }) => (
- <Alert
- style={{
- marginBottom: 24,
- }}
- message={content}
- type="error"
- showIcon
- />
- );
- /**
- * 此方法会跳转到 redirect 参数所在的位置
- */
- const goto = () => {
- if (!history) return;
- setTimeout(() => {
- const { query } = history.location;
- const { redirect } = query as {
- redirect: string;
- };
- history.push(redirect || '/');
- }, 10);
- };
- const Login: React.FC<{}> = () => {
- const [submitting, setSubmitting] = useState(false);
- const [userLoginState, setUserLoginState] = useState<API.LoginStateType>({});
- const [type, setType] = useState<string>('account');
- const { initialState, setInitialState } = useModel('@@initialState');
- const intl = useIntl();
- const fetchUserInfo = async () => {
- const userInfo = await initialState?.fetchUserInfo?.();
- if (userInfo) {
- setInitialState({
- ...initialState,
- settings: {
- menu: {
- loading: true,
- },
- },
- currentUser: userInfo,
- });
- const menuData = await selectNavList();
- setInitialState({
- ...initialState,
- currentUser: userInfo,
- settings: {
- menu: {
- loading: false,
- },
- },
- menuData: menuData.data,
- });
- }
- };
- const handleSubmit = async (values: LoginParamsType) => {
- setSubmitting(true);
- try {
- // 登录
- await fakeAccountLogin({ ...values, type });
- await fetchUserInfo();
- message.success('登录成功!');
- goto();
- } catch (error) {
- console.log(error, 'error'); // 如果失败去设置用户错误信息
- setUserLoginState({
- status: 'error',
- type: 'account',
- });
- }
- setSubmitting(false);
- };
- const { status, type: loginType } = userLoginState;
- return (
- <div className={styles.container}>
- <div className={styles.lang}>{SelectLang && <SelectLang />}</div>
- <div className={styles.content}>
- <div className={styles.top}>
- <div className={styles.header}>
- <Link to="/">
- <img alt="logo" className={styles.logo} src="/logo.svg" />
- <span className={styles.title}>Ant Design</span>
- </Link>
- </div>
- <div className={styles.desc}>Ant Design 是西湖区最具影响力的 Web 设计规范</div>
- </div>
- <div className={styles.main}>
- <ProForm
- initialValues={{
- remeber: true,
- }}
- submitter={{
- searchConfig: {
- submitText: intl.formatMessage({
- id: 'pages.login.submit',
- defaultMessage: '登录',
- }),
- },
- render: (_, dom) => dom.pop(),
- submitButtonProps: {
- loading: submitting,
- size: 'large',
- style: {
- width: '100%',
- },
- },
- }}
- onFinish={async (values) => {
- handleSubmit(values);
- }}
- >
- <Tabs activeKey={type} onChange={setType}>
- <Tabs.TabPane
- key="account"
- tab={intl.formatMessage({
- id: 'pages.login.accountLogin.tab',
- defaultMessage: '账户密码登录',
- })}
- />
- <Tabs.TabPane
- key="mobile"
- tab={intl.formatMessage({
- id: 'pages.login.phoneLogin.tab',
- defaultMessage: '手机号登录',
- })}
- />
- </Tabs>
- {status === 'error' && loginType === 'account' && (
- <LoginMessage
- content={intl.formatMessage({
- id: 'pages.login.accountLogin.errorMessage',
- defaultMessage: '账户或密码错误(admin/ant.design)',
- })}
- />
- )}
- {type === 'account' && (
- <>
- <ProFormText
- name="mobile"
- fieldProps={{
- size: 'large',
- prefix: <UserOutlined className={styles.prefixIcon} />,
- }}
- placeholder={intl.formatMessage({
- id: 'pages.login.username.placeholder',
- defaultMessage: '用户名: admin or user',
- })}
- rules={[
- {
- required: true,
- message: '用户名是必填项!',
- },
- ]}
- />
- <ProFormText.Password
- name="password"
- fieldProps={{
- size: 'large',
- prefix: <LockTwoTone className={styles.prefixIcon} />,
- }}
- placeholder={intl.formatMessage({
- id: 'pages.login.password.placeholder',
- defaultMessage: '密码: ant.design',
- })}
- rules={[
- {
- required: true,
- message: '密码是必填项!',
- },
- ]}
- />
- </>
- )}
- {status === 'error' && loginType === 'mobile' && <LoginMessage content="验证码错误" />}
- {type === 'mobile' && (
- <>
- <ProFormText
- fieldProps={{
- size: 'large',
- prefix: <MobileTwoTone className={styles.prefixIcon} />,
- }}
- name="mobile"
- placeholder={intl.formatMessage({
- id: 'pages.login.phoneNumber.placeholder',
- defaultMessage: '手机号',
- })}
- rules={[
- {
- required: true,
- message: '手机号是必填项!',
- },
- {
- pattern: /^1\d{10}$/,
- message: '不合法的手机号!',
- },
- ]}
- />
- <ProFormCaptcha
- fieldProps={{
- size: 'large',
- prefix: <MailTwoTone className={styles.prefixIcon} />,
- }}
- captchaProps={{
- size: 'large',
- }}
- placeholder={intl.formatMessage({
- id: 'pages.login.captcha.placeholder',
- defaultMessage: '请输入验证码',
- })}
- captchaTextRender={(timing, count) =>
- timing
- ? `${count} ${intl.formatMessage({
- id: 'pages.getCaptchaSecondText',
- defaultMessage: '获取验证码',
- })}`
- : intl.formatMessage({
- id: 'pages.login.phoneLogin.getVerificationCode',
- defaultMessage: '获取验证码',
- })
- }
- name="captcha"
- rules={[
- {
- required: true,
- message: '验证码是必填项!',
- },
- ]}
- onGetCaptcha={async (mobile) => {
- const result = await getFakeCaptcha(mobile);
- if (result === false) {
- return;
- }
- message.success('获取验证码成功!验证码为:1234');
- }}
- />
- </>
- )}
- <div
- style={{
- marginBottom: 24,
- }}
- >
- <ProFormCheckbox noStyle name="remeber">
- 自动登录
- </ProFormCheckbox>
- <a
- style={{
- float: 'right',
- }}
- >
- 忘记密码 ?
- </a>
- </div>
- </ProForm>
- <Space className={styles.other}>
- 其他登录方式 :
- <AlipayCircleOutlined className={styles.icon} />
- <TaobaoCircleOutlined className={styles.icon} />
- <WeiboCircleOutlined className={styles.icon} />
- </Space>
- </div>
- </div>
- <Footer />
- </div>
- );
- };
- export default Login;
|