mi-assessment/server/MiAssessment/src/MiAssessment.Admin/Services/DepartmentService.cs
2026-02-03 14:25:01 +08:00

317 lines
11 KiB
C#

using MiAssessment.Admin.Data;
using MiAssessment.Admin.Entities;
using MiAssessment.Admin.Models.AdminUser;
using MiAssessment.Admin.Models.Common;
using MiAssessment.Admin.Models.Department;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
namespace MiAssessment.Admin.Services;
/// <summary>
/// 部门服务实现
/// </summary>
public class DepartmentService : IDepartmentService
{
private readonly AdminDbContext _dbContext;
private readonly ILogger<DepartmentService> _logger;
public DepartmentService(AdminDbContext dbContext, ILogger<DepartmentService> logger)
{
_dbContext = dbContext;
_logger = logger;
}
/// <inheritdoc />
public async Task<List<DepartmentTreeDto>> GetDepartmentTreeAsync()
{
var departments = await _dbContext.Departments
.Include(d => d.AdminUsers)
.OrderBy(d => d.SortOrder)
.ThenBy(d => d.Id)
.ToListAsync();
return BuildDepartmentTree(departments, 0);
}
/// <inheritdoc />
public async Task<DepartmentDto> GetByIdAsync(long id)
{
var department = await _dbContext.Departments
.Include(d => d.DepartmentMenus)
.FirstOrDefaultAsync(d => d.Id == id);
if (department == null)
{
throw new AdminException(AdminErrorCodes.InvalidParameter, "部门不存在");
}
return new DepartmentDto
{
Id = department.Id,
ParentId = department.ParentId,
Name = department.Name,
Code = department.Code,
Description = department.Description,
SortOrder = department.SortOrder,
Status = department.Status,
CreatedAt = department.CreatedAt,
UpdatedAt = department.UpdatedAt,
MenuIds = department.DepartmentMenus.Select(dm => dm.MenuId).ToList()
};
}
/// <inheritdoc />
public async Task<long> CreateAsync(CreateDepartmentRequest request)
{
// 验证父部门是否存在
if (request.ParentId > 0)
{
var parentExists = await _dbContext.Departments.AnyAsync(d => d.Id == request.ParentId);
if (!parentExists)
{
throw new AdminException(AdminErrorCodes.InvalidParameter, "父部门不存在");
}
}
// 检查编码是否重复
if (!string.IsNullOrWhiteSpace(request.Code))
{
var codeExists = await _dbContext.Departments.AnyAsync(d => d.Code == request.Code);
if (codeExists)
{
throw new AdminException(AdminErrorCodes.DuplicateDepartmentCode, "部门编码已存在");
}
}
var department = new Entities.Department
{
ParentId = request.ParentId,
Name = request.Name,
Code = request.Code,
Description = request.Description,
SortOrder = request.SortOrder,
Status = request.Status,
CreatedAt = DateTime.Now
};
_dbContext.Departments.Add(department);
await _dbContext.SaveChangesAsync();
_logger.LogInformation("创建部门成功: {DepartmentId} - {DepartmentName}", department.Id, department.Name);
return department.Id;
}
/// <inheritdoc />
public async Task UpdateAsync(long id, UpdateDepartmentRequest request)
{
var department = await _dbContext.Departments.FindAsync(id);
if (department == null)
{
throw new AdminException(AdminErrorCodes.InvalidParameter, "部门不存在");
}
// 验证父部门是否存在
if (request.ParentId > 0)
{
// 不能将自己设为父部门
if (request.ParentId == id)
{
throw new AdminException(AdminErrorCodes.DepartmentCircularReference, "不能将部门设为自己的子部门");
}
var parentExists = await _dbContext.Departments.AnyAsync(d => d.Id == request.ParentId);
if (!parentExists)
{
throw new AdminException(AdminErrorCodes.InvalidParameter, "父部门不存在");
}
// 检查是否会形成循环引用(不能将部门设为其子孙部门的子部门)
if (await IsDescendantAsync(request.ParentId, id))
{
throw new AdminException(AdminErrorCodes.DepartmentCircularReference, "不能将部门设为其子部门的子部门");
}
}
// 检查编码是否重复(排除自己)
if (!string.IsNullOrWhiteSpace(request.Code))
{
var codeExists = await _dbContext.Departments.AnyAsync(d => d.Code == request.Code && d.Id != id);
if (codeExists)
{
throw new AdminException(AdminErrorCodes.DuplicateDepartmentCode, "部门编码已存在");
}
}
department.ParentId = request.ParentId;
department.Name = request.Name;
department.Code = request.Code;
department.Description = request.Description;
department.SortOrder = request.SortOrder;
department.Status = request.Status;
department.UpdatedAt = DateTime.Now;
await _dbContext.SaveChangesAsync();
_logger.LogInformation("更新部门成功: {DepartmentId} - {DepartmentName}", department.Id, department.Name);
}
/// <inheritdoc />
public async Task DeleteAsync(long id)
{
var department = await _dbContext.Departments.FindAsync(id);
if (department == null)
{
throw new AdminException(AdminErrorCodes.InvalidParameter, "部门不存在");
}
// 检查是否有子部门
var hasChildren = await _dbContext.Departments.AnyAsync(d => d.ParentId == id);
if (hasChildren)
{
throw new AdminException(AdminErrorCodes.DepartmentHasChildren, "该部门下有子部门,无法删除");
}
// 检查是否有用户
var hasUsers = await _dbContext.AdminUsers.AnyAsync(u => u.DepartmentId == id);
if (hasUsers)
{
throw new AdminException(AdminErrorCodes.DepartmentHasUsers, "该部门下有用户,无法删除");
}
// 删除关联数据
var departmentMenus = await _dbContext.DepartmentMenus.Where(dm => dm.DepartmentId == id).ToListAsync();
_dbContext.DepartmentMenus.RemoveRange(departmentMenus);
_dbContext.Departments.Remove(department);
await _dbContext.SaveChangesAsync();
_logger.LogInformation("删除部门成功: {DepartmentId} - {DepartmentName}", id, department.Name);
}
/// <inheritdoc />
public async Task<List<long>> GetMenuIdsAsync(long departmentId)
{
var department = await _dbContext.Departments.FindAsync(departmentId);
if (department == null)
{
throw new AdminException(AdminErrorCodes.InvalidParameter, "部门不存在");
}
return await _dbContext.DepartmentMenus
.Where(dm => dm.DepartmentId == departmentId)
.Select(dm => dm.MenuId)
.ToListAsync();
}
/// <inheritdoc />
public async Task AssignMenusAsync(long departmentId, List<long> menuIds)
{
var department = await _dbContext.Departments.FindAsync(departmentId);
if (department == null)
{
throw new AdminException(AdminErrorCodes.InvalidParameter, "部门不存在");
}
// 删除现有关联
var existingMenus = await _dbContext.DepartmentMenus.Where(dm => dm.DepartmentId == departmentId).ToListAsync();
_dbContext.DepartmentMenus.RemoveRange(existingMenus);
// 添加新关联
if (menuIds.Any())
{
var newMenus = menuIds.Distinct().Select(menuId => new DepartmentMenu
{
DepartmentId = departmentId,
MenuId = menuId
});
_dbContext.DepartmentMenus.AddRange(newMenus);
}
await _dbContext.SaveChangesAsync();
_logger.LogInformation("部门 {DepartmentId} 分配菜单成功,菜单数量: {Count}", departmentId, menuIds.Count);
}
/// <inheritdoc />
public async Task<List<AdminUserDto>> GetDepartmentUsersAsync(long departmentId)
{
var department = await _dbContext.Departments.FindAsync(departmentId);
if (department == null)
{
throw new AdminException(AdminErrorCodes.InvalidParameter, "部门不存在");
}
return await _dbContext.AdminUsers
.Where(u => u.DepartmentId == departmentId)
.Include(u => u.AdminUserRoles)
.ThenInclude(ur => ur.Role)
.Select(u => new AdminUserDto
{
Id = u.Id,
Username = u.Username,
RealName = u.RealName,
Avatar = u.Avatar,
Email = u.Email,
Phone = u.Phone,
DepartmentId = u.DepartmentId,
DepartmentName = department.Name,
Status = u.Status,
LastLoginTime = u.LastLoginTime,
LastLoginIp = u.LastLoginIp,
CreatedAt = u.CreatedAt,
UpdatedAt = u.UpdatedAt,
Remark = u.Remark,
RoleIds = u.AdminUserRoles.Select(ur => ur.RoleId).ToList(),
RoleNames = u.AdminUserRoles.Select(ur => ur.Role.Name).ToList()
})
.ToListAsync();
}
/// <summary>
/// 构建部门树
/// </summary>
private List<DepartmentTreeDto> BuildDepartmentTree(List<Entities.Department> departments, long parentId)
{
return departments
.Where(d => d.ParentId == parentId)
.Select(d => new DepartmentTreeDto
{
Id = d.Id,
ParentId = d.ParentId,
Name = d.Name,
Code = d.Code,
SortOrder = d.SortOrder,
Status = d.Status,
UserCount = d.AdminUsers.Count,
Children = BuildDepartmentTree(departments, d.Id)
})
.ToList();
}
/// <summary>
/// 检查 targetId 是否是 departmentId 的子孙部门
/// </summary>
private async Task<bool> IsDescendantAsync(long targetId, long departmentId)
{
var children = await _dbContext.Departments
.Where(d => d.ParentId == departmentId)
.Select(d => d.Id)
.ToListAsync();
if (children.Contains(targetId))
{
return true;
}
foreach (var childId in children)
{
if (await IsDescendantAsync(targetId, childId))
{
return true;
}
}
return false;
}
}