package service import ( "context" "errors" "git.huangwc.com/pig/pig-farm-controller/internal/app/dto" domain_notify "git.huangwc.com/pig/pig-farm-controller/internal/domain/notify" "git.huangwc.com/pig/pig-farm-controller/internal/infra/logs" "git.huangwc.com/pig/pig-farm-controller/internal/infra/models" "git.huangwc.com/pig/pig-farm-controller/internal/infra/repository" "git.huangwc.com/pig/pig-farm-controller/internal/infra/utils/token" "gorm.io/gorm" ) // UserService 定义用户服务接口 type UserService interface { CreateUser(ctx context.Context, req *dto.CreateUserRequest) (*dto.CreateUserResponse, error) Login(ctx context.Context, req *dto.LoginRequest) (*dto.LoginResponse, error) SendTestNotification(ctx context.Context, userID uint, req *dto.SendTestNotificationRequest) error } // userService 实现了 UserService 接口 type userService struct { ctx context.Context userRepo repository.UserRepository tokenGenerator token.Generator notifyService domain_notify.Service } // NewUserService 创建并返回一个新的 UserService 实例 func NewUserService( ctx context.Context, userRepo repository.UserRepository, tokenGenerator token.Generator, notifyService domain_notify.Service, ) UserService { return &userService{ ctx: ctx, userRepo: userRepo, tokenGenerator: tokenGenerator, notifyService: notifyService, } } // CreateUser 创建新用户 func (s *userService) CreateUser(ctx context.Context, req *dto.CreateUserRequest) (*dto.CreateUserResponse, error) { serviceCtx, logger := logs.Trace(ctx, s.ctx, "CreateUser") user := &models.User{ Username: req.Username, Password: req.Password, // 密码会在 BeforeSave 钩子中哈希 } if err := s.userRepo.Create(serviceCtx, user); err != nil { logger.Errorf("创建用户: 创建用户失败: %v", err) // 尝试查询用户,以判断是否是用户名重复导致的错误 _, findErr := s.userRepo.FindByUsername(serviceCtx, req.Username) if findErr == nil { // 如果能找到用户,说明是用户名重复 return nil, errors.New("用户名已存在") } // 其他创建失败的情况 return nil, errors.New("创建用户失败") } return &dto.CreateUserResponse{ Username: user.Username, ID: user.ID, }, nil } // Login 用户登录 func (s *userService) Login(ctx context.Context, req *dto.LoginRequest) (*dto.LoginResponse, error) { serviceCtx, logger := logs.Trace(ctx, s.ctx, "Login") // 使用新的方法,通过唯一标识符(用户名、邮箱等)查找用户 user, err := s.userRepo.FindUserForLogin(serviceCtx, req.Identifier) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return nil, errors.New("登录凭证不正确") } logger.Errorf("登录: 查询用户失败: %v", err) return nil, errors.New("登录失败") } if !user.CheckPassword(req.Password) { return nil, errors.New("登录凭证不正确") } // 登录成功,生成 JWT token tokenString, err := s.tokenGenerator.GenerateToken(user.ID) if err != nil { logger.Errorf("登录: 生成令牌失败: %v", err) return nil, errors.New("登录失败,无法生成认证信息") } return &dto.LoginResponse{ Username: user.Username, ID: user.ID, Token: tokenString, }, nil } // SendTestNotification 发送测试通知 func (s *userService) SendTestNotification(ctx context.Context, userID uint, req *dto.SendTestNotificationRequest) error { serviceCtx, logger := logs.Trace(ctx, s.ctx, "SendTestNotification") err := s.notifyService.SendTestMessage(serviceCtx, userID, req.Type) if err != nil { logger.Errorf("发送测试通知: 服务层调用失败: %v", err) return errors.New("发送测试消息失败: " + err.Error()) } logger.Infof("发送测试通知: 成功为用户 %d 发送类型为 %s 的测试消息", userID, req.Type) return nil }