| | |
| | | { |
| | | name: 'login', |
| | | path: '/user/login', |
| | | component: './User/Login', |
| | | component: './User/Login/index2', |
| | | }, |
| | | ], |
| | | }, |
| | |
| | | .header-title { |
| | | font-size: xx-large; |
| | | color: #eee; |
| | | } |
| | | |
| | | .ant-pro-form-login-page-logo { |
| | | width: 200px; |
| | | height: 100%; |
| | | margin: 30px 0; |
| | | } |
New file |
| | |
| | | import { |
| | | LockOutlined, |
| | | MobileOutlined, |
| | | UserOutlined, |
| | | } from '@ant-design/icons'; |
| | | import { |
| | | LoginFormPage, |
| | | ProConfigProvider, |
| | | ProFormCaptcha, |
| | | ProFormCheckbox, |
| | | ProFormText, |
| | | } from '@ant-design/pro-components'; |
| | | import { Button, Divider, Space, Tabs, message, theme } from 'antd'; |
| | | import { useState } from 'react'; |
| | | import { FormattedMessage, history, SelectLang, useIntl, useModel, Helmet } from '@umijs/max'; |
| | | |
| | | import logo from './logo.png' |
| | | |
| | | const Page = () => { |
| | | const intl = useIntl(); |
| | | |
| | | const [loginType, setLoginType] = useState('account'); |
| | | const { token } = theme.useToken(); |
| | | |
| | | const handleSubmit = async (values) => { |
| | | try { |
| | | const r = await request('/api/login', { |
| | | method: 'POST', |
| | | headers: { |
| | | 'Content-Type': 'application/json' |
| | | }, |
| | | data: values |
| | | }) |
| | | |
| | | if (r.code === 200) { |
| | | message.success(intl.formatMessage({ |
| | | id: 'pages.login.success', |
| | | defaultMessage: '登录成功!', |
| | | })); |
| | | setToken(r.data.accessToken, values.autoLogin); |
| | | await fetchUserInfo(); |
| | | const urlParams = new URL(window.location.href).searchParams; |
| | | history.push(urlParams.get('redirect') || '/'); |
| | | return; |
| | | } |
| | | setUserLoginState({ |
| | | status: r.code, |
| | | type: type, |
| | | }) |
| | | } catch (error) { |
| | | console.log(error); |
| | | message.error(intl.formatMessage({ |
| | | id: 'pages.login.failure', |
| | | defaultMessage: '登录失败,请重试!', |
| | | })); |
| | | } |
| | | } |
| | | |
| | | return ( |
| | | <div |
| | | style={{ |
| | | backgroundColor: 'white', |
| | | height: '100vh', |
| | | }} |
| | | > |
| | | <LoginFormPage |
| | | backgroundImageUrl="https://mdn.alipayobjects.com/huamei_gcee1x/afts/img/A*y0ZTS6WLwvgAAAAAAAAAAAAADml6AQ/fmt.webp" |
| | | logo={logo} |
| | | backgroundVideoUrl="https://gw.alipayobjects.com/v/huamei_gcee1x/afts/video/jXRBRK_VAwoAAAAAAAAAAAAAK4eUAQBr" |
| | | // title="陆晓涛" |
| | | // subTitle="陆晓涛..." |
| | | containerStyle={{ |
| | | backgroundColor: 'rgba(0, 0, 0,0.65)', |
| | | backdropFilter: 'blur(4px)', |
| | | }} |
| | | initialValues={{ |
| | | username: 'root', |
| | | password: '123456', |
| | | autoLogin: true, |
| | | }} |
| | | onFinish={async (values) => { |
| | | await handleSubmit(values); |
| | | }} |
| | | > |
| | | <Tabs |
| | | centered |
| | | activeKey={loginType} |
| | | onChange={(activeKey) => setLoginType(activeKey)} |
| | | > |
| | | <Tabs.TabPane key={'account'} tab={'账号密码登录'} /> |
| | | <Tabs.TabPane key={'phone'} tab={'手机号登录'} /> |
| | | </Tabs> |
| | | {loginType === 'account' && ( |
| | | <> |
| | | <ProFormText |
| | | name="username" |
| | | fieldProps={{ |
| | | size: 'large', |
| | | prefix: ( |
| | | <UserOutlined |
| | | style={{ |
| | | color: token.colorText, |
| | | }} |
| | | className={'prefixIcon'} |
| | | /> |
| | | ), |
| | | }} |
| | | placeholder={'用户名: root'} |
| | | rules={[ |
| | | { |
| | | required: true, |
| | | message: '请输入用户名!', |
| | | }, |
| | | ]} |
| | | /> |
| | | <ProFormText.Password |
| | | name="password" |
| | | fieldProps={{ |
| | | size: 'large', |
| | | prefix: ( |
| | | <LockOutlined |
| | | style={{ |
| | | color: token.colorText, |
| | | }} |
| | | className={'prefixIcon'} |
| | | /> |
| | | ), |
| | | }} |
| | | placeholder={'密码: 123456'} |
| | | rules={[ |
| | | { |
| | | required: true, |
| | | message: '请输入密码!', |
| | | }, |
| | | ]} |
| | | /> |
| | | </> |
| | | )} |
| | | {loginType === 'phone' && ( |
| | | <> |
| | | <ProFormText |
| | | fieldProps={{ |
| | | size: 'large', |
| | | prefix: ( |
| | | <MobileOutlined |
| | | style={{ |
| | | color: token.colorText, |
| | | }} |
| | | className={'prefixIcon'} |
| | | /> |
| | | ), |
| | | }} |
| | | name="mobile" |
| | | placeholder={'手机号'} |
| | | rules={[ |
| | | { |
| | | required: true, |
| | | message: '请输入手机号!', |
| | | }, |
| | | { |
| | | pattern: /^1\d{10}$/, |
| | | message: '手机号格式错误!', |
| | | }, |
| | | ]} |
| | | /> |
| | | <ProFormCaptcha |
| | | fieldProps={{ |
| | | size: 'large', |
| | | prefix: ( |
| | | <LockOutlined |
| | | style={{ |
| | | color: token.colorText, |
| | | }} |
| | | className={'prefixIcon'} |
| | | /> |
| | | ), |
| | | }} |
| | | captchaProps={{ |
| | | size: 'large', |
| | | }} |
| | | placeholder={'请输入验证码'} |
| | | captchaTextRender={(timing, count) => { |
| | | if (timing) { |
| | | return `${count} ${'获取验证码'}`; |
| | | } |
| | | return '获取验证码'; |
| | | }} |
| | | name="captcha" |
| | | rules={[ |
| | | { |
| | | required: true, |
| | | message: '请输入验证码!', |
| | | }, |
| | | ]} |
| | | onGetCaptcha={async () => { |
| | | // message.success('获取验证码成功!验证码为:1234'); |
| | | message.warning('未开启手机号登录! '); |
| | | }} |
| | | /> |
| | | </> |
| | | )} |
| | | <div |
| | | style={{ |
| | | marginBlockEnd: 24, |
| | | }} |
| | | > |
| | | <ProFormCheckbox noStyle name="autoLogin"> |
| | | 自动登录 |
| | | </ProFormCheckbox> |
| | | </div> |
| | | </LoginFormPage> |
| | | </div> |
| | | ); |
| | | }; |
| | | |
| | | export default () => { |
| | | return ( |
| | | <ProConfigProvider dark> |
| | | <Page /> |
| | | </ProConfigProvider> |
| | | ); |
| | | }; |