package service import ( "errors" "health-ai/internal/model" "health-ai/internal/repository/impl" "health-ai/pkg/jwt" "golang.org/x/crypto/bcrypt" ) type AuthService struct { userRepo *impl.UserRepositoryImpl } func NewAuthService() *AuthService { return &AuthService{ userRepo: impl.NewUserRepository(), } } // RegisterRequest 注册请求 type RegisterRequest struct { Phone string `json:"phone" binding:"required"` Password string `json:"password" binding:"required,min=6"` Nickname string `json:"nickname"` } // LoginRequest 登录请求 type LoginRequest struct { Phone string `json:"phone" binding:"required"` Password string `json:"password" binding:"required"` } // AuthResponse 认证响应 type AuthResponse struct { Token string `json:"token"` UserID uint `json:"user_id"` Nickname string `json:"nickname"` Avatar string `json:"avatar"` SurveyCompleted bool `json:"survey_completed"` } // UserInfoResponse 用户信息响应 type UserInfoResponse struct { UserID uint `json:"user_id"` Phone string `json:"phone"` Email string `json:"email"` Nickname string `json:"nickname"` Avatar string `json:"avatar"` SurveyCompleted bool `json:"survey_completed"` } // Register 用户注册 func (s *AuthService) Register(req *RegisterRequest) (*AuthResponse, error) { // 检查手机号是否已注册 existing, _ := s.userRepo.GetByPhone(req.Phone) if existing.ID > 0 { return nil, errors.New("手机号已注册") } // 加密密码 hash, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost) if err != nil { return nil, errors.New("密码加密失败") } // 创建用户 user := &model.User{ Phone: req.Phone, PasswordHash: string(hash), Nickname: req.Nickname, } if user.Nickname == "" { // 默认昵称:手机号后4位 user.Nickname = "用户" + req.Phone[len(req.Phone)-4:] } if err := s.userRepo.Create(user); err != nil { return nil, errors.New("创建用户失败") } // 生成 Token token, err := jwt.GenerateToken(user.ID) if err != nil { return nil, errors.New("生成Token失败") } return &AuthResponse{ Token: token, UserID: user.ID, Nickname: user.Nickname, Avatar: user.Avatar, SurveyCompleted: user.SurveyCompleted, }, nil } // Login 用户登录 func (s *AuthService) Login(req *LoginRequest) (*AuthResponse, error) { user, err := s.userRepo.GetByPhone(req.Phone) if err != nil { return nil, errors.New("用户不存在") } if err := bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(req.Password)); err != nil { return nil, errors.New("密码错误") } token, err := jwt.GenerateToken(user.ID) if err != nil { return nil, errors.New("生成Token失败") } return &AuthResponse{ Token: token, UserID: user.ID, Nickname: user.Nickname, Avatar: user.Avatar, SurveyCompleted: user.SurveyCompleted, }, nil } // GetUserInfo 获取用户信息 func (s *AuthService) GetUserInfo(userID uint) (*UserInfoResponse, error) { user, err := s.userRepo.GetByID(userID) if err != nil { return nil, errors.New("用户不存在") } return &UserInfoResponse{ UserID: user.ID, Phone: user.Phone, Email: user.Email, Nickname: user.Nickname, Avatar: user.Avatar, SurveyCompleted: user.SurveyCompleted, }, nil } // RefreshToken 刷新Token func (s *AuthService) RefreshToken(oldToken string) (string, error) { return jwt.RefreshToken(oldToken) } // UpdateProfile 更新用户资料 func (s *AuthService) UpdateProfile(userID uint, nickname, avatar string) error { user, err := s.userRepo.GetByID(userID) if err != nil { return errors.New("用户不存在") } if nickname != "" { user.Nickname = nickname } if avatar != "" { user.Avatar = avatar } return s.userRepo.Update(user) }