diff --git a/frontend/src/pages/auth/Login.tsx b/frontend/src/pages/auth/Login.tsx index ed712f2..46c956f 100644 --- a/frontend/src/pages/auth/Login.tsx +++ b/frontend/src/pages/auth/Login.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react' +import { useState, useEffect } from 'react' import { useNavigate, Link } from 'react-router-dom' import { Eye, EyeOff } from 'lucide-react' import Logo from '../../components/ui/Logo' @@ -23,8 +23,9 @@ export default function Login() { const [showPassword, setShowPassword] = useState(false) const [error, setError] = useState('') const [loading, setLoading] = useState(false) + const [remember, setRemember] = useState(false) - const { register, handleSubmit, formState: { errors } } = useForm({ + const { register, handleSubmit, setValue, formState: { errors } } = useForm({ resolver: zodResolver(schema), defaultValues: { phone: '13800000001', @@ -32,11 +33,31 @@ export default function Login() { }, }) + // 读取记住的账号密码 + useEffect(() => { + try { + const saved = localStorage.getItem('admin-login-remember') + if (saved) { + const { phone, password } = JSON.parse(saved) + if (phone) setValue('phone', phone) + if (password) setValue('password', password) + setRemember(true) + } + } catch { + // 忽略解析错误 + } + }, [setValue]) + const onSubmit = async (data: FormData) => { setError('') setLoading(true) try { const res = await api.post('/auth/login', data) as any + if (remember) { + localStorage.setItem('admin-login-remember', JSON.stringify({ phone: data.phone, password: data.password })) + } else { + localStorage.removeItem('admin-login-remember') + } setAuth(res.data.user, res.data.accessToken, res.data.refreshToken) navigate('/') } catch (err: any) { @@ -92,6 +113,16 @@ export default function Login() { {errors.password &&

{errors.password.message}

} + + diff --git a/frontend/src/pages/platform/PlatformLogin.tsx b/frontend/src/pages/platform/PlatformLogin.tsx index 6ceba42..953267f 100644 --- a/frontend/src/pages/platform/PlatformLogin.tsx +++ b/frontend/src/pages/platform/PlatformLogin.tsx @@ -1,8 +1,9 @@ /** * 平台管理员登录页 * 独立入口 /platform/login,仅 SUPER_ADMIN 角色可登录 + * 支持记住手机号和密码(localStorage) */ -import { useState } from 'react' +import { useState, useEffect } from 'react' import { useNavigate, Link } from 'react-router-dom' import { Eye, EyeOff, Shield } from 'lucide-react' import { useForm } from 'react-hook-form' @@ -20,14 +21,17 @@ const schema = z.object({ type FormData = z.infer +const STORAGE_KEY = 'platform-login-remember' + export default function PlatformLogin() { const navigate = useNavigate() const { setAuth } = useAuthStore() const [showPassword, setShowPassword] = useState(false) const [error, setError] = useState('') const [loading, setLoading] = useState(false) + const [remember, setRemember] = useState(false) - const { register, handleSubmit, formState: { errors } } = useForm({ + const { register, handleSubmit, setValue, formState: { errors } } = useForm({ resolver: zodResolver(schema), defaultValues: { phone: '13800000000', @@ -35,11 +39,32 @@ export default function PlatformLogin() { }, }) + // 读取记住的账号密码 + useEffect(() => { + try { + const saved = localStorage.getItem(STORAGE_KEY) + if (saved) { + const { phone, password } = JSON.parse(saved) + if (phone) setValue('phone', phone) + if (password) setValue('password', password) + setRemember(true) + } + } catch { + // 忽略解析错误 + } + }, [setValue]) + const onSubmit = async (data: FormData) => { setError('') setLoading(true) try { const res = await api.post('/auth/platform-login', data) as any + // 登录成功后保存/清除记住的账号密码 + if (remember) { + localStorage.setItem(STORAGE_KEY, JSON.stringify({ phone: data.phone, password: data.password })) + } else { + localStorage.removeItem(STORAGE_KEY) + } setAuth(res.data.user, res.data.accessToken, res.data.refreshToken) navigate('/platform/dashboard') } catch (err: any) { @@ -103,6 +128,16 @@ export default function PlatformLogin() { {errors.password &&

{errors.password.message}

} + +