huangxiaoqiang
昨天 7f3a2e67f82c2d286e902b028b422bf07e9aacb6
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_StorageTaskServices/Task/Partial/Dt_TaskService.cs
@@ -1,10 +1,11 @@
using Masuit.Tools;
using Mapster;
using Masuit.Tools;
using SixLabors.Fonts.Tables.AdvancedTypographic;
using SqlSugar;
using WIDESEA_Common.CustomModels;
using WIDESEA_Core.Const;
using WIDESEA_DTO.MOM;
using WIDESEA_DTO.WMS;
using WIDESEA_Model.Models.Basic;
using WIDESEAWCS_Model.Models;
using WIDESEAWCS_QuartzJob.Models;
@@ -184,6 +185,12 @@
            if (!result.Success)
            {
                List<string> strings = new List<string>() { "2036","2038","2084","2086"};
                if (input.Position.Contains(strings))
                {
                    Console.WriteLine($"{result.MOMMessage}");
                    return null;
                }
                var taskNG = new Dt_Task
                {
                    CurrentAddress = input.Position,
@@ -204,6 +211,7 @@
                    ProcessCode = result.ProcessCode,
                };
                return taskNG;
            }
            if (result.SerialNos.Count <= 0)
@@ -587,17 +595,50 @@
    #region 直接出库任务完成
    public async Task<WebResponseContent> CompleteInToOutTaskAsync(Dt_Task task)
    public async Task<WebResponseContent> CompleteInToOutTaskAsync(Dt_Task task,DtStockInfo stock)
    {
        WebResponseContent content = new WebResponseContent();
        try
        {
            //添加历史
            var taskHty = CreateHistoricalTask(task);
            // 添加历史任务
            var isTaskHtyAdd = await _task_HtyRepository.AddDataAsync(taskHty) > 0;
            //删除任务
            BaseDal.DeleteData(task);
            DtStockInfo_Hty stockInfo_Hty = null;
            if (stock != null)
            {
                stockInfo_Hty = stock.Adapt<DtStockInfo_Hty>();
                stockInfo_Hty.ModifyDate = DateTime.Now;
            }
            var taskHty = task.Adapt<Dt_Task_Hty>();
            taskHty.FinishTime = DateTime.Now;
            taskHty.OperateType = App.User.UserName != null ? (int)OperateTypeEnum.人工完成 : (int)OperateTypeEnum.自动完成;
            taskHty.Creater = App.User.UserName != null ? App.User.UserName : "System";
            var location = _locationRepository.QueryFirst(x => x.LocationCode == task.SourceAddress && x.RoadwayNo == task.Roadway);
            if(location != null)
            {
                int lastStatus = location.LocationStatus;
                location.LocationStatus = (int)LocationEnum.Free;
                _locationStatusChangeRecordRepository.AddLocationStatusChangeRecord(location, lastStatus, (int)StatusChangeTypeEnum.AutomaticDelivery, task.TaskNum);
            }
            task.TaskState = (int)TaskOutStatusEnum.OutFinish;
            // 事务处理
            await _unitOfWorkManage.UseTranAsync(async () =>
            {
                if (stockInfo_Hty != null)
                {
                    await DeleteStockInfoAsync(stock.Id);
                    await DeleteStockInfoDetailsAsync(stock.StockInfoDetails);
                    await AddStockInfoHtyAsync(stockInfo_Hty);
                }
                if (location != null)
                {
                    await UpdateLocationAsync(location);
                }
                await DeleteTaskAsync(task.TaskId);
                await AddTaskHtyAsync(taskHty);
            });
            return content.OK();
        }
@@ -1036,6 +1077,7 @@
        WebResponseContent content = new WebResponseContent();
        try
        {
            LogFactory.GetLog($"包装请求出库任务").Info(true, $"【请求参数】:【{JsonConvert.SerializeObject(json)}】{Environment.NewLine}{Environment.NewLine}");
            Dt_StationManager station = _stationManagerRepository.QueryFirst(x => x.stationChildCode == json.Position && x.stationType == 12 && x.stationArea == "Call");
            if (station == null) { throw new Exception($"未找到包装站台信息,请检查传入参数{json.Position}"); }
@@ -1086,7 +1128,6 @@
                                .OrderBy(x => x.OutboundTime)
                                .FirstAsync();
            if (stockInfo == null) throw new Exception($"库内{station.productLine}无满足条件的库存可出库");
            DtLocationInfo locationInfo = _locationRepository.QueryFirst(x => x.AreaId == 5 && x.LocationCode == stockInfo.LocationCode);
@@ -1108,14 +1149,12 @@
                SourceAddress = stockInfo.LocationCode,
                TaskState = (int)TaskOutStatusEnum.OutNew,
                TaskType = (int)TaskOutboundTypeEnum.Outbound,
                TaskNum = await BaseDal.GetTaskNo(),
                TaskNum = BaseDal.GetTaskNo().Result,
                Creater = "System",
                ProductionLine = stockInfo.ProductionLine,
                ProcessCode = stockInfo.ProcessCode,
            };
            WMSTaskDTO taskDTO = CreateTaskDTO(task);
            int lastStatus = locationInfo.LocationStatus;
            BaseDal.AddData(task);
@@ -1126,11 +1165,15 @@
            _locationStatusChangeRecordRepository.AddLocationStatusChangeRecord(stockInfo.LocationInfo, lastStatus, (int)StatusChangeTypeEnum.AutomaticDelivery, task.TaskNum);
            LogFactory.GetLog($"包装请求出库任务").Info(true, $"【返回参数】:【{JsonConvert.SerializeObject(taskDTO)}】{Environment.NewLine}{Environment.NewLine}");
            return content.OK(data: taskDTO);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"CW3至包装出库异常:{ex.ToString()}");
            LogFactory.GetLog($"包装请求出库任务").Info(true, $"【异常】:【{ex.Message}】{Environment.NewLine}【{ex.StackTrace}】{Environment.NewLine}{Environment.NewLine}");
            return content.Error($"失败:{ex.Message}");
        }
    }
