package adminauth import ( "errors" "time" "hfb_sys/backend/internal/model" "hfb_sys/backend/internal/modules/auth" "golang.org/x/crypto/bcrypt" "gorm.io/gorm" ) const ( defaultAdminUsername = "admin" defaultAdminPassword = "admin123456" ) type Repository struct { db *gorm.DB jwt *auth.JWTManager } func NewRepository(db *gorm.DB, jwt *auth.JWTManager) *Repository { return &Repository{db: db, jwt: jwt} } func (r *Repository) Login(username string, password string) (LoginResult, error) { if err := r.ensureDefaultAdmin(); err != nil { return LoginResult{}, err } var admin model.AdminUser if err := r.db.Where("username = ?", username).First(&admin).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return LoginResult{}, ErrInvalidCredential } return LoginResult{}, err } if admin.Status != "active" { return LoginResult{}, ErrAdminDisabled } if err := bcrypt.CompareHashAndPassword([]byte(admin.PasswordHash), []byte(password)); err != nil { return LoginResult{}, ErrInvalidCredential } now := time.Now() admin.LastLoginAt = &now if err := r.db.Save(&admin).Error; err != nil { return LoginResult{}, err } tokens, err := r.jwt.GenerateSubjectPair(admin.ID, admin.Username, "admin") if err != nil { return LoginResult{}, err } return LoginResult{Admin: toDTO(admin), Tokens: tokens}, nil } func (r *Repository) FindByID(id uint64) (*AdminDTO, error) { var admin model.AdminUser if err := r.db.First(&admin, id).Error; err != nil { return nil, err } if admin.Status != "active" { return nil, ErrAdminDisabled } dto := toDTO(admin) return &dto, nil } func (r *Repository) ensureDefaultAdmin() error { var count int64 if err := r.db.Model(&model.AdminUser{}).Count(&count).Error; err != nil { return err } if count > 0 { return nil } hash, err := bcrypt.GenerateFromPassword([]byte(defaultAdminPassword), bcrypt.DefaultCost) if err != nil { return err } admin := model.AdminUser{ Username: defaultAdminUsername, PasswordHash: string(hash), Nickname: "超级管理员", Status: "active", } return r.db.Create(&admin).Error } func toDTO(admin model.AdminUser) AdminDTO { return AdminDTO{ ID: admin.ID, Username: admin.Username, Nickname: admin.Nickname, Status: admin.Status, LastLoginAt: admin.LastLoginAt, } }