package service import ( "errors" "fmt" "seeyon-filesystem/config" "seeyon-filesystem/dto" "seeyon-filesystem/model" "seeyon-filesystem/repository" "seeyon-filesystem/utils" ) // AdminService 管理后台服务 // 包含用户管理、存储策略管理、组织架构管理 type AdminService struct { userRepo *repository.UserRepository roleRepo *repository.RoleRepository userRoleRepo *repository.UserRoleRepository deptRepo *repository.DepartmentRepository policyRepo *repository.StoragePolicyRepository } func NewAdminService() *AdminService { return &AdminService{ userRepo: repository.NewUserRepository(), roleRepo: repository.NewRoleRepository(), userRoleRepo: repository.NewUserRoleRepository(), deptRepo: repository.NewDepartmentRepository(), policyRepo: repository.NewStoragePolicyRepository(), } } // ========== 用户管理 ========== // DefaultPassword 新用户默认密码 const DefaultPassword = "123456" // CreateUser 创建用户 func (s *AdminService) CreateUser(req *dto.UserCreateRequest) error { existing, _ := s.userRepo.FindByUsername(req.Username) if existing != nil { return errors.New("用户名已存在") } // 使用指定密码, 或默认密码 password := req.Password if password == "" { password = DefaultPassword } hashed, err := utils.HashPassword(password) if err != nil { return errors.New("密码加密失败") } user := &model.User{ Username: req.Username, Password: hashed, Email: req.Email, Nickname: req.Nickname, Role: "user", Status: 1, StorageQuota: req.StorageQuota, MustChangePwd: 1, // 新用户首次登录必须改密码 } if user.StorageQuota == 0 { user.StorageQuota = 10737418240 } if user.Nickname == "" { user.Nickname = req.Username } if err := s.userRepo.Create(user); err != nil { return fmt.Errorf("创建用户失败: %w", err) } // 分配角色 if len(req.RoleIDs) > 0 { s.userRoleRepo.SetUserRoles(user.ID, req.RoleIDs) } else { // 未指定角色时, 自动分配默认角色(user) var defaultRole model.Role if config.DB.Where("name = ?", "user").First(&defaultRole).Error == nil { config.DB.Create(&model.UserRole{UserID: user.ID, RoleID: defaultRole.ID}) } } return nil } // ListUsers 分页查询用户列表 func (s *AdminService) ListUsers(page, size int) ([]dto.UserVO, int64, error) { users, total, err := s.userRepo.List(page, size) if err != nil { return nil, 0, err } vos := make([]dto.UserVO, 0, len(users)) for _, u := range users { vo := dto.UserVO{ ID: u.ID, Username: u.Username, Email: u.Email, Nickname: u.Nickname, Avatar: u.Avatar, Status: u.Status, StorageQuota: u.StorageQuota, UsedStorage: u.UsedStorage, CreatedAt: u.CreatedAt.Format("2006-01-02 15:04:05"), } // 获取用户角色 roles, _ := s.userRoleRepo.GetUserRoles(u.ID) for _, r := range roles { vo.Roles = append(vo.Roles, dto.RoleVO{ID: r.ID, Name: r.Name, DisplayName: r.DisplayName}) } vos = append(vos, vo) } return vos, total, nil } // UpdateUser 更新用户 func (s *AdminService) UpdateUser(userID uint64, req *dto.UserUpdateRequest) error { user, err := s.userRepo.FindByID(userID) if err != nil { return errors.New("用户不存在") } if req.Email != "" { user.Email = req.Email } if req.Nickname != "" { user.Nickname = req.Nickname } if req.Status != nil { user.Status = *req.Status } if req.StorageQuota != nil { user.StorageQuota = *req.StorageQuota } if err := s.userRepo.Update(user); err != nil { return fmt.Errorf("更新用户失败: %w", err) } // 更新角色 if req.RoleIDs != nil { s.userRoleRepo.SetUserRoles(userID, req.RoleIDs) } return nil } // DeleteUser 删除用户 func (s *AdminService) DeleteUser(userID uint64) error { user, err := s.userRepo.FindByID(userID) if err != nil { return errors.New("用户不存在") } if user.Username == "admin" { return errors.New("不能删除管理员账号") } return s.userRepo.Delete(userID) } // ResetPassword 重置用户密码 func (s *AdminService) ResetPassword(userID uint64, newPassword string) error { user, err := s.userRepo.FindByID(userID) if err != nil { return errors.New("用户不存在") } hashed, err := utils.HashPassword(newPassword) if err != nil { return errors.New("密码加密失败") } user.Password = hashed return s.userRepo.Update(user) } // ========== 存储策略管理 ========== // CreateStoragePolicy 创建存储策略 func (s *AdminService) CreateStoragePolicy(req *dto.StoragePolicyCreateRequest) error { policy := &model.StoragePolicy{ Name: req.Name, Type: req.Type, Status: 1, Config: model.PolicyConfig{ BasePath: req.Config.BasePath, Endpoint: req.Config.Endpoint, Bucket: req.Config.Bucket, AccessKey: req.Config.AccessKey, SecretKey: req.Config.SecretKey, Region: req.Config.Region, UseSSL: req.Config.UseSSL, }, } return s.policyRepo.Create(policy) } // ListStoragePolicies 查询所有存储策略 func (s *AdminService) ListStoragePolicies() ([]dto.StoragePolicyVO, error) { policies, err := s.policyRepo.List() if err != nil { return nil, err } vos := make([]dto.StoragePolicyVO, 0, len(policies)) for _, p := range policies { vos = append(vos, dto.StoragePolicyVO{ ID: p.ID, Name: p.Name, Type: p.Type, Status: p.Status, Config: dto.PolicyConfigDTO{ BasePath: p.Config.BasePath, Endpoint: p.Config.Endpoint, Bucket: p.Config.Bucket, AccessKey: p.Config.AccessKey, SecretKey: "***", // 不返回密钥 Region: p.Config.Region, UseSSL: p.Config.UseSSL, }, CreatedAt: p.CreatedAt.Format("2006-01-02 15:04:05"), }) } return vos, nil } // UpdateStoragePolicy 更新存储策略 func (s *AdminService) UpdateStoragePolicy(id uint64, req *dto.StoragePolicyUpdateRequest) error { policy, err := s.policyRepo.FindByID(id) if err != nil { return errors.New("存储策略不存在") } if req.Name != "" { policy.Name = req.Name } if req.Status != nil { policy.Status = *req.Status } if req.Config != nil { policy.Config = model.PolicyConfig{ BasePath: req.Config.BasePath, Endpoint: req.Config.Endpoint, Bucket: req.Config.Bucket, AccessKey: req.Config.AccessKey, SecretKey: req.Config.SecretKey, Region: req.Config.Region, UseSSL: req.Config.UseSSL, } } return s.policyRepo.Update(policy) } // DeleteStoragePolicy 删除存储策略 func (s *AdminService) DeleteStoragePolicy(id uint64) error { return s.policyRepo.Delete(id) } // ========== 组织架构管理 ========== // CreateDepartment 创建部门 func (s *AdminService) CreateDepartment(req *dto.DeptCreateRequest) error { parentPath := "/" if req.ParentID > 0 { parent, err := s.deptRepo.FindByID(req.ParentID) if err != nil { return errors.New("上级部门不存在") } parentPath = parent.Path } dept := &model.Department{ Name: req.Name, Code: req.Code, ParentID: req.ParentID, LeaderID: req.LeaderID, SortOrder: req.SortOrder, Path: parentPath, Status: 1, } if err := s.deptRepo.Create(dept); err != nil { return fmt.Errorf("创建部门失败: %w", err) } // 更新物化路径 dept.Path = fmt.Sprintf("%s%d/", parentPath, dept.ID) return s.deptRepo.Update(dept) } // ListDepartments 查询所有部门(树形) func (s *AdminService) ListDepartments() ([]dto.DeptVO, error) { depts, err := s.deptRepo.List() if err != nil { return nil, err } // 构建树形结构 deptMap := make(map[uint64]*dto.DeptVO) var roots []dto.DeptVO for _, d := range depts { vo := dto.DeptVO{ ID: d.ID, Name: d.Name, Code: d.Code, ParentID: d.ParentID, Path: d.Path, LeaderID: d.LeaderID, SortOrder: d.SortOrder, Status: d.Status, } deptMap[d.ID] = &vo } for _, d := range depts { vo := deptMap[d.ID] if d.ParentID == 0 { roots = append(roots, *vo) } else if parent, ok := deptMap[d.ParentID]; ok { parent.Children = append(parent.Children, *vo) } } return roots, nil } // UpdateDepartment 更新部门 func (s *AdminService) UpdateDepartment(id uint64, req *dto.DeptUpdateRequest) error { dept, err := s.deptRepo.FindByID(id) if err != nil { return errors.New("部门不存在") } if req.Name != "" { dept.Name = req.Name } if req.Code != "" { dept.Code = req.Code } dept.LeaderID = req.LeaderID dept.SortOrder = req.SortOrder if req.Status != nil { dept.Status = *req.Status } return s.deptRepo.Update(dept) } // DeleteDepartment 删除部门 func (s *AdminService) DeleteDepartment(id uint64) error { hasChildren, _ := s.deptRepo.HasChildren(id) if hasChildren { return errors.New("该部门下有子部门, 请先删除子部门") } userCount, _ := s.deptRepo.CountUsers(id) if userCount > 0 { return errors.New("该部门下有用户, 请先移除用户") } return s.deptRepo.Delete(id) }