2 changed files with 128 additions and 0 deletions
@ -0,0 +1,3 @@ |
|||
[submodule ".claude/skills/zero-skills"] |
|||
path = .claude/skills/zero-skills |
|||
url = https://github.com/zeromicro/zero-skills.git |
|||
@ -0,0 +1,125 @@ |
|||
# 后端热重载 + 登录方式改造 设计文档 |
|||
|
|||
**日期**: 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 字段保留,仅改为非必填 |
|||
Loading…
Reference in new issue