更新登录
Change-Id: I0b2663f4291f573625222995b09a99ac53c2a081
diff --git a/src/pages/User/Login/index.tsx b/src/pages/User/Login/index.tsx
index e29032e..b8a44ff 100644
--- a/src/pages/User/Login/index.tsx
+++ b/src/pages/User/Login/index.tsx
@@ -22,6 +22,8 @@
import React, { useEffect, useState } from 'react';
import { flushSync } from 'react-dom';
import { clearSessionToken, setSessionToken } from '@/access';
+import './index.less';
+import { registerUser } from '@/services/bt/index';
const ActionIcons = () => {
const langClassName = useEmotionCss(({ token }) => {
@@ -96,7 +98,7 @@
display: 'flex',
flexDirection: 'column',
height: '100vh',
- overflow: 'auto',
+ overflow: 'hidden',
backgroundImage:
"url('https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/V-_oS6r-i7wAAAAAAAAAAAAAFl94AQBr')",
backgroundSize: '100% 100%',
@@ -159,6 +161,7 @@
message.error(defaultLoginFailureMessage);
}
};
+
const { code } = userLoginState;
const loginType = type;
@@ -171,7 +174,8 @@
className={containerClassName}
style={{
backgroundImage:
- "url('https://images.unsplash.com/photo-1462331940025-496dfbfc7564?auto=format&fit=crop&w=1500&q=80')",
+ "linear-gradient(120deg, #232526 0%, #414345 100%), url('https://images.unsplash.com/photo-1462331940025-496dfbfc7564?auto=format&fit=crop&w=1500&q=80')",
+ backgroundBlendMode: 'overlay',
backgroundSize: 'cover',
backgroundPosition: 'center',
minHeight: '100vh',
@@ -199,7 +203,6 @@
background: 'radial-gradient(ellipse at bottom, #1b2735 0%, #090a0f 100%)',
}}
>
- {/* 可以集成粒子库如 tsParticles 或者简单用 CSS 动画 */}
<svg width="100%" height="100%">
{[...Array(60)].map((_, i) => (
<circle
@@ -225,303 +228,403 @@
zIndex: 1,
}}
>
- <LoginForm
- contentStyle={{
- minWidth: 320,
- maxWidth: 400,
- background: 'rgba(25, 34, 54, 0.92)',
- borderRadius: 16,
+ <div
+ style={{
+ background: 'rgba(30, 34, 54, 0.96)',
+ borderRadius: 20,
boxShadow: '0 8px 32px 0 rgba(31, 38, 135, 0.37)',
- border: '1px solid rgba(255,255,255,0.18)',
- padding: '32px 32px 24px 32px',
+ border: '1px solid rgba(255,255,255,0.12)',
+ padding: '36px 24px 28px 24px',
+ minWidth: 340,
+ maxWidth: 420,
+ width: '100%',
color: '#fff',
- }}
- // logo={
- // <img
- // alt="logo"
- // src="/planet-logo.svg"
- // style={{
- // width: 64,
- // height: 64,
- // filter: 'drop-shadow(0 0 8px #fff8) drop-shadow(0 0 16px #6cf)',
- // marginBottom: 8,
- // }}
- // />
- // }
- title={
- <span style={{ color: '#fff', fontWeight: 700, fontSize: 28, letterSpacing: 2 }}>
- ThunderHub
- </span>
- }
- subTitle={
- <span style={{ color: '#b3c7f9', fontSize: 16 }}>
- 探索你的专属星球,畅享PT世界 JRX MSY ZYT HXQ LJB
- </span>
- }
- initialValues={{
- autoLogin: true,
- }}
- // actions={[
- // <FormattedMessage
- // key="loginWith"
- // id="pages.login.loginWith"
- // defaultMessage="其他登录方式"
- // />,
- // <ActionIcons key="icons" />,
- // ]}
- onFinish={async (values) => {
- await handleSubmit(values as API.LoginParams);
+ backdropFilter: 'blur(8px)',
+ position: 'relative',
+ transition: 'max-width 0.2s cubic-bezier(.4,2,.6,1)',
+ overflow: 'hidden',
}}
>
- <Tabs
- activeKey={type}
- onChange={setType}
- centered
- items={[
- {
- key: 'account',
- label: (
- <span style={{ color: '#fff' }}>
- {intl.formatMessage({
- id: 'pages.login.accountLogin.tab',
- defaultMessage: '账户密码登录',
- })}
- </span>
- ),
- },
- {
- key: 'mobile',
- label: (
- <span style={{ color: '#fff' }}>
- {intl.formatMessage({
- id: 'pages.login.phoneLogin.tab',
- defaultMessage: '手机号登录',
- })}
- </span>
- ),
- },
- ]}
- style={{ marginBottom: 24 }}
- />
-
- {code !== 200 && loginType === 'account' && (
- <LoginMessage
- content={intl.formatMessage({
- id: 'pages.login.accountLogin.errorMessage',
- defaultMessage: '账户或密码错误(admin/admin123)',
- })}
- />
- )}
- {type === 'account' && (
- <>
- <ProFormText
- name="username"
- initialValue="admin"
- fieldProps={{
- size: 'large',
- prefix: <UserOutlined style={{ color: '#6cf' }} />,
- style: { background: 'rgba(255,255,255,0.08)', color: '#fff' },
- }}
- placeholder={intl.formatMessage({
- id: 'pages.login.username.placeholder',
- defaultMessage: '用户名: admin',
- })}
- rules={[
- {
- required: true,
- message: (
- <FormattedMessage
- id="pages.login.username.required"
- defaultMessage="请输入用户名!"
- />
- ),
- },
- ]}
- />
- <ProFormText.Password
- name="password"
- initialValue="admin123"
- fieldProps={{
- size: 'large',
- prefix: <LockOutlined style={{ color: '#6cf' }} />,
- style: { background: 'rgba(255,255,255,0.08)', color: '#fff' },
- }}
- placeholder={intl.formatMessage({
- id: 'pages.login.password.placeholder',
- defaultMessage: '密码: admin123',
- })}
- rules={[
- {
- required: true,
- message: (
- <FormattedMessage
- id="pages.login.password.required"
- defaultMessage="请输入密码!"
- />
- ),
- },
- ]}
- />
- <Row>
- <Col flex={3}>
- <ProFormText
- style={{
- float: 'right',
- background: 'rgba(255,255,255,0.08)',
- color: '#fff',
- }}
- name="code"
- placeholder={intl.formatMessage({
- id: 'pages.login.captcha.placeholder',
- defaultMessage: '请输入验证',
- })}
- rules={[
- {
- required: true,
- message: (
- <FormattedMessage
- id="pages.searchTable.updateForm.ruleName.nameRules"
- defaultMessage="请输入验证啊"
- />
- ),
- },
- ]}
- />
- </Col>
- <Col flex={2}>
- <Image
- src={captchaCode}
- alt="验证码"
- style={{
- display: 'inline-block',
- verticalAlign: 'top',
- cursor: 'pointer',
- paddingLeft: '10px',
- width: '100px',
- borderRadius: 8,
- boxShadow: '0 0 8px #6cf8',
- background: '#fff',
- }}
- preview={false}
- onClick={() => getCaptchaCode()}
- />
- </Col>
- </Row>
- </>
- )}
-
- {code !== 200 && loginType === 'mobile' && (
- <LoginMessage content="验证码错误" />
- )}
- {type === 'mobile' && (
- <>
- <ProFormText
- fieldProps={{
- size: 'large',
- prefix: <MobileOutlined style={{ color: '#6cf' }} />,
- style: { background: 'rgba(255,255,255,0.08)', color: '#fff' },
- }}
- 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: <LockOutlined style={{ color: '#6cf' }} />,
- style: { background: 'rgba(255,255,255,0.08)', color: '#fff' },
- }}
- 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: (
- <FormattedMessage
- id="pages.login.captcha.required"
- defaultMessage="请输入验证码!"
- />
- ),
- },
- ]}
- onGetCaptcha={async (phone) => {
- const result = await getFakeCaptcha({
- phone,
- });
- if (!result) {
- return;
- }
- message.success('获取验证码成功!验证码为:1234');
- }}
- />
- </>
- )}
- <div
- style={{
- marginBottom: 24,
- color: '#b3c7f9',
- }}
- >
- <ProFormCheckbox>
- <a
- style={{
- float: 'right',
- color: '#fff',
- fontSize: 14,
- }}>
- <FormattedMessage id="pages.login.rememberMe" defaultMessage="自动登录" />
- </a>
- </ProFormCheckbox>
- <a
+ <div style={{ textAlign: 'center', marginBottom: 24 }}>
+ <img
+ src="/logo.svg"
+ alt="ThunderHub"
style={{
- float: 'right',
- color: '#6cf',
+ width: 54,
+ height: 48,
+ marginBottom: 8,
+ filter: 'drop-shadow(0 0 8px #6cf8)',
+ }}
+ />
+ <div
+ style={{
+ color: '#fff',
+ fontWeight: 700,
+ fontSize: 26,
+ letterSpacing: 2,
+ marginBottom: 4,
+ fontFamily: 'Montserrat, sans-serif',
}}
>
- <FormattedMessage id="pages.login.forgotPassword" defaultMessage="忘记密码" />
- </a>
+ ThunderHub
+ </div>
+ <div style={{ color: '#b3c7f9', fontSize: 14, letterSpacing: 1 }}>
+ 探索你的专属星球,畅享PT世界
+ <span style={{ color: '#6cf', marginLeft: 8, fontWeight: 500, fontSize: 12 }}>
+ JRX MSY ZYT HXQ LJB
+ </span>
+ </div>
</div>
- </LoginForm>
+ <LoginForm
+ contentStyle={{
+ background: 'transparent',
+ boxShadow: 'none',
+ padding: 0,
+ color: '#fff',
+ width: '100%',
+ overflow: 'hidden',
+ }}
+ initialValues={{
+ autoLogin: true,
+ }}
+ onFinish={async (values) => {
+ if (type === 'account') {
+ await handleSubmit(values as API.LoginParams);
+ } else {
+ try {
+ const response = await registerUser(
+ values.username ?? '',
+ values.password ?? '',
+ values.inviteCode ?? ''
+ );
+ if (response.code === 0) {
+ message.success('注册成功!');
+ // 注册成功后自动跳转到登录页或自动登录
+ setType('account');
+ } else {
+ message.error(response.msg || '注册失败,请重试!');
+ clearSessionToken();
+ setUserLoginState({ ...response, type });
+ }
+ } catch (error) {
+ message.error('注册失败,请重试!');
+ }
+ }
+ }}
+ submitter={false}
+ >
+ <Tabs
+ activeKey={type}
+ onChange={setType}
+ centered
+ items={[
+ {
+ key: 'account',
+ label: (
+ <span style={{ color: '#fff', fontWeight: 500, fontSize: 16 }}>
+ {intl.formatMessage({
+ id: 'pages.login.accountLogin.tab',
+ defaultMessage: '账户密码登录',
+ })}
+ </span>
+ ),
+ },
+ {
+ key: 'mobile',
+ label: (
+ <span style={{ color: '#fff', fontWeight: 500, fontSize: 16 }}>
+ {intl.formatMessage({
+ id: 'pages.login.phoneLogin.tab',
+ defaultMessage: '注册',
+ })}
+ </span>
+ ),
+ },
+ ]}
+ style={{ marginBottom: 24 }}
+ indicatorSize={36}
+ />
+
+ {code !== 200 && loginType === 'account' && (
+ <LoginMessage
+ content={intl.formatMessage({
+ id: 'pages.login.accountLogin.errorMessage',
+ defaultMessage: '账户或密码错误',
+ })}
+ />
+ )}
+ {type === 'account' && (
+ <>
+ <ProFormText
+ name="username"
+ fieldProps={{
+ size: 'large',
+ prefix: <UserOutlined style={{ color: '#6cf' }} />,
+ style: {
+ background: 'rgba(255,255,255,0.08)',
+ color: '#fff',
+ borderRadius: 8,
+ },
+ }}
+ placeholder={intl.formatMessage({
+ id: 'pages.login.username.placeholder',
+ })}
+ rules={[
+ {
+ required: true,
+ message: (
+ <FormattedMessage
+ id="pages.login.username.required"
+ defaultMessage="请输入用户名!"
+ />
+ ),
+ },
+ ]}
+ />
+ <ProFormText.Password
+ name="password"
+ fieldProps={{
+ size: 'large',
+ prefix: <LockOutlined style={{ color: '#6cf' }} />,
+ style: {
+ background: 'rgba(255,255,255,0.08)',
+ color: '#fff',
+ borderRadius: 8,
+ },
+ }}
+ placeholder={intl.formatMessage({
+ id: 'pages.login.password.placeholder',
+ })}
+ rules={[
+ {
+ required: true,
+ message: (
+ <FormattedMessage
+ id="pages.login.password.required"
+ defaultMessage="请输入密码!"
+ />
+ ),
+ },
+ ]}
+ />
+ <Row>
+ <Col flex={3}>
+ <ProFormText
+ style={{
+ float: 'right',
+ background: 'rgba(255,255,255,0.08)',
+ color: '#fff',
+ borderRadius: 8,
+ }}
+ name="code"
+ placeholder={intl.formatMessage({
+ id: 'pages.login.captcha.placeholder',
+ defaultMessage: '请输入验证',
+ })}
+ rules={[
+ {
+ required: true,
+ message: (
+ <FormattedMessage
+ id="pages.searchTable.updateForm.ruleName.nameRules"
+ defaultMessage="请输入验证啊"
+ />
+ ),
+ },
+ ]}
+ />
+ </Col>
+ <Col flex={2}>
+ <Image
+ src={captchaCode}
+ alt="验证码"
+ style={{
+ display: 'inline-block',
+ verticalAlign: 'top',
+ cursor: 'pointer',
+ paddingLeft: '10px',
+ width: '90px',
+ borderRadius: 8,
+ boxShadow: '0 0 8px #6cf8',
+ background: '#fff',
+ }}
+ preview={false}
+ onClick={() => getCaptchaCode()}
+ />
+ </Col>
+ </Row>
+ </>
+ )}
+
+ {code !== 200 && loginType === 'mobile' && (
+ <LoginMessage content="验证码错误" />
+ )}
+ {type === 'mobile' && (
+ <>
+ <ProFormText
+ fieldProps={{
+ size: 'large',
+ prefix: <LockOutlined style={{ color: '#6cf' }} />, // 换成钥匙图标
+ style: {
+ background: 'rgba(255,255,255,0.08)',
+ color: '#fff',
+ borderRadius: 8,
+ },
+ }}
+ name="inviteCode"
+ placeholder={intl.formatMessage({
+ id: 'pages.login.inviteCode.placeholder',
+ defaultMessage: '请输入邀请码',
+ })}
+ rules={[
+ {
+ required: true,
+ message: (
+ <FormattedMessage
+ id="pages.login.inviteCode.required"
+ defaultMessage="请输入邀请码!"
+ />
+ ),
+ },
+ ]}
+ />
+ <ProFormText
+ fieldProps={{
+ size: 'large',
+ prefix: <UserOutlined style={{ color: '#6cf' }} />,
+ style: {
+ background: 'rgba(255,255,255,0.08)',
+ color: '#fff',
+ borderRadius: 8,
+ },
+ }}
+ name="username"
+ placeholder={intl.formatMessage({
+ id: 'pages.login.username.placeholder',
+ defaultMessage: '请输入用户名',
+ })}
+ rules={[
+ {
+ required: true,
+ message: (
+ <FormattedMessage
+ id="pages.login.username.required"
+ defaultMessage="请输入用户名!"
+ />
+ ),
+ },
+ ]}
+ />
+ <ProFormText.Password
+ fieldProps={{
+ size: 'large',
+ prefix: <LockOutlined style={{ color: '#6cf' }} />,
+ style: {
+ background: 'rgba(255,255,255,0.08)',
+ color: '#fff',
+ borderRadius: 8,
+ },
+ }}
+ name="password"
+ placeholder={intl.formatMessage({
+ id: 'pages.login.password.placeholder',
+ defaultMessage: '请输入密码',
+ })}
+ rules={[
+ {
+ required: true,
+ message: (
+ <FormattedMessage
+ id="pages.login.password.required"
+ defaultMessage="请输入密码!"
+ />
+ ),
+ },
+ ]}
+ />
+ </>
+ )}
+ {type === 'account' && (
+ <div
+ style={{
+ marginBottom: 24,
+ color: '#b3c7f9',
+ display: 'flex',
+ alignItems: 'center',
+ justifyContent: 'space-between',
+ fontSize: 13,
+ }}
+ >
+ <ProFormCheckbox>
+ <span style={{ color: '#fff' }}>
+ <FormattedMessage id="pages.login.rememberMe" defaultMessage="自动登录" />
+ </span>
+ </ProFormCheckbox>
+ <a
+ style={{
+ color: '#6cf',
+ }}
+ >
+ <FormattedMessage id="pages.login.forgotPassword" defaultMessage="忘记密码" />
+ </a>
+ </div>
+ )}
+ {/* 登录/注册按钮 */}
+ <div style={{ marginTop: 24, display: 'flex', gap: 16 }}>
+ {type === 'account' && (
+ <button
+ type="submit"
+ style={{
+ width: '100%',
+ background: 'linear-gradient(90deg, #6cf 0%, #3E71FF 100%)',
+ color: '#fff',
+ border: 'none',
+ borderRadius: 8,
+ padding: '12px 0',
+ fontSize: 16,
+ fontWeight: 600,
+ cursor: 'pointer',
+ boxShadow: '0 2px 8px #6cf4',
+ letterSpacing: 2,
+ }}
+ onClick={() => {
+ // 触发表单提交,登录
+ document.querySelector('form')?.dispatchEvent(new Event('submit', { cancelable: true, bubbles: true }));
+ }}
+ >
+ 登录
+ </button>
+ )}
+ {type === 'mobile' && (
+ <button
+ type="button"
+ style={{
+ width: '100%',
+ background: 'linear-gradient(90deg, #6cf 0%, #3E71FF 100%)',
+ color: '#fff',
+ border: 'none',
+ borderRadius: 8,
+ padding: '12px 0',
+ fontSize: 16,
+ fontWeight: 600,
+ cursor: 'pointer',
+ boxShadow: '0 2px 8px #6cf4',
+ letterSpacing: 2,
+ }}
+ onClick={async () => {
+ // 触发表单校验并注册
+ const form = document.querySelector('form');
+ if (form) {
+ form.dispatchEvent(new Event('submit', { cancelable: true, bubbles: true }));
+ }
+ }}
+ >
+ 注册
+ </button>
+ )}
+ </div>
+ </LoginForm>
+ </div>
</div>
<Footer />
</div>