371 lines
8.9 KiB
Go
371 lines
8.9 KiB
Go
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)
|
|
}
|