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; } }