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;
///
/// 部门服务实现
///
public class DepartmentService : IDepartmentService
{
private readonly AdminDbContext _dbContext;
private readonly ILogger _logger;
public DepartmentService(AdminDbContext dbContext, ILogger logger)
{
_dbContext = dbContext;
_logger = logger;
}
///
public async Task> GetDepartmentTreeAsync()
{
var departments = await _dbContext.Departments
.Include(d => d.AdminUsers)
.OrderBy(d => d.SortOrder)
.ThenBy(d => d.Id)
.ToListAsync();
return BuildDepartmentTree(departments, 0);
}
///
public async Task 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()
};
}
///
public async Task 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;
}
///
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);
}
///
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);
}
///
public async Task> 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();
}
///
public async Task AssignMenusAsync(long departmentId, List 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);
}
///
public async Task> 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();
}
///
/// 构建部门树
///
private List BuildDepartmentTree(List 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();
}
///
/// 检查 targetId 是否是 departmentId 的子孙部门
///
private async Task 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;
}
}