user.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. package service
  2. import (
  3. "context"
  4. "github.com/go-nunu/nunu-layout-advanced/internal/model"
  5. "github.com/go-nunu/nunu-layout-advanced/internal/repository"
  6. "github.com/pkg/errors"
  7. "golang.org/x/crypto/bcrypt"
  8. "time"
  9. )
  10. type RegisterRequest struct {
  11. Username string `json:"username" binding:"required"`
  12. Password string `json:"password" binding:"required"`
  13. Email string `json:"email" binding:"required,email"`
  14. }
  15. type LoginRequest struct {
  16. Username string `json:"username" binding:"required"`
  17. Password string `json:"password" binding:"required"`
  18. }
  19. type UpdateProfileRequest struct {
  20. Nickname string `json:"nickname"`
  21. Email string `json:"email" binding:"required,email"`
  22. Avatar string `json:"avatar"`
  23. }
  24. type ChangePasswordRequest struct {
  25. OldPassword string `json:"oldPassword" binding:"required"`
  26. NewPassword string `json:"newPassword" binding:"required"`
  27. }
  28. type UserService interface {
  29. Register(ctx context.Context, req *RegisterRequest) error
  30. Login(ctx context.Context, req *LoginRequest) (string, error)
  31. GetProfile(ctx context.Context, userId string) (*model.User, error)
  32. UpdateProfile(ctx context.Context, userId string, req *UpdateProfileRequest) error
  33. GenerateToken(ctx context.Context, userId string) (string, error)
  34. }
  35. type userService struct {
  36. userRepo repository.UserRepository
  37. *Service
  38. }
  39. func NewUserService(service *Service, userRepo repository.UserRepository) UserService {
  40. return &userService{
  41. userRepo: userRepo,
  42. Service: service,
  43. }
  44. }
  45. func (s *userService) Register(ctx context.Context, req *RegisterRequest) error {
  46. // 检查用户名是否已存在
  47. if user, err := s.userRepo.GetByUsername(ctx, req.Username); err == nil && user != nil {
  48. return errors.New("username already exists")
  49. }
  50. hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
  51. if err != nil {
  52. return errors.Wrap(err, "failed to hash password")
  53. }
  54. // 生成用户ID
  55. userId, err := s.sid.GenString()
  56. if err != nil {
  57. return errors.Wrap(err, "failed to generate user ID")
  58. }
  59. // 创建用户
  60. user := &model.User{
  61. UserId: userId,
  62. Username: req.Username,
  63. Password: string(hashedPassword),
  64. Email: req.Email,
  65. }
  66. if err = s.userRepo.Create(ctx, user); err != nil {
  67. return errors.Wrap(err, "failed to create user")
  68. }
  69. return nil
  70. }
  71. func (s *userService) Login(ctx context.Context, req *LoginRequest) (string, error) {
  72. user, err := s.userRepo.GetByUsername(ctx, req.Username)
  73. if err != nil || user == nil {
  74. return "", errors.Wrap(err, "failed to get user by username")
  75. }
  76. err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(req.Password))
  77. if err != nil {
  78. return "", errors.Wrap(err, "failed to hash password")
  79. }
  80. // 生成JWT token
  81. token, err := s.GenerateToken(ctx, user.UserId)
  82. if err != nil {
  83. return "", errors.Wrap(err, "failed to generate JWT token")
  84. }
  85. return token, nil
  86. }
  87. func (s *userService) GetProfile(ctx context.Context, userId string) (*model.User, error) {
  88. user, err := s.userRepo.GetByID(ctx, userId)
  89. if err != nil {
  90. return nil, errors.Wrap(err, "failed to get user by ID")
  91. }
  92. return user, nil
  93. }
  94. func (s *userService) UpdateProfile(ctx context.Context, userId string, req *UpdateProfileRequest) error {
  95. user, err := s.userRepo.GetByID(ctx, userId)
  96. if err != nil {
  97. return errors.Wrap(err, "failed to get user by ID")
  98. }
  99. user.Email = req.Email
  100. user.Nickname = req.Nickname
  101. if err = s.userRepo.Update(ctx, user); err != nil {
  102. return errors.Wrap(err, "failed to update user")
  103. }
  104. return nil
  105. }
  106. func (s *userService) GenerateToken(ctx context.Context, userId string) (string, error) {
  107. // 生成JWT token
  108. token, err := s.jwt.GenToken(userId, time.Now().Add(time.Hour*24*90))
  109. if err != nil {
  110. return "", errors.Wrap(err, "failed to generate JWT token")
  111. }
  112. return token, nil
  113. }