style(Auth): 登录弹窗改为 Tab 切换布局
- 改为单列布局 (450px),右上角折角图标切换微信/手机登录 - 微信登录: 显示二维码图标,切换到手机显示手机图标 - 验证码登录: 添加内容区标题和副标题 - 关闭按钮移除,点击蒙层关闭弹窗 - 验证码倒计时按钮颜色改为金色 - 调整表单区域间距:上方紧凑,下方留白 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
// src/components/Auth/AuthFormContent.js
|
// src/components/Auth/AuthFormContent.js
|
||||||
// 统一的认证表单组件 - Ant Design 版本 - 黑金主题
|
// 统一的认证表单组件 - Ant Design 版本 - 黑金主题 - Tab 切换布局
|
||||||
import React, { useState, useEffect, useRef } from "react";
|
import React, { useState, useEffect, useRef } from "react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { Form, Input, Button, Typography, Space, Row, Col, Modal, message } from 'antd';
|
import { Form, Input, Button, Typography, Modal, message, Tooltip } from 'antd';
|
||||||
import { LockOutlined, WechatOutlined } from '@ant-design/icons';
|
import { LockOutlined, WechatOutlined, MobileOutlined, QrcodeOutlined } from '@ant-design/icons';
|
||||||
import { useBreakpointValue } from "@chakra-ui/react";
|
import { useBreakpointValue } from "@chakra-ui/react";
|
||||||
import { useAuth } from "../../contexts/AuthContext";
|
import { useAuth } from "../../contexts/AuthContext";
|
||||||
import { useAuthModal } from "../../hooks/useAuthModal";
|
import { useAuthModal } from "../../hooks/useAuthModal";
|
||||||
@@ -16,7 +16,7 @@ import { logger } from '../../utils/logger';
|
|||||||
import { getApiBase } from '../../utils/apiConfig';
|
import { getApiBase } from '../../utils/apiConfig';
|
||||||
import { useAuthEvents } from '../../hooks/useAuthEvents';
|
import { useAuthEvents } from '../../hooks/useAuthEvents';
|
||||||
|
|
||||||
const { Text, Link, Title } = Typography;
|
const { Link } = Typography;
|
||||||
|
|
||||||
// 黑金主题样式
|
// 黑金主题样式
|
||||||
const THEME = {
|
const THEME = {
|
||||||
@@ -27,18 +27,47 @@ const THEME = {
|
|||||||
bgElevated: '#1A1A2E',
|
bgElevated: '#1A1A2E',
|
||||||
lineDefault: 'rgba(212, 175, 55, 0.3)',
|
lineDefault: 'rgba(212, 175, 55, 0.3)',
|
||||||
lineEmphasis: 'rgba(212, 175, 55, 0.5)',
|
lineEmphasis: 'rgba(212, 175, 55, 0.5)',
|
||||||
|
lineSubtle: 'rgba(212, 175, 55, 0.15)',
|
||||||
textPrimary: 'rgba(255, 255, 255, 0.95)',
|
textPrimary: 'rgba(255, 255, 255, 0.95)',
|
||||||
|
textSecondary: 'rgba(255, 255, 255, 0.6)',
|
||||||
textMuted: 'rgba(255, 255, 255, 0.4)',
|
textMuted: 'rgba(255, 255, 255, 0.4)',
|
||||||
wechat: '#07C160',
|
wechat: '#07C160',
|
||||||
};
|
};
|
||||||
|
|
||||||
const styles = {
|
const styles = {
|
||||||
formTitle: {
|
// 右上角折角切换图标
|
||||||
color: THEME.goldPrimary,
|
cornerSwitch: {
|
||||||
fontWeight: 600,
|
position: 'absolute',
|
||||||
letterSpacing: '0.05em',
|
top: '-32px',
|
||||||
marginBottom: '16px',
|
right: '-32px',
|
||||||
|
width: '64px',
|
||||||
|
height: '64px',
|
||||||
|
cursor: 'pointer',
|
||||||
|
zIndex: 10,
|
||||||
|
overflow: 'hidden',
|
||||||
},
|
},
|
||||||
|
cornerTriangle: {
|
||||||
|
position: 'absolute',
|
||||||
|
top: 0,
|
||||||
|
right: 0,
|
||||||
|
width: 0,
|
||||||
|
height: 0,
|
||||||
|
borderStyle: 'solid',
|
||||||
|
borderWidth: '0 64px 64px 0',
|
||||||
|
transition: 'all 0.2s ease',
|
||||||
|
},
|
||||||
|
cornerIcon: {
|
||||||
|
position: 'absolute',
|
||||||
|
top: '12px',
|
||||||
|
right: '8px',
|
||||||
|
fontSize: '18px',
|
||||||
|
color: '#fff',
|
||||||
|
transform: 'rotate(0deg)',
|
||||||
|
},
|
||||||
|
// 内容区域
|
||||||
|
contentArea: {
|
||||||
|
},
|
||||||
|
// 输入框
|
||||||
input: {
|
input: {
|
||||||
background: THEME.bgInput,
|
background: THEME.bgInput,
|
||||||
border: `1px solid ${THEME.lineDefault}`,
|
border: `1px solid ${THEME.lineDefault}`,
|
||||||
@@ -46,6 +75,7 @@ const styles = {
|
|||||||
height: '44px',
|
height: '44px',
|
||||||
borderRadius: '8px',
|
borderRadius: '8px',
|
||||||
},
|
},
|
||||||
|
// 提交按钮
|
||||||
submitBtn: {
|
submitBtn: {
|
||||||
height: '48px',
|
height: '48px',
|
||||||
fontSize: '16px',
|
fontSize: '16px',
|
||||||
@@ -56,31 +86,82 @@ const styles = {
|
|||||||
color: THEME.bgElevated,
|
color: THEME.bgElevated,
|
||||||
boxShadow: '0 4px 15px rgba(212, 175, 55, 0.3)',
|
boxShadow: '0 4px 15px rgba(212, 175, 55, 0.3)',
|
||||||
},
|
},
|
||||||
|
// 隐私文本
|
||||||
privacyText: {
|
privacyText: {
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
fontSize: '12px',
|
fontSize: '12px',
|
||||||
color: THEME.textMuted,
|
color: THEME.textMuted,
|
||||||
marginTop: '12px',
|
marginTop: '8px',
|
||||||
},
|
},
|
||||||
privacyLink: {
|
privacyLink: {
|
||||||
color: THEME.goldPrimary,
|
color: THEME.goldPrimary,
|
||||||
textDecoration: 'underline',
|
textDecoration: 'underline',
|
||||||
|
fontSize: '12px',
|
||||||
},
|
},
|
||||||
wechatBtn: {
|
// 底部分割线区域
|
||||||
color: THEME.wechat,
|
bottomDivider: {
|
||||||
padding: '4px 8px',
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
marginTop: '24px',
|
||||||
|
gap: '12px',
|
||||||
},
|
},
|
||||||
otherLoginText: {
|
dividerLine: {
|
||||||
|
flex: 1,
|
||||||
|
height: '1px',
|
||||||
|
background: `linear-gradient(to right, transparent, ${THEME.lineDefault}, transparent)`,
|
||||||
|
},
|
||||||
|
otherLoginWrapper: {
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
gap: '8px',
|
||||||
color: THEME.textMuted,
|
color: THEME.textMuted,
|
||||||
fontSize: '12px',
|
fontSize: '12px',
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
},
|
||||||
|
otherLoginIcon: {
|
||||||
|
cursor: 'pointer',
|
||||||
|
padding: '4px 8px',
|
||||||
|
borderRadius: '4px',
|
||||||
|
transition: 'all 0.2s ease',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
gap: '4px',
|
||||||
|
},
|
||||||
|
// 内容区小标题
|
||||||
|
contentTitle: {
|
||||||
|
textAlign: 'left',
|
||||||
|
marginBottom: '4px',
|
||||||
|
},
|
||||||
|
contentTitleText: {
|
||||||
|
color: THEME.goldPrimary,
|
||||||
|
fontSize: '20px',
|
||||||
|
fontWeight: 600,
|
||||||
|
letterSpacing: '0.05em',
|
||||||
|
},
|
||||||
|
contentSubtitle: {
|
||||||
|
textAlign: 'left',
|
||||||
|
color: THEME.textSecondary,
|
||||||
|
fontSize: '12px',
|
||||||
|
marginBottom: '24px',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// 统一配置对象
|
// 统一配置对象
|
||||||
const AUTH_CONFIG = {
|
const AUTH_CONFIG = {
|
||||||
|
// 大标题(固定不变)
|
||||||
title: "价值前沿",
|
title: "价值前沿",
|
||||||
subtitle: "开启您的投资之旅",
|
subtitle: "开启您的投资之旅",
|
||||||
formTitle: "登陆/注册",
|
// 微信登录内容区文案
|
||||||
|
wechat: {
|
||||||
|
title: "微信安全登录",
|
||||||
|
subtitle: "未注册的微信号登录时将自动创建价值前沿账号",
|
||||||
|
},
|
||||||
|
// 验证码登录内容区文案
|
||||||
|
phone: {
|
||||||
|
title: "手机号登录",
|
||||||
|
subtitle: "未注册手机号登录时将自动创建价值前沿账号",
|
||||||
|
},
|
||||||
buttonText: "登录/注册",
|
buttonText: "登录/注册",
|
||||||
loadingText: "验证中...",
|
loadingText: "验证中...",
|
||||||
successDescription: "欢迎!",
|
successDescription: "欢迎!",
|
||||||
@@ -102,7 +183,10 @@ export default function AuthFormContent() {
|
|||||||
const config = AUTH_CONFIG;
|
const config = AUTH_CONFIG;
|
||||||
const isMountedRef = useRef(true);
|
const isMountedRef = useRef(true);
|
||||||
|
|
||||||
// 状态
|
// Tab 状态: 'wechat' | 'phone'
|
||||||
|
const [activeTab, setActiveTab] = useState('wechat');
|
||||||
|
|
||||||
|
// 表单状态
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const [showNicknamePrompt, setShowNicknamePrompt] = useState(false);
|
const [showNicknamePrompt, setShowNicknamePrompt] = useState(false);
|
||||||
const [currentPhone, setCurrentPhone] = useState("");
|
const [currentPhone, setCurrentPhone] = useState("");
|
||||||
@@ -117,6 +201,12 @@ export default function AuthFormContent() {
|
|||||||
// 事件追踪
|
// 事件追踪
|
||||||
const authEvents = useAuthEvents({ component: 'AuthFormContent', isMobile });
|
const authEvents = useAuthEvents({ component: 'AuthFormContent', isMobile });
|
||||||
|
|
||||||
|
// 切换 Tab
|
||||||
|
const handleTabChange = (tab) => {
|
||||||
|
setActiveTab(tab);
|
||||||
|
authEvents.trackLoginPageViewed(); // 追踪切换
|
||||||
|
};
|
||||||
|
|
||||||
// 输入变化处理
|
// 输入变化处理
|
||||||
const handleInputChange = (e) => {
|
const handleInputChange = (e) => {
|
||||||
const { name, value } = e.target;
|
const { name, value } = e.target;
|
||||||
@@ -266,7 +356,7 @@ export default function AuthFormContent() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 微信H5登录
|
// 微信H5登录(移动端)
|
||||||
const handleWechatH5Login = async () => {
|
const handleWechatH5Login = async () => {
|
||||||
authEvents.trackWechatLoginInitiated('icon_button');
|
authEvents.trackWechatLoginInitiated('icon_button');
|
||||||
try {
|
try {
|
||||||
@@ -295,96 +385,202 @@ export default function AuthFormContent() {
|
|||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
// 渲染手机验证码登录表单
|
||||||
|
const renderPhoneForm = () => (
|
||||||
|
<div>
|
||||||
|
{/* 内容区小标题 */}
|
||||||
|
<div style={styles.contentTitle}>
|
||||||
|
<span style={styles.contentTitleText}>{config.phone.title}</span>
|
||||||
|
</div>
|
||||||
|
<div style={styles.contentSubtitle}>{config.phone.subtitle}</div>
|
||||||
|
|
||||||
|
<Form layout="vertical" onFinish={handleSubmit}>
|
||||||
|
<Form.Item style={{ marginBottom: '24px' }}>
|
||||||
|
<Input
|
||||||
|
name="phone"
|
||||||
|
value={formData.phone}
|
||||||
|
onChange={handleInputChange}
|
||||||
|
placeholder="请输入11位手机号"
|
||||||
|
size="large"
|
||||||
|
style={styles.input}
|
||||||
|
prefix={<MobileOutlined style={{ color: THEME.textMuted }} />}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item style={{ marginBottom: '24px' }}>
|
||||||
|
<VerificationCodeInput
|
||||||
|
value={formData.verificationCode}
|
||||||
|
onChange={handleInputChange}
|
||||||
|
onSendCode={sendVerificationCode}
|
||||||
|
countdown={countdown}
|
||||||
|
isLoading={isLoading}
|
||||||
|
isSending={sendingCode}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item style={{ marginBottom: '48px', marginTop: '16px' }}>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
htmlType="submit"
|
||||||
|
size="large"
|
||||||
|
block
|
||||||
|
loading={isLoading}
|
||||||
|
icon={<LockOutlined />}
|
||||||
|
style={styles.submitBtn}
|
||||||
|
>
|
||||||
|
{isLoading ? config.loadingText : config.buttonText}
|
||||||
|
</Button>
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<div style={styles.privacyText}>
|
||||||
|
登录即表示您同意价值前沿{" "}
|
||||||
|
<Link
|
||||||
|
href="/home/user-agreement"
|
||||||
|
target="_blank"
|
||||||
|
onClick={authEvents.trackUserAgreementClicked}
|
||||||
|
style={styles.privacyLink}
|
||||||
|
>
|
||||||
|
《用户协议》
|
||||||
|
</Link>
|
||||||
|
{" "}和{" "}
|
||||||
|
<Link
|
||||||
|
href="/home/privacy-policy"
|
||||||
|
target="_blank"
|
||||||
|
onClick={authEvents.trackPrivacyPolicyClicked}
|
||||||
|
style={styles.privacyLink}
|
||||||
|
>
|
||||||
|
《隐私政策》
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
// 渲染微信登录区域
|
||||||
|
const renderWechatLogin = () => (
|
||||||
|
<div>
|
||||||
|
<WechatRegister />
|
||||||
|
<div style={{ ...styles.privacyText, marginTop: '16px' }}>
|
||||||
|
扫码即表示同意{" "}
|
||||||
|
<Link
|
||||||
|
href="/home/user-agreement"
|
||||||
|
target="_blank"
|
||||||
|
onClick={authEvents.trackUserAgreementClicked}
|
||||||
|
style={styles.privacyLink}
|
||||||
|
>
|
||||||
|
《用户协议》
|
||||||
|
</Link>
|
||||||
|
{" "}和{" "}
|
||||||
|
<Link
|
||||||
|
href="/home/privacy-policy"
|
||||||
|
target="_blank"
|
||||||
|
onClick={authEvents.trackPrivacyPolicyClicked}
|
||||||
|
style={styles.privacyLink}
|
||||||
|
>
|
||||||
|
《隐私政策》
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
// 渲染底部其他登录方式
|
||||||
|
const renderBottomDivider = () => {
|
||||||
|
const isWechatTab = activeTab === 'wechat';
|
||||||
|
|
||||||
|
// 移动端微信 Tab 下不显示底部切换(因为移动端微信是 H5 跳转)
|
||||||
|
if (isMobile && isWechatTab) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={styles.bottomDivider}>
|
||||||
|
<div style={styles.dividerLine} />
|
||||||
|
<div style={styles.otherLoginWrapper}>
|
||||||
|
<span>其他登录方式:</span>
|
||||||
|
{isWechatTab ? (
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
...styles.otherLoginIcon,
|
||||||
|
color: THEME.goldPrimary,
|
||||||
|
}}
|
||||||
|
onClick={() => handleTabChange('phone')}
|
||||||
|
onMouseEnter={(e) => {
|
||||||
|
e.currentTarget.style.background = 'rgba(212, 175, 55, 0.1)';
|
||||||
|
}}
|
||||||
|
onMouseLeave={(e) => {
|
||||||
|
e.currentTarget.style.background = 'transparent';
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MobileOutlined /> 手机
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
...styles.otherLoginIcon,
|
||||||
|
color: THEME.wechat,
|
||||||
|
}}
|
||||||
|
onClick={isMobile ? handleWechatH5Login : () => handleTabChange('wechat')}
|
||||||
|
onMouseEnter={(e) => {
|
||||||
|
e.currentTarget.style.background = 'rgba(7, 193, 96, 0.1)';
|
||||||
|
}}
|
||||||
|
onMouseLeave={(e) => {
|
||||||
|
e.currentTarget.style.background = 'transparent';
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<WechatOutlined /> 微信
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div style={styles.dividerLine} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取右上角折角的颜色(根据要切换到的登录方式)
|
||||||
|
const getCornerColor = () => {
|
||||||
|
// 显示要切换到的方式的颜色
|
||||||
|
return activeTab === 'wechat' ? THEME.goldPrimary : THEME.wechat;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取右上角图标
|
||||||
|
const getCornerIcon = () => {
|
||||||
|
// 显示要切换到的方式的图标:手机图标 或 二维码图标
|
||||||
|
return activeTab === 'wechat' ? <MobileOutlined /> : <QrcodeOutlined />;
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="auth-form-content">
|
<div className="auth-form-content" style={{ position: 'relative' }}>
|
||||||
|
{/* 右上角折角切换图标 */}
|
||||||
|
<Tooltip
|
||||||
|
title={activeTab === 'wechat' ? '切换到验证码登录' : '切换到微信登录'}
|
||||||
|
placement="left"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={styles.cornerSwitch}
|
||||||
|
onClick={() => handleTabChange(activeTab === 'wechat' ? 'phone' : 'wechat')}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
...styles.cornerTriangle,
|
||||||
|
borderColor: `transparent ${getCornerColor()} transparent transparent`,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<span style={styles.cornerIcon}>
|
||||||
|
{getCornerIcon()}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
|
||||||
|
{/* 大标题(固定不变) */}
|
||||||
<AuthHeader title={config.title} subtitle={config.subtitle} />
|
<AuthHeader title={config.title} subtitle={config.subtitle} />
|
||||||
|
|
||||||
<Row gutter={isMobile ? 0 : 32} align="top">
|
{/* 内容区域 */}
|
||||||
{/* 左侧表单 */}
|
<div style={styles.contentArea}>
|
||||||
<Col xs={24} md={14}>
|
{activeTab === 'wechat' ? renderWechatLogin() : renderPhoneForm()}
|
||||||
<Title level={5} style={styles.formTitle}>{config.formTitle}</Title>
|
</div>
|
||||||
|
|
||||||
<Form layout="vertical" onFinish={handleSubmit}>
|
{/* 底部其他登录方式 */}
|
||||||
<Form.Item>
|
{renderBottomDivider()}
|
||||||
<Input
|
|
||||||
name="phone"
|
|
||||||
value={formData.phone}
|
|
||||||
onChange={handleInputChange}
|
|
||||||
placeholder="请输入11位手机号"
|
|
||||||
size="large"
|
|
||||||
style={styles.input}
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
|
||||||
|
|
||||||
<Form.Item>
|
|
||||||
<VerificationCodeInput
|
|
||||||
value={formData.verificationCode}
|
|
||||||
onChange={handleInputChange}
|
|
||||||
onSendCode={sendVerificationCode}
|
|
||||||
countdown={countdown}
|
|
||||||
isLoading={isLoading}
|
|
||||||
isSending={sendingCode}
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
|
||||||
|
|
||||||
{/* 移动端微信登录 */}
|
|
||||||
{isMobile && (
|
|
||||||
<div style={{ display: 'flex', alignItems: 'center', marginBottom: '16px' }}>
|
|
||||||
<Text style={styles.otherLoginText}>其他登录方式:</Text>
|
|
||||||
<Button
|
|
||||||
type="text"
|
|
||||||
icon={<WechatOutlined />}
|
|
||||||
onClick={handleWechatH5Login}
|
|
||||||
disabled={isLoading}
|
|
||||||
style={styles.wechatBtn}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<Form.Item>
|
|
||||||
<Button
|
|
||||||
type="primary"
|
|
||||||
htmlType="submit"
|
|
||||||
size="large"
|
|
||||||
block
|
|
||||||
loading={isLoading}
|
|
||||||
icon={<LockOutlined />}
|
|
||||||
style={styles.submitBtn}
|
|
||||||
>
|
|
||||||
{isLoading ? config.loadingText : config.buttonText}
|
|
||||||
</Button>
|
|
||||||
</Form.Item>
|
|
||||||
|
|
||||||
<div style={styles.privacyText}>
|
|
||||||
登录即表示您同意价值前沿{" "}
|
|
||||||
<Link
|
|
||||||
href="/home/user-agreement"
|
|
||||||
target="_blank"
|
|
||||||
onClick={authEvents.trackUserAgreementClicked}
|
|
||||||
style={styles.privacyLink}
|
|
||||||
>
|
|
||||||
《用户协议》
|
|
||||||
</Link>
|
|
||||||
{" "}和{" "}
|
|
||||||
<Link
|
|
||||||
href="/home/privacy-policy"
|
|
||||||
target="_blank"
|
|
||||||
onClick={authEvents.trackPrivacyPolicyClicked}
|
|
||||||
style={styles.privacyLink}
|
|
||||||
>
|
|
||||||
《隐私政策》
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</Form>
|
|
||||||
</Col>
|
|
||||||
|
|
||||||
{/* 右侧微信二维码 - 仅桌面端 */}
|
|
||||||
{!isMobile && (
|
|
||||||
<Col xs={24} md={10}>
|
|
||||||
<WechatRegister />
|
|
||||||
</Col>
|
|
||||||
)}
|
|
||||||
</Row>
|
|
||||||
|
|
||||||
{/* 昵称设置引导 */}
|
{/* 昵称设置引导 */}
|
||||||
<Modal
|
<Modal
|
||||||
|
|||||||
@@ -58,10 +58,21 @@
|
|||||||
.ant-modal-close {
|
.ant-modal-close {
|
||||||
color: @color-text-secondary !important;
|
color: @color-text-secondary !important;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
|
// 关闭按钮放在弹窗外侧右上角(弹窗右边外面)
|
||||||
|
top: 0 !important;
|
||||||
|
right: -50px !important;
|
||||||
|
inset-inline-end: -50px !important;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
background: rgba(255, 255, 255, 0.15) !important;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: @color-gold-primary !important;
|
color: @color-gold-primary !important;
|
||||||
background: rgba(212, 175, 55, 0.1) !important;
|
background: rgba(255, 255, 255, 0.25) !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -395,6 +406,121 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==================== Tab 切换样式 ====================
|
||||||
|
.auth-modal .tab-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-modal .tab-wrapper {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
background: rgba(26, 26, 46, 0.6);
|
||||||
|
padding: 4px;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid @color-line-default;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-modal .tab-btn {
|
||||||
|
padding: 8px 24px;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
color: @color-text-secondary;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
|
||||||
|
&:hover:not(.active) {
|
||||||
|
color: @color-gold-primary;
|
||||||
|
background: rgba(212, 175, 55, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background: @color-gold-gradient;
|
||||||
|
color: @color-bg-elevated;
|
||||||
|
font-weight: 600;
|
||||||
|
box-shadow: 0 2px 8px rgba(212, 175, 55, 0.3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-modal .switch-icon {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
color: @color-text-secondary;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 8px;
|
||||||
|
border-radius: 6px;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: @color-gold-primary;
|
||||||
|
background: rgba(212, 175, 55, 0.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 底部分割线 ====================
|
||||||
|
.auth-modal .bottom-divider {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 24px;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-modal .divider-line {
|
||||||
|
flex: 1;
|
||||||
|
height: 1px;
|
||||||
|
background: linear-gradient(to right, transparent, @color-line-default, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-modal .other-login-wrapper {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
color: @color-text-muted;
|
||||||
|
font-size: 12px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-modal .other-login-icon {
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 4px 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
|
||||||
|
&.phone {
|
||||||
|
color: @color-gold-primary;
|
||||||
|
&:hover {
|
||||||
|
background: rgba(212, 175, 55, 0.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.wechat {
|
||||||
|
color: @color-wechat;
|
||||||
|
&:hover {
|
||||||
|
background: rgba(7, 193, 96, 0.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 内容区域 ====================
|
||||||
|
.auth-modal .content-area {
|
||||||
|
min-height: 280px;
|
||||||
|
}
|
||||||
|
|
||||||
// ==================== 响应式适配 ====================
|
// ==================== 响应式适配 ====================
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.auth-modal.ant-modal {
|
.auth-modal.ant-modal {
|
||||||
@@ -415,4 +541,9 @@
|
|||||||
width: 200px;
|
width: 200px;
|
||||||
height: 200px;
|
height: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.auth-modal .tab-btn {
|
||||||
|
padding: 6px 16px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,15 +65,15 @@ export default function AuthModalManager() {
|
|||||||
}
|
}
|
||||||
}, [isAuthModalOpen]);
|
}, [isAuthModalOpen]);
|
||||||
|
|
||||||
// 响应式宽度配置
|
// 响应式宽度配置 - 单列布局
|
||||||
const modalMaxW = useBreakpointValue(
|
const modalMaxW = useBreakpointValue(
|
||||||
{
|
{
|
||||||
base: "90%",
|
base: "90%",
|
||||||
sm: "90%",
|
sm: "90%",
|
||||||
md: "700px",
|
md: "450px",
|
||||||
lg: "700px"
|
lg: "450px"
|
||||||
},
|
},
|
||||||
{ fallback: "700px", ssr: false }
|
{ fallback: "450px", ssr: false }
|
||||||
);
|
);
|
||||||
|
|
||||||
// Ant Design 5.x Modal styles 属性 - 直接覆盖 CSS-in-JS 样式
|
// Ant Design 5.x Modal styles 属性 - 直接覆盖 CSS-in-JS 样式
|
||||||
@@ -111,15 +111,13 @@ export default function AuthModalManager() {
|
|||||||
width={modalMaxW}
|
width={modalMaxW}
|
||||||
centered
|
centered
|
||||||
destroyOnHidden={true}
|
destroyOnHidden={true}
|
||||||
maskClosable={false}
|
maskClosable={true}
|
||||||
keyboard={true}
|
keyboard={true}
|
||||||
zIndex={999}
|
zIndex={999}
|
||||||
className="auth-modal"
|
className="auth-modal"
|
||||||
rootClassName="auth-modal-root"
|
rootClassName="auth-modal-root"
|
||||||
styles={modalStyles}
|
styles={modalStyles}
|
||||||
closeIcon={
|
closable={false}
|
||||||
<span style={{ color: THEME.textSecondary, fontSize: '16px' }}>✕</span>
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<AuthFormContent />
|
<AuthFormContent />
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|||||||
@@ -35,13 +35,13 @@ const styles = {
|
|||||||
},
|
},
|
||||||
sendCodeBtnDisabled: {
|
sendCodeBtnDisabled: {
|
||||||
background: 'transparent',
|
background: 'transparent',
|
||||||
color: THEME.textMuted,
|
color: THEME.goldPrimary,
|
||||||
border: `1px solid ${THEME.lineDefault}`,
|
border: `1px solid ${THEME.lineEmphasis}`,
|
||||||
borderLeft: 'none',
|
borderLeft: 'none',
|
||||||
minWidth: '120px',
|
minWidth: '120px',
|
||||||
height: '44px',
|
height: '44px',
|
||||||
borderRadius: '0 8px 8px 0',
|
borderRadius: '0 8px 8px 0',
|
||||||
opacity: 0.5,
|
opacity: 0.8,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ const getStatusColor = (status) => {
|
|||||||
|
|
||||||
const getStatusText = (status) => STATUS_MESSAGES[status] || "点击按钮获取二维码";
|
const getStatusText = (status) => STATUS_MESSAGES[status] || "点击按钮获取二维码";
|
||||||
|
|
||||||
export default function WechatRegister() {
|
export default function WechatRegister({ subtitle }) {
|
||||||
const { closeModal } = useAuthModal();
|
const { closeModal } = useAuthModal();
|
||||||
const { refreshSession } = useAuth();
|
const { refreshSession } = useAuth();
|
||||||
const authEvents = useAuthEvents({ component: 'WechatRegister', isMobile: false });
|
const authEvents = useAuthEvents({ component: 'WechatRegister', isMobile: false });
|
||||||
@@ -299,6 +299,9 @@ export default function WechatRegister() {
|
|||||||
return (
|
return (
|
||||||
<div style={styles.container}>
|
<div style={styles.container}>
|
||||||
<Title level={5} style={styles.title}>微信登陆</Title>
|
<Title level={5} style={styles.title}>微信登陆</Title>
|
||||||
|
<Text style={{ display: 'block', textAlign: 'center', color: 'rgba(255, 255, 255, 0.5)', fontSize: '12px', marginBottom: '12px' }}>
|
||||||
|
未注册的微信号登录时将自动创建价值前沿账号
|
||||||
|
</Text>
|
||||||
|
|
||||||
<div ref={containerRef} style={styles.qrcodeContainer}>
|
<div ref={containerRef} style={styles.qrcodeContainer}>
|
||||||
{wechatStatus === WECHAT_STATUS.WAITING ? (
|
{wechatStatus === WECHAT_STATUS.WAITING ? (
|
||||||
|
|||||||
Reference in New Issue
Block a user