user.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  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. }
  34. type userService struct {
  35. userRepo repository.UserRepository
  36. *Service
  37. }
  38. func NewUserService(service *Service, userRepo repository.UserRepository) UserService {
  39. return &userService{
  40. userRepo: userRepo,
  41. Service: service,
  42. }
  43. }
  44. func (s *userService) Register(ctx context.Context, req *RegisterRequest) error {
  45. // 检查用户名是否已存在
  46. if user, err := s.userRepo.GetByUsername(ctx, req.Username); err == nil && user != nil {
  47. return errors.New("username already exists")
  48. }
  49. hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
  50. if err != nil {
  51. return errors.Wrap(err, "failed to hash password")
  52. }
  53. // Generate user ID
  54. userId, err := s.sid.GenString()
  55. if err != nil {
  56. return errors.Wrap(err, "failed to generate user ID")
  57. }
  58. // Create a user
  59. user := &model.User{
  60. UserId: userId,
  61. Username: req.Username,
  62. Password: string(hashedPassword),
  63. Email: req.Email,
  64. }
  65. if err = s.userRepo.Create(ctx, user); err != nil {
  66. return errors.Wrap(err, "failed to create user")
  67. }
  68. return nil
  69. }
  70. func (s *userService) Login(ctx context.Context, req *LoginRequest) (string, error) {
  71. user, err := s.userRepo.GetByUsername(ctx, req.Username)
  72. if err != nil || user == nil {
  73. return "", errors.Wrap(err, "failed to get user by username")
  74. }
  75. err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(req.Password))
  76. if err != nil {
  77. return "", errors.Wrap(err, "failed to hash password")
  78. }
  79. token, err := s.jwt.GenToken(user.UserId, time.Now().Add(time.Hour*24*90))
  80. if err != nil {
  81. return "", errors.Wrap(err, "failed to generate JWT token")
  82. }
  83. return token, nil
  84. }
  85. func (s *userService) GetProfile(ctx context.Context, userId string) (*model.User, error) {
  86. user, err := s.userRepo.GetByID(ctx, userId)
  87. if err != nil {
  88. return nil, errors.Wrap(err, "failed to get user by ID")
  89. }
  90. return user, nil
  91. }
  92. func (s *userService) UpdateProfile(ctx context.Context, userId string, req *UpdateProfileRequest) error {
  93. user, err := s.userRepo.GetByID(ctx, userId)
  94. if err != nil {
  95. return errors.Wrap(err, "failed to get user by ID")
  96. }
  97. user.Email = req.Email
  98. user.Nickname = req.Nickname
  99. if err = s.userRepo.Update(ctx, user); err != nil {
  100. return errors.Wrap(err, "failed to update user")
  101. }
  102. return nil
  103. }