using Microsoft.AspNetCore.Mvc; using SqlSugar; using WIDESEA_Core; using WIDESEA_Model.Models; namespace WIDESEA_WMSServer.Controllers.Dashboard { /// /// 仪表盘 /// [Route("api/Dashboard")] [ApiController] public class DashboardController : ControllerBase { private readonly ISqlSugarClient _db; public DashboardController(ISqlSugarClient db) { _db = db; } /// /// 总览数据 /// [HttpGet("Overview")] public async Task Overview() { var today = DateTime.Today; var firstDayOfMonth = new DateTime(today.Year, today.Month, 1); // 今日入库数 var todayInbound = await _db.Queryable() .Where(t => t.InsertTime >= today && t.TaskType >= 500 && t.TaskType < 600) .CountAsync(); // 今日出库数 var todayOutbound = await _db.Queryable() .Where(t => t.InsertTime >= today && t.TaskType >= 100 && t.TaskType < 200) .CountAsync(); // 本月入库数 var monthInbound = await _db.Queryable() .Where(t => t.InsertTime >= firstDayOfMonth && t.TaskType >= 500 && t.TaskType < 600) .CountAsync(); // 本月出库数 var monthOutbound = await _db.Queryable() .Where(t => t.InsertTime >= firstDayOfMonth && t.TaskType >= 100 && t.TaskType < 200) .CountAsync(); // 当前总库存 var totalStock = await _db.Queryable().CountAsync(); return WebResponseContent.Instance.OK(null, new { TodayInbound = todayInbound, TodayOutbound = todayOutbound, MonthInbound = monthInbound, MonthOutbound = monthOutbound, TotalStock = totalStock }); } /// /// 每日统计 /// [HttpGet("DailyStats")] public async Task DailyStats([FromQuery] int days = 30) { if (days <= 0) days = 30; if (days > 365) days = 365; var startDate = DateTime.Today.AddDays(-days + 1); var query = await _db.Queryable() .Where(t => t.InsertTime >= startDate) .Select(t => new { t.InsertTime, t.TaskType }) .ToListAsync(); var result = query .GroupBy(t => t.InsertTime.Date) .Select(g => new { Date = g.Key.ToString("yyyy-MM-dd"), Inbound = g.Count(t => t.TaskType >= 500 && t.TaskType < 600), Outbound = g.Count(t => t.TaskType >= 100 && t.TaskType < 200) }) .OrderBy(x => x.Date) .ToList(); return WebResponseContent.Instance.OK(null, result); } /// /// 每周统计 /// [HttpGet("WeeklyStats")] public async Task WeeklyStats([FromQuery] int weeks = 12) { if (weeks <= 0) weeks = 12; var startDate = DateTime.Today.AddDays(-weeks * 7); var query = await _db.Queryable() .Where(t => t.InsertTime >= startDate) .Select(t => new { t.InsertTime, t.TaskType }) .ToListAsync(); var result = query .GroupBy(t => GetWeekKey(t.InsertTime)) .Select(g => new { Week = g.Key, Inbound = g.Count(t => t.TaskType >= 500 && t.TaskType < 600), Outbound = g.Count(t => t.TaskType >= 100 && t.TaskType < 200) }) .OrderBy(x => x.Week) .ToList(); return WebResponseContent.Instance.OK(null, result); } private string GetWeekKey(DateTime date) { // 获取周一开始的周 (ISO 8601) var diff = (7 + (date.DayOfWeek - DayOfWeek.Monday)) % 7; var monday = date.AddDays(-diff); var weekNum = System.Globalization.CultureInfo.InvariantCulture .Calendar.GetWeekOfYear(monday, System.Globalization.CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday); return $"{monday.Year}-W{weekNum:D2}"; } /// /// 每月统计 /// [HttpGet("MonthlyStats")] public async Task MonthlyStats([FromQuery] int months = 12) { if (months <= 0) months = 12; var startDate = DateTime.Today.AddMonths(-months + 1); startDate = new DateTime(startDate.Year, startDate.Month, 1); var query = await _db.Queryable() .Where(t => t.InsertTime >= startDate) .Select(t => new { t.InsertTime, t.TaskType }) .ToListAsync(); var result = query .GroupBy(t => new { t.InsertTime.Year, t.InsertTime.Month }) .Select(g => new { Month = $"{g.Key.Year}-{g.Key.Month:D2}", Inbound = g.Count(t => t.TaskType >= 500 && t.TaskType < 600), Outbound = g.Count(t => t.TaskType >= 100 && t.TaskType < 200) }) .OrderBy(x => x.Month) .ToList(); return WebResponseContent.Instance.OK(null, result); } /// /// 库存库龄分布 /// [HttpGet("StockAgeDistribution")] public async Task StockAgeDistribution() { var now = DateTime.Now; // 使用 SQL 直接分组统计,避免加载所有数据到内存 var result = new[] { new { Range = "7天内", Count = await _db.Queryable().Where(s => SqlFunc.DateDiff(DateType.Day, s.CreateDate, now) <= 7).CountAsync() }, new { Range = "7-30天", Count = await _db.Queryable().Where(s => SqlFunc.DateDiff(DateType.Day, s.CreateDate, now) > 7 && SqlFunc.DateDiff(DateType.Day, s.CreateDate, now) <= 30).CountAsync() }, new { Range = "30-90天", Count = await _db.Queryable().Where(s => SqlFunc.DateDiff(DateType.Day, s.CreateDate, now) > 30 && SqlFunc.DateDiff(DateType.Day, s.CreateDate, now) <= 90).CountAsync() }, new { Range = "90天以上", Count = await _db.Queryable().Where(s => SqlFunc.DateDiff(DateType.Day, s.CreateDate, now) > 90).CountAsync() } }; return WebResponseContent.Instance.OK(null, result); } /// /// 各仓库库存分布 /// [HttpGet("StockByWarehouse")] public async Task StockByWarehouse() { // 先查询仓库名称 var warehouses = await _db.Queryable() .Select(w => new { w.WarehouseId, w.WarehouseName }) .ToListAsync(); var warehouseDict = warehouses.ToDictionary(w => w.WarehouseId, w => w.WarehouseName); // 查询库存数据并在内存中分组 var stocks = await _db.Queryable() .Select(s => new { s.WarehouseId }) .ToListAsync(); var result = stocks .GroupBy(s => s.WarehouseId) .Select(g => new { Warehouse = warehouseDict.TryGetValue(g.Key, out var name) ? name : $"仓库{g.Key}", Count = g.Count() }) .ToList(); return WebResponseContent.Instance.OK(null, result); } } }