refactor: Update service and repository methods to use context

- Refactored multiple service and repository methods to accept context as a parameter, enhancing consistency and enabling better control over request lifecycles.
- Updated handlers to utilize context in method calls, improving error handling and performance.
- Cleaned up Dockerfile by removing unnecessary whitespace.
This commit is contained in:
lan
2025-12-03 15:27:12 +08:00
parent 4824a997dd
commit 0bcd9336c4
32 changed files with 833 additions and 497 deletions

View File

@@ -1,12 +1,6 @@
package service
import (
"carrotskin/internal/model"
"carrotskin/internal/repository"
"carrotskin/pkg/auth"
"carrotskin/pkg/config"
"carrotskin/pkg/database"
"carrotskin/pkg/redis"
"context"
"errors"
"fmt"
@@ -14,6 +8,14 @@ import (
"strings"
"time"
apperrors "carrotskin/internal/errors"
"carrotskin/internal/model"
"carrotskin/internal/repository"
"carrotskin/pkg/auth"
"carrotskin/pkg/config"
"carrotskin/pkg/database"
"carrotskin/pkg/redis"
"go.uber.org/zap"
)
@@ -54,21 +56,21 @@ func NewUserService(
func (s *userService) Register(ctx context.Context, username, password, email, avatar string) (*model.User, string, error) {
// 检查用户名是否已存在
existingUser, err := s.userRepo.FindByUsername(username)
existingUser, err := s.userRepo.FindByUsername(ctx, username)
if err != nil {
return nil, "", err
}
if existingUser != nil {
return nil, "", errors.New("用户名已存在")
return nil, "", apperrors.ErrUserAlreadyExists
}
// 检查邮箱是否已存在
existingEmail, err := s.userRepo.FindByEmail(email)
existingEmail, err := s.userRepo.FindByEmail(ctx, email)
if err != nil {
return nil, "", err
}
if existingEmail != nil {
return nil, "", errors.New("邮箱已被注册")
return nil, "", apperrors.ErrEmailAlreadyExists
}
// 加密密码
@@ -98,7 +100,7 @@ func (s *userService) Register(ctx context.Context, username, password, email, a
Points: 0,
}
if err := s.userRepo.Create(user); err != nil {
if err := s.userRepo.Create(ctx, user); err != nil {
return nil, "", err
}
@@ -126,9 +128,9 @@ func (s *userService) Login(ctx context.Context, usernameOrEmail, password, ipAd
var err error
if strings.Contains(usernameOrEmail, "@") {
user, err = s.userRepo.FindByEmail(usernameOrEmail)
user, err = s.userRepo.FindByEmail(ctx, usernameOrEmail)
} else {
user, err = s.userRepo.FindByUsername(usernameOrEmail)
user, err = s.userRepo.FindByUsername(ctx, usernameOrEmail)
}
if err != nil {
@@ -166,12 +168,12 @@ func (s *userService) Login(ctx context.Context, usernameOrEmail, password, ipAd
// 更新最后登录时间
now := time.Now()
user.LastLoginAt = &now
_ = s.userRepo.UpdateFields(user.ID, map[string]interface{}{
_ = s.userRepo.UpdateFields(ctx, user.ID, map[string]interface{}{
"last_login_at": now,
})
// 记录成功登录日志
s.logSuccessLogin(user.ID, ipAddress, userAgent)
s.logSuccessLogin(ctx, user.ID, ipAddress, userAgent)
return user, token, nil
}
@@ -180,7 +182,7 @@ func (s *userService) GetByID(ctx context.Context, id int64) (*model.User, error
// 使用 Cached 装饰器自动处理缓存
cacheKey := s.cacheKeys.User(id)
return database.Cached(ctx, s.cache, cacheKey, func() (*model.User, error) {
return s.userRepo.FindByID(id)
return s.userRepo.FindByID(ctx, id)
}, 5*time.Minute)
}
@@ -188,12 +190,12 @@ func (s *userService) GetByEmail(ctx context.Context, email string) (*model.User
// 使用 Cached 装饰器自动处理缓存
cacheKey := s.cacheKeys.UserByEmail(email)
return database.Cached(ctx, s.cache, cacheKey, func() (*model.User, error) {
return s.userRepo.FindByEmail(email)
return s.userRepo.FindByEmail(ctx, email)
}, 5*time.Minute)
}
func (s *userService) UpdateInfo(ctx context.Context, user *model.User) error {
err := s.userRepo.Update(user)
err := s.userRepo.Update(ctx, user)
if err != nil {
return err
}
@@ -209,7 +211,7 @@ func (s *userService) UpdateInfo(ctx context.Context, user *model.User) error {
}
func (s *userService) UpdateAvatar(ctx context.Context, userID int64, avatarURL string) error {
err := s.userRepo.UpdateFields(userID, map[string]interface{}{
err := s.userRepo.UpdateFields(ctx, userID, map[string]interface{}{
"avatar": avatarURL,
})
if err != nil {
@@ -223,7 +225,7 @@ func (s *userService) UpdateAvatar(ctx context.Context, userID int64, avatarURL
}
func (s *userService) ChangePassword(ctx context.Context, userID int64, oldPassword, newPassword string) error {
user, err := s.userRepo.FindByID(userID)
user, err := s.userRepo.FindByID(ctx, userID)
if err != nil || user == nil {
return errors.New("用户不存在")
}
@@ -237,7 +239,7 @@ func (s *userService) ChangePassword(ctx context.Context, userID int64, oldPassw
return errors.New("密码加密失败")
}
err = s.userRepo.UpdateFields(userID, map[string]interface{}{
err = s.userRepo.UpdateFields(ctx, userID, map[string]interface{}{
"password": hashedPassword,
})
if err != nil {
@@ -251,7 +253,7 @@ func (s *userService) ChangePassword(ctx context.Context, userID int64, oldPassw
}
func (s *userService) ResetPassword(ctx context.Context, email, newPassword string) error {
user, err := s.userRepo.FindByEmail(email)
user, err := s.userRepo.FindByEmail(ctx, email)
if err != nil || user == nil {
return errors.New("用户不存在")
}
@@ -261,7 +263,7 @@ func (s *userService) ResetPassword(ctx context.Context, email, newPassword stri
return errors.New("密码加密失败")
}
err = s.userRepo.UpdateFields(user.ID, map[string]interface{}{
err = s.userRepo.UpdateFields(ctx, user.ID, map[string]interface{}{
"password": hashedPassword,
})
if err != nil {
@@ -279,17 +281,17 @@ func (s *userService) ResetPassword(ctx context.Context, email, newPassword stri
func (s *userService) ChangeEmail(ctx context.Context, userID int64, newEmail string) error {
// 获取旧邮箱
oldUser, _ := s.userRepo.FindByID(userID)
oldUser, _ := s.userRepo.FindByID(ctx, userID)
existingUser, err := s.userRepo.FindByEmail(newEmail)
existingUser, err := s.userRepo.FindByEmail(ctx, newEmail)
if err != nil {
return err
}
if existingUser != nil && existingUser.ID != userID {
return errors.New("邮箱已被其他用户使用")
return apperrors.ErrEmailAlreadyExists
}
err = s.userRepo.UpdateFields(userID, map[string]interface{}{
err = s.userRepo.UpdateFields(ctx, userID, map[string]interface{}{
"email": newEmail,
})
if err != nil {
@@ -346,7 +348,7 @@ func (s *userService) ValidateAvatarURL(ctx context.Context, avatarURL string) e
}
func (s *userService) GetMaxProfilesPerUser() int {
config, err := s.configRepo.GetByKey("max_profiles_per_user")
config, err := s.configRepo.GetByKey(context.Background(), "max_profiles_per_user")
if err != nil || config == nil {
return 5
}
@@ -359,7 +361,7 @@ func (s *userService) GetMaxProfilesPerUser() int {
}
func (s *userService) GetMaxTexturesPerUser() int {
config, err := s.configRepo.GetByKey("max_textures_per_user")
config, err := s.configRepo.GetByKey(context.Background(), "max_textures_per_user")
if err != nil || config == nil {
return 50
}
@@ -374,7 +376,7 @@ func (s *userService) GetMaxTexturesPerUser() int {
// 私有辅助方法
func (s *userService) getDefaultAvatar() string {
config, err := s.configRepo.GetByKey("default_avatar")
config, err := s.configRepo.GetByKey(context.Background(), "default_avatar")
if err != nil || config == nil || config.Value == "" {
return ""
}
@@ -410,14 +412,14 @@ func (s *userService) recordLoginFailure(ctx context.Context, usernameOrEmail, i
identifier := usernameOrEmail + ":" + ipAddress
count, _ := RecordLoginFailure(ctx, s.redis, identifier)
if count >= MaxLoginAttempts {
s.logFailedLogin(userID, ipAddress, userAgent, reason+"-账号已锁定")
s.logFailedLogin(ctx, userID, ipAddress, userAgent, reason+"-账号已锁定")
return
}
}
s.logFailedLogin(userID, ipAddress, userAgent, reason)
s.logFailedLogin(ctx, userID, ipAddress, userAgent, reason)
}
func (s *userService) logSuccessLogin(userID int64, ipAddress, userAgent string) {
func (s *userService) logSuccessLogin(ctx context.Context, userID int64, ipAddress, userAgent string) {
log := &model.UserLoginLog{
UserID: userID,
IPAddress: ipAddress,
@@ -425,10 +427,10 @@ func (s *userService) logSuccessLogin(userID int64, ipAddress, userAgent string)
LoginMethod: "PASSWORD",
IsSuccess: true,
}
_ = s.userRepo.CreateLoginLog(log)
_ = s.userRepo.CreateLoginLog(ctx, log)
}
func (s *userService) logFailedLogin(userID int64, ipAddress, userAgent, reason string) {
func (s *userService) logFailedLogin(ctx context.Context, userID int64, ipAddress, userAgent, reason string) {
log := &model.UserLoginLog{
UserID: userID,
IPAddress: ipAddress,
@@ -437,5 +439,5 @@ func (s *userService) logFailedLogin(userID int64, ipAddress, userAgent, reason
IsSuccess: false,
FailureReason: reason,
}
_ = s.userRepo.CreateLoginLog(log)
_ = s.userRepo.CreateLoginLog(ctx, log)
}