fix(login): replace phone OTP login with phone+password login
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
06c2d02c21
commit
b9c83c1db7
|
|
@ -1,6 +1,6 @@
|
|||
'use client';
|
||||
|
||||
import { useState, useRef } from 'react';
|
||||
import { useState } from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import Link from 'next/link';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
|
@ -21,34 +21,9 @@ export default function LoginPage() {
|
|||
const [email, setEmail] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [phone, setPhone] = useState('');
|
||||
const [smsCode, setSmsCode] = useState('');
|
||||
const [smsCooldown, setSmsCooldown] = useState(0);
|
||||
const [smsSending, setSmsSending] = useState(false);
|
||||
const cooldownRef = useRef<ReturnType<typeof setInterval> | null>(null);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const handleSendSms = async () => {
|
||||
if (!phone.trim()) { setError('请先填写手机号'); return; }
|
||||
setError(null);
|
||||
setSmsSending(true);
|
||||
try {
|
||||
await apiClient('/api/v1/auth/sms/send', { method: 'POST', body: { phone: phone.trim(), purpose: 'login' } });
|
||||
setSmsCooldown(60);
|
||||
if (cooldownRef.current) clearInterval(cooldownRef.current);
|
||||
cooldownRef.current = setInterval(() => {
|
||||
setSmsCooldown((prev) => {
|
||||
if (prev <= 1) { clearInterval(cooldownRef.current!); return 0; }
|
||||
return prev - 1;
|
||||
});
|
||||
}, 1000);
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : '发送失败,请重试');
|
||||
} finally {
|
||||
setSmsSending(false);
|
||||
}
|
||||
};
|
||||
|
||||
const saveSession = (data: LoginResponse) => {
|
||||
localStorage.setItem('access_token', data.accessToken);
|
||||
localStorage.setItem('refresh_token', data.refreshToken);
|
||||
|
|
@ -73,10 +48,9 @@ export default function LoginPage() {
|
|||
});
|
||||
saveSession(data);
|
||||
} else {
|
||||
if (!smsCode.trim()) { setError('请输入短信验证码'); setIsLoading(false); return; }
|
||||
const data = await apiClient<LoginResponse>('/api/v1/auth/login/otp', {
|
||||
const data = await apiClient<LoginResponse>('/api/v1/auth/login', {
|
||||
method: 'POST',
|
||||
body: { phone: phone.trim(), smsCode: smsCode.trim() },
|
||||
body: { phone: phone.trim(), password },
|
||||
});
|
||||
saveSession(data);
|
||||
}
|
||||
|
|
@ -130,15 +104,9 @@ export default function LoginPage() {
|
|||
className="w-full px-3 py-2 bg-input border rounded-md" placeholder="+86 138 0000 0000" required />
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-1">短信验证码</label>
|
||||
<div className="flex gap-2">
|
||||
<input type="text" value={smsCode} onChange={(e) => setSmsCode(e.target.value)}
|
||||
className="flex-1 px-3 py-2 bg-input border rounded-md" placeholder="6 位验证码" maxLength={6} required />
|
||||
<button type="button" onClick={handleSendSms} disabled={smsSending || smsCooldown > 0}
|
||||
className="px-4 py-2 text-sm font-medium bg-secondary text-secondary-foreground rounded-md hover:opacity-90 disabled:opacity-50 whitespace-nowrap">
|
||||
{smsSending ? '发送中...' : smsCooldown > 0 ? `${smsCooldown}s` : '获取验证码'}
|
||||
</button>
|
||||
</div>
|
||||
<label className="block text-sm font-medium mb-1">{t('password')}</label>
|
||||
<input type="password" value={password} onChange={(e) => setPassword(e.target.value)}
|
||||
className="w-full px-3 py-2 bg-input border rounded-md" required />
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
|
|
|||
Loading…
Reference in New Issue