xiazhengtongxue
3 天以前 51922d7093b9c8f52417bfdd0fe9aa087d1fb5be
Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Dashboard/DashboardController.cs
@@ -2,6 +2,7 @@
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using WIDESEA_Common.LocationEnum;
using WIDESEA_Common.StockEnum;
using WIDESEA_Core;
using WIDESEA_Model.Models;
@@ -71,10 +72,10 @@
        }
        /// <summary>
        /// 每日统计
        /// 每日统计(按巷道号分组,指定仓库)
        /// </summary>
        [HttpGet("DailyStats"), AllowAnonymous]
        public async Task<WebResponseContent> DailyStats([FromQuery] int days = 30)
        public async Task<WebResponseContent> DailyStats([FromQuery] int days = 10)
        {
            try
            {
@@ -84,9 +85,16 @@
                var startDate = DateTime.Today.AddDays(-days + 1);
                var endDate = DateTime.Today; // 包含今天
                // 指定要统计的仓库(巷道号)
                var specifiedRoadways = new List<string>
        {
            "GWSC1", "CWSC1", "HCSC1", "ZJSC1", "FJSC1"
        };
                var query = await _db.Queryable<Dt_Task_Hty>()
                    .Where(t => t.InsertTime >= startDate && t.InsertTime <= endDate)
                    .Select(t => new { t.InsertTime, t.TaskType })
                    .Where(t => specifiedRoadways.Contains(t.Roadway)) // 只查询指定巷道号的数据
                    .Select(t => new { t.InsertTime, t.TaskType, t.Roadway })
                    .ToListAsync();
                // 生成日期范围
@@ -96,40 +104,57 @@
                    allDates.Add(date);
                }
                // 按日期分组统计
                // 按巷道号和日期分组统计
                var groupedData = query
                    .GroupBy(t => t.InsertTime.Date)
                    .GroupBy(t => new { t.Roadway, Date = t.InsertTime.Date })
                    .Select(g => new
                    {
                        Date = g.Key,
                        Roadway = g.Key.Roadway,
                        Date = g.Key.Date,
                        Inbound = g.Count(t => t.TaskType >= 200 && t.TaskType < 300),
                        Outbound = g.Count(t => t.TaskType >= 100 && t.TaskType < 200)
                    })
                    .ToDictionary(x => x.Date, x => x);
                    .ToList();
                // 补全缺失日期
                var result = allDates.Select(date =>
                // 构建结果:每个指定仓库对应一个日期列表
                var result = specifiedRoadways.Select(roadway =>
                {
                    if (groupedData.TryGetValue(date, out var data))
                    // 获取该巷道号的分组数据字典
                    var roadwayData = groupedData
                        .Where(g => g.Roadway == roadway)
                        .ToDictionary(x => x.Date, x => x);
                    // 补全缺失日期,确保每天都有数据(默认为0)
                    var dailyStats = allDates.Select(date =>
                    {
                        return new
                        if (roadwayData.TryGetValue(date, out var data))
                        {
                            Date = date.ToString("MM-dd"),
                            Inbound = data.Inbound,
                            Outbound = data.Outbound
                        };
                    }
                    else
                            return new
                            {
                                Date = date.ToString("MM-dd"),
                                Inbound = data.Inbound,
                                Outbound = data.Outbound
                            };
                        }
                        else
                        {
                            return new
                            {
                                Date = date.ToString("MM-dd"),
                                Inbound = 0,
                                Outbound = 0
                            };
                        }
                    })
                    .OrderBy(x => x.Date)
                    .ToList();
                    return new
                    {
                        return new
                        {
                            Date = date.ToString("MM-dd"),
                            Inbound = 0,
                            Outbound = 0
                        };
                    }
                        Roadway = roadway,
                        DailyStats = dailyStats
                    };
                })
                .OrderBy(x => x.Date)
                .ToList();
                return WebResponseContent.Instance.OK(null, result);
@@ -139,6 +164,7 @@
                return WebResponseContent.Instance.Error($"每日统计获取失败: {ex.Message}");
            }
        }
        /// <summary>
        /// 每周统计
        /// </summary>
