using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using MilitaryTrainingManagement.Authorization; using MilitaryTrainingManagement.Models.DTOs; using MilitaryTrainingManagement.Models.Enums; using MilitaryTrainingManagement.Services.Interfaces; namespace MilitaryTrainingManagement.Controllers; /// /// 物资配额控制器 /// [Authorize] public class AllocationsController : BaseApiController { private readonly IAllocationService _allocationService; private readonly IOrganizationalAuthorizationService _authorizationService; public AllocationsController( IAllocationService allocationService, IOrganizationalAuthorizationService authorizationService) { _allocationService = allocationService; _authorizationService = authorizationService; } /// /// 获取当前用户可见的所有物资配额 /// [HttpGet] public async Task GetAll() { var unitId = GetCurrentUnitId(); var unitLevel = GetCurrentUnitLevel(); if (unitId == null || unitLevel == null) return Unauthorized(new { message = "无法获取用户组织信息" }); // 师团级可以看到所有配额,其他级别只能看到分配给自己及下级的配额 IEnumerable allocations; if (unitLevel == OrganizationalLevel.Division) { allocations = await _allocationService.GetAllAsync(); } else { allocations = await _allocationService.GetVisibleToUnitAsync(unitId.Value); } var response = allocations.Select(MapToResponse); return Ok(response); } /// /// 获取当前单位创建的物资配额 /// [HttpGet("my")] public async Task GetMyAllocations() { var unitId = GetCurrentUnitId(); if (unitId == null) return Unauthorized(new { message = "无法获取用户组织信息" }); var allocations = await _allocationService.GetByUnitAsync(unitId.Value); var response = allocations.Select(MapToResponse); return Ok(response); } /// /// 获取分配给当前单位的配额分配记录 /// [HttpGet("distributions")] public async Task GetMyDistributions() { var unitId = GetCurrentUnitId(); if (unitId == null) return Unauthorized(new { message = "无法获取用户组织信息" }); var distributions = await _allocationService.GetDistributionsForUnitAsync(unitId.Value); var response = distributions.Select(MapDistributionToResponse); return Ok(response); } /// /// 根据ID获取物资配额 /// [HttpGet("{id}")] public async Task GetById(int id) { var unitId = GetCurrentUnitId(); if (unitId == null) return Unauthorized(new { message = "无法获取用户组织信息" }); var allocation = await _allocationService.GetByIdAsync(id); if (allocation == null) return NotFound(new { message = "配额不存在" }); // 检查访问权限:只能查看自己创建的或分配给自己及下级的配额 var canAccess = allocation.CreatedByUnitId == unitId.Value || allocation.Distributions.Any(d => _authorizationService.CanAccessUnitAsync(unitId.Value, d.TargetUnitId).GetAwaiter().GetResult()); if (!canAccess) return Forbid(); return Ok(MapToResponse(allocation)); } /// /// 创建物资配额 /// 需求2.1:师团管理员可以创建物资类别 /// 需求2.2:创建配额需要物资名称、单位、总配额和目标单位 /// 需求2.4:创建后自动分发给目标单位 /// [HttpPost] [Authorize(Policy = "DivisionLevel")] public async Task Create([FromBody] CreateAllocationRequest request) { var unitId = GetCurrentUnitId(); if (unitId == null) return Unauthorized(new { message = "无法获取用户组织信息" }); // 验证必填字段 if (!ModelState.IsValid) return BadRequest(ModelState); try { var allocation = await _allocationService.CreateAsync( request.Category, request.MaterialName, request.Unit, request.TotalQuota, unitId.Value, request.Distributions); return CreatedAtAction(nameof(GetById), new { id = allocation.Id }, MapToResponse(allocation)); } catch (ArgumentException ex) { return BadRequest(new { message = ex.Message }); } } /// /// 更新物资配额基本信息 /// [HttpPut("{id}")] [Authorize(Policy = "DivisionLevel")] public async Task Update(int id, [FromBody] UpdateAllocationRequest request) { var unitId = GetCurrentUnitId(); if (unitId == null) return Unauthorized(new { message = "无法获取用户组织信息" }); // 验证必填字段 if (!ModelState.IsValid) return BadRequest(ModelState); // 检查配额是否存在 var existingAllocation = await _allocationService.GetByIdAsync(id); if (existingAllocation == null) return NotFound(new { message = "配额不存在" }); // 检查是否有权限修改(只能修改自己创建的配额) if (existingAllocation.CreatedByUnitId != unitId.Value) return Forbid(); try { var allocation = await _allocationService.UpdateAsync( id, request.Category, request.MaterialName, request.Unit, request.TotalQuota); return Ok(MapToResponse(await _allocationService.GetByIdAsync(id) ?? allocation)); } catch (ArgumentException ex) { return BadRequest(new { message = ex.Message }); } } /// /// 更新配额分配记录 /// [HttpPut("{id}/distributions")] [Authorize(Policy = "DivisionLevel")] public async Task UpdateDistributions(int id, [FromBody] Dictionary distributions) { var unitId = GetCurrentUnitId(); if (unitId == null) return Unauthorized(new { message = "无法获取用户组织信息" }); // 检查配额是否存在 var existingAllocation = await _allocationService.GetByIdAsync(id); if (existingAllocation == null) return NotFound(new { message = "配额不存在" }); // 检查是否有权限修改 if (existingAllocation.CreatedByUnitId != unitId.Value) return Forbid(); try { var allocation = await _allocationService.UpdateDistributionsAsync(id, distributions); return Ok(MapToResponse(allocation)); } catch (ArgumentException ex) { return BadRequest(new { message = ex.Message }); } } /// /// 删除物资配额 /// [HttpDelete("{id}")] [Authorize(Policy = "DivisionLevel")] public async Task Delete(int id) { var unitId = GetCurrentUnitId(); if (unitId == null) return Unauthorized(new { message = "无法获取用户组织信息" }); // 检查配额是否存在 var existingAllocation = await _allocationService.GetByIdAsync(id); if (existingAllocation == null) return NotFound(new { message = "配额不存在" }); // 检查是否有权限删除 if (existingAllocation.CreatedByUnitId != unitId.Value) return Forbid(); try { await _allocationService.DeleteAsync(id); return NoContent(); } catch (ArgumentException ex) { return BadRequest(new { message = ex.Message }); } } /// /// 验证配额分配是否有效 /// [HttpPost("validate")] public async Task ValidateDistributions([FromBody] CreateAllocationRequest request) { var isValid = await _allocationService.ValidateDistributionQuotasAsync( request.TotalQuota, request.Distributions); var targetUnitsExist = await _allocationService.ValidateTargetUnitsExistAsync( request.Distributions.Keys); return Ok(new { quotaValid = isValid, targetUnitsExist = targetUnitsExist, isValid = isValid && targetUnitsExist, message = !isValid ? "分配配额总和超过总配额指标" : !targetUnitsExist ? "目标单位不存在" : "验证通过" }); } /// /// 映射实体到响应DTO /// private static AllocationResponse MapToResponse(Models.Entities.MaterialAllocation allocation) { return new AllocationResponse { Id = allocation.Id, Category = allocation.Category, MaterialName = allocation.MaterialName, Unit = allocation.Unit, TotalQuota = allocation.TotalQuota, CreatedByUnitId = allocation.CreatedByUnitId, CreatedByUnitName = allocation.CreatedByUnit?.Name ?? string.Empty, CreatedAt = allocation.CreatedAt, Distributions = allocation.Distributions.Select(d => new AllocationDistributionResponse { Id = d.Id, TargetUnitId = d.TargetUnitId, TargetUnitName = d.TargetUnit?.Name ?? string.Empty, UnitQuota = d.UnitQuota, ActualCompletion = d.ActualCompletion, CompletionRate = d.CompletionRate, ReportedAt = d.ReportedAt, ReportedByUserName = d.ReportedByUser?.DisplayName }).ToList() }; } /// /// 映射分配记录到响应DTO /// private static AllocationDistributionResponse MapDistributionToResponse(Models.Entities.AllocationDistribution distribution) { return new AllocationDistributionResponse { Id = distribution.Id, TargetUnitId = distribution.TargetUnitId, TargetUnitName = distribution.TargetUnit?.Name ?? string.Empty, UnitQuota = distribution.UnitQuota, ActualCompletion = distribution.ActualCompletion, CompletionRate = distribution.CompletionRate, ReportedAt = distribution.ReportedAt, ReportedByUserName = distribution.ReportedByUser?.DisplayName }; } }