1
heshaofeng
2026-01-07 51197dd4ca2a95dc86f11261d255b6cba8b21263
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/BigGreenService/BigGreenService.cs
@@ -1,5 +1,6 @@
using IBigBreenService;
using Microsoft.IdentityModel.Tokens;
using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime;
using SqlSugar;
using System;
using System.Collections.Generic;
@@ -14,6 +15,7 @@
using WIDESEA_Core.BaseRepository;
using WIDESEA_Core.Helper;
using WIDESEA_Model.Models;
using WIDESEA_Model.Models.Basic;
namespace BigGreenService
{
@@ -27,8 +29,9 @@
        private readonly IRepository<Dt_Task_Hty> _taskHtyRepository;
        private readonly IRepository<Dt_Task> _taskRepository;
        private readonly IRepository<Dt_StockInfo> _stockInfoRepository;
        private readonly IRepository<Dt_MaterialExpirationDate> _materialExpirationDateRepository;
        public BigGreenService(IRepository<Dt_StockInfoDetail> stockInfoDetailRepository, IRepository<Dt_OutboundOrder> outBoundOrderRepository, IRepository<Dt_LocationInfo> locationInfoRepository,IRepository<Dt_OutboundOrderDetail> outBoundOrderDetailRepository, IRepository<Dt_InboundOrderDetail> inboundOrderDetailRepository,IRepository<Dt_Task> taskRepository,IRepository<Dt_Task_Hty> taskHtyRepository, IRepository<Dt_StockInfo> stockInfoRepository)
        public BigGreenService(IRepository<Dt_StockInfoDetail> stockInfoDetailRepository, IRepository<Dt_OutboundOrder> outBoundOrderRepository, IRepository<Dt_LocationInfo> locationInfoRepository, IRepository<Dt_OutboundOrderDetail> outBoundOrderDetailRepository, IRepository<Dt_InboundOrderDetail> inboundOrderDetailRepository, IRepository<Dt_Task> taskRepository, IRepository<Dt_Task_Hty> taskHtyRepository, IRepository<Dt_StockInfo> stockInfoRepository, IRepository<Dt_MaterialExpirationDate> materialExpirationDateRepository)
        {
            _stockInfoDetailRepository = stockInfoDetailRepository;
            _outBoundOrderRepository = outBoundOrderRepository;
@@ -38,6 +41,7 @@
            _taskRepository = taskRepository;
            _taskHtyRepository = taskHtyRepository;
            _stockInfoRepository = stockInfoRepository;
            _materialExpirationDateRepository = materialExpirationDateRepository;
        }
        public WebResponseContent GetBigGreenData()
        {
@@ -50,27 +54,28 @@
                (int)OutOrderStatusEnum.出库中,
                (int)OutOrderStatusEnum.未开始
            };
            var unOutBound =_outBoundOrderRepository.Db.Queryable<Dt_OutboundOrder>().Where(x =>targetStatus.Contains(x.OrderStatus)).Count();
            var unOutBound = _outBoundOrderRepository.Db.Queryable<Dt_OutboundOrder>().Where(x => targetStatus.Contains(x.OrderStatus)).Count();
            //计算库位利用率
            var freeLocation =_locationInfoRepository.Db.Queryable<Dt_LocationInfo>().Where(x=>x.LocationStatus==(int)LocationStatusEnum.Free).Count();
            var inStockLocation =_locationInfoRepository.Db.Queryable<Dt_LocationInfo>().Where(x => x.LocationStatus == (int)LocationStatusEnum.InStock || x.LocationStatus == (int)LocationStatusEnum.Pallet).Count();
            var freeLocation = _locationInfoRepository.Db.Queryable<Dt_LocationInfo>().Where(x => x.LocationStatus == (int)LocationStatusEnum.Free).Count();
            var inStockLocation = _locationInfoRepository.Db.Queryable<Dt_LocationInfo>().Where(x => x.LocationStatus == (int)LocationStatusEnum.InStock || x.LocationStatus == (int)LocationStatusEnum.Pallet).Count();
            int totalLocation = freeLocation + inStockLocation;
            decimal locationUtilizationRate = totalLocation == 0
                ? 0
                : Math.Round((decimal)inStockLocation / totalLocation, 4)*100;
                : Math.Round((decimal)inStockLocation / totalLocation, 4) * 100;
            //计算入库任务和出库任务完成数量
            var inboundCount =_taskHtyRepository.Db.Queryable<Dt_Task_Hty>().Where(x => x.TaskType >= 500 && x.TaskType < 900 && x.CreateDate.ToString("yyyy-MM-dd") == DateTime.Now.ToString("yyyy-MM-dd")).Count();
            var outboundCount =_taskHtyRepository.Db.Queryable<Dt_Task_Hty>().Where(x => x.TaskType >= 100 && x.TaskType < 500 && x.CreateDate.ToString("yyyy-MM-dd") == DateTime.Now.ToString("yyyy-MM-dd")).Count();
            var inboundCount = _taskHtyRepository.Db.Queryable<Dt_Task_Hty>().Where(x => x.TaskType >= 500 && x.TaskType < 900 && x.CreateDate.ToString("yyyy-MM-dd") == DateTime.Now.ToString("yyyy-MM-dd")).Count();
            var outboundCount = _taskHtyRepository.Db.Queryable<Dt_Task_Hty>().Where(x => x.TaskType >= 100 && x.TaskType < 500 && x.CreateDate.ToString("yyyy-MM-dd") == DateTime.Now.ToString("yyyy-MM-dd")).Count();
            //计算有货料箱数量
            var inStockPallet = _stockInfoRepository.Db.Queryable<Dt_StockInfo>().Where(x => x.PalletType ==(int) PalletTypeEnum.None && !string.IsNullOrEmpty(x.LocationCode)).Count();
            var inStockPallet = _stockInfoRepository.Db.Queryable<Dt_StockInfo>().Where(x => x.PalletType == (int)PalletTypeEnum.None && !string.IsNullOrEmpty(x.LocationCode)).Count();
            //计算空箱数量
            var freeStockPallet = _stockInfoRepository.Db.Queryable<Dt_StockInfo>().Where(x => x.PalletType == (int)PalletTypeEnum.Empty && !string.IsNullOrEmpty(x.LocationCode)).Count();
            // 4. èŽ·å–è¿‘7日每日出入库明细(核心修改:调用上面的方法)
            var dailyInOutBoundList = Get7DaysDailyInOutBound();
            var nearExpirationList = GetMaterialsNearExpiration();
            //获取作业统计
            var completeTask = SimpleStatistics();
            //任务
@@ -78,7 +83,7 @@
            var bigGreenData = new BigGreenDataDto
            {
                TotalStockQuantity=totalStockQuantity,
                TotalStockQuantity = totalStockQuantity,
                UnOutBoundOrderCount = unOutBound,
                LocationUtilizationRate = locationUtilizationRate,
                DailyInOutBoundList = dailyInOutBoundList,
@@ -87,7 +92,8 @@
                OutboundCount = outboundCount,
                InStockPallet = inStockPallet,
                FreeStockPallet = freeStockPallet,
                CompleteTask = completeTask
                CompleteTask = completeTask,
                NearExpirationList = nearExpirationList
            };
            return WebResponseContent.Instance.OK(data: bigGreenData);
        }
