corps/src/MilitaryTrainingManagement/Services/Implementations/OrganizationService.cs
2026-01-16 00:43:02 +08:00

211 lines
6.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Microsoft.EntityFrameworkCore;
using MilitaryTrainingManagement.Data;
using MilitaryTrainingManagement.Models.Entities;
using MilitaryTrainingManagement.Models.Enums;
using MilitaryTrainingManagement.Services.Interfaces;
namespace MilitaryTrainingManagement.Services.Implementations;
/// <summary>
/// 组织管理服务实现
/// </summary>
public class OrganizationService : IOrganizationService
{
private readonly ApplicationDbContext _context;
public OrganizationService(ApplicationDbContext context)
{
_context = context;
}
public async Task<OrganizationalUnit?> GetByIdAsync(int id)
{
return await _context.OrganizationalUnits
.Include(u => u.Parent)
.Include(u => u.Children)
.FirstOrDefaultAsync(u => u.Id == id);
}
public async Task<IEnumerable<OrganizationalUnit>> GetAllAsync()
{
var allUnits = await _context.OrganizationalUnits
.OrderBy(u => u.Level)
.ThenBy(u => u.CreatedAt) // 按创建时间排序,新的在后面
.ToListAsync();
// 构建树形结构,只返回顶级节点(师团级)
var rootUnits = allUnits.Where(u => u.ParentId == null).OrderBy(u => u.CreatedAt).ToList();
// 递归构建子节点
foreach (var root in rootUnits)
{
BuildChildrenTree(root, allUnits);
}
return rootUnits;
}
private void BuildChildrenTree(OrganizationalUnit parent, List<OrganizationalUnit> allUnits)
{
var children = allUnits.Where(u => u.ParentId == parent.Id).OrderBy(u => u.CreatedAt).ToList();
parent.Children = children;
foreach (var child in children)
{
child.Parent = parent;
BuildChildrenTree(child, allUnits);
}
}
public async Task<IEnumerable<OrganizationalUnit>> GetSubordinatesAsync(int unitId)
{
var unit = await _context.OrganizationalUnits.FindAsync(unitId);
if (unit == null)
return Enumerable.Empty<OrganizationalUnit>();
return await GetAllSubordinatesRecursiveAsync(unitId);
}
private async Task<List<OrganizationalUnit>> GetAllSubordinatesRecursiveAsync(int unitId)
{
var result = new List<OrganizationalUnit>();
var directChildren = await _context.OrganizationalUnits
.Where(u => u.ParentId == unitId)
.ToListAsync();
foreach (var child in directChildren)
{
result.Add(child);
var grandChildren = await GetAllSubordinatesRecursiveAsync(child.Id);
result.AddRange(grandChildren);
}
return result;
}
public async Task<OrganizationalUnit> CreateAsync(string name, OrganizationalLevel level, int? parentId)
{
if (parentId.HasValue)
{
var parent = await _context.OrganizationalUnits.FindAsync(parentId.Value);
if (parent == null)
throw new ArgumentException("父级组织单位不存在");
if ((int)level <= (int)parent.Level)
throw new ArgumentException("子级组织层级必须低于父级");
}
else if (level != OrganizationalLevel.Division)
{
throw new ArgumentException("非师团级组织必须有父级单位");
}
var unit = new OrganizationalUnit
{
Name = name,
Level = level,
ParentId = parentId,
CreatedAt = DateTime.UtcNow
};
_context.OrganizationalUnits.Add(unit);
await _context.SaveChangesAsync();
return unit;
}
public async Task<OrganizationalUnit> UpdateAsync(int id, string name)
{
var unit = await _context.OrganizationalUnits.FindAsync(id);
if (unit == null)
throw new ArgumentException("组织单位不存在");
unit.Name = name;
await _context.SaveChangesAsync();
return unit;
}
public async Task DeleteAsync(int id)
{
var unit = await _context.OrganizationalUnits
.Include(u => u.Children)
.FirstOrDefaultAsync(u => u.Id == id);
if (unit == null)
throw new ArgumentException("组织单位不存在");
if (unit.Children.Any())
throw new InvalidOperationException("无法删除有下级单位的组织");
// 检查是否有关联的用户账户
var hasUsers = await _context.UserAccounts
.AnyAsync(u => u.OrganizationalUnitId == id);
if (hasUsers)
throw new InvalidOperationException("无法删除有关联用户的组织");
_context.OrganizationalUnits.Remove(unit);
await _context.SaveChangesAsync();
}
public async Task<bool> IsSubordinateOfAsync(int unitId, int potentialParentId)
{
var unit = await _context.OrganizationalUnits.FindAsync(unitId);
if (unit == null)
return false;
var currentParentId = unit.ParentId;
while (currentParentId.HasValue)
{
if (currentParentId.Value == potentialParentId)
return true;
var parent = await _context.OrganizationalUnits.FindAsync(currentParentId.Value);
currentParentId = parent?.ParentId;
}
return false;
}
public async Task<IEnumerable<int>> GetAllSubordinateIdsAsync(int unitId)
{
var subordinates = await GetAllSubordinatesRecursiveAsync(unitId);
return subordinates.Select(u => u.Id);
}
public async Task<bool> IsUnitOrSubordinateAsync(int userUnitId, int targetUnitId)
{
// 如果是同一个单位直接返回true
if (userUnitId == targetUnitId)
return true;
// 检查目标单位是否是用户单位的下级
return await IsSubordinateOfAsync(targetUnitId, userUnitId);
}
public async Task<bool> IsParentUnitAsync(int parentUnitId, int childUnitId)
{
var childUnit = await _context.OrganizationalUnits.FindAsync(childUnitId);
if (childUnit == null)
return false;
// 检查直接父级关系
if (childUnit.ParentId == parentUnitId)
return true;
// 检查是否是上级单位(递归向上查找)
return await IsSubordinateOfAsync(childUnitId, parentUnitId);
}
public async Task<IEnumerable<int>> GetAllAncestorIdsAsync(int unitId)
{
var result = new List<int>();
var currentUnit = await _context.OrganizationalUnits.FindAsync(unitId);
while (currentUnit?.ParentId != null)
{
result.Add(currentUnit.ParentId.Value);
currentUnit = await _context.OrganizationalUnits.FindAsync(currentUnit.ParentId.Value);
}
return result;
}
}