corps/src/MilitaryTrainingManagement/Controllers/StatsController.cs
2026-01-13 16:40:57 +08:00

103 lines
3.2 KiB
C#

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using MilitaryTrainingManagement.Data;
using MilitaryTrainingManagement.Models.Enums;
namespace MilitaryTrainingManagement.Controllers;
/// <summary>
/// 统计数据控制器
/// </summary>
[Authorize]
public class StatsController : BaseApiController
{
private readonly ApplicationDbContext _context;
public StatsController(ApplicationDbContext context)
{
_context = context;
}
/// <summary>
/// 获取首页统计数据
/// </summary>
[HttpGet("dashboard")]
public async Task<IActionResult> GetDashboardStats()
{
var unitId = GetCurrentUnitId();
var unitLevel = GetCurrentUnitLevel();
if (unitId == null || unitLevel == null)
return Unauthorized(new { message = "无法获取用户组织信息" });
// 获取当前单位及下级单位ID列表
var unitIds = await GetUnitAndSubordinateIds(unitId.Value);
// 统计配额数
var allocationsCount = await _context.MaterialAllocations
.Where(a => a.CreatedByUnitId == unitId.Value || unitIds.Contains(a.CreatedByUnitId))
.CountAsync();
// 统计完成率
var distributions = await _context.AllocationDistributions
.Where(d => unitIds.Contains(d.TargetUnitId))
.ToListAsync();
decimal completionRate = 0;
if (distributions.Any())
{
var totalQuota = distributions.Sum(d => d.UnitQuota);
var totalCompletion = distributions.Sum(d => d.ActualCompletion ?? 0);
if (totalQuota > 0)
{
completionRate = Math.Round((totalCompletion / totalQuota) * 100, 1);
}
}
// 统计人员数
var personnelCount = await _context.Personnel
.Where(p => unitIds.Contains(p.SubmittedByUnitId) && p.Status == PersonnelStatus.Approved)
.CountAsync();
// 统计待审批数(仅师团级别显示)
var pendingApprovals = 0;
if (unitLevel == OrganizationalLevel.Division)
{
pendingApprovals = await _context.ApprovalRequests
.Where(r => r.Status == ApprovalStatus.Pending)
.CountAsync();
// 加上待审批的人员
pendingApprovals += await _context.Personnel
.Where(p => p.Status == PersonnelStatus.Pending)
.CountAsync();
}
return Ok(new
{
allocations = allocationsCount,
completionRate = completionRate,
personnel = personnelCount,
pendingApprovals = pendingApprovals
});
}
private async Task<List<int>> GetUnitAndSubordinateIds(int unitId)
{
var result = new List<int> { unitId };
var children = await _context.OrganizationalUnits
.Where(u => u.ParentId == unitId)
.Select(u => u.Id)
.ToListAsync();
foreach (var childId in children)
{
var subIds = await GetUnitAndSubordinateIds(childId);
result.AddRange(subIds);
}
return result;
}
}