|
|
@@ -1,15 +1,22 @@
|
|
|
-import { AlipayCircleOutlined, TaobaoCircleOutlined, WeiboCircleOutlined } from '@ant-design/icons';
|
|
|
-import { Alert, Checkbox } from 'antd';
|
|
|
+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 { Link, connect, Dispatch, useIntl, FormattedMessage } from 'umi';
|
|
|
+import ProForm, { ProFormCaptcha, ProFormCheckbox, ProFormText } from '@ant-design/pro-form';
|
|
|
+import { connect, Dispatch, useIntl, FormattedMessage } from 'umi';
|
|
|
import { StateType } from '@/models/login';
|
|
|
-import { LoginParamsType } from '@/services/login';
|
|
|
+import { getFakeCaptcha, LoginParamsType } from '@/services/login';
|
|
|
import { ConnectState } from '@/models/connect';
|
|
|
-import LoginForm from './components/Login';
|
|
|
|
|
|
-import styles from './style.less';
|
|
|
+import styles from './index.less';
|
|
|
|
|
|
-const { Tab, UserName, Password, Mobile, Captcha, Submit } = LoginForm;
|
|
|
interface LoginProps {
|
|
|
dispatch: Dispatch;
|
|
|
userLogin: StateType;
|
|
|
@@ -32,7 +39,6 @@ const LoginMessage: React.FC<{
|
|
|
const Login: React.FC<LoginProps> = (props) => {
|
|
|
const { userLogin = {}, submitting } = props;
|
|
|
const { status, type: loginType } = userLogin;
|
|
|
- const [autoLogin, setAutoLogin] = useState(true);
|
|
|
const [type, setType] = useState<string>('account');
|
|
|
const intl = useIntl();
|
|
|
|
|
|
@@ -45,131 +51,187 @@ const Login: React.FC<LoginProps> = (props) => {
|
|
|
};
|
|
|
return (
|
|
|
<div className={styles.main}>
|
|
|
- <LoginForm activeKey={type} onTabChange={setType} onSubmit={handleSubmit}>
|
|
|
- <Tab
|
|
|
- key="account"
|
|
|
- tab={intl.formatMessage({
|
|
|
- id: 'pages.login.accountLogin.tab',
|
|
|
- defaultMessage: '账户密码登录',
|
|
|
- })}
|
|
|
- >
|
|
|
- {status === 'error' && loginType === 'account' && !submitting && (
|
|
|
- <LoginMessage
|
|
|
- content={intl.formatMessage({
|
|
|
- id: 'pages.login.accountLogin.errorMessage',
|
|
|
- defaultMessage: '账户或密码错误(admin/ant.design)',
|
|
|
- })}
|
|
|
- />
|
|
|
- )}
|
|
|
-
|
|
|
- <UserName
|
|
|
- name="userName"
|
|
|
- placeholder={intl.formatMessage({
|
|
|
- id: 'pages.login.username.placeholder',
|
|
|
- defaultMessage: '用户名: admin or user',
|
|
|
+ <ProForm
|
|
|
+ initialValues={{
|
|
|
+ autoLogin: true,
|
|
|
+ }}
|
|
|
+ submitter={{
|
|
|
+ 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: '账户密码登录',
|
|
|
})}
|
|
|
- rules={[
|
|
|
- {
|
|
|
- required: true,
|
|
|
- message: (
|
|
|
- <FormattedMessage
|
|
|
- id="pages.login.username.required"
|
|
|
- defaultMessage="请输入用户名!"
|
|
|
- />
|
|
|
- ),
|
|
|
- },
|
|
|
- ]}
|
|
|
/>
|
|
|
- <Password
|
|
|
- name="password"
|
|
|
- placeholder={intl.formatMessage({
|
|
|
- id: 'pages.login.password.placeholder',
|
|
|
- defaultMessage: '密码: ant.design',
|
|
|
+ <Tabs.TabPane
|
|
|
+ key="mobile"
|
|
|
+ tab={intl.formatMessage({
|
|
|
+ id: 'pages.login.phoneLogin.tab',
|
|
|
+ defaultMessage: '手机号登录',
|
|
|
})}
|
|
|
- rules={[
|
|
|
- {
|
|
|
- required: true,
|
|
|
- message: (
|
|
|
- <FormattedMessage
|
|
|
- id="pages.login.password.required"
|
|
|
- defaultMessage="请输入密码!"
|
|
|
- />
|
|
|
- ),
|
|
|
- },
|
|
|
- ]}
|
|
|
/>
|
|
|
- </Tab>
|
|
|
- <Tab
|
|
|
- key="mobile"
|
|
|
- tab={intl.formatMessage({
|
|
|
- id: 'pages.login.phoneLogin.tab',
|
|
|
- defaultMessage: '手机号登录',
|
|
|
- })}
|
|
|
- >
|
|
|
- {status === 'error' && loginType === 'mobile' && !submitting && (
|
|
|
- <LoginMessage
|
|
|
- content={intl.formatMessage({
|
|
|
- id: 'pages.login.phoneLogin.errorMessage',
|
|
|
- defaultMessage: '验证码错误',
|
|
|
- })}
|
|
|
- />
|
|
|
- )}
|
|
|
- <Mobile
|
|
|
- name="mobile"
|
|
|
- placeholder={intl.formatMessage({
|
|
|
- id: 'pages.login.phoneNumber.placeholder',
|
|
|
- defaultMessage: '手机号',
|
|
|
- })}
|
|
|
- rules={[
|
|
|
- {
|
|
|
- required: true,
|
|
|
- message: (
|
|
|
- <FormattedMessage
|
|
|
- id="pages.login.phoneNumber.required"
|
|
|
- defaultMessage="请输入手机号!"
|
|
|
- />
|
|
|
- ),
|
|
|
- },
|
|
|
- {
|
|
|
- pattern: /^1\d{10}$/,
|
|
|
- message: (
|
|
|
- <FormattedMessage
|
|
|
- id="pages.login.phoneNumber.invalid"
|
|
|
- defaultMessage="手机号格式错误!"
|
|
|
- />
|
|
|
- ),
|
|
|
- },
|
|
|
- ]}
|
|
|
- />
|
|
|
- <Captcha
|
|
|
- name="captcha"
|
|
|
- placeholder={intl.formatMessage({
|
|
|
- id: 'pages.login.captcha.placeholder',
|
|
|
- defaultMessage: '验证码',
|
|
|
- })}
|
|
|
- countDown={120}
|
|
|
- getCaptchaButtonText=""
|
|
|
- getCaptchaSecondText={intl.formatMessage({
|
|
|
- id: 'pages.getCaptchaSecondText',
|
|
|
- defaultMessage: '秒',
|
|
|
+ </Tabs>
|
|
|
+
|
|
|
+ {status === 'error' && loginType === 'account' && !submitting && (
|
|
|
+ <LoginMessage
|
|
|
+ content={intl.formatMessage({
|
|
|
+ id: 'pages.login.accountLogin.errorMessage',
|
|
|
+ defaultMessage: '账户或密码错误(admin/ant.design)',
|
|
|
})}
|
|
|
- rules={[
|
|
|
- {
|
|
|
- required: true,
|
|
|
- message: (
|
|
|
- <FormattedMessage
|
|
|
- id="pages.login.captcha.required"
|
|
|
- defaultMessage="请输入验证码!"
|
|
|
- />
|
|
|
- ),
|
|
|
- },
|
|
|
- ]}
|
|
|
/>
|
|
|
- </Tab>
|
|
|
- <div>
|
|
|
- <Checkbox checked={autoLogin} onChange={(e) => setAutoLogin(e.target.checked)}>
|
|
|
+ )}
|
|
|
+ {type === 'account' && (
|
|
|
+ <>
|
|
|
+ <ProFormText
|
|
|
+ name="userName"
|
|
|
+ fieldProps={{
|
|
|
+ size: 'large',
|
|
|
+ prefix: <UserOutlined className={styles.prefixIcon} />,
|
|
|
+ }}
|
|
|
+ placeholder={intl.formatMessage({
|
|
|
+ id: 'pages.login.username.placeholder',
|
|
|
+ defaultMessage: '用户名: admin or user',
|
|
|
+ })}
|
|
|
+ rules={[
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: (
|
|
|
+ <FormattedMessage
|
|
|
+ id="pages.login.username.required"
|
|
|
+ defaultMessage="请输入用户名!"
|
|
|
+ />
|
|
|
+ ),
|
|
|
+ },
|
|
|
+ ]}
|
|
|
+ />
|
|
|
+ <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: (
|
|
|
+ <FormattedMessage
|
|
|
+ id="pages.login.password.required"
|
|
|
+ defaultMessage="请输入密码!"
|
|
|
+ />
|
|
|
+ ),
|
|
|
+ },
|
|
|
+ ]}
|
|
|
+ />
|
|
|
+ </>
|
|
|
+ )}
|
|
|
+
|
|
|
+ {status === 'error' && loginType === 'mobile' && !submitting && (
|
|
|
+ <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: (
|
|
|
+ <FormattedMessage
|
|
|
+ id="pages.login.phoneNumber.required"
|
|
|
+ defaultMessage="请输入手机号!"
|
|
|
+ />
|
|
|
+ ),
|
|
|
+ },
|
|
|
+ {
|
|
|
+ pattern: /^1\d{10}$/,
|
|
|
+ message: (
|
|
|
+ <FormattedMessage
|
|
|
+ id="pages.login.phoneNumber.invalid"
|
|
|
+ defaultMessage="手机号格式错误!"
|
|
|
+ />
|
|
|
+ ),
|
|
|
+ },
|
|
|
+ ]}
|
|
|
+ />
|
|
|
+ <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: (
|
|
|
+ <FormattedMessage
|
|
|
+ id="pages.login.captcha.required"
|
|
|
+ defaultMessage="请输入验证码!"
|
|
|
+ />
|
|
|
+ ),
|
|
|
+ },
|
|
|
+ ]}
|
|
|
+ onGetCaptcha={async (mobile) => {
|
|
|
+ const result = await getFakeCaptcha(mobile);
|
|
|
+ if (result === false) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ message.success('获取验证码成功!验证码为:1234');
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ </>
|
|
|
+ )}
|
|
|
+ <div
|
|
|
+ style={{
|
|
|
+ marginBottom: 24,
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <ProFormCheckbox noStyle name="autoLogin">
|
|
|
<FormattedMessage id="pages.login.rememberMe" defaultMessage="自动登录" />
|
|
|
- </Checkbox>
|
|
|
+ </ProFormCheckbox>
|
|
|
<a
|
|
|
style={{
|
|
|
float: 'right',
|
|
|
@@ -178,19 +240,13 @@ const Login: React.FC<LoginProps> = (props) => {
|
|
|
<FormattedMessage id="pages.login.forgotPassword" defaultMessage="忘记密码" />
|
|
|
</a>
|
|
|
</div>
|
|
|
- <Submit loading={submitting}>
|
|
|
- <FormattedMessage id="pages.login.submit" defaultMessage="登录" />
|
|
|
- </Submit>
|
|
|
- <div className={styles.other}>
|
|
|
- <FormattedMessage id="pages.login.loginWith" defaultMessage="其他登录方式" />
|
|
|
- <AlipayCircleOutlined className={styles.icon} />
|
|
|
- <TaobaoCircleOutlined className={styles.icon} />
|
|
|
- <WeiboCircleOutlined className={styles.icon} />
|
|
|
- <Link className={styles.register} to="/user/register">
|
|
|
- <FormattedMessage id="pages.login.registerAccount" defaultMessage="注册账户" />
|
|
|
- </Link>
|
|
|
- </div>
|
|
|
- </LoginForm>
|
|
|
+ </ProForm>
|
|
|
+ <Space className={styles.other}>
|
|
|
+ <FormattedMessage id="pages.login.loginWith" defaultMessage="其他登录方式" />
|
|
|
+ <AlipayCircleOutlined className={styles.icon} />
|
|
|
+ <TaobaoCircleOutlined className={styles.icon} />
|
|
|
+ <WeiboCircleOutlined className={styles.icon} />
|
|
|
+ </Space>
|
|
|
</div>
|
|
|
);
|
|
|
};
|