| | |
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// 每日统计
|
| | | /// 每日统计(按巷道号分组,指定仓库)
|
| | | /// </summary>
|
| | | [HttpGet("DailyStats"), AllowAnonymous]
|
| | | public async Task<WebResponseContent> DailyStats([FromQuery] int days = 30)
|
| | | public async Task<WebResponseContent> DailyStats([FromQuery] int days = 10)
|
| | | {
|
| | | try
|
| | | {
|
| | |
| | | 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();
|
| | |
|
| | | // 生成日期范围
|
| | |
| | | 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);
|
| | |
| | | return WebResponseContent.Instance.Error($"每日统计获取失败: {ex.Message}");
|
| | | }
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// 每周统计
|
| | | /// </summary>
|
| | |
| | | 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([FromQuery] int months = 12, string Roadway = null)
|
| | | {
|
| | | try
|
| | | {
|
| | |
| | | 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>
|
| | | {
|
| | | { "FJSC1", "负极卷1号仓库" },
|
| | | { "ZJSC1", "正极卷1号仓库" },
|
| | | { "GWSC1", "高温1号仓库" },
|
| | | { "CWSC1", "常温1号仓库" },
|
| | | { "HCSC1", "分容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
|
| | | {
|
| | |
| | | {
|
| | | Month = monthKey,
|
| | | Inbound = stat.Inbound,
|
| | | Outbound = stat.Outbound
|
| | | Outbound = stat.Outbound,
|
| | | Roadway = Roadway,
|
| | | RoadwayName = !string.IsNullOrEmpty(Roadway) && roadwayNames.ContainsKey(Roadway)
|
| | | ? roadwayNames[Roadway]
|
| | | : null
|
| | | });
|
| | | }
|
| | | else
|
| | |
| | | {
|
| | | Month = monthKey,
|
| | | Inbound = 0,
|
| | | Outbound = 0
|
| | | Outbound = 0,
|
| | | Roadway = Roadway,
|
| | | RoadwayName = !string.IsNullOrEmpty(Roadway) && roadwayNames.ContainsKey(Roadway)
|
| | | ? roadwayNames[Roadway]
|
| | | : null
|
| | | });
|
| | | }
|
| | | }
|
| | |
| | | }
|
| | | catch (Exception ex)
|
| | | {
|
| | | // 记录异常日志(实际项目中建议使用日志框架)
|
| | | // _logger.LogError(ex, "每月统计获取失败");
|
| | |
|
| | | return WebResponseContent.Instance.Error($"每月统计获取失败: {ex.Message}");
|
| | | }
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// 库存库龄分布
|
| | | /// </summary>
|
| | |
| | | var occupiedLocations = occupiedLocationGroups.FirstOrDefault(og => og.WarehouseId == w.WarehouseId)?.OccupiedLocations ?? 0;
|
| | | var emptyLocations = totalLocations - occupiedLocations;
|
| | |
|
| | | var occupiedPercentage = totalLocations > 0 ? Math.Round((double)occupiedLocations / totalLocations * 100, 2) : 0.0;
|
| | | var emptyPercentage = totalLocations > 0 ? Math.Round((double)emptyLocations / totalLocations * 100, 2) : 0.0;
|
| | | var occupiedPercentage = totalLocations > 0 ? Math.Round((double)occupiedLocations / totalLocations * 100, 0) : 0.0;
|
| | | var emptyPercentage = totalLocations > 0 ? Math.Round((double)emptyLocations / totalLocations * 100, 0) : 0.0;
|
| | |
|
| | | return new
|
| | | {
|
| | |
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | } |