| ¶Ô±ÈÐÂÎļþ |
| | |
| | | using Microsoft.AspNetCore.Mvc; |
| | | using SqlSugar; |
| | | using WIDESEA_Core; |
| | | using WIDESEA_Model.Models; |
| | | |
| | | namespace WIDESEA_WMSServer.Controllers.Dashboard |
| | | { |
| | | /// <summary> |
| | | /// 仪表ç |
| | | /// </summary> |
| | | [Route("api/Dashboard")] |
| | | [ApiController] |
| | | public class DashboardController : ControllerBase |
| | | { |
| | | private readonly ISqlSugarClient _db; |
| | | |
| | | public DashboardController(ISqlSugarClient db) |
| | | { |
| | | _db = db; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ»è§æ°æ® |
| | | /// </summary> |
| | | [HttpGet("Overview")] |
| | | public async Task<WebResponseContent> Overview() |
| | | { |
| | | var today = DateTime.Today; |
| | | var firstDayOfMonth = new DateTime(today.Year, today.Month, 1); |
| | | |
| | | // 仿¥å
¥åºæ° |
| | | var todayInbound = await _db.Queryable<Dt_Task_Hty>() |
| | | .Where(t => t.InsertTime >= today && t.TaskType >= 500 && t.TaskType < 600) |
| | | .CountAsync(); |
| | | |
| | | // 仿¥åºåºæ° |
| | | var todayOutbound = await _db.Queryable<Dt_Task_Hty>() |
| | | .Where(t => t.InsertTime >= today && t.TaskType >= 100 && t.TaskType < 200) |
| | | .CountAsync(); |
| | | |
| | | // æ¬æå
¥åºæ° |
| | | var monthInbound = await _db.Queryable<Dt_Task_Hty>() |
| | | .Where(t => t.InsertTime >= firstDayOfMonth && t.TaskType >= 500 && t.TaskType < 600) |
| | | .CountAsync(); |
| | | |
| | | // æ¬æåºåºæ° |
| | | var monthOutbound = await _db.Queryable<Dt_Task_Hty>() |
| | | .Where(t => t.InsertTime >= firstDayOfMonth && t.TaskType >= 100 && t.TaskType < 200) |
| | | .CountAsync(); |
| | | |
| | | // å½åæ»åºå |
| | | var totalStock = await _db.Queryable<Dt_StockInfo>().CountAsync(); |
| | | |
| | | return WebResponseContent.Instance.OK(null, new |
| | | { |
| | | TodayInbound = todayInbound, |
| | | TodayOutbound = todayOutbound, |
| | | MonthInbound = monthInbound, |
| | | MonthOutbound = monthOutbound, |
| | | TotalStock = totalStock |
| | | }); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ¯æ¥ç»è®¡ |
| | | /// </summary> |
| | | [HttpGet("DailyStats")] |
| | | public async Task<WebResponseContent> 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<Dt_Task_Hty>() |
| | | .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); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ¯å¨ç»è®¡ |
| | | /// </summary> |
| | | [HttpGet("WeeklyStats")] |
| | | public async Task<WebResponseContent> WeeklyStats([FromQuery] int weeks = 12) |
| | | { |
| | | if (weeks <= 0) weeks = 12; |
| | | |
| | | var startDate = DateTime.Today.AddDays(-weeks * 7); |
| | | |
| | | var query = await _db.Queryable<Dt_Task_Hty>() |
| | | .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}"; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ¯æç»è®¡ |
| | | /// </summary> |
| | | [HttpGet("MonthlyStats")] |
| | | public async Task<WebResponseContent> 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<Dt_Task_Hty>() |
| | | .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); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// åºååºé¾åå¸ |
| | | /// </summary> |
| | | [HttpGet("StockAgeDistribution")] |
| | | public async Task<WebResponseContent> StockAgeDistribution() |
| | | { |
| | | var now = DateTime.Now; |
| | | |
| | | // ä½¿ç¨ SQL ç´æ¥åç»ç»è®¡ï¼é¿å
å è½½æææ°æ®å°å
å |
| | | var result = new[] |
| | | { |
| | | new { Range = "7天å
", Count = await _db.Queryable<Dt_StockInfo>().Where(s => SqlFunc.DateDiff(DateType.Day, s.CreateDate, now) <= 7).CountAsync() }, |
| | | new { Range = "7-30天", Count = await _db.Queryable<Dt_StockInfo>().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<Dt_StockInfo>().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<Dt_StockInfo>().Where(s => SqlFunc.DateDiff(DateType.Day, s.CreateDate, now) > 90).CountAsync() } |
| | | }; |
| | | |
| | | return WebResponseContent.Instance.OK(null, result); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// åä»åºåºååå¸ |
| | | /// </summary> |
| | | [HttpGet("StockByWarehouse")] |
| | | public async Task<WebResponseContent> StockByWarehouse() |
| | | { |
| | | // å
æ¥è¯¢ä»åºåç§° |
| | | var warehouses = await _db.Queryable<Dt_Warehouse>() |
| | | .Select(w => new { w.WarehouseId, w.WarehouseName }) |
| | | .ToListAsync(); |
| | | var warehouseDict = warehouses.ToDictionary(w => w.WarehouseId, w => w.WarehouseName); |
| | | |
| | | // æ¥è¯¢åºåæ°æ®å¹¶å¨å
åä¸åç» |
| | | var stocks = await _db.Queryable<Dt_StockInfo>() |
| | | .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); |
| | | } |
| | | } |
| | | } |