🔐 登录 / 注册页
同一页面通过 mode 状态切换「登录」和「注册」两个视图。登录成功后后端返回 JWT,存入 localStorage,下次请求带上 Authorization Header。
页面结构
- Logo:顶部 Logo 文字
- Tab 切换:「登录」/「注册」切换按钮
- 表单区:根据 mode 渲染不同字段
- 提交按钮:「登录」或「注册」
- 社交登录:微信登录按钮(仅登录模式显示)
- 提示文字:Tab 下方切换提示
触发时机详解
登录模式(默认)
1. 输入手机号 + 密码 → POST /api/auth/login
触发条件:填写手机号 + 密码 → 点击"登录"按钮 → 发送 POST 请求
POST
/api/auth/login
✅ 点击"登录"按钮触发
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
phone | string | 必填 | 手机号(11位数字) |
password | string | 必填 | 密码(至少6位) |
成功响应:
{"token": "eyJhbG...", "user": {"id": "string", "phone": "...", "nickname": "...", ...}}
错误响应: {"error": "手机号或密码错误"}
2. 登录成功 → 存储 token → 跳转 /home
触发条件:POST /api/auth/login 返回 200 且有 token 字段
localStorage.setItem("token", data.token)localStorage.setItem("user", JSON.stringify(data.user))- 导航到
/home
3. 登录失败 → 显示错误提示
触发条件:POST /api/auth/login 返回 error 字段
- 显示红色提示文字
⚠️ {error} - 表单保持可编辑状态,用户可修改后重试
4. 点击「微信登录」→ 跳转微信授权(外部)
触发条件:点击"微信登录"按钮 → window.open 打开微信授权页面
说明:微信 OAuth 流程为外部跳转,需前端自行实现回调逻辑(当前 LoginPage 中微信登录按钮存在,但 callback 处理可能不完整)
注册模式
5. 点击「注册」Tab → 切换到注册视图
触发条件:点击"注册"文字按钮 → setMode("register") → 表单重置,显示注册字段
6. 填写注册信息 → POST /api/auth/register
触发条件:填写手机号 + 验证码 + 密码 + 确认密码 → 点击"注册"按钮
POST
/api/auth/register
✅ 点击"注册"按钮触发
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
phone | string | 必填 | 手机号(11位数字,唯一) |
code | string | 必填 | 短信验证码(6位数字) |
password | string | 必填 | 密码(至少6位) |
confirmPassword | string | 必填 | 确认密码(需与 password 相同) |
成功响应:
{"token": "eyJhbG...", "user": {"id": "...", "phone": "...", ...}}
错误响应: {"error": "手机号已被注册"}
7. 前端校验(无需请求)
校验规则:
- 手机号 ≠ 11位数字 → 提示"请输入11位手机号"
- 验证码 ≠ 6位数字 → 提示"请输入6位验证码"
- 密码长度 < 6 → 提示"密码至少6位"
- 确认密码 ≠ 密码 → 提示"两次密码不一致"
8. 注册成功 → 自动登录 → 跳转 /home
触发条件:POST /api/auth/register 返回 200 → 自动存储 token → Navigate to /home
9. 发送验证码 → POST /api/auth/send-code
触发条件:注册表单中点击"发送验证码"按钮 → 60秒倒计时按钮禁用
POST
/api/auth/send-code
✅ 点击"发送验证码"按钮触发
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
phone | string | 必填 | 手机号 |
type | string | 必填 | 固定 "register" |
响应: {"message": "验证码已发送"}
防抖:点击后按钮进入60秒倒计时(
setCooldown(60)),倒计时结束前不可再次点击。页面跳转规则
10. 已登录用户访问登录页
触发条件:localStorage 中存在 token 时访问 /login → 直接 Navigate to /home(阻止已登录用户访问登录页)
11. App 初始化时的路由守卫
触发条件:App 首次加载 → 检查 localStorage.token → 有 token → redirect to="/home",无 token → redirect to="/login"
// App.jsx 中的路由守卫逻辑
if (token && location.pathname === "/login") {
return <Navigate to="/home" />
}
if (!token && location.pathname !== "/login") {
return <Navigate to="/login" />;
}