healthapp
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

161 lines
3.9 KiB

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)
}