package repository import ( "context" "fmt" "gofaster/internal/auth/model" "gorm.io/gorm" ) type UserRepository interface { Create(ctx context.Context, user *model.User) error GetByID(ctx context.Context, id uint) (*model.User, error) GetByUsername(ctx context.Context, username string) (*model.User, error) GetByEmail(ctx context.Context, email string) (*model.User, error) Update(ctx context.Context, user *model.User) error Delete(ctx context.Context, id uint) error List(ctx context.Context, offset, limit int) ([]*model.User, int64, error) // 登录相关方法 IncrementPasswordError(ctx context.Context, userID uint) error ResetPasswordError(ctx context.Context, userID uint) error UpdateLastLogin(ctx context.Context, userID uint, ip string) error GetUserWithRoles(ctx context.Context, userID uint) (*model.User, error) } type userRepository struct { db *gorm.DB } func NewUserRepository(db *gorm.DB) UserRepository { return &userRepository{ db: db, } } func (r *userRepository) Create(ctx context.Context, user *model.User) error { return r.db.WithContext(ctx).Create(user).Error } func (r *userRepository) GetByID(ctx context.Context, id uint) (*model.User, error) { var user model.User err := r.db.WithContext(ctx).First(&user, id).Error if err != nil { return nil, err } return &user, nil } func (r *userRepository) GetByUsername(ctx context.Context, username string) (*model.User, error) { var user model.User err := r.db.WithContext(ctx).Where("username = ?", username).First(&user).Error if err != nil { return nil, err } return &user, nil } func (r *userRepository) GetByEmail(ctx context.Context, email string) (*model.User, error) { var user model.User err := r.db.WithContext(ctx).Where("email = ?", email).First(&user).Error if err != nil { return nil, err } return &user, nil } func (r *userRepository) Update(ctx context.Context, user *model.User) error { // 使用Updates方法,只更新非零值字段,避免更新密码 return r.db.WithContext(ctx).Model(user).Updates(map[string]interface{}{ "username": user.Username, "email": user.Email, "phone": user.Phone, "status": user.Status, "password_error_count": user.PasswordErrorCount, "locked_at": user.LockedAt, "last_login_at": user.LastLoginAt, "last_login_ip": user.LastLoginIP, "password_changed_at": user.PasswordChangedAt, "force_change_password": user.ForceChangePassword, "updated_at": user.UpdatedAt, }).Error } func (r *userRepository) Delete(ctx context.Context, id uint) error { return r.db.WithContext(ctx).Delete(&model.User{}, id).Error } func (r *userRepository) List(ctx context.Context, offset, limit int) ([]*model.User, int64, error) { var users []*model.User var total int64 // 添加调试日志 fmt.Printf("🔍 [用户查询] 开始查询用户列表,offset=%d, limit=%d\n", offset, limit) err := r.db.WithContext(ctx).Model(&model.User{}).Count(&total).Error if err != nil { fmt.Printf("🔍 [用户查询] 统计总数失败: %v\n", err) return nil, 0, err } fmt.Printf("🔍 [用户查询] 数据库中共有 %d 条用户记录\n", total) err = r.db.WithContext(ctx).Offset(offset).Limit(limit).Find(&users).Error if err != nil { fmt.Printf("🔍 [用户查询] 查询用户列表失败: %v\n", err) return nil, 0, err } fmt.Printf("🔍 [用户查询] 查询到 %d 条用户记录\n", len(users)) // 打印查询到的用户信息 for i, user := range users { fmt.Printf("🔍 [用户查询] 用户 %d: ID=%d, Username=%s, Email=%s, Status=%d\n", i+1, user.ID, user.Username, user.Email, user.Status) } return users, total, nil } // IncrementPasswordError 增加密码错误次数 func (r *userRepository) IncrementPasswordError(ctx context.Context, userID uint) error { // 先获取当前用户信息 var user model.User if err := r.db.WithContext(ctx).First(&user, userID).Error; err != nil { return err } // 增加错误次数 user.PasswordErrorCount++ // 如果达到5次错误,锁定账户 if user.PasswordErrorCount >= 5 { user.Status = 3 // 设置为锁定状态 now := r.db.NowFunc() user.LockedAt = &now } // 保存更新 return r.db.WithContext(ctx).Save(&user).Error } // ResetPasswordError 重置密码错误次数 func (r *userRepository) ResetPasswordError(ctx context.Context, userID uint) error { return r.db.WithContext(ctx).Model(&model.User{}). Where("id = ?", userID). Updates(map[string]interface{}{ "password_error_count": 0, "status": 1, "locked_at": nil, }).Error } // UpdateLastLogin 更新最后登录信息 func (r *userRepository) UpdateLastLogin(ctx context.Context, userID uint, ip string) error { return r.db.WithContext(ctx).Model(&model.User{}). Where("id = ?", userID). Updates(map[string]interface{}{ "last_login_at": gorm.Expr("NOW()"), "last_login_ip": ip, }).Error } // GetUserWithRoles 获取用户及其角色信息 func (r *userRepository) GetUserWithRoles(ctx context.Context, userID uint) (*model.User, error) { var user model.User err := r.db.WithContext(ctx). Preload("Roles"). Preload("Roles.Permissions"). First(&user, userID).Error if err != nil { return nil, err } return &user, nil }