# 后端热重载 + 登录方式改造 设计文档 **日期**: 2026-02-14 **状态**: 已批准 ## 概述 两项改造: 1. 后端引入 Air 热重载,保存文件自动重启 2. 登录从邮箱改为手机号/用户名,注册移除邮箱必填,JWT Claims 移除 email --- ## 设计一:Air 热重载 ### 方案 使用 [Air](https://github.com/air-verse/air) 监听 `.go` 和 `.yaml` 文件变化,自动编译重启。 ### 新增文件 `backend/.air.toml`: - 监听 `.go`, `.yaml` 文件 - 排除 `tmp/`, `vendor/`, `tests/` - 编译到 `tmp/base.exe` - 延迟 1000ms 防抖 ### 启动方式 ```bash # 安装(一次性) go install github.com/air-verse/air@latest # 开发启动 cd backend && air ``` ### 影响范围 - 新增 `backend/.air.toml` - `backend/.gitignore` 加 `tmp/` - 零侵入现有代码 --- ## 设计二:登录方式改造 ### API 变更 **LoginRequest**: ``` Account string `json:"account" validate:"required"` // 手机号或用户名 Password string `json:"password" validate:"required,min=6,max=32"` ``` **RegisterRequest**: ``` Username string `json:"username" validate:"required,min=3,max=32"` Password string `json:"password" validate:"required,min=6,max=32"` Phone string `json:"phone" validate:"required"` // 必填 Email string `json:"email,optional"` // 可选 ``` ### 后端 Login 逻辑 单一输入框,后端正则自动识别: - `^\d{11}$` → 手机号 → `FindOneByPhone` - 否则 → 用户名 → `FindOneByUsername` ### Model 层 新增: - `FindOneByPhone(ctx, db, phone) (*User, error)` - `FindOneByUsername(ctx, db, username) (*User, error)` ### JWT Claims 变更 移除 `Email` 字段: ```go type Claims struct { UserID int64 `json:"userId"` Username string `json:"username"` Role string `json:"role"` jwt.RegisteredClaims } func GenerateToken(userId int64, username, role string) (string, error) ``` 影响调用点:loginlogic, registerlogic, refreshtokenlogic, ssologic, authmiddleware ### Register 逻辑 - 检查 username 唯一性(FindOneByUsername) - 检查 phone 唯一性(FindOneByPhone) - email 可选,不做唯一性检查 ### 种子超级管理员 ```go admin := &model.User{ Username: "admin", Phone: "13800000000", Email: "", Password: md5("admin123"), Role: "super_admin", Source: "system", } // 查找改为 FindOneByUsername(ctx, db, "admin") ``` ### 前端变更 | 文件 | 变更 | |------|------| | `types/index.ts` | `LoginRequest.email` → `.account`; `RegisterRequest.email` 可选, `.phone` 必填 | | `services/api.ts` | `login()` 传 `account` | | `contexts/AuthContext.tsx` | `login(email, password)` → `login(account, password)`; JWT 解析移除 email | | `pages/LoginPage.tsx` | 输入框: Mail 图标 → User 图标, placeholder "手机号 / 用户名", `type="text"` | ### 不变的部分 - SSO 登录流程(Casdoor 自有账号体系) - 用户管理 CRUD、Profile 接口 - `user_entity.go` 的 email 字段保留,仅改为非必填