@@ -189,14 +215,11 @@
            return $"{monday.Year}-W{weekNum:D2}";
        }
        /// <summary>
        /// 每月统计
        /// </summary>
        /// <remarks>
        /// 按年月统计入站和出站任务数量
        /// </remarks>
        [HttpGet("MonthlyStats"), AllowAnonymous]
        public async Task<WebResponseContent> MonthlyStats([FromQuery] int months = 12)
        public async Task<WebResponseContent> MonthlyStats(int months, string roadway)
        {
            try
            {
@@ -205,8 +228,28 @@
                var startDate = DateTime.Today.AddMonths(-months + 1);
                startDate = new DateTime(startDate.Year, startDate.Month, 1);
                var monthlyStats = await _db.Queryable<Dt_Task_Hty>()
                    .Where(t => t.InsertTime >= startDate)
                // 仓库名称映射
                var roadwayNames = new Dictionary<string, string>
        {
            { "GWSC1", "高温1号仓库" },
            { "CWSC1", "常温1号仓库" },
            { "HCSC1", "分容1号仓库" },
            { "FJSC1", "负极卷1号仓库" },
            { "ZJSC1", "正极卷1号仓库" },
        };
                // 构建查询
                var query = _db.Queryable<Dt_Task_Hty>()
                    .Where(t => t.InsertTime >= startDate);
                // 如果指定了道路,添加道路过滤条件
                if (!string.IsNullOrEmpty(roadway))
                {
                    query = query.Where(t => t.Roadway == roadway);
                }
                var monthlyStats = await query
                    .GroupBy(t => new { t.InsertTime.Year, t.InsertTime.Month })
                    .Select(t => new
                    {
@@ -252,7 +295,11 @@
                        {
                            Month = monthKey,
                            Inbound = stat.Inbound,
                            Outbound = stat.Outbound
                            Outbound = stat.Outbound,
                            Roadway = roadway,
                            RoadwayName = !string.IsNullOrEmpty(roadway) && roadwayNames.ContainsKey(roadway)
                                ? roadwayNames[roadway]
                                : null
                        });
                    }
                    else
@@ -261,7 +308,11 @@
                        {
                            Month = monthKey,
                            Inbound = 0,
                            Outbound = 0
                            Outbound = 0,
                            Roadway = roadway,
                            RoadwayName = !string.IsNullOrEmpty(roadway) && roadwayNames.ContainsKey(roadway)
                                ? roadwayNames[roadway]
                                : null
                        });
                    }
                }
@@ -270,13 +321,9 @@
            }
            catch (Exception ex)
            {
                // 记录异常日志(实际项目中建议使用日志框架)
                // _logger.LogError(ex, "每月统计获取失败");
                return WebResponseContent.Instance.Error($"每月统计获取失败: {ex.Message}");
            }
        }
        /// <summary>
        /// 库存库龄分布
        /// </summary>
@@ -369,5 +416,87 @@
                return WebResponseContent.Instance.Error($"各仓库库存分布获取失败: {ex.Message}");
            }
        }
        /// <summary>
        /// 查询各仓库电池/有货数量和空托盘数量
        /// </summary>
        /// <remarks>
        /// 仓库ID规则:1=高温库, 2=常温库, 3=化成库, 6/7=极卷库
        /// <br/>
        /// 统计规则:
        /// <br/>
        /// - 高温/常温/化成库:统计 电池数量(StockStatus=6) 和 空托盘数量(StockStatus=22)
        /// <br/>
        /// - 极卷库(6/7):统计 有货数量(StockStatus≠22) 和 空托盘数量(StockStatus=22)
        /// <br/>
        /// 通过返回数据中的 StockStatus 和 Count 可以进一步查询明细电池。
        /// </remarks>
        [HttpGet("StockAndTrayCount"), AllowAnonymous]
        public async Task<WebResponseContent> StockAndTrayCount()
        {
            try
            {
                var warehouseIds = new[] { 1, 2, 3, 6, 7 };
                var warehouseNames = new Dictionary<int, string>
        {
            { 1, "高温库" },
            { 2, "常温库" },
            { 3, "化成库" },
            { 6, "极卷库" },
            { 7, "极卷库" }
        };
                var result = new List<object>();
                foreach (var warehouseId in warehouseIds)
                {
                    var warehouseName = warehouseNames.GetValueOrDefault(warehouseId, $"仓库{warehouseId}");
                    if (warehouseId == 6 || warehouseId == 7)
                    {
                        var totalCount = await _db.Queryable<Dt_StockInfo>()
                            .Where(s => s.WarehouseId == warehouseId)
                            .CountAsync();
                        var emptyTrayCount = await _db.Queryable<Dt_StockInfo>()
                            .Where(s => s.WarehouseId == warehouseId && s.StockStatus == (int)StockStatusEmun.空托盘库存)
                            .CountAsync();
                        result.Add(new
                        {
                            WarehouseId = warehouseId,
                            WarehouseName = warehouseName,
                            HasGoodsCount = totalCount - emptyTrayCount,
                            EmptyTrayCount = emptyTrayCount,
                        });
                    }
                    else
                    {
                        var batteryCount = await _db.Queryable<Dt_StockInfo>()
                            .Where(s => s.WarehouseId == warehouseId && s.StockStatus == (int)StockStatusEmun.入库完成)
                            .LeftJoin<Dt_StockInfoDetail>((s, d) => s.Id == d.StockId)
                            .CountAsync();
                        var emptyTrayCount = await _db.Queryable<Dt_StockInfo>()
                            .Where(s => s.WarehouseId == warehouseId && s.StockStatus == (int)StockStatusEmun.空托盘库存)
                            .CountAsync();
                        result.Add(new
                        {
                            WarehouseId = warehouseId,
                            WarehouseName = warehouseName,
                            BatteryCount = batteryCount,
                            EmptyTrayCount = emptyTrayCount,
                        });
                    }
                }
                return WebResponseContent.Instance.OK(null, result);
            }
            catch (Exception ex)
            {
                return WebResponseContent.Instance.Error($"电池和空托盘数量查询失败: {ex.Message}");
            }
        }
    }
}
}