feat: 平台登录页+企业登录页添加记住账号密码功能
This commit is contained in:
@@ -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<FormData>({
|
||||
const { register, handleSubmit, setValue, formState: { errors } } = useForm<FormData>({
|
||||
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 && <p className="text-xs text-red-500 mt-1">{errors.password.message}</p>}
|
||||
</div>
|
||||
|
||||
<label className="flex items-center gap-2 cursor-pointer select-none">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={remember}
|
||||
onChange={(e) => setRemember(e.target.checked)}
|
||||
className="w-4 h-4 rounded border-gray-300 text-primary focus:ring-primary focus:ring-offset-0"
|
||||
/>
|
||||
<span className="text-sm text-gray-500">记住账号密码</span>
|
||||
</label>
|
||||
|
||||
<Button type="submit" className="w-full" disabled={loading}>
|
||||
{loading ? '登录中...' : '登录'}
|
||||
</Button>
|
||||
|
||||
@@ -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<typeof schema>
|
||||
|
||||
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<FormData>({
|
||||
const { register, handleSubmit, setValue, formState: { errors } } = useForm<FormData>({
|
||||
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 && <p className="text-xs text-red-400 mt-1">{errors.password.message}</p>}
|
||||
</div>
|
||||
|
||||
<label className="flex items-center gap-2 cursor-pointer select-none">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={remember}
|
||||
onChange={(e) => setRemember(e.target.checked)}
|
||||
className="w-4 h-4 rounded border-slate-600 bg-slate-800 text-amber-400 focus:ring-amber-400 focus:ring-offset-0"
|
||||
/>
|
||||
<span className="text-sm text-slate-400">记住账号密码</span>
|
||||
</label>
|
||||
|
||||
<Button type="submit" className="w-full bg-amber-400 text-slate-950 hover:bg-amber-300" disabled={loading}>
|
||||
{loading ? '登录中...' : '登录'}
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user