@@ -1139,37 +1182,37 @@
    #region 火警出库
    public WebResponseContent EmergencyTask(object obj)
    public WebResponseContent EmergencyTask(Object obj)
    {
        WebResponseContent content = new WebResponseContent();
        var emergencyTask = new DTSEmergencyTask();
        try
        {
            Console.WriteLine($"火警参数:{obj.ToString()}");
            emergencyTask = JsonConvert.DeserializeObject<DTSEmergencyTask>(obj.ToString());
            if (emergencyTask == null) throw new Exception("火警参数为空");
            string[] strings = emergencyTask.LocationCode.Split("-");
            string[] Roadways = strings[0].Select(x => x.ToString()).ToArray();
            string Roadway = string.Empty;
            switch (Roadways[0])
            {
                case "J":
                    Roadway = "JZSC" + Roadways[1];
                        break;
                case "G":
                    Roadway = "GWSC" + Roadways[1];
                    break;
                case "C":
                    Roadway = "CWSC" + Roadways[1];
                    break;
                default: throw new Exception("未识别库位编码");
            }
            string Roadway = strings[0];
            //switch (Roadways[0])
            //{
            //    case "J":
            //        Roadway = "JZSC" + Roadways[1];
            //        break;
            //    case "G":
            //        Roadway = "GWSC" + Roadways[1];
            //        break;
            //    case "C":
            //        Roadway = "CWSC" + Roadways[1];
            //        break;
            //    default: throw new Exception("未识别库位编码");
            //}
            int Row = Convert.ToInt16(strings[1]);
            int Column= Convert.ToInt16(strings[2]);
            int Layer= Convert.ToInt16(strings[3]);
            if (!strings[0].Contains("SC")) throw new Exception("未知库区");
            for (int i = 0; i < 2; i++)
            {
                DtLocationInfo locationInfo = _locationRepository.QueryFirst(x => x.Row == Convert.ToInt16(strings[1]) && x.Column == Convert.ToInt16(strings[2]) && x.Layer == (i == 0 ? Convert.ToInt16(strings[3]) * 2 - 1 : Convert.ToInt16(strings[3]) * 2) && x.RoadwayNo == Roadway);
                DtLocationInfo locationInfo = _locationRepository.QueryFirst(x => x.Row == Row && x.Column == Column && x.Layer == (i == 0 ? Layer - 1 : Layer) && x.RoadwayNo == Roadway);
                if (locationInfo == null)
                {
                    throw new Exception("未知库位");
@@ -1236,16 +1279,19 @@
                    TaskType = task.TaskType,
                };
                List<WMSTaskDTO> taskDTOs = new List<WMSTaskDTO>();
                taskDTOs.Add(taskDTO);
                var configs = _configService.GetConfigsByCategory(CateGoryConst.CONFIG_SYS_IPAddress);
                var ipAddress = configs.FirstOrDefault(x => x.ConfigKey == SysConfigConst.WCSIPAddress)?.ConfigValue;
                var ReceiveByWMSTask = configs.FirstOrDefault(x => x.ConfigKey == SysConfigConst.ReceiveByWMSTask)?.ConfigValue;
                var ReceiveByWMSTask = configs.FirstOrDefault(x => x.ConfigKey == SysConfigConst.ReceiveWMSTask)?.ConfigValue;
                if (ReceiveByWMSTask == null || ipAddress == null)
                {
                    throw new Exception("WMS IP 未配置");
                }
                var wmsIpAddrss = ipAddress + ReceiveByWMSTask;
                var respon = HttpHelper.Post(wmsIpAddrss, JsonConvert.SerializeObject(taskDTO));
                var respon = HttpHelper.Post(wmsIpAddrss, JsonConvert.SerializeObject(taskDTOs));
                if (respon != null)
                {
                    WebResponseContent respone = JsonConvert.DeserializeObject<WebResponseContent>(respon.ToString());
@@ -1442,20 +1488,7 @@
            var now = DateTime.Now;
            var startOfDay = new DateTime(now.Year, now.Month, now.Day);
            var endOfDay = startOfDay.AddDays(1);
            var filteredItems = _stockInfoRepository.Db.Queryable<DtStockInfo>()
                                .Where(x => x.OutboundTime >= startOfDay && x.OutboundTime < endOfDay && x.IsFull)
                                .Includes(x => x.StockInfoDetails)
                                .ToList();
            var result = filteredItems
                .GroupBy(x => x.AreaCode)
                .Select(g => new GroupedStockInfo
                {
                    AreaCode = g.Key,
                    TotalQuantity = g.Sum(item => item.StockInfoDetails?.Count ?? 0),
                    Items = g.ToList()
                })
                .ToList();
            var result = _stockInfoRepository.Db.Queryable<DtStockInfo>().ToList();
            return content.OK(data: result);
        }
        catch (Exception ex)
@@ -1517,4 +1550,160 @@
    }
    #endregion
    public WebResponseContent GetTimeout()
    {
        WebResponseContent content = new WebResponseContent();
        try
        {
            var now = DateTime.Now;
            // 使用Subtract方法
            var threeHoursAgo = now.Subtract(TimeSpan.FromHours(3));
            List<DtStockInfo> dtStocks = _stockInfoRepository.Db.Queryable<DtStockInfo>()
                               .Where(x => x.OutboundTime < threeHoursAgo).ToList();
            return content.OK1(total1:dtStocks.Count, data: dtStocks);
        }
        catch (Exception ex)
        {
            return content.Error(ex.Message);
        }
    }
    public WebResponseContent Getproductionstatistics()
    {
        WebResponseContent content = new WebResponseContent();
        try
        {
            var now = DateTime.Now;
            var thirtyDaysAgo = now.AddDays(-30);
            var roadwayMappings = new Dictionary<string, string> {
    { "JZ", "静置库" },
    { "CH", "陈化库" },
    { "FR", "分容库" },
    { "GW", "高温库" },
    { "CW", "常温库" }
};
            var roadwayKeys = roadwayMappings.Keys.ToArray();
            var taskTypes = new[] { 100, 104, 200, 204 };
            var taskHty = _task_HtyRepository.Db.Queryable<Dt_Task_Hty>()
                .Where(it =>
                    it.CreateDate >= thirtyDaysAgo &&
                    it.CreateDate <= now &&
                    taskTypes.Contains(it.TaskType) &&
                    roadwayKeys.Any(rk => it.Roadway.Contains(rk)))
                .ToList()
                .Select(t => new {
                    OriginalRoadway = t.Roadway,
                    RoadwayKey = roadwayKeys.FirstOrDefault(rk => t.Roadway.Contains(rk)),
                    TaskType = t.TaskType,
                    CreateDate = t.CreateDate
                })
                .Where(t => t.RoadwayKey != null)
                .GroupBy(t => new {
                    RoadwayKey = t.RoadwayKey,
                    Date = t.CreateDate.Date,
                    Hour = t.CreateDate.Hour
                })
                .OrderByDescending(group => group.Key.Date)
                .ThenByDescending(group => group.Key.Hour)
                .Select(group => new TaskHourData
                {
                    Hour = $"{group.Key.Date:yyyy/M/d} {(group.Key.Hour == 23 ? "23:00-24:00" : $"{group.Key.Hour}:00-{group.Key.Hour + 1}:00")}",
                    Roadway = roadwayMappings[group.Key.RoadwayKey],
                    TaskType100Count = group.Count(t => t.TaskType == 100),
                    TaskType104Count = group.Count(t => t.TaskType == 104),
                    TaskType200Count = group.Count(t => t.TaskType == 200),
                    TaskType204Count = group.Count(t => t.TaskType == 204)
                })
                .ToList();
            // 按日期和库位分组,找出每天的最后一个小时
            var dailyLastHours = taskHty
                .GroupBy(item => new {
                    Date = DateTime.Parse(item.Hour.Split(' ')[0]),
                    item.Roadway
                })
                .Select(group => new {
                    Date = group.Key.Date,
                    Roadway = group.Key.Roadway,
                    LastHour = group.Max(item => int.Parse(item.Hour.Split(' ')[1].Split(':')[0]))
                })
                .ToList();
            // 生成汇总数据(调整Hour格式为"日期+日汇总")
            var summaryItems = dailyLastHours
                .Select(dailyLastHour => {
                    // 找到该日期该库位的所有小时数据
                    var dailyItems = taskHty
                        .Where(item =>
                            DateTime.Parse(item.Hour.Split(' ')[0]) == dailyLastHour.Date &&
                            item.Roadway == dailyLastHour.Roadway)
                        .ToList();
                    return new TaskHourData
                    {
                        Hour = $"{dailyLastHour.Date:yyyy/M/d}日汇总", // 修改Hour格式
                        Roadway = dailyLastHour.Roadway,
                        TaskType100Count = dailyItems.Sum(item => item.TaskType100Count),
                        TaskType104Count = dailyItems.Sum(item => item.TaskType104Count),
                        TaskType200Count = dailyItems.Sum(item => item.TaskType200Count),
                        TaskType204Count = dailyItems.Sum(item => item.TaskType204Count),
                        IsSummary = true
                    };
                })
                .ToList();
            // 将汇总数据添加到结果中
            taskHty = taskHty.Concat(summaryItems).ToList();
            // 调整排序逻辑:先按日期降序,再按是否汇总(汇总在前),最后按小时降序
            taskHty = taskHty
                .OrderByDescending(item => {
                    var datePart = item.Hour.Contains("日汇总")
                ? item.Hour.Split("日汇总")[0]
                : item.Hour.Split(' ')[0];
                    return DateTime.Parse(datePart);
                })
            .ThenByDescending(item => item.IsSummary) // 汇总数据排在前面
            .ThenByDescending(item => {
                if (!item.IsSummary && item.Hour.Contains(' '))
                {
                    return int.Parse(item.Hour.Split(' ')[1].Split(':')[0]);
                }
                return 0;
            })
            .ToList();
            return content.OK1(total1: taskHty.Count, data: taskHty);
        }
        catch (Exception ex)
        {
            return content.Error(ex.Message);
        }
    }
    public WebResponseContent GetLocationStatus()
    {
        WebResponseContent content = new WebResponseContent();
        try
        {
            List<DtLocationInfo> LocationList = _locationRepository.Db.Queryable<DtLocationInfo>().Where(x => x.LocationStatus != 2 && x.LocationStatus != 0).ToList();
            return content.OK1(total1: LocationList.Count, data: LocationList);
        }
        catch (Exception ex)
        {
            return content.Error(ex.Message);
        }
    }
}
internal class TaskHourData
{
    public string Hour { get; set; }
    public string Roadway { get; set; }
    public int TaskType100Count { get; set; }
    public int TaskType104Count { get; set; }
    public int TaskType200Count { get; set; }
    public int TaskType204Count { get; set; }
    public bool IsSummary { get; set; } = false;
}