blob: 70b5573ecb99ffe916f51cdb35c84b79a65535b3 [file] [log] [blame]
import React, { useState } from 'react';
import { useApi } from '@/hooks/request';
import request from '@/utils/request';
import { postUserLogin } from '@/api/auth';
import { useAppDispatch } from '@/hooks/store';
import style from './login.module.css';
import { useNavigate } from 'react-router';
import logo from '&/assets/logo.png';
import { getUserInfo } from '@/api/user';
import debounce from 'lodash/debounce';
import { message } from 'antd';
const Login: React.FC = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [showRegister, setShowRegister] = useState(false);
const [inviteCode, setInviteCode] = useState('');
const [registerEmail, setRegisterEmail] = useState('');
const [registerPassword, setRegisterPassword] = useState('');
const [emailCode, setEmailCode] = useState('');
const [codeBtnDisabled, setCodeBtnDisabled] = useState(false);
const [codeBtnText, setCodeBtnText] = useState('发送验证码');
const [codeTimer, setCodeTimer] = useState<NodeJS.Timeout | null>(null);
const dispatch = useAppDispatch();
const [messageApi, contextHolder] = message.useMessage();
const { refresh: postUserLoginRefresh } = useApi(
() => request.post(postUserLogin, { email, password}), false);
const { refresh: getUserInfoRefresh } = useApi(
() => request.get(getUserInfo), false);
const nav = useNavigate();
const showErrorMessage = async (msg: string) => {
messageApi.error(msg);
};
// 登录逻辑
const handleLogin = debounce(async () => {
try {
const res =await postUserLoginRefresh({email, password});
console.log("res", res);
if (res==null ||(res as any).error) {
alert('Login failed. Please check your credentials.');
return;
}
dispatch({ type: "user/login", payload: res });
const userInfo = await getUserInfoRefresh();
if (userInfo == null || (userInfo as any).error) {
throw new Error('获取用户信息失败');
}
dispatch({ type: "user/getUserInfo", payload: userInfo.userInfo });
//设置宠物初始化参数
localStorage.setItem('petState', JSON.stringify({
mood: 30,
hunger: 50,
timestamp: Date.now()
}));
nav('/');
} catch (error) {
showErrorMessage('登录失败,请检查您的用户名和密码');
}
}, 1000) as () => void;
// 发送验证码逻辑
const handleSendCode = async () => {
if (!registerEmail) {
showErrorMessage('请填写邮箱');
return;
}
setCodeBtnDisabled(true);
let seconds = 60;
setCodeBtnText(`已发送(${seconds}s)`);
const timer = setInterval(() => {
seconds -= 1;
setCodeBtnText(`已发送(${seconds}s)`);
if (seconds <= 0) {
clearInterval(timer);
setCodeBtnDisabled(false);
setCodeBtnText('发送验证码');
}
}, 1000);
setCodeTimer(timer);
// TODO: 调用发送验证码接口
message.success('验证码已发送');
};
// 切换回登录
const handleBackToLogin = () => {
setShowRegister(false);
setInviteCode('');
setRegisterEmail('');
setRegisterPassword('');
setEmailCode('');
if (codeTimer) clearInterval(codeTimer);
setCodeBtnDisabled(false);
setCodeBtnText('发送验证码');
};
// 注册逻辑(仅前端校验,实际应调用注册接口)
const handleRegister = async () => {
if (!inviteCode || !registerEmail || !registerPassword || !emailCode) {
showErrorMessage('请填写完整信息');
return;
}
// TODO: 调用注册接口
message.success('注册成功,请登录');
handleBackToLogin();
};
const handleLogoClick = () => {
nav('/');
};
return (
<div className={style.form}>
{contextHolder}
<img className={style.logo} src={logo} alt="logo" onClick={handleLogoClick} />
{!showRegister ? (
<>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
className={style.email}
placeholder="Enter your email"
/>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
className={style.password}
placeholder="Enter your password"
/>
<button className={style.submit} onClick={() => handleLogin()}>登录</button>
<button className={style.register} onClick={() => setShowRegister(true)}>注册</button>
<button className={style.forget}>忘记密码</button>
</>
) : (
<>
<input
type="text"
value={inviteCode}
onChange={(e) => setInviteCode(e.target.value)}
className={style.invite}
placeholder="邀请码"
/>
<input
type="email"
value={registerEmail}
onChange={(e) => setRegisterEmail(e.target.value)}
className={style.email}
placeholder="邮箱"
/>
<input
type="password"
value={registerPassword}
onChange={(e) => setRegisterPassword(e.target.value)}
className={style.password}
placeholder="密码"
/>
<div style={{ display: 'flex',width:'80%', alignItems: 'center', gap: 8, padding:'10px' }}>
<input
type="text"
value={emailCode}
onChange={(e) => setEmailCode(e.target.value)}
className={style.code}
placeholder="邮箱验证码"
style={{ flex: 1 }}
/>
<button
className={style.sendCode}
onClick={handleSendCode}
disabled={codeBtnDisabled}
style={{
background: codeBtnDisabled ? '#ccc' : undefined,
color: codeBtnDisabled ? '#888' : undefined,
cursor: codeBtnDisabled ? 'not-allowed' : 'pointer'
}}
>
{codeBtnText}
</button>
</div>
<button className={style.submit} onClick={handleRegister}>注册</button>
<button className={style.back} onClick={handleBackToLogin}>返回登录</button>
</>
)}
</div>
);
};
export default Login;