From 39560f05135971b338533f95ef191a2adc76102f Mon Sep 17 00:00:00 2001 From: chenshuai2144 Date: Mon, 12 Jul 2021 14:31:10 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=8F=B0=20chore:=20fix=20deploy=20error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/User/Login/index.less | 114 ++++++++++++ src/pages/User/Login/index.tsx | 318 ++++++++++++++++++++++++++++++++ 2 files changed, 432 insertions(+) create mode 100644 src/pages/User/Login/index.less create mode 100644 src/pages/User/Login/index.tsx diff --git a/src/pages/User/Login/index.less b/src/pages/User/Login/index.less new file mode 100644 index 00000000..f2ef746d --- /dev/null +++ b/src/pages/User/Login/index.less @@ -0,0 +1,114 @@ +@import '~antd/es/style/themes/default.less'; + +.container { + display: flex; + flex-direction: column; + height: 100vh; + overflow: auto; + background: @layout-body-background; +} + +.lang { + width: 100%; + height: 40px; + line-height: 44px; + text-align: right; + :global(.ant-dropdown-trigger) { + margin-right: 24px; + } +} + +.content { + flex: 1; + padding: 32px 0; +} + +@media (min-width: @screen-md-min) { + .container { + background-image: url('https://gw.alipayobjects.com/zos/rmsportal/TVYTbAXWheQpRcWDaDMu.svg'); + background-repeat: no-repeat; + background-position: center 110px; + background-size: 100%; + } + + .content { + padding: 32px 0 24px; + } +} + +.top { + text-align: center; +} + +.header { + height: 44px; + line-height: 44px; + a { + text-decoration: none; + } +} + +.logo { + height: 44px; + margin-right: 16px; + vertical-align: top; +} + +.title { + position: relative; + top: 2px; + color: @heading-color; + font-weight: 600; + font-size: 33px; + font-family: Avenir, 'Helvetica Neue', Arial, Helvetica, sans-serif; +} + +.desc { + margin-top: 12px; + margin-bottom: 40px; + color: @text-color-secondary; + font-size: @font-size-base; +} + +.main { + width: 328px; + margin: 0 auto; + @media screen and (max-width: @screen-sm) { + width: 95%; + max-width: 328px; + } + + :global { + .@{ant-prefix}-tabs-nav-list { + margin: auto; + font-size: 16px; + } + } + + .icon { + margin-left: 16px; + color: rgba(0, 0, 0, 0.2); + font-size: 24px; + vertical-align: middle; + cursor: pointer; + transition: color 0.3s; + + &:hover { + color: @primary-color; + } + } + + .other { + margin-top: 24px; + line-height: 22px; + text-align: left; + .register { + float: right; + } + } + + .prefixIcon { + color: @primary-color; + font-size: @font-size-base; + } +} diff --git a/src/pages/User/Login/index.tsx b/src/pages/User/Login/index.tsx new file mode 100644 index 00000000..fb5a923f --- /dev/null +++ b/src/pages/User/Login/index.tsx @@ -0,0 +1,318 @@ +import { + AlipayCircleOutlined, + LockOutlined, + MobileOutlined, + 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 { login } from '@/services/ant-design-pro/api'; +import { getFakeCaptcha } from '@/services/ant-design-pro/login'; + +import styles from './index.less'; + +const LoginMessage: React.FC<{ + content: string; +}> = ({ content }) => ( + +); + +/** 此方法会跳转到 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({}); + const [type, setType] = useState('account'); + const { initialState, setInitialState } = useModel('@@initialState'); + + const intl = useIntl(); + + const fetchUserInfo = async () => { + const userInfo = await initialState?.fetchUserInfo?.(); + if (userInfo) { + setInitialState({ + ...initialState, + currentUser: userInfo, + }); + } + }; + + const handleSubmit = async (values: API.LoginParams) => { + setSubmitting(true); + try { + // 登录 + const msg = await login({ ...values, type }); + if (msg.status === 'ok') { + const defaultloginSuccessMessage = intl.formatMessage({ + id: 'pages.login.success', + defaultMessage: '登录成功!', + }); + message.success(defaultloginSuccessMessage); + await fetchUserInfo(); + goto(); + return; + } + // 如果失败去设置用户错误信息 + setUserLoginState(msg); + } catch (error) { + const defaultloginFailureMessage = intl.formatMessage({ + id: 'pages.login.failure', + defaultMessage: '登录失败,请重试!', + }); + + message.error(defaultloginFailureMessage); + } + setSubmitting(false); + }; + const { status, type: loginType } = userLoginState; + + return ( +
+
+ {SelectLang && } +
+
+
+
+ + logo + Ant Design + +
+
+ {intl.formatMessage({ id: 'pages.layouts.userLayout.title' })} +
+
+ +
+ dom.pop(), + submitButtonProps: { + loading: submitting, + size: 'large', + style: { + width: '100%', + }, + }, + }} + onFinish={async (values) => { + handleSubmit(values as API.LoginParams); + }} + > + + + + + + {status === 'error' && loginType === 'account' && ( + + )} + {type === 'account' && ( + <> + , + }} + placeholder={intl.formatMessage({ + id: 'pages.login.username.placeholder', + defaultMessage: '用户名: admin or user', + })} + rules={[ + { + required: true, + message: ( + + ), + }, + ]} + /> + , + }} + placeholder={intl.formatMessage({ + id: 'pages.login.password.placeholder', + defaultMessage: '密码: ant.design', + })} + rules={[ + { + required: true, + message: ( + + ), + }, + ]} + /> + + )} + + {status === 'error' && 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 === false) { + return; + } + message.success('获取验证码成功!验证码为:1234'); + }} + /> + + )} +
+ + + + + + +
+
+ + + + + + +
+
+
+ ); +}; + +export default Login;