package service import ( "time" "golang.org/x/crypto/bcrypt" ) type User struct { ID int64 Email string Username string Wechat string Notes string PasswordHash string Role string Balance float64 Concurrency int Status string AllowedGroups []int64 CreatedAt time.Time UpdatedAt time.Time ApiKeys []ApiKey Subscriptions []UserSubscription } func (u *User) IsAdmin() bool { return u.Role == RoleAdmin } func (u *User) IsActive() bool { return u.Status == StatusActive } // CanBindGroup checks whether a user can bind to a given group. // For standard groups: // - If AllowedGroups is non-empty, only allow binding to IDs in that list. // - If AllowedGroups is empty (nil or length 0), allow binding to any non-exclusive group. func (u *User) CanBindGroup(groupID int64, isExclusive bool) bool { if len(u.AllowedGroups) > 0 { for _, id := range u.AllowedGroups { if id == groupID { return true } } return false } return !isExclusive } func (u *User) SetPassword(password string) error { hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) if err != nil { return err } u.PasswordHash = string(hash) return nil } func (u *User) CheckPassword(password string) bool { return bcrypt.CompareHashAndPassword([]byte(u.PasswordHash), []byte(password)) == nil }