@@ -120,13 +126,12 @@
                })
                .ToList()
                .GroupBy(x => x.Date)
                .ToDictionary(k => k.Key , g => g.Sum(x => (decimal?)x.OverOutQuantity) ?? 0); // è½¬ä¸ºå­—典方便匹配
                .ToDictionary(k => k.Key, g => g.Sum(x => (decimal?)x.OverOutQuantity) ?? 0); // è½¬ä¸ºå­—典方便匹配
            // 3. æŸ¥è¯¢æ¯æ—¥å…¥åº“明细(按日期分组)
            var dailyInboundList = _inboundOrderDetailRepository.Db
                .Queryable<Dt_InboundOrderDetail>()
                .Where(x => x.CreateDate != null // è¿‡æ»¤ç©ºæ—¥æœŸ
                         && x.CreateDate >= startDate
                .Where(x => x.CreateDate >= startDate
                         && x.CreateDate < endDate.AddDays(1))
                .Select(x => new
                {
@@ -134,7 +139,7 @@
                    x.OverInQuantity
                })
                .ToList()
                .GroupBy(x=>x.Date)
                .GroupBy(x => x.Date)
                .ToDictionary(k => k.Key, g => g.Sum(x => (decimal?)x.OverInQuantity) ?? 0); // è½¬ä¸ºå­—典方便匹配
            // 4. åˆå¹¶æ¯æ—¥æ•°æ®ï¼ˆç¡®ä¿7天日期完整,无数据补0)
@@ -143,7 +148,7 @@
                Date = date,
                DailyOutboundQuantity = dailyOutboundList.ContainsKey(date) ? dailyOutboundList[date] : 0,
                DailyInboundQuantity = dailyInboundList.ContainsKey(date) ? dailyInboundList[date] : 0,
            }).ToList();
            return dailyInOutBoundList;
