feat():learning后台管理项目初始化

This commit is contained in:
yuj
2025-12-04 16:23:46 +08:00
parent 39886d50d2
commit 88e048f4d1
154 changed files with 28966 additions and 6 deletions

View File

@@ -0,0 +1,404 @@
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_adminfalse表示不存在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
}