初始化
This commit is contained in:
363
server/service/admin_service.go
Normal file
363
server/service/admin_service.go
Normal file
@@ -0,0 +1,363 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
Reference in New Issue
Block a user