236 lines
5.9 KiB
Go
236 lines
5.9 KiB
Go
package service
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"yinli-api/internal/model"
|
|
"yinli-api/internal/repository"
|
|
"yinli-api/pkg/auth"
|
|
|
|
"github.com/jinzhu/gorm"
|
|
)
|
|
|
|
// UserService 用户服务接口
|
|
type UserService interface {
|
|
Register(req *model.UserRegisterRequest) (*model.LoginResponse, error)
|
|
Login(req *model.UserLoginRequest) (*model.LoginResponse, error)
|
|
GetProfile(userID uint) (*model.UserResponse, error)
|
|
UpdateProfile(userID uint, updates map[string]interface{}) (*model.UserResponse, error)
|
|
ChangePassword(userID uint, oldPassword, newPassword string) error
|
|
GetUserList(offset, limit int) ([]*model.UserResponse, int64, error)
|
|
DeleteUser(userID uint) error
|
|
UpdateUserStatus(userID uint, status int) error
|
|
}
|
|
|
|
// userService 用户服务实现
|
|
type userService struct {
|
|
userRepo repository.UserRepository
|
|
}
|
|
|
|
// NewUserService 创建用户服务实例
|
|
func NewUserService(userRepo repository.UserRepository) UserService {
|
|
return &userService{
|
|
userRepo: userRepo,
|
|
}
|
|
}
|
|
|
|
// Register 用户注册
|
|
func (s *userService) Register(req *model.UserRegisterRequest) (*model.LoginResponse, error) {
|
|
// 检查用户名是否已存在
|
|
exists, err := s.userRepo.ExistsByName(req.Name)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("检查用户名失败: %w", err)
|
|
}
|
|
if exists {
|
|
return nil, errors.New("用户名已存在")
|
|
}
|
|
|
|
// 创建用户
|
|
user := &model.User{
|
|
Name: req.Name,
|
|
Password: req.Password, // 密码会在BeforeCreate钩子中加密
|
|
Status: 1,
|
|
}
|
|
|
|
if err := s.userRepo.Create(user); err != nil {
|
|
return nil, fmt.Errorf("创建用户失败: %w", err)
|
|
}
|
|
|
|
// 生成JWT令牌
|
|
token, err := auth.GenerateToken(user.ID, user.Name)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("生成令牌失败: %w", err)
|
|
}
|
|
|
|
return &model.LoginResponse{
|
|
User: user.ToResponse(),
|
|
Token: token,
|
|
}, nil
|
|
}
|
|
|
|
// Login 用户登录
|
|
func (s *userService) Login(req *model.UserLoginRequest) (*model.LoginResponse, error) {
|
|
// 根据用户名查找用户
|
|
user, err := s.userRepo.GetByName(req.Name)
|
|
if err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return nil, errors.New("用户名或密码错误")
|
|
}
|
|
return nil, fmt.Errorf("查找用户失败: %w", err)
|
|
}
|
|
|
|
// 检查用户状态
|
|
if !user.IsActive() {
|
|
return nil, errors.New("用户账号已被禁用")
|
|
}
|
|
|
|
// 验证密码
|
|
if !user.CheckPassword(req.Password) {
|
|
return nil, errors.New("用户名或密码错误")
|
|
}
|
|
|
|
// 生成JWT令牌
|
|
token, err := auth.GenerateToken(user.ID, user.Name)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("生成令牌失败: %w", err)
|
|
}
|
|
|
|
return &model.LoginResponse{
|
|
User: user.ToResponse(),
|
|
Token: token,
|
|
}, nil
|
|
}
|
|
|
|
// GetProfile 获取用户资料
|
|
func (s *userService) GetProfile(userID uint) (*model.UserResponse, error) {
|
|
user, err := s.userRepo.GetByID(userID)
|
|
if err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return nil, errors.New("用户不存在")
|
|
}
|
|
return nil, fmt.Errorf("获取用户信息失败: %w", err)
|
|
}
|
|
|
|
return user.ToResponse(), nil
|
|
}
|
|
|
|
// UpdateProfile 更新用户资料
|
|
func (s *userService) UpdateProfile(userID uint, updates map[string]interface{}) (*model.UserResponse, error) {
|
|
user, err := s.userRepo.GetByID(userID)
|
|
if err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return nil, errors.New("用户不存在")
|
|
}
|
|
return nil, fmt.Errorf("获取用户信息失败: %w", err)
|
|
}
|
|
|
|
// 检查用户名是否重复
|
|
if newName, exists := updates["name"]; exists {
|
|
if newName != user.Name {
|
|
exists, err := s.userRepo.ExistsByName(newName.(string))
|
|
if err != nil {
|
|
return nil, fmt.Errorf("检查用户名失败: %w", err)
|
|
}
|
|
if exists {
|
|
return nil, errors.New("用户名已存在")
|
|
}
|
|
}
|
|
}
|
|
|
|
// 更新用户信息
|
|
for key, value := range updates {
|
|
switch key {
|
|
case "name":
|
|
user.Name = value.(string)
|
|
case "status":
|
|
user.Status = value.(int)
|
|
}
|
|
}
|
|
|
|
if err := s.userRepo.Update(user); err != nil {
|
|
return nil, fmt.Errorf("更新用户信息失败: %w", err)
|
|
}
|
|
|
|
return user.ToResponse(), nil
|
|
}
|
|
|
|
// ChangePassword 修改密码
|
|
func (s *userService) ChangePassword(userID uint, oldPassword, newPassword string) error {
|
|
user, err := s.userRepo.GetByID(userID)
|
|
if err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return errors.New("用户不存在")
|
|
}
|
|
return fmt.Errorf("获取用户信息失败: %w", err)
|
|
}
|
|
|
|
// 验证旧密码
|
|
if !user.CheckPassword(oldPassword) {
|
|
return errors.New("原密码错误")
|
|
}
|
|
|
|
// 设置新密码
|
|
if err := user.SetPassword(newPassword); err != nil {
|
|
return fmt.Errorf("设置新密码失败: %w", err)
|
|
}
|
|
|
|
// 更新用户
|
|
if err := s.userRepo.Update(user); err != nil {
|
|
return fmt.Errorf("更新密码失败: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetUserList 获取用户列表
|
|
func (s *userService) GetUserList(offset, limit int) ([]*model.UserResponse, int64, error) {
|
|
users, total, err := s.userRepo.List(offset, limit)
|
|
if err != nil {
|
|
return nil, 0, fmt.Errorf("获取用户列表失败: %w", err)
|
|
}
|
|
|
|
responses := make([]*model.UserResponse, len(users))
|
|
for i, user := range users {
|
|
responses[i] = user.ToResponse()
|
|
}
|
|
|
|
return responses, total, nil
|
|
}
|
|
|
|
// DeleteUser 删除用户
|
|
func (s *userService) DeleteUser(userID uint) error {
|
|
// 检查用户是否存在
|
|
_, err := s.userRepo.GetByID(userID)
|
|
if err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return errors.New("用户不存在")
|
|
}
|
|
return fmt.Errorf("获取用户信息失败: %w", err)
|
|
}
|
|
|
|
if err := s.userRepo.Delete(userID); err != nil {
|
|
return fmt.Errorf("删除用户失败: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// UpdateUserStatus 更新用户状态
|
|
func (s *userService) UpdateUserStatus(userID uint, status int) error {
|
|
// 检查用户是否存在
|
|
_, err := s.userRepo.GetByID(userID)
|
|
if err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return errors.New("用户不存在")
|
|
}
|
|
return fmt.Errorf("获取用户信息失败: %w", err)
|
|
}
|
|
|
|
if err := s.userRepo.UpdateStatus(userID, status); err != nil {
|
|
return fmt.Errorf("更新用户状态失败: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|