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