import { encryptPassword } from '../utils/cryptots'; import React, { useState, useEffect } from 'react'; import { useNavigate, Link } from 'react-router-dom'; import { authService, RegisterRequest } from '../services/authService'; import { userApi } from '../services/userApi'; import { Mail, Lock, User, Phone, GraduationCap, AlertCircle, CheckCircle2 } from 'lucide-react'; import { Loader2 } from '../icons/commonIcons'; import PasswordStrengthIndicator from '../components/PasswordStrengthIndicator'; import { BrandingContext } from '../App'; const Register: React.FC = () => { const navigate = useNavigate(); const branding = React.useContext(BrandingContext); const [formData, setFormData] = useState({ username: '', password: '', email: '', phone: '', nickname: '', }); // 手机验证码 const [smsCode, setSmsCode] = useState(''); const [smsSending, setSmsSending] = useState(false); const [smsCountdown, setSmsCountdown] = useState(0); // 邮箱验证码 const [emailCode, setEmailCode] = useState(''); const [emailSending, setEmailSending] = useState(false); const [emailCountdown, setEmailCountdown] = useState(0); const [emailVerified, setEmailVerified] = useState(false); const [confirmPassword, setConfirmPassword] = useState(''); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [success, setSuccess] = useState(false); const [autoLoginLoading, setAutoLoginLoading] = useState(false); const [passwordMeetsRequirements, setPasswordMeetsRequirements] = useState(false); useEffect(() => { if (smsCountdown <= 0) return; const timer = setTimeout(() => setSmsCountdown(c => c - 1), 1000); return () => clearTimeout(timer); }, [smsCountdown]); useEffect(() => { if (emailCountdown <= 0) return; const timer = setTimeout(() => setEmailCountdown(c => c - 1), 1000); return () => clearTimeout(timer); }, [emailCountdown]); // 邮箱变化时重置验证状态 useEffect(() => { setEmailVerified(false); setEmailCode(''); }, [formData.email]); const handleInputChange = (field: keyof RegisterRequest, value: string) => { setFormData(prev => ({ ...prev, [field]: value })); setError(null); }; const handleSendSms = async () => { if (!formData.phone || formData.phone.length !== 11) { setError('请先填写正确的手机号'); return; } setSmsSending(true); setError(null); try { await userApi.sendSmsCode(formData.phone, 'register'); setSmsCountdown(60); } catch (e: any) { setError(e.message || '发送失败'); } finally { setSmsSending(false); } }; const handleSendEmailCode = async () => { if (!formData.email) { setError('请先填写邮箱'); return; } const emailRe = /^[^@\s]+@[^@\s]+\.[^@\s]+$/; if (!emailRe.test(formData.email)) { setError('邮箱格式不正确'); return; } setEmailSending(true); setError(null); try { await userApi.sendEmailCode(formData.email, 'register'); setEmailCountdown(60); } catch (e: any) { setError(e.message || '发送失败'); } finally { setEmailSending(false); } }; const validateForm = (): boolean => { if (!formData.username.trim()) { setError('请输入用户名'); return false; } if (formData.username.length < 3) { setError('用户名至少需要3个字符'); return false; } if (!formData.password) { setError('请输入密码'); return false; } if (formData.password.length < 6) { setError('密码至少需要6个字符'); return false; } if (!passwordMeetsRequirements) { setError('密码强度太弱,请至少包含字母和数字两种字符'); return false; } if (formData.password !== confirmPassword) { setError('两次输入的密码不一致'); return false; } if (!formData.phone) { setError('请输入手机号'); return false; } if (formData.phone.length !== 11) { setError('请输入正确的11位手机号'); return false; } if (!smsCode) { setError('请输入手机验证码'); return false; } // 填了邮箱必须验证 if (formData.email) { if (!emailCode) { setError('请输入邮箱验证码'); return false; } } return true; }; const handleRegister = async (e: React.FormEvent) => { e.preventDefault(); setError(null); if (!validateForm()) return; setLoading(true); try { const encryptedPassword = encryptPassword(formData.password); const registerData: RegisterRequest = { username: formData.username, password: encryptedPassword, nickname: formData.nickname || formData.username, phone: formData.phone, sms_code: smsCode, ...(formData.email ? { email: formData.email, email_code: emailCode } : {}), }; const response = await authService.register(registerData); if (response.code === 200) { setSuccess(true); } else { setError(response.message || '注册失败,请稍后重试'); } } catch (err) { setError(err instanceof Error ? err.message : '注册失败,请稍后重试'); } finally { setLoading(false); } }; const handleAutoLogin = async () => { setAutoLoginLoading(true); try { const encryptedPassword = encryptPassword(formData.password); const loginResponse = await authService.login(formData.username, encryptedPassword); if (loginResponse.code === 200) { navigate('/'); } else { navigate('/login'); } } catch { navigate('/login'); } finally { setAutoLoginLoading(false); } }; if (success) { return (

注册成功!

您的账号已创建成功

); } const showEmailCodeInput = !!formData.email && /^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(formData.email); return (
{branding.system_logo ? logo : }

注册{branding.system_name}

创建您的账号

{error && (

{error}

)}
{/* 用户名 */}
handleInputChange('username', e.target.value)} placeholder="请输入用户名(至少3个字符)" className="w-full pl-10 pr-4 py-3 bg-gray-50 border border-gray-200 rounded-xl text-sm outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-all" required />
{/* 手机号(必填) */}
handleInputChange('phone', e.target.value)} placeholder="请输入手机号" maxLength={11} className="w-full pl-10 pr-4 py-3 bg-gray-50 border border-gray-200 rounded-xl text-sm outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-all" required />
{/* 手机验证码 */}
setSmsCode(e.target.value)} placeholder="请输入验证码" maxLength={6} className="flex-1 px-4 py-3 bg-gray-50 border border-gray-200 rounded-xl text-sm outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-all" required />
{/* 邮箱(可选) */}
handleInputChange('email', e.target.value)} placeholder="请输入邮箱(可选)" className="w-full pl-10 pr-4 py-3 bg-gray-50 border border-gray-200 rounded-xl text-sm outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-all" />

绑定邮箱后可通过邮箱验证码找回密码

{/* 邮箱验证码(仅当邮箱格式正确时显示) */} {showEmailCodeInput && (
{ setEmailCode(e.target.value); setEmailVerified(false); }} placeholder="请输入邮箱验证码" maxLength={6} className="flex-1 px-4 py-3 bg-gray-50 border border-gray-200 rounded-xl text-sm outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-all" />

验证码已发送至 {formData.email}

)} {/* 昵称 */}
handleInputChange('nickname', e.target.value)} placeholder="请输入昵称(默认为用户名)" className="w-full pl-10 pr-4 py-3 bg-gray-50 border border-gray-200 rounded-xl text-sm outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-all" />
{/* 密码 */}
handleInputChange('password', e.target.value)} placeholder="请输入密码(至少6个字符)" className="w-full pl-10 pr-4 py-3 bg-gray-50 border border-gray-200 rounded-xl text-sm outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-all" required />
{formData.password && (
)}
{/* 确认密码 */}
{ setConfirmPassword(e.target.value); setError(null); }} placeholder="请再次输入密码" className="w-full pl-10 pr-4 py-3 bg-gray-50 border border-gray-200 rounded-xl text-sm outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-all" required />

已有账号?{' '} 立即登录

); }; export default Register;