@@ -159,7 +164,7 @@
                    (int)t.TaskType >= 100 && (int)t.TaskType <= 299 ? "出库" :
                    (int)t.TaskType >= 500 && (int)t.TaskType <= 699 ? "入库" : "其他"
                )
                .Where(g => g.Key == "出库" || g.Key == "入库")
                .Where(g => g.Key == "出库" || g.Key == "入库")
                .Select(g => new SimpleStatisticsDTO
                {
                    TaskType = g.Key,
@@ -233,6 +238,8 @@
            public int FreeStockPallet { get; set; }
            public List<SimpleStatisticsDTO> CompleteTask { get; set; }
            public NearExpirationDTO NearExpirationList { get; set; }
        }
        /// <summary>
@@ -263,6 +270,84 @@
            public int Count { get; set; }
        }
        public class NearExpirationDTO
        {
            public int DaysToExpiration { get; set; }
            public List<Dt_StockInfoDetail> Details { get; set; }
            public string LocationCode { get; set; }
            public string PalletCode { get; set; }
        }
        ///<summary>
        ///获取近30天要过期的物料
        /// </summary>
        public NearExpirationDTO GetMaterialsNearExpiration()
        {
            // åˆå§‹åŒ–返回DTO
            var resultDTO = new NearExpirationDTO
            {
                Details = new List<Dt_StockInfoDetail>(),
                LocationCode = string.Empty,
                PalletCode = string.Empty,
                DaysToExpiration = 0 // åˆå§‹åŒ–天数
            };
            DateTime currentTime = DateTime.Now;
            DateTime thirtyDaysLater = currentTime.AddDays(30);
            // ç­›é€‰30天内过期的库存明细
            var nearExpirationList = _stockInfoDetailRepository.Db.Queryable<Dt_StockInfoDetail>()
                .Where(x => (x.ValidDate.Value - x.CreateDate).TotalDays <= 30)
                .ToList();
            // æ— ç¬¦åˆæ¡ä»¶çš„æ˜Žç»†ï¼Œç›´æŽ¥è¿”回
            if (!nearExpirationList.Any())
            {
                return resultDTO;
            }
            var firstStockId = nearExpirationList.First().StockId;
            var stock = _stockInfoRepository.Db.Queryable<Dt_StockInfo>()
                .First(x => x.Id == firstStockId);
            if (stock == null)
            {
                return resultDTO;
            }
            resultDTO.LocationCode = stock.LocationCode;
            resultDTO.PalletCode = stock.PalletCode;
            int minDaysToExpiration = int.MaxValue;
            foreach (var detail in nearExpirationList)
            {
                TimeSpan totalDaysToExpiration = detail.ValidDate.Value - detail.CreateDate;
                double remainingDays = totalDaysToExpiration.TotalDays;
                int daysToExpiration = (int)Math.Ceiling(Math.Max(0, remainingDays));
                if (daysToExpiration < minDaysToExpiration)
                {
                    minDaysToExpiration = daysToExpiration;
                }
                resultDTO.Details.Add(detail);
            }
            resultDTO.DaysToExpiration = minDaysToExpiration;
            return resultDTO;
        }
    }
}