package service import ( "errors" "fmt" "math/rand" "time" "affiliate_dash/internal/model" "affiliate_dash/internal/pkg/jwt" "golang.org/x/crypto/bcrypt" "gorm.io/gorm" ) type AuthService struct { db *gorm.DB jwt *jwt.Manager } func NewAuthService(db *gorm.DB, jm *jwt.Manager) *AuthService { return &AuthService{db: db, jwt: jm} } type LoginResult struct { Token string `json:"token"` User *model.User `json:"user"` } func (s *AuthService) Login(username, password string) (*LoginResult, error) { var user model.User if err := s.db.Where("username = ?", username).First(&user).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return nil, errors.New("用户名或密码错误") } return nil, err } if user.Status != 1 { return nil, errors.New("账号已禁用") } if err := bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(password)); err != nil { return nil, errors.New("用户名或密码错误") } token, err := s.jwt.Generate(user.ID, user.Username, user.Role) if err != nil { return nil, err } return &LoginResult{Token: token, User: &user}, nil } func (s *AuthService) Register(username, password, nickname string) (*model.User, error) { var count int64 s.db.Model(&model.User{}).Where("username = ?", username).Count(&count) if count > 0 { return nil, errors.New("用户名已存在") } hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) if err != nil { return nil, err } user := &model.User{ Username: username, PasswordHash: string(hash), Nickname: nickname, Role: model.RoleDistributor, Status: 1, InviteCode: generateInviteCode(), } if user.Nickname == "" { user.Nickname = username } if err := s.db.Create(user).Error; err != nil { return nil, err } return user, nil } func (s *AuthService) GetProfile(userID uint) (*model.User, error) { var user model.User if err := s.db.First(&user, userID).Error; err != nil { return nil, err } return &user, nil } func (s *AuthService) EnsureAdmin() error { var count int64 s.db.Model(&model.User{}).Where("role = ?", model.RoleAdmin).Count(&count) if count > 0 { return nil } hash, err := bcrypt.GenerateFromPassword([]byte("admin123"), bcrypt.DefaultCost) if err != nil { return err } admin := &model.User{ Username: "admin", PasswordHash: string(hash), Nickname: "管理员", Role: model.RoleAdmin, Status: 1, InviteCode: "ADMIN001", } return s.db.Create(admin).Error } func generateInviteCode() string { r := rand.New(rand.NewSource(time.Now().UnixNano())) return fmt.Sprintf("D%06d", r.Intn(1000000)) }