From 72d3ca0660b837e269d93d96c9e18c83667767b8 Mon Sep 17 00:00:00 2001 From: yanlongqi Date: Wed, 12 Nov 2025 21:56:00 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=99=BB=E5=BD=95=E7=95=8C=E9=9D=A2?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=AE=B0=E4=BD=8F=E5=AF=86=E7=A0=81=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加"记住密码"复选框,提升用户体验 - 实现自动保存和填充用户名密码 - 支持取消记住密码时自动清除已保存信息 - 使用localStorage存储登录凭证 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- web/src/pages/Login.tsx | 42 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/web/src/pages/Login.tsx b/web/src/pages/Login.tsx index e677722..49573ba 100644 --- a/web/src/pages/Login.tsx +++ b/web/src/pages/Login.tsx @@ -1,6 +1,6 @@ import React, { useState, useEffect } from 'react' import { useNavigate } from 'react-router-dom' -import { Form, Input, Button, Card, Modal, message, Typography, Radio, Alert } from 'antd' +import { Form, Input, Button, Card, Modal, message, Typography, Radio, Alert, Checkbox } from 'antd' import { UserOutlined, LockOutlined, IdcardOutlined } from '@ant-design/icons' import { fetchWithAuth } from '../utils/request' import styles from './Login.module.less' @@ -27,12 +27,28 @@ const Login: React.FC = () => { const [loading, setLoading] = useState(false) const [registerModalVisible, setRegisterModalVisible] = useState(false) const [userTypeModalVisible, setUserTypeModalVisible] = useState(false) // 用户类型补充模态框 + const [rememberMe, setRememberMe] = useState(false) // 记住密码状态 // const [userType, setUserType] = useState('') // 临时存储用户选择的类型 const [loginForm] = Form.useForm() const [registerForm] = Form.useForm() const [userTypeForm] = Form.useForm() - // 如果已登录,重定向到首页 + // 页面加载时读取保存的登录信息 + useEffect(() => { + const savedUsername = localStorage.getItem('savedUsername') + const savedPassword = localStorage.getItem('savedPassword') + const savedRememberMe = localStorage.getItem('rememberMe') === 'true' + + if (savedRememberMe && savedUsername && savedPassword) { + loginForm.setFieldsValue({ + username: savedUsername, + password: savedPassword + }) + setRememberMe(true) + } + }, [loginForm]) + + // 如果已登录,重定向到首页 useEffect(() => { const token = localStorage.getItem('token') if (token) { @@ -52,9 +68,22 @@ const Login: React.FC = () => { const data: LoginResponse = await response.json() if (data.success && data.data) { + // 保存登录凭证 localStorage.setItem('token', data.data.token) localStorage.setItem('user', JSON.stringify(data.data.user)) + // 处理记住密码 + if (rememberMe) { + localStorage.setItem('savedUsername', values.username) + localStorage.setItem('savedPassword', values.password) + localStorage.setItem('rememberMe', 'true') + } else { + // 取消记住密码时清除保存的信息 + localStorage.removeItem('savedUsername') + localStorage.removeItem('savedPassword') + localStorage.removeItem('rememberMe') + } + // 检查是否需要补充用户类型 if (data.need_user_type) { setUserTypeModalVisible(true) @@ -172,6 +201,15 @@ const Login: React.FC = () => { /> + + setRememberMe(e.target.checked)} + > + 记住密码 + + +