package services import ( "context" "errors" "fmt" "goalfymax-admin/internal/models" "goalfymax-admin/internal/storage" "goalfymax-admin/pkg/utils" "go.uber.org/zap" ) // UserService 用户服务接口 type UserService interface { Login(req *models.LoginRequest) (*models.LoginResponse, error) Create(req *models.UserCreateRequest) (*models.User, error) GetByID(id uint) (*models.User, error) Update(id uint, req *models.UserUpdateRequest) (*models.User, error) Delete(id uint) error List(req *models.UserListRequest) ([]models.User, int64, error) ListWithRoles(req *models.UserListRequest) ([]models.UserWithRoles, int64, error) UpdateStatus(id uint, status int) error UpdateRole(id uint, roleID uint) error CheckUserSystemRole(userID int) (bool, error) ChangeUserSystemRole(userID int, systemRole string) error } type userService struct { userStorage storage.UserStorage rbacStorage storage.RBACStorage goalfyMaxUserStorage storage.GoalfyMaxUserStorage jwtManager *utils.JWTManager logger *utils.Logger ssoAdminService SSOAdminService } // NewUserService 创建用户服务实例 func NewUserService(userStorage storage.UserStorage, rbacStorage storage.RBACStorage, goalfyMaxUserStorage storage.GoalfyMaxUserStorage, jwtManager *utils.JWTManager, logger *utils.Logger, ssoAdminService SSOAdminService) UserService { return &userService{ userStorage: userStorage, rbacStorage: rbacStorage, goalfyMaxUserStorage: goalfyMaxUserStorage, jwtManager: jwtManager, logger: logger, ssoAdminService: ssoAdminService, } } // Login 用户登录 func (s *userService) Login(req *models.LoginRequest) (*models.LoginResponse, error) { // 获取用户信息 user, err := s.userStorage.GetByUsername(req.Username) if err != nil { s.logger.Error("用户不存在", zap.String("username", req.Username)) return nil, errors.New("用户名或密码错误") } // 检查用户状态 if user.Status != 1 { s.logger.Error("用户已被禁用", zap.String("username", req.Username)) return nil, errors.New("用户已被禁用") } // SSO用户不需要密码验证,直接通过 // 生成JWT token token, err := s.jwtManager.GenerateToken(user.ID, user.Username) if err != nil { s.logger.Error("生成token失败", zap.Error(err)) return nil, errors.New("登录失败") } // 记录登录日志 // 这里应该调用日志存储服务记录登录日志 s.logger.Info("用户登录成功", zap.String("username", user.Username)) return &models.LoginResponse{ Token: token, User: *user, ExpireAt: 0, // 实际应该计算过期时间 }, nil } // Create 创建用户 func (s *userService) Create(req *models.UserCreateRequest) (*models.User, error) { // 验证用户名是否已存在 _, err := s.userStorage.GetByUsername(req.Username) if err == nil { return nil, errors.New("用户名已存在") } // 验证邮箱是否已存在 _, err = s.userStorage.GetByEmail(req.Email) if err == nil { return nil, errors.New("邮箱已存在") } // 1. 先调用SSO创建用户 ctx := context.Background() ssoReq := &SSOAdminUserCreateRequest{ Username: req.Username, Email: req.Email, Phone: "", // 默认空手机号 Password: req.Password, } ssoUser, err := s.ssoAdminService.CreateUser(ctx, ssoReq) if err != nil { return nil, fmt.Errorf("SSO创建用户失败: %w", err) } // 2. 设置系统角色为sys_admin if err := s.ssoAdminService.SetSystemRole(ctx, ssoUser.ID, "sys_admin"); err != nil { // 如果设置失败,记录错误但不阻止用户创建 fmt.Printf("警告: 设置系统角色失败: %v\n", err) } // 设置角色ID,如果没有指定则使用默认角色 roleID := req.RoleID if roleID == 0 { defaultRoleID, err := s.getDefaultRole() if err != nil { s.logger.Error("获取默认角色失败", zap.Error(err)) return nil, errors.New("获取默认角色失败") } roleID = defaultRoleID } // 创建用户 user := &models.User{ Username: req.Username, Email: req.Email, Nickname: req.Nickname, Status: 1, SSOProvider: req.SSOProvider, RoleID: roleID, } err = s.userStorage.Create(user) if err != nil { s.logger.Error("创建用户失败", zap.Error(err)) return nil, errors.New("创建用户失败") } s.logger.Info("用户创建成功", zap.String("username", user.Username), zap.Uint("role_id", roleID)) return user, nil } // GetByID 根据ID获取用户 func (s *userService) GetByID(id uint) (*models.User, error) { return s.userStorage.GetByID(id) } // Update 更新用户 func (s *userService) Update(id uint, req *models.UserUpdateRequest) (*models.User, error) { // 获取用户信息 user, err := s.userStorage.GetByID(id) if err != nil { return nil, errors.New("用户不存在") } // 更新用户信息 if req.Nickname != "" { user.Nickname = req.Nickname } if req.Email != "" { // 检查邮箱是否已被其他用户使用 existingUser, err := s.userStorage.GetByEmail(req.Email) if err == nil && existingUser.ID != id { return nil, errors.New("邮箱已被其他用户使用") } user.Email = req.Email } if req.Avatar != "" { user.Avatar = req.Avatar } if req.Status != nil { user.Status = *req.Status } if req.RoleID != nil { user.RoleID = *req.RoleID } if req.SSOProvider != "" { user.SSOProvider = req.SSOProvider } err = s.userStorage.Update(user) if err != nil { s.logger.Error("更新用户失败", zap.Error(err)) return nil, errors.New("更新用户失败") } s.logger.Info("用户更新成功", zap.Uint("user_id", id)) return user, nil } // Delete 删除用户 func (s *userService) Delete(id uint) error { // 检查用户是否存在 _, err := s.userStorage.GetByID(id) if err != nil { return errors.New("用户不存在") } err = s.userStorage.Delete(id) if err != nil { s.logger.Error("删除用户失败", zap.Error(err)) return errors.New("删除用户失败") } s.logger.Info("用户删除成功", zap.Uint("user_id", id)) return nil } // List 获取用户列表 func (s *userService) List(req *models.UserListRequest) ([]models.User, int64, error) { return s.userStorage.List(req) } // UpdateStatus 更新用户状态 func (s *userService) UpdateStatus(id uint, status int) error { // 检查用户是否存在 _, err := s.userStorage.GetByID(id) if err != nil { return errors.New("用户不存在") } err = s.userStorage.UpdateStatus(id, status) if err != nil { s.logger.Error("更新用户状态失败", zap.Error(err)) return errors.New("更新用户状态失败") } s.logger.Info("用户状态更新成功", zap.Uint("user_id", id), zap.Int("status", status)) return nil } // ListWithRoles 获取用户列表(包含角色信息) func (s *userService) ListWithRoles(req *models.UserListRequest) ([]models.UserWithRoles, int64, error) { // 获取用户列表 users, total, err := s.userStorage.List(req) if err != nil { return nil, 0, err } // 为每个用户查询角色信息 usersWithRoles := make([]models.UserWithRoles, len(users)) for i, user := range users { if user.RoleID == 0 { // role_id 为 0 表示未分配角色,直接返回空角色 s.logger.Debug("用户未分配角色", zap.Uint("userID", user.ID)) usersWithRoles[i] = models.UserWithRoles{User: user, Role: nil} continue } // 查询用户角色 role, err := s.rbacStorage.GetRoleByID(user.RoleID) if err != nil { s.logger.Warn("获取用户角色失败", zap.Uint("userID", user.ID), zap.Uint("roleID", user.RoleID), zap.Error(err)) // 如果获取角色失败,仍然返回用户信息,但角色为空 usersWithRoles[i] = models.UserWithRoles{ User: user, Role: nil, } } else { usersWithRoles[i] = models.UserWithRoles{ User: user, Role: role, } } } return usersWithRoles, total, nil } // getDefaultRole 获取默认角色(L5全员) func (s *userService) getDefaultRole() (uint, error) { // 查询默认角色ID var roleID uint err := s.rbacStorage.GetDefaultRoleID(&roleID) if err != nil { s.logger.Error("获取默认角色失败", zap.Error(err)) return 0, errors.New("获取默认角色失败") } return roleID, nil } // UpdateRole 更新用户角色 func (s *userService) UpdateRole(id uint, roleID uint) error { // 检查用户是否存在 user, err := s.userStorage.GetByID(id) if err != nil { s.logger.Error("获取用户信息失败", zap.Uint("user_id", id), zap.Error(err)) return errors.New("用户不存在") } // 更新用户角色 user.RoleID = roleID err = s.userStorage.Update(user) if err != nil { s.logger.Error("更新用户角色失败", zap.Uint("user_id", id), zap.Uint("role_id", roleID), zap.Error(err)) return errors.New("更新用户角色失败") } s.logger.Info("用户角色更新成功", zap.Uint("user_id", id), zap.Uint("role_id", roleID)) return nil } // CheckUserSystemRole 检查用户在系统用户管理表中的角色 // 返回: true表示存在(sys_admin),false表示不存在(custom) func (s *userService) CheckUserSystemRole(userID int) (bool, error) { // admin_users表的id字段就是SSO用户ID // 所以通过userID查询admin_users表,如果存在则说明是系统管理员 _, err := s.userStorage.GetByID(uint(userID)) if err != nil { // 如果查询失败(用户不存在),返回false return false, nil } // 用户存在,返回true return true, nil } // ChangeUserSystemRole 变更用户在SSO中的系统角色 // 同时需要在admin_users表中添加或删除记录 func (s *userService) ChangeUserSystemRole(userID int, systemRole string) error { ctx := context.Background() // 1. 先调用SSO接口变更角色 err := s.ssoAdminService.SetSystemRole(ctx, userID, systemRole) if err != nil { s.logger.Error("调用SSO接口变更角色失败", zap.Int("user_id", userID), zap.String("system_role", systemRole), zap.Error(err)) return fmt.Errorf("调用SSO接口变更角色失败: %w", err) } // 2. 根据角色变更,更新admin_users表 if systemRole == "sys_admin" { // 设置为系统管理员:需要确保admin_users表中存在该用户 _, err := s.userStorage.GetByID(uint(userID)) if err != nil { // 用户不存在,需要创建 // 从GoalfyMax用户表获取用户信息 goalfyUser, err := s.goalfyMaxUserStorage.GetByUserID(userID) if err != nil { s.logger.Error("获取GoalfyMax用户信息失败", zap.Int("user_id", userID), zap.Error(err)) return fmt.Errorf("获取GoalfyMax用户信息失败: %w", err) } // 获取默认角色ID(系统管理员角色) defaultRoleID, err := s.getDefaultRole() if err != nil { s.logger.Error("获取默认角色失败", zap.Error(err)) // 如果获取默认角色失败,使用角色ID 5(系统管理员) defaultRoleID = 5 } // 创建admin_users记录 // 注意:admin_users表的id字段对应SSO用户ID user := &models.User{ BaseModel: models.BaseModel{ ID: uint(userID), // 使用SSO用户ID作为主键 }, Username: goalfyUser.Username, Email: goalfyUser.Email, Nickname: goalfyUser.Nickname, Status: 1, SSOProvider: "default", RoleID: defaultRoleID, } // 使用storage的Create方法,它应该能处理指定ID的情况 err = s.userStorage.Create(user) if err != nil { s.logger.Error("创建admin_users记录失败", zap.Int("user_id", userID), zap.Error(err)) return fmt.Errorf("创建admin_users记录失败: %w", err) } s.logger.Info("创建系统管理员用户成功", zap.Int("user_id", userID)) } else { // 用户已存在,更新状态为正常(如果需要) s.logger.Info("用户已是系统管理员", zap.Int("user_id", userID)) } } else if systemRole == "custom" { // 设置为普通用户:需要删除admin_users表中的记录(软删除) _, err := s.userStorage.GetByID(uint(userID)) if err == nil { // 用户存在,删除记录 err = s.userStorage.Delete(uint(userID)) if err != nil { s.logger.Error("删除admin_users记录失败", zap.Int("user_id", userID), zap.Error(err)) return fmt.Errorf("删除admin_users记录失败: %w", err) } s.logger.Info("删除系统管理员用户成功", zap.Int("user_id", userID)) } else { s.logger.Info("用户不是系统管理员,无需删除", zap.Int("user_id", userID)) } } else { return fmt.Errorf("无效的系统角色: %s", systemRole) } s.logger.Info("用户系统角色变更成功", zap.Int("user_id", userID), zap.String("system_role", systemRole)) return nil }