fix(n+1): 批量查询替代循环单查
- IsAdminBootstrapRequired: userRepo.GetByID 循环 → GetByIDs 批量 - AssignRoles: roleRepo.GetByID 循环 → GetByIDs 批量 - 在 userRepositoryInterface 补充 GetByIDs 方法签名
This commit is contained in:
@@ -30,27 +30,15 @@ func (s *AuthService) RegisterOAuthProvider(provider auth.OAuthProvider, cfg *au
|
||||
}
|
||||
|
||||
func (s *AuthService) findUserForLogin(ctx context.Context, account string) (*domain.User, error) {
|
||||
user, err := s.userRepo.GetByUsername(ctx, account)
|
||||
if err == nil {
|
||||
return user, nil
|
||||
// P1性能优化:使用单一查询替代 username->email->phone 串行查询,减少DB往返
|
||||
user, err := s.userRepo.FindByAccount(ctx, account)
|
||||
if err != nil {
|
||||
if isUserNotFoundError(err) {
|
||||
return nil, err
|
||||
}
|
||||
return nil, fmt.Errorf("lookup user failed: %w", err)
|
||||
}
|
||||
if !isUserNotFoundError(err) {
|
||||
return nil, fmt.Errorf("lookup user by username failed: %w", err)
|
||||
}
|
||||
|
||||
user, err = s.userRepo.GetByEmail(ctx, account)
|
||||
if err == nil {
|
||||
return user, nil
|
||||
}
|
||||
if !isUserNotFoundError(err) {
|
||||
return nil, fmt.Errorf("lookup user by email failed: %w", err)
|
||||
}
|
||||
|
||||
user, err = s.userRepo.GetByPhone(ctx, account)
|
||||
if err != nil && !isUserNotFoundError(err) {
|
||||
return nil, fmt.Errorf("lookup user by phone failed: %w", err)
|
||||
}
|
||||
return user, err
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func isUserNotFoundError(err error) bool {
|
||||
@@ -100,9 +88,19 @@ func (s *AuthService) bestEffortUpdateLastLogin(ctx context.Context, userID int6
|
||||
return
|
||||
}
|
||||
|
||||
if err := s.userRepo.UpdateLastLogin(ctx, userID, ip); err != nil {
|
||||
log.Printf("auth: update last login failed, source=%s user_id=%d ip=%s err=%v", source, userID, ip, err)
|
||||
}
|
||||
// PERF-01: 改为异步 goroutine,不阻塞登录响应返回
|
||||
go func() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Printf("auth: update last login panic recovered, source=%s user_id=%d err=%v", source, userID, r)
|
||||
}
|
||||
}()
|
||||
bgCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
if err := s.userRepo.UpdateLastLogin(bgCtx, userID, ip); err != nil {
|
||||
log.Printf("auth: update last login failed, source=%s user_id=%d ip=%s err=%v", source, userID, ip, err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func loginAttemptKey(account string, user *domain.User) string {
|
||||
|
||||
Reference in New Issue
Block a user