using Masuit.Tools; using SqlSugar; using WIDESEA_Common.CustomModels; using WIDESEA_Core.Const; using WIDESEA_DTO.MOM; using WIDESEA_DTO.WMS; using WIDESEAWCS_Model.Models; using WIDESEAWCS_QuartzJob.Models; namespace WIDESEA_StorageTaskServices; public partial class Dt_TaskService : ServiceBase, IDt_TaskService { #region 请求任务入库 /// /// 请求入库 /// /// 请求模型 /// 包含任务信息的响应内容 public async Task RequestInTask(RequestTaskDto input) { // 创建一个WebResponseContent对象 WebResponseContent content = new WebResponseContent(); try { // 调用BaseDal.QueryFirstAsync方法,查询任务 var task = await BaseDal.QueryFirstAsync(x => x.PalletCode == input.PalletCode); if (task != null) { //if (task.TaskState == (int)TaskInStatusEnum.InNew) { // 创建WMS任务 //WMSTaskDTO taskDTO = new WMSTaskDTO() //{ // TaskNum = task.TaskNum.Value, // Grade = 1, // PalletCode = task.PalletCode, // RoadWay = task.Roadway, // SourceAddress = task.SourceAddress, // TargetAddress = task.TargetAddress, // TaskState = task.TaskState.Value, // Id = 0, // TaskType = task.TaskType, // ProductionLine = task.ProductionLine, //}; WMSTaskDTO taskDTO = CreateTaskDTO(task); return content.OK(data: taskDTO); } } // 调用CreateNewTask方法,创建新任务 content = await CreateNewTask(input); } catch (Exception err) { // 如果发生异常,则调用content.Error方法,记录错误信息,并输出错误信息 content.Error(err.Message); Console.WriteLine(err.Message); } // 返回content return content; } /// /// /// /// 请求参数 /// 实框空框标识 /// private async Task CreateNewTask(RequestTaskDto input) { try { WebResponseContent content = new WebResponseContent(); var stationinfo = _stationManagerRepository.QueryFirst(x => x.stationChildCode == input.Position); if (stationinfo == null) throw new Exception("未知站台"); if (stationinfo.stationType != 7) { if (input.PalletCode == null || input.PalletCode.Trim() == "") return content.Error($"【{stationinfo.remark}】托盘条码为空"); } var task = await CreateNewTaskByStation(input, stationinfo); // 尝试添加新任务 if (task == null) return content.Error(); var taskId = await BaseDal.AddDataAsync(task); bool isResult = taskId > 0; if (isResult) { // 创建WMS任务 WMSTaskDTO taskDTO = new WMSTaskDTO() { TaskNum = task.TaskNum.Value, Grade = task.Grade.Value, PalletCode = task.PalletCode, RoadWay = task.Roadway, SourceAddress = task.SourceAddress, TargetAddress = task.TargetAddress, TaskState = task.TaskState.Value, Id = 0, TaskType = task.TaskType, ProductionLine = task.ProductionLine }; content.OK(data: taskDTO); } else content.Error("添加任务失败"); return content; } catch (Exception ex) { throw new Exception(ex.Message); } } /// /// 根据请求参数和站台 做不同任务处理 /// /// /// /// /// private async Task CreateNewTaskByStation(RequestTaskDto input, Dt_StationManager stationManager) { try { Dt_Task task = null; switch (stationManager.stationType) { case 6: case 1: task = await CreateInTaskAsync(input, stationManager); break; //case 2: case 3: //异常排出给WCS处理 //case 4: case 5: task = await CreateInToOutTaskAsync(input, stationManager); break; case 7: task = await CreateEmptyOutTaskAsync(input, stationManager); break; case 15: task = await CheckAbnormalTaskAsync(input, stationManager); break; default: throw new Exception("未知站台类型"); } return task; } catch (Exception ex) { throw new Exception(ex.Message); } } #region 直接出库任务 private async Task CreateInToOutTaskAsync(RequestTaskDto input, Dt_StationManager stationManager) { try { //if (stationManager.stationType != 5) throw new Exception("错误的调取"); input.EquiCodeMOM = "24MEJQ11-1006-1"; // 创建一个TrayCellsStatusDto对象,并赋值 TrayCellsStatusDto trayCells = new TrayCellsStatusDto() { Software = "WMS", TrayBarcode = input.PalletCode, //EquipmentCode = "EQ_CWJZ01" EquipmentCode = input.EquiCodeMOM }; // 调用GetTrayCellStatusAsync方法,获取整盘电芯 WebResponseContent content = await GetTrayCellStatusAsync(trayCells); // 如果状态为false,则返回content if (!content.Status) throw new Exception(content.Message); // 组盘信息 // 将content.Data转换为ResultTrayCellsStatus对象 var result = JsonConvert.DeserializeObject(content.Data.ToString()); if (!result.Success) { var taskNG = new Dt_Task { CurrentAddress = input.Position, Grade = 1, Roadway = input.Roadways, TargetAddress = stationManager.stationNGLocation, Dispatchertime = DateTime.Now, MaterialNo = "", NextAddress = stationManager.stationNGChildCode, OrderNo = null, PalletCode = input.PalletCode, SourceAddress = stationManager.stationLocation, TaskState = (int)TaskInStatusEnum.Line_InFinish, TaskType = (int)TaskOutboundTypeEnum.InToOut, TaskNum = await BaseDal.GetTaskNo(), Creater = "System", ProductionLine = result.ProductionLine, ProcessCode = result.ProcessCode, }; return taskNG; } if (result.SerialNos.Count <= 0) { ConsoleHelper.WriteErrorLine(result.MOMMessage); if (stationManager.stationType != 3) { var taskNG = new Dt_Task { CurrentAddress = input.Position, Grade = 3, Roadway = input.Roadways, TargetAddress = stationManager.stationNGLocation, Dispatchertime = DateTime.Now, MaterialNo = "", NextAddress = stationManager.stationNGChildCode, OrderNo = null, PalletCode = input.PalletCode, SourceAddress = stationManager.stationLocation, TaskState = (int)TaskInStatusEnum.Line_InFinish, TaskType = (int)TaskOutboundTypeEnum.InToOut, TaskNum = await BaseDal.GetTaskNo(), Creater = "System" }; return taskNG; } else { //无电芯 → 当空框? 还是返回异常? return null; } } // 处理异常电芯情况 //var serialNosError = result.SerialNos.Where(x => x.SerialNoStatus != 1 && x.SerialNoStatus != 4).ToList(); //if (serialNosError.Count > 0) //{ // if (stationManager.stationType != 3) // { // var taskNG = new Dt_Task // { // CurrentAddress = input.Position, // Grade = 1, // Roadway = input.Roadways, // TargetAddress = stationManager.stationNGLocation, // Dispatchertime = DateTime.Now, // MaterialNo = "", // NextAddress = stationManager.stationNGChildCode, // OrderNo = null, // PalletCode = input.PalletCode, // SourceAddress = stationManager.stationLocation, // TaskState = (int)TaskInStatusEnum.Line_InFinish, // TaskType = (int)TaskOutboundTypeEnum.InToOut, // TaskNum = await BaseDal.GetTaskNo(), // Creater = "System", // ProductionLine = result.ProductionLine, // ProcessCode = result.ProcessCode, // }; // return taskNG; // } // else // { // Console.WriteLine($"站台{stationManager.stationChildCode}MOM返回电芯异常:{result.MOMMessage}"); // return null; // } //} //else //{ // throw new Exception($"站台{stationManager.stationChildCode}MOM返回电芯异常:{result.MOMMessage}"); //} var targetStation = _stationManagerRepository.QueryFirst(x => x.stationPLC == stationManager.stationPLC && x.Roadway == stationManager.Roadway && x.stationType == 2); var task = new Dt_Task { CurrentAddress = input.Position, Grade = 3, Roadway = input.Roadways, TargetAddress = targetStation.stationLocation, Dispatchertime = DateTime.Now, MaterialNo = "", NextAddress = input.Roadways, OrderNo = null, PalletCode = input.PalletCode, SourceAddress = stationManager.stationLocation, TaskState = (int)TaskInStatusEnum.Line_InFinish, TaskType = (int)TaskOutboundTypeEnum.InToOut, TaskNum = await BaseDal.GetTaskNo(), Creater = "System", ProductionLine = result.ProductionLine, ProcessCode = result.ProcessCode, }; return task; } catch (Exception ex) { throw new Exception(ex.Message); } } #endregion 直接出库任务 #region 入库任务 private async Task CreateInTaskAsync(RequestTaskDto input, Dt_StationManager stationManager) { if (stationManager.stationType != 1 && stationManager.stationType != 6) throw new Exception("错误的调取"); DtLocationInfo locationInfo = null; if (stationManager.stationType == 1 && stationManager.Roadway.Contains("FR")) { locationInfo = await RequestLocation(input, true); } else { locationInfo = await RequestLocation(input); } //DtLocationInfo locationInfo = await RequestLocation(input); if (locationInfo == null) throw new Exception("库位已满"); // 创建一个TrayCellsStatusDto对象,并赋值 TrayCellsStatusDto trayCells = new TrayCellsStatusDto() { Software = "WMS", TrayBarcode = input.PalletCode, //EquipmentCode = "EQ_CWJZ01" EquipmentCode = input.EquiCodeMOM }; // 调用GetTrayCellStatusAsync方法,获取整盘电芯 WebResponseContent content = await GetTrayCellStatusAsync(trayCells); // 如果状态为false,则返回content if (!content.Status) throw new Exception(content.Message); // 将content.Data转换为ResultTrayCellsStatus对象 var result = JsonConvert.DeserializeObject(content.Data.ToString()); if (stationManager.stationType == 6 && result.ProductionLine.IsNullOrEmpty()) { ConsoleHelper.WriteErrorLine($"当前托盘无产线,联系MOM添加产线"); throw new Exception("当前托盘无产线,联系MOM添加产线"); } if (stationManager.stationType == 1) { #region if (result.SerialNos.Count <= 0) { ConsoleHelper.WriteErrorLine(result.MOMMessage); var taskNG = new Dt_Task { CurrentAddress = input.Position, Grade = 1, Roadway = input.Roadways, TargetAddress = stationManager.stationNGLocation, Dispatchertime = DateTime.Now, MaterialNo = "", NextAddress = stationManager.stationNGChildCode, OrderNo = null, PalletCode = input.PalletCode, SourceAddress = stationManager.stationLocation, TaskState = (int)TaskInStatusEnum.Line_InFinish, TaskType = (int)TaskOutboundTypeEnum.InToOut, TaskNum = await BaseDal.GetTaskNo(), Creater = "System", ProductionLine = result.ProductionLine, ProcessCode = result.ProcessCode, }; return taskNG; } //Console.WriteLine(result); //// TODO 获取本地料框属性与整盘电芯属性获取的值进行对比,如果一致则继续,否则返回错误信息 ////var productions = await _productionRepository.QueryDataAsync(x => result.TrayBarcodePropertys.Select(x => x.TrayBarcodeProperty).ToList().Contains(x.TrayBarcodeProperty)); ////if (productions.Count <= 0) //// return content.Error("料框属性不存在"); //// 调用CreateBoxingInfo方法,创建组盘信息 var boxing = CreateBoxingInfo(result, input.PalletCode); if (boxing == null) throw new Exception("组盘失败"); //// 调用GetProcessApplyAsync方法,获取工艺路线 //ProcessApplyDto process = await GetProcessApplyAsync(input, result); //// 如果process为null,则返回content //if (process == null) return content; //// 调用_processApplyService.GetProcessApplyAsync方法,获取工艺申请 //content = await _processApplyService.GetProcessApplyAsync(process); //// 如果状态为false,则返回null //if (!content.Status) return content.Error("工艺申请失败"); ////// 调用GetProcessResponseAsync方法,获取工艺响应 ////var processResponse = await GetProcessResponseAsync(process, input.Position); var isBox = await _boxingInfoRepository.AddDataNavAsync(boxing); #endregion 入库任务 } var task = new Dt_Task { CurrentAddress = input.Position, Grade = 1, Roadway = input.Roadways, TargetAddress = locationInfo.LocationCode, Dispatchertime = DateTime.Now, MaterialNo = "", NextAddress = input.Roadways, OrderNo = null, PalletCode = input.PalletCode, SourceAddress = stationManager.stationLocation, TaskState = (int)TaskInStatusEnum.Line_InFinish, TaskType = stationManager.stationType == 1 ? (int)TaskInboundTypeEnum.Inbound : (int)TaskInboundTypeEnum.InTray, TaskNum = await BaseDal.GetTaskNo(), Creater = "System", ProductionLine = result.ProductionLine, ProcessCode = result.ProcessCode, }; int lastStatus = locationInfo.LocationStatus; ConsoleHelper.WriteSuccessLine($"修改前:" + lastStatus.ToString()); locationInfo.LocationStatus = (int)LocationEnum.FreeDisable; ConsoleHelper.WriteSuccessLine($"修改后:" + locationInfo.LocationStatus.ToString()); await UpdateLocationAsync(locationInfo); _locationStatusChangeRecordRepository.AddLocationStatusChangeRecord(locationInfo, lastStatus, (int)StatusChangeTypeEnum.AutomaticStorage, task.TaskNum); return task; } #endregion 请求任务入库 #region 库位分配 #region 获取货位 /// /// /// /// 请求参数 /// 是否未检测库位类型 /// private async Task RequestLocation(RequestTaskDto requestTask, bool isCheckRequest = false) { try { List locations; if (isCheckRequest) { locations = await _locationRepository.QueryDataAsync(x => x.LocationStatus == (int)LocationEnum.Free && x.RoadwayNo == requestTask.Roadways && x.EnalbeStatus == 1 && x.LocationType == 2 && x.Remark == "1"); } else { locations = await _locationRepository.QueryDataAsync(x => x.LocationStatus == (int)LocationEnum.Distribute && x.RoadwayNo == requestTask.Roadways && x.EnalbeStatus == 1 && x.LocationType == 1); if (locations.IsNullOrEmpty()) { locations = await _locationRepository.QueryDataAsync(x => x.LocationStatus == (int)LocationEnum.Free && x.RoadwayNo == requestTask.Roadways && x.EnalbeStatus == 1 && x.LocationType == 1); } } if (locations == null) { return null; } return locations.OrderBy(x => x.Layer).ThenBy(x => x.Column).ThenBy(x => x.Row).FirstOrDefault(); } catch (Exception err) { Console.WriteLine(err.Message.ToString()); return null; } } #endregion 获取货位 #region 异常口入库获取库位 private async Task RequestLocationByAbnormal(RequestTaskDto requestTask, bool isCheckRequest = false) { try { List locations; if (isCheckRequest) { locations = await _locationRepository.QueryDataAsync(x => x.LocationStatus == (int)LocationEnum.Free && x.RoadwayNo == requestTask.Roadways && x.EnalbeStatus == 1 && x.LocationType == 2 && x.Remark == "1"); } else { locations = await _locationRepository.QueryDataAsync(x => x.LocationStatus == (int)LocationEnum.Free && x.RoadwayNo == requestTask.Roadways && x.EnalbeStatus == 1 && x.LocationType == 1); } if (locations == null) { return null; } return locations.OrderBy(x => x.Layer).ThenBy(x => x.Column).ThenBy(x => x.Row).FirstOrDefault(); } catch (Exception err) { Console.WriteLine(err.Message.ToString()); return null; } } #endregion 异常口入库获取库位 #endregion 库位分配 // 获取工艺申请 private Task GetProcessApplyAsync(RequestTaskDto input, ResultTrayCellsStatus content) { // 创建一个ProcessApplyDto对象,并赋值 return Task.FromResult(new ProcessApplyDto() { EquipmentCode = input.EquiCodeMOM, Software = "WMS", //WipOrderNo = result.BindCode," SerialNos = content.SerialNos.Select(item => new SerialNos { SerialNo = item.SerialNo }).ToList() }); } #endregion 请求任务入库 #region 创建空框出库任务 public async Task CreateEmptyOutTaskAsync(RequestTaskDto input, Dt_StationManager stationManager) { try { if (stationManager.stationType != 7) throw new Exception("错误的调取"); // 从缓存中获取库存信息 //IDictionary? stockInfos = _simpleCacheService.HashGetAll(WIDESEA_Cache.CacheConst.Cache_DtStockInfo); //List stockInfoList = stockInfos.Values.ToList(); //var stockinfo1 = stockInfoList.OrderBy(x => x.CreateDate) // .ToList(); //var stockinfo = stockinfo1.Where(x => x.LocationInfo != null && !x.IsFull && x.LocationInfo.RoadwayNo == stationManager.Roadway) // .FirstOrDefault(); var stockinfo = await _stockInfoRepository.Db.Queryable() .Where(x => !x.IsFull && x.LocationInfo.RoadwayNo == stationManager.Roadway) .OrderBy(x=>x.CreateDate) .FirstAsync(); if (stockinfo == null) return null; var task = new Dt_Task { CurrentAddress = input.Position, Grade = 2, Roadway = input.Roadways, TargetAddress = stationManager.stationLocation, Dispatchertime = DateTime.Now, MaterialNo = "", NextAddress = input.Roadways, OrderNo = null, PalletCode = stockinfo.PalletCode, SourceAddress = stockinfo.LocationCode, TaskState = (int)TaskOutStatusEnum.OutNew, TaskType = (int)TaskOutboundTypeEnum.OutTray, TaskNum = await BaseDal.GetTaskNo(), Creater = "System", ProductionLine = stockinfo.ProductionLine, }; //_simpleCacheService.HashDel(WIDESEA_Cache.CacheConst.Cache_DtStockInfo, new string[] { task.PalletCode }); return task; } catch (Exception ex) { throw new Exception(ex.Message); } } #endregion #region 直接出库任务完成 public async Task CompleteInToOutTaskAsync(Dt_Task task) { WebResponseContent content = new WebResponseContent(); try { //添加历史 var taskHty = CreateHistoricalTask(task); // 添加历史任务 var isTaskHtyAdd = await _task_HtyRepository.AddDataAsync(taskHty) > 0; //删除任务 BaseDal.DeleteData(task); return content.OK(); } catch (Exception ex) { return content.Error(ex.Message); } } #endregion #region 异常口任务检测 /// /// 异常排出口入库校验 所有异常交给WCS做原地址NG处理 /// /// /// /// /// public async Task CheckAbnormalTaskAsync(RequestTaskDto input, Dt_StationManager stationManager) { try { if (stationManager.stationType == 15) throw new Exception(""); // 创建一个TrayCellsStatusDto对象,并赋值 TrayCellsStatusDto trayCells = new TrayCellsStatusDto() { Software = "WMS", TrayBarcode = input.PalletCode, //EquipmentCode = "EQ_CWJZ01" EquipmentCode = input.EquiCodeMOM }; // 调用GetTrayCellStatusAsync方法,获取整盘电芯 WebResponseContent content = await GetTrayCellStatusAsync(trayCells); // 如果状态为false,则返回content if (!content.Status) //获取整盘电芯数据, 如异常 使用空框类型入库 { ConsoleHelper.WriteErrorLine(content.Message); throw new Exception("MOM整盘电芯属性获取异常"); } // 添加组盘信息 // 将content.Data转换为ResultTrayCellsStatus对象 var result = JsonConvert.DeserializeObject(content.Data.ToString()); if (result.SerialNos.Count <= 0) //如调用成功 但电芯为0则定为空盘 { DtLocationInfo EmptylocationInfo = await RequestLocationByAbnormal(input); if (EmptylocationInfo == null) throw new Exception("库位已满"); var Epmtytask = new Dt_Task { CurrentAddress = input.Position, Grade = 4, //优先处理异常排出口的任务 防止正常需排出异常口的任务堵线 Roadway = input.Roadways, TargetAddress = EmptylocationInfo.LocationCode, Dispatchertime = DateTime.Now, MaterialNo = "", NextAddress = input.Roadways, OrderNo = null, PalletCode = input.PalletCode, SourceAddress = stationManager.stationLocation, TaskState = (int)TaskInStatusEnum.Line_InFinish, TaskType = (int)TaskInboundTypeEnum.InTray, TaskNum = await BaseDal.GetTaskNo(), Creater = "System", ProductionLine = result.ProductionLine, ProcessCode = result.ProcessCode, }; return Epmtytask; } //Console.WriteLine(result); //// TODO 获取本地料框属性与整盘电芯属性获取的值进行对比,如果一致则继续,否则返回错误信息 ////var productions = await _productionRepository.QueryDataAsync(x => result.TrayBarcodePropertys.Select(x => x.TrayBarcodeProperty).ToList().Contains(x.TrayBarcodeProperty)); ////if (productions.Count <= 0) //// return content.Error("料框属性不存在"); //// 调用CreateBoxingInfo方法,创建组盘信息 var boxing = CreateBoxingInfo(result, input.PalletCode); if (boxing == null) throw new Exception("组盘失败"); if (!stationManager.Roadway.Contains("FR")) //非分容库区 入库验证工艺路线 { // 调用GetProcessApplyAsync方法,获取工艺路线 ProcessApplyDto process = await GetProcessApplyAsync(input, result); // 如果process为null,则返回content if (process == null) throw new Exception("工艺请求参数异常"); // 调用_processApplyService.GetProcessApplyAsync方法,获取工艺申请 content = await _processApplyService.GetProcessApplyAsync(process); // 如果状态为false,则返回null if (!content.Status) throw new Exception("工艺申请失败"); } ////// 调用GetProcessResponseAsync方法,获取工艺响应 ////var processResponse = await GetProcessResponseAsync(process, input.Position); DtLocationInfo locationInfo = null; if (stationManager.Roadway.Contains("FR")) { locationInfo = await RequestLocation(input, true); } else { locationInfo = await RequestLocationByAbnormal(input); } //DtLocationInfo locationInfo = await RequestLocation(input); if (locationInfo == null) throw new Exception("库位已满"); var task = new Dt_Task { CurrentAddress = input.Position, Grade = 3, //优先处理异常排出口的任务 防止正常需排出异常口的任务堵线 Roadway = input.Roadways, TargetAddress = locationInfo.LocationCode, Dispatchertime = DateTime.Now, MaterialNo = "", NextAddress = input.Roadways, OrderNo = null, PalletCode = input.PalletCode, SourceAddress = stationManager.stationLocation, TaskState = (int)TaskInStatusEnum.Line_InFinish, TaskType = (int)TaskInboundTypeEnum.Inbound, TaskNum = await BaseDal.GetTaskNo(), Creater = "System", ProductionLine = result.ProductionLine, ProcessCode = result.ProcessCode, }; var isBox = await _boxingInfoRepository.AddDataNavAsync(boxing); int lastStatus = locationInfo.LocationStatus; ConsoleHelper.WriteSuccessLine($"修改前:" + lastStatus.ToString()); locationInfo.LocationStatus = (int)LocationEnum.FreeDisable; ConsoleHelper.WriteSuccessLine($"修改后:" + locationInfo.LocationStatus.ToString()); await UpdateLocationAsync(locationInfo); _locationStatusChangeRecordRepository.AddLocationStatusChangeRecord(locationInfo, lastStatus, (int)StatusChangeTypeEnum.AutomaticStorage, task.TaskNum); return task; } catch (Exception ex) { throw new Exception(ex.Message); } } #endregion #region 移库任务事务 private async Task ExecuteTransaction(DtStockInfo stock, Dt_Task_Hty taskHty, DtLocationInfo fromLocation, DtLocationInfo toLocation, int taskId) { _unitOfWorkManage.BeginTran(); try { var isUpdateStock = _stockInfoRepository.UpdateData(stock); // 添加历史任务 var isTaskHtyAdd = await _task_HtyRepository.AddDataAsync(taskHty) > 0; // 修改移库前货位状态 var isUpdateLocF = _locationRepository.UpdateData(fromLocation); var isUpdateLocT = _locationRepository.UpdateData(toLocation); // 删除任务数据 var isTaskDelete = await Delete(taskId); // 提交或回滚事务 if (isUpdateStock && isTaskHtyAdd && isTaskDelete && isUpdateLocF && isUpdateLocT) { LogFactory.GetLog("任务完成").InfoFormat(true, "任务完成", $"事务处理完成,提交事务。添加历史任务:{isTaskHtyAdd},删除任务数据:{isTaskDelete},更新或添加库存:{isUpdateStock},修改移库前货位状态:{isUpdateLocF}"); _unitOfWorkManage.CommitTran(); return true; } else { LogFactory.GetLog("任务完成").InfoFormat(true, "任务完成", $"数据处理失败,请检查数据是否正确,数据回滚。添加历史任务:{isTaskHtyAdd},删除任务数据:{isTaskDelete},更新库存:{isUpdateStock},修改移库前货位状态:{isUpdateLocF}"); _unitOfWorkManage.RollbackTran(); return false; } } catch (Exception err) { LogFactory.GetLog("任务完成").InfoFormat(true, $"任务完成,系统异常,异常信息:{err.Message}", "无参数"); _unitOfWorkManage.RollbackTran(); throw new Exception(err.Message); // 抛出异常以便外部捕获 } } #endregion MyRegion #region 检测高温库是否有可出库库存 public WebResponseContent StockCheckingAsync() { WebResponseContent webResponseContent = new WebResponseContent(); try { Task.Run(async () => { while (true) { try { Thread.Sleep(TimeSpan.FromMinutes(10)); var area = await _areaInfoRepository.QueryFirstAsync(x => x.AreaCode == "GWSC1"); var devices = SqlSugarHelper.DbWCS.Queryable() .Where(x => x.DeviceStatus == "1") .Where(x => x.DeviceCode.Contains("GWSC")) .ToList(); var deviceCode = devices.Select(x => x.DeviceCode).ToList(); var stockInfo = await _stockInfoRepository.Db.Queryable() .Includes(x => x.LocationInfo) // 预加载LocationInfo .Includes(x => x.StockInfoDetails) // 预加载StockInfoDetails .Where(x => x.AreaCode == area.AreaCode && x.OutboundTime < DateTime.Now && x.IsFull == true) // 过滤条件 .Where(x => x.LocationInfo.LocationStatus == (int)LocationEnum.InStock && x.LocationInfo.AreaId == area.AreaID) // 过滤条件 .WhereIF(!deviceCode.IsNullOrEmpty(), x => deviceCode.Contains(x.LocationInfo.RoadwayNo)) .OrderBy(x => x.OutboundTime) // 排序 .ToListAsync(); // 获取第一个元素 if (stockInfo.Count <= 0) continue; foreach (var item in stockInfo) { var hasTask = BaseDal.QueryFirst(x => x.PalletCode == item.PalletCode); if (hasTask != null) { Console.WriteLine("已存在出库任务"); continue; } string position = string.Empty; if (item.LocationInfo.RoadwayNo == "GWSC1") position = "1059"; else position = "1065"; var task = CreateTask(item, position, (int)TaskOutboundTypeEnum.Outbound); task.NextAddress = "002-000-002"; // 创建任务DTO WMSTaskDTO taskDTO = CreateTaskDTO(task); var configs = _configService.GetConfigsByCategory(CateGoryConst.CONFIG_SYS_IPAddress); var wmsBase = configs.FirstOrDefault(x => x.ConfigKey == SysConfigConst.WCSIPAddress)?.ConfigValue; var ipAddress = configs.FirstOrDefault(x => x.ConfigKey == SysConfigConst.ReceiveTask)?.ConfigValue; if (wmsBase == null || ipAddress == null) { throw new InvalidOperationException("WMS IP 未配置"); } var wmsIpAddress = wmsBase + ipAddress; var result = HttpHelper.PostAsync(wmsIpAddress, taskDTO.ToJsonString()).Result; var content = JsonConvert.DeserializeObject(result); if (content.Status) { int lastStatus = item.LocationInfo.LocationStatus; await BaseDal.AddDataAsync(task); // 更新库存位置状态为不可用 item.LocationInfo.LocationStatus = (int)LocationEnum.InStockDisable; await _locationRepository.UpdateDataAsync(item.LocationInfo); _locationStatusChangeRecordRepository.AddLocationStatusChangeRecord(item.LocationInfo, lastStatus, (int)StatusChangeTypeEnum.AutomaticDelivery, task.TaskNum); } } } catch (Exception ex) { Console.WriteLine(ex.Message); } } }); return webResponseContent.OK(); } catch (Exception ex) { Console.WriteLine(ex.Message.ToString()); return webResponseContent.Error(ex.Message); } } #endregion 检测高温库是否有可出库库存 #region 常温补空托盘至分容 private static readonly Dictionary requestTrackerToCW = new(); public async Task GetFROutTrayToCW(RequestTaskDto taskDTO) { WebResponseContent content = new WebResponseContent(); try { //string requestKey = JsonConvert.SerializeObject(taskDTO); //// 检查请求次数和时间限制 //if (requestTrackerToCW.TryGetValue(requestKey, out var requestInfo)) //{ // if (requestInfo.Count > 5 && DateTime.Now < requestInfo.LastRequestTime.AddMinutes(2)) // { // // 如果请求次数超过限制且未超过10分钟,抛出异常 // throw new InvalidOperationException("请求次数已达到限制,请稍后再试。"); // } //} //// 更新请求跟踪信息 //if (requestTrackerToCW.ContainsKey(requestKey)) //{ // requestTrackerToCW[requestKey] = (requestInfo.Count + 1, DateTime.Now); //} //else //{ // requestTrackerToCW[requestKey] = (1, DateTime.Now); //} var station = _stationManagerRepository.QueryFirst(x => x.stationChildCode == taskDTO.Position && x.stationStatus == "1"); var locations = _locationRepository.QueryData(x => x.RoadwayNo == station.Roadway && x.LocationStatus == (int)LocationEnum.Free && x.LocationType == 1); if (locations.Count > 10) { ConsoleHelper.WriteColorLine(locations.Count.ToString(), ConsoleColor.Blue); var location = locations.OrderBy(x => x.Layer).ThenBy(x => x.Column).ThenBy(x => x.Row).FirstOrDefault(); var stockInfo = await QueryStockInfoForEmptyTrayFRAsync("CWSC1", "10086", taskDTO.ProductionLine); if (stockInfo != null) { var task = CreateTask(stockInfo, taskDTO.Position, (int)TaskOutboundTypeEnum.OutTray); // 创建任务DTO WMSTaskDTO wmsTask = CreateTaskDTO(task); // 更新库存位置状态为不可用 int lastStatus = location.LocationStatus; stockInfo.LocationInfo.LocationStatus = (int)LocationEnum.InStockDisable; location.LocationStatus = (int)LocationEnum.Distribute; await _unitOfWorkManage.UseTranAsync(async () => { await BaseDal.AddDataAsync(task); await _locationRepository.UpdateDataAsync(stockInfo.LocationInfo); await _locationRepository.UpdateDataAsync(location); }); _locationStatusChangeRecordRepository.AddLocationStatusChangeRecord(location, lastStatus, (int)StatusChangeTypeEnum.AutomaticDelivery, task.TaskNum); // 返回成功响应 //requestTrackerToCW.Remove(requestKey); return content.OK(data: wmsTask); } else content.Error("常温空托盘数量不足"); } } catch (Exception ex) { content.Error(ex.Message); } return content; } /// /// 查询空盘库存信息 /// private async Task QueryStockInfoForEmptyTrayFRAsync(string areaCode, string position, string productLine) { var area = await _areaInfoRepository.QueryFirstAsync(x => x.AreaCode == areaCode); ConsoleHelper.WriteColorLine(position + "..." + areaCode, ConsoleColor.Magenta); var station = await _stationManagerRepository.QueryFirstAsync(x => x.stationChildCode == position && x.stationType == 17); ConsoleHelper.WriteColorLine(station.Roadway, ConsoleColor.Magenta); var stackers = station.Roadway.Split(',').ToList(); var deviceCode = SqlSugarHelper.DbWCS.Queryable() .Where(x => x.DeviceStatus == "1") .Where(x => stackers.Contains(x.DeviceCode)) .ToList().Select(x => x.DeviceCode).ToList(); // 从缓存中获取库存信息 //IDictionary? stockInfos = _simpleCacheService.HashGetAll(WIDESEA_Cache.CacheConst.Cache_DtStockInfo); //List stockInfoList = stockInfos.Values.ToList(); //var result1 = stockInfoList.Where(x => x.ProductionLine == productLine) // .Where(x => x.AreaCode == areaCode && x.IsFull == false) // .WhereIF(!deviceCode.IsNullOrEmpty(), x => x.LocationInfo != null && deviceCode.Contains(x.LocationInfo.RoadwayNo)) // .OrderBy(x => x.CreateDate) // 排序 // .ToList(); // 转换为列表 //var result = result1.Where(x => x.StockInfoDetails != null && x.StockInfoDetails.Any(y => y.MaterielCode == "空托盘")) // .Where(x => x.LocationInfo != null && x.LocationInfo.LocationStatus == (int)LocationEnum.InStock && x.LocationInfo.AreaId == area.AreaID && x.LocationInfo.EnalbeStatus == (int)EnableEnum.Enable) // 过滤条件 // .FirstOrDefault(); // 获取第一个元素 //if (result != null) // _simpleCacheService.HashDel(WIDESEA_Cache.CacheConst.Cache_DtStockInfo, new string[] { result.PalletCode }); //else // ConsoleHelper.WriteColorLine($"常温{productLine}空托盘库存不足", ConsoleColor.Red); var result = await _stockInfoRepository.Db.Queryable() .Includes(x => x.LocationInfo) .Includes(x => x.StockInfoDetails) .Where(x => x.AreaCode == areaCode && x.IsFull == false && x.ProductionLine == productLine) .WhereIF(!deviceCode.IsNullOrEmpty(), x => deviceCode.Contains(x.LocationInfo.RoadwayNo)) .Where(x => x.LocationInfo.LocationStatus == (int)LocationEnum.InStock && x.LocationInfo.AreaId == area.AreaID && x.LocationInfo.EnalbeStatus == (int)EnableEnum.Enable) // 过滤条件 .Where(x => x.StockInfoDetails.Any(y => y.MaterielCode == "空托盘")) .OrderBy(x => x.CreateDate) // 排序 .FirstAsync(); if (result.IsNullOrEmpty()) ConsoleHelper.WriteColorLine($"常温{productLine}空托盘库存不足", ConsoleColor.Red); return result; } #endregion #region 常温3出库至包装 // 用于追踪每个请求的调用次数和最后请求时间。 private static readonly Dictionary requestTracker = new(); /// /// 常温3出库至包装 /// /// /// public async Task RequestOutTaskToBZAsync(RequestTaskDto json) { WebResponseContent content = new WebResponseContent(); try { Dt_StationManager station = _stationManagerRepository.QueryFirst(x => x.stationChildCode == json.Position && x.stationType == 12 && x.stationArea == "Call"); if (station == null) { throw new Exception($"未找到包装站台信息,请检查传入参数{json.Position}"); } var deviceCode = SqlSugarHelper.DbWCS.Queryable() .Where(x => x.DeviceStatus == "1") .Where(x => x.DeviceCode.Contains("CWSC")) // 过滤条件 .ToList().Select(x => x.DeviceCode).ToList(); //var outBoundMateriel = AppSettings.app("OutBoundMateriel"); var outBoundMateriel = _dt_ChangeoversRepository.QueryData(x => x.Status == "1").ToList(); List? materielCodes = outBoundMateriel.Count != 0 ? outBoundMateriel.Where(x => x.ProductionLine == station.productLine && x.ProcessCode == "CWSC3") .Select(x => x.MaterielCode) .ToList() : null; #region //// 从缓存中获取库存信息 //IDictionary? stockInfos = _simpleCacheService.HashGetAll(WIDESEA_Cache.CacheConst.Cache_DtStockInfo); //List stockInfoList = stockInfos.Values.ToList(); //// 修改后的查询代码 //var stockInfo1 = stockInfoList // .Where(x => x.ProductionLine == station.productLine) // .Where(x => x.AreaCode == "CWSC3" && x.IsFull == true) // .OrderBy(x => x.OutboundTime) // .ToList(); //var stockInfo = stockInfo1 // // 增加对 LocationInfo 的空值检查 // .Where(x => x.LocationInfo != null && x.LocationInfo.LocationStatus == (int)LocationEnum.InStock) // // 增加对 LocationInfo 的空值检查 // .WhereIF(!deviceCode.IsNullOrEmpty(), x => x.LocationInfo != null && deviceCode.Contains(x.LocationInfo.RoadwayNo)) // .WhereIF(!materielCodes.IsNullOrEmpty(), x => x.StockInfoDetails != null && x.StockInfoDetails.Any(y => materielCodes.Contains(y.MaterielCode))) // .FirstOrDefault(); // 修改后的查询代码 #endregion var stockInfo = await _stockInfoRepository.Db.Queryable() .Includes(x => x.LocationInfo) .Includes(x => x.StockInfoDetails) .Where(x => x.ProductionLine == station.productLine) .Where(x => x.AreaCode == "CWSC3" && x.IsFull == true) // 增加对 LocationInfo 的空值检查 .Where(x => x.LocationInfo.LocationStatus == (int)LocationEnum.InStock) // 增加对 LocationInfo 的空值检查 .WhereIF(!deviceCode.IsNullOrEmpty(), x => deviceCode.Contains(x.LocationInfo.RoadwayNo)) .WhereIF(!materielCodes.IsNullOrEmpty(), x => x.StockInfoDetails.Any(y => materielCodes.Contains(y.MaterielCode))) .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); Dt_StationManager OutStation = _stationManagerRepository.QueryFirst(x => x.stationPLC == "1016" && x.stationType == 10 && x.Roadway == locationInfo.RoadwayNo && x.stationStatus == "1"); // 创建新任务实例 var task = new Dt_Task { CurrentAddress = stockInfo.LocationCode, Grade = 1, Roadway = locationInfo.RoadwayNo, TargetAddress = json.Position, Dispatchertime = DateTime.Now, MaterialNo = "", NextAddress = OutStation.stationChildCode, OrderNo = null, PalletCode = stockInfo.PalletCode, SourceAddress = stockInfo.LocationCode, TaskState = (int)TaskOutStatusEnum.OutNew, TaskType = (int)TaskOutboundTypeEnum.Outbound, TaskNum = await BaseDal.GetTaskNo(), Creater = "System", ProductionLine = stockInfo.ProductionLine, ProcessCode = stockInfo.ProcessCode, }; WMSTaskDTO taskDTO = CreateTaskDTO(task); int lastStatus = locationInfo.LocationStatus; BaseDal.AddData(task); stockInfo.LocationInfo.LocationStatus = (int)LocationEnum.InStockDisable; _locationRepository.UpdateData(stockInfo.LocationInfo); //_simpleCacheService.HashDel(WIDESEA_Cache.CacheConst.Cache_DtStockInfo, new string[] { taskDTO.PalletCode }); _locationStatusChangeRecordRepository.AddLocationStatusChangeRecord(stockInfo.LocationInfo, lastStatus, (int)StatusChangeTypeEnum.AutomaticDelivery, task.TaskNum); return content.OK(data: taskDTO); } catch (Exception ex) { Console.WriteLine($"CW3至包装出库异常:{ex.ToString()}"); return content.Error($"失败:{ex.Message}"); } } #endregion #region 火警出库 public WebResponseContent EmergencyTask(Object obj) { WebResponseContent content = new WebResponseContent(); var emergencyTask = new DTSEmergencyTask(); try { emergencyTask = JsonConvert.DeserializeObject(obj.ToString()); if (emergencyTask == null) throw new Exception("火警参数为空"); string[] strings = emergencyTask.LocationCode.Split("-"); 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 == Row && x.Column == Column && x.Layer == (i == 0 ? Layer - 1 : Layer) && x.RoadwayNo == Roadway); if (locationInfo == null) { throw new Exception("未知库位"); } //查找消防站台 var station = _stationManagerRepository.QueryFirst(t => t.Roadway == locationInfo.RoadwayNo && t.stationType == (int)StationManager.FireStation); if (station == null) { throw new Exception("消防站台未配置!"); } //查找库存信息 var stockInfo = _stockInfoRepository.QueryFirst(x => x.LocationCode == locationInfo.LocationCode && x.LocationInfo.RoadwayNo == locationInfo.RoadwayNo); //托盘码 string barcode = string.Empty; if (stockInfo != null) { barcode = stockInfo.PalletCode; } else { //无库存信息,生成随机托盘码 barcode = "M" + DateTime.Now.ToString("MMddHHmmss") + "-" + new Random().Next(100, 1000); } Dt_Task fireTask = BaseDal.QueryFirst(x => x.TaskType == (int)TaskOutboundTypeEnum.OutFireAlarm && x.SourceAddress == locationInfo.LocationCode && x.Roadway == station.Roadway); if (fireTask != null) { throw new Exception("已添加火警出库任务"); } int taskNum = BaseDal.GetTaskNo().Result; Dt_Task task = new Dt_Task { CreateDate = DateTime.Now, Creater = "DTS", CurrentAddress = locationInfo.LocationCode, Grade = i == 0 ? 5 : 3, Dispatchertime = DateTime.Now, PalletCode = barcode, Roadway = station.Roadway, SourceAddress = locationInfo.LocationCode, TaskState = (int)TaskOutStatusEnum.OutNew, TaskType = (int)TaskOutboundTypeEnum.OutFireAlarm, TargetAddress = station.stationLocation, NextAddress = station.stationLocation, TaskNum = taskNum, //_taskRepository.GetTaskNo().Result, TaskId = 0, }; // 尝试添加新任务 WMSTaskDTO taskDTO = new WMSTaskDTO() { TaskNum = task.TaskNum.Value, Grade = 1, PalletCode = task.PalletCode, RoadWay = task.Roadway, SourceAddress = task.SourceAddress, TargetAddress = task.TargetAddress, TaskState = task.TaskState.Value, Id = 0, TaskType = task.TaskType, }; 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; if (ReceiveByWMSTask == null || ipAddress == null) { throw new Exception("WMS IP 未配置"); } var wmsIpAddrss = ipAddress + ReceiveByWMSTask; var respon = HttpHelper.Post(wmsIpAddrss, JsonConvert.SerializeObject(taskDTO)); if (respon != null) { WebResponseContent respone = JsonConvert.DeserializeObject(respon.ToString()); if (respone.Status) { var taskId = BaseDal.AddData(task); } else { throw new Exception("WCS处理失败:" + respone.Message); } } else { throw new Exception("请求处理失败"); } } LogFactory.GetLog("DTS火警出库").Info(true, $"\r\r--------------------------------------"); LogFactory.GetLog("DTS火警出库").Info(true, obj.ToJsonString()); return content.OK(); } catch (Exception ex) { LogFactory.GetLog("DTS火警出库").Info(true, $"\r\r--------------------------------------"); LogFactory.GetLog("DTS火警出库").Info(true, ex.Message); return content.Error(ex.Message); } } #endregion #region 分容空框入库改为直接出库 public async Task SetEmptyOutbyInToOutAsync(RequestTaskDto request) { WebResponseContent content = new WebResponseContent(); var task = await BaseDal.QueryFirstAsync(x => x.PalletCode == request.PalletCode); if (!task.IsNullOrEmpty()) { var fromStation = await _stationManagerRepository.QueryFirstAsync(x => x.stationChildCode == request.Position); var toStation = await _stationManagerRepository.QueryFirstAsync(x => x.stationType == 7 && x.productLine == fromStation.productLine && x.stationArea == fromStation.stationArea); if (!toStation.IsNullOrEmpty()) { var location = await _locationRepository.QueryFirstAsync(x => x.LocationCode == task.TargetAddress && x.AreaId == int.Parse(fromStation.stationArea)); task.TargetAddress = toStation.stationLocation; task.NextAddress = toStation.stationChildCode; task.Grade = 3; task.TaskType = (int)TaskOutboundTypeEnum.InToOut; task.TaskState = (int)TaskOutStatusEnum.OutNew; location.LocationStatus = (int)LocationEnum.Free; await _locationRepository.UpdateDataAsync(location); await BaseDal.UpdateDataAsync(task); return content.OK("成功"); } else { ConsoleHelper.WriteErrorLine("分容空框入库改为直接出库:未找到对应站台"); content.Error("未找到对应站台"); } } else { ConsoleHelper.WriteErrorLine("分容空框入库改为直接出库:未找到任务"); content.Error("未找到任务"); } return content; } #endregion #region 分容空框出库改为直接出库 /// /// 分容空框出库改为直接出库 /// /// /// public async Task SetEmptyOutbyInToOutOneAsync(RequestTaskDto request) { WebResponseContent content = new WebResponseContent(); var task = await BaseDal.QueryFirstAsync(x => x.PalletCode == request.PalletCode); if (!task.IsNullOrEmpty()) { var toStation = await _stationManagerRepository.QueryFirstAsync(x => x.stationChildCode == request.Position); var fromStation = await _stationManagerRepository.QueryFirstAsync(x => x.stationType == 6 && x.productLine == toStation.productLine && x.stationArea == toStation.stationArea); if (!fromStation.IsNullOrEmpty()) { //var location = await _locationRepository.QueryFirstAsync(x => x.LocationCode == task.TargetAddress && x.AreaId == int.Parse(fromStation.stationArea)); task.SourceAddress = toStation.stationLocation; task.CurrentAddress = toStation.stationChildCode; task.Grade = 3; task.TaskType = (int)TaskOutboundTypeEnum.InToOut; task.TaskState = (int)TaskOutStatusEnum.OutNew; //location.LocationStatus = (int)LocationEnum.Free; //await _locationRepository.UpdateDataAsync(location); await BaseDal.UpdateDataAsync(task); return content.OK("成功"); } else { ConsoleHelper.WriteErrorLine("分容空框出库改为直接出库:未找到对应站台"); content.Error("未找到对应站台"); } } else { ConsoleHelper.WriteErrorLine("分容空框出库改为直接出库:未找到任务"); content.Error("未找到任务"); } return content; } /// /// 获取任务类型描述方法 /// /// /// private string GetTaskTypeDesc(int taskType) { return taskType switch { (int)TaskInboundTypeEnum.Inbound => TaskInboundTypeEnum.Inbound.GetIntegralRuleTypeEnumDesc(), (int)TaskInboundTypeEnum.InTray => TaskInboundTypeEnum.InTray.GetIntegralRuleTypeEnumDesc(), (int)TaskInboundTypeEnum.InNG => TaskInboundTypeEnum.InNG.GetIntegralRuleTypeEnumDesc(), (int)TaskInboundTypeEnum.InQuality => TaskInboundTypeEnum.InQuality.GetIntegralRuleTypeEnumDesc(), (int)TaskOutboundTypeEnum.OutTray => TaskOutboundTypeEnum.OutTray.GetIntegralRuleTypeEnumDesc(), (int)TaskOutboundTypeEnum.Outbound => TaskOutboundTypeEnum.Outbound.GetIntegralRuleTypeEnumDesc(), (int)TaskOutboundTypeEnum.OutNG => TaskOutboundTypeEnum.OutNG.GetIntegralRuleTypeEnumDesc(), (int)TaskOutboundTypeEnum.InToOut=> TaskOutboundTypeEnum.InToOut.GetIntegralRuleTypeEnumDesc(), }; } #endregion #region 大屏接口 /// /// 获取任务信息 /// /// public WebResponseContent GetTaskInfo() { WebResponseContent content = new WebResponseContent(); try { var task = BaseDal.QueryData(x => true).ToList(); var newTask = task.Select(x => new { x.PalletCode, x.Roadway, x.SourceAddress, x.TargetAddress, x.ProductionLine, TaskType = new List { GetTaskTypeDesc(x.TaskType) }[0], // 每个任务独立生成 TaskType TaskState = new List { GetTaskStateDesc(x.TaskState) }[0] // 每个任务独立生成 TaskState }).ToList(); return content.OK(data: newTask); } catch (Exception ex) { return content.Error(ex.Message); } } // 定义获取任务状态描述方法 private string GetTaskStateDesc(int? taskState) { return taskState switch { (int)TaskInStatusEnum.InNew => TaskInStatusEnum.InNew.GetIntegralRuleTypeEnumDesc(), (int)TaskInStatusEnum.Line_InExecuting => TaskInStatusEnum.Line_InExecuting.GetIntegralRuleTypeEnumDesc(), (int)TaskInStatusEnum.Line_InFinish => TaskInStatusEnum.Line_InFinish.GetIntegralRuleTypeEnumDesc(), (int)TaskInStatusEnum.SC_InExecuting => TaskInStatusEnum.SC_InExecuting.GetIntegralRuleTypeEnumDesc(), (int)TaskInStatusEnum.SC_InFinish => TaskInStatusEnum.SC_InFinish.GetIntegralRuleTypeEnumDesc(), (int)TaskOutStatusEnum.OutNew => TaskOutStatusEnum.OutNew.GetIntegralRuleTypeEnumDesc(), (int)TaskOutStatusEnum.SC_OutExecuting => TaskOutStatusEnum.SC_OutExecuting.GetIntegralRuleTypeEnumDesc(), (int)TaskOutStatusEnum.SC_OutFinish => TaskOutStatusEnum.SC_OutFinish.GetIntegralRuleTypeEnumDesc(), (int)TaskOutStatusEnum.Line_OutExecuting => TaskOutStatusEnum.Line_OutExecuting.GetIntegralRuleTypeEnumDesc(), (int)TaskOutStatusEnum.Line_OutFinish => TaskOutStatusEnum.Line_OutFinish.GetIntegralRuleTypeEnumDesc(), }; } /// /// 获取库存信息 /// /// public WebResponseContent GetStockInfo() { WebResponseContent content = new WebResponseContent(); try { var now = DateTime.Now; var startOfDay = new DateTime(now.Year, now.Month, now.Day); var endOfDay = startOfDay.AddDays(1); var filteredItems = _stockInfoRepository.Db.Queryable() .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(); return content.OK(data: result); } catch (Exception ex) { return content.Error(ex.Message); } } /// /// 获取货位状态 /// /// public WebResponseContent GetStockQuantity() { WebResponseContent content = new WebResponseContent(); try { var location = _locationRepository.Db.Queryable().ToList(); return content.OK(data: location); } catch (Exception ex) { return content.Error(ex.Message); } } public WebResponseContent Getproductionvolume() { WebResponseContent content = new WebResponseContent(); try { var now = DateTime.Now; var startOfDay = new DateTime(now.Year, now.Month, now.Day); var endOfDay1 = startOfDay.AddDays(-7); var taskHty = _task_HtyRepository.Db.Queryable().Where(it => it.CreateDate > endOfDay1).ToList(); return content.OK(data: taskHty); } catch (Exception ex) { return content.Error(ex.Message); } } public WebResponseContent Getoutput() { WebResponseContent content = new WebResponseContent(); try { var now = DateTime.Now; var firstDayOfYear = new DateTime(now.Year, 1, 1); var taskHty = _task_HtyRepository.Db.Queryable().Where(it => it.CreateDate > firstDayOfYear && it.TaskType == 100).ToList(); return content.OK(data: taskHty); } catch (Exception ex) { return content.Error(ex.Message); } } #endregion public WebResponseContent GetTimeout() { WebResponseContent content = new WebResponseContent(); try { var now = DateTime.Now; // 使用Subtract方法 var threeHoursAgo = now.Subtract(TimeSpan.FromHours(3)); List dtStocks = _stockInfoRepository.Db.Queryable() .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 { { "JZ", "静置库" }, { "CH", "陈化库" }, { "FR", "分容库" }, { "GW", "高温库" }, { "CW", "常温库" } }; var roadwayKeys = roadwayMappings.Keys.ToArray(); var taskHty = _task_HtyRepository.Db.Queryable() .Where(it => it.CreateDate >= thirtyDaysAgo && it.CreateDate <= now && it.TaskType == 100 && roadwayKeys.Any(rk => it.Roadway.Contains(rk))) .ToList() .Select(t => new { OriginalRoadway = t.Roadway, MatchedKey = roadwayKeys.FirstOrDefault(rk => t.Roadway.Contains(rk)), CreateDate = t.CreateDate }) .Where(t => t.MatchedKey != null) .GroupBy(t => new { RoadwayKey = t.MatchedKey, Date = t.CreateDate.Date, Hour = t.CreateDate.Hour }) .OrderByDescending(group => group.Key.Date) .ThenByDescending(group => group.Key.Hour) .Select(group => new { Hour = $"{group.Key.Date:yyyy/M/d} {group.Key.Hour}:00", Count = group.Count(), Roadway = roadwayMappings[group.Key.RoadwayKey] // 映射为中文名称 }) .ToList(); return content.OK1(total1: taskHty.Count, data: taskHty); } catch (Exception ex) { return content.Error(ex.Message); } } }