**统计功能**: - 新增UserAnswerRecord模型记录用户答题历史 - 实现GetStatistics接口,统计题库总数、已答题数、正确率 - 在提交答案时自动记录答题历史 - 前端连接真实统计接口,显示实时数据 **认证系统优化**: - 新增Auth中间件,实现基于Token的身份验证 - 登录和注册时自动生成并保存Token到数据库 - 所有需要登录的接口都通过Auth中间件保护 - 统一处理未授权请求,返回401状态码 **错题练习功能**: - 新增GetRandomWrongQuestion接口,随机获取错题 - 支持错题练习模式(/question?mode=wrong) - 优化错题本页面UI,移除已掌握功能 - 新增"开始错题练习"按钮,直接进入练习模式 **数据库迁移**: - 新增user_answer_records表,记录用户答题历史 - User表新增token字段,存储用户登录凭证 **技术改进**: - 统一错误处理,区分401未授权和404未找到 - 优化答题流程,记录历史和错题分离处理 - 移除异步记录错题,改为同步处理保证数据一致性 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
67 lines
1.9 KiB
Go
67 lines
1.9 KiB
Go
package models
|
|
|
|
import (
|
|
"time"
|
|
|
|
"golang.org/x/crypto/bcrypt"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// User 用户结构
|
|
type User struct {
|
|
ID uint `gorm:"primaryKey" json:"id"`
|
|
Username string `gorm:"uniqueIndex;not null;size:50" json:"username"`
|
|
Password string `gorm:"not null;size:255" json:"-"` // json:"-" 表示在JSON响应中不返回密码
|
|
Token string `gorm:"size:255;index" json:"-"` // 用户登录token
|
|
Avatar string `gorm:"size:255" json:"avatar"`
|
|
Nickname string `gorm:"size:50" json:"nickname"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
|
|
}
|
|
|
|
// HashPassword 加密密码
|
|
func (u *User) HashPassword(password string) error {
|
|
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
u.Password = string(hashedPassword)
|
|
return nil
|
|
}
|
|
|
|
// CheckPassword 验证密码
|
|
func (u *User) CheckPassword(password string) bool {
|
|
err := bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
|
|
return err == nil
|
|
}
|
|
|
|
// UserData 存储所有用户的结构(用于兼容旧的文件存储方式)
|
|
type UserData map[string]User
|
|
|
|
// LoginRequest 登录请求
|
|
type LoginRequest struct {
|
|
Username string `json:"username" binding:"required"`
|
|
Password string `json:"password" binding:"required"`
|
|
}
|
|
|
|
// LoginResponse 登录响应
|
|
type LoginResponse struct {
|
|
Token string `json:"token"`
|
|
User UserInfoResponse `json:"user"`
|
|
}
|
|
|
|
// UserInfoResponse 用户信息响应(不包含密码)
|
|
type UserInfoResponse struct {
|
|
Username string `json:"username"`
|
|
Avatar string `json:"avatar"`
|
|
Nickname string `json:"nickname"`
|
|
}
|
|
|
|
// RegisterRequest 注册请求
|
|
type RegisterRequest struct {
|
|
Username string `json:"username" binding:"required"`
|
|
Password string `json:"password" binding:"required,min=6"`
|
|
Nickname string `json:"nickname"`
|
|
}
|