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