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) { Console.WriteLine($"{JsonConvert.SerializeObject(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("错误的调取"); var stockInfo = await QueryStockInfoForEmptyTrayFRAsync("CWSC1", "10086", input.ProductionLine); if (stockInfo == null) return null; var task = new Dt_Task { CurrentAddress = input.Position, Grade = 2, Roadway = stockInfo.LocationInfo.RoadwayNo, TargetAddress = stationManager.stationLocation, Dispatchertime = DateTime.Now, MaterialNo = "", NextAddress = input.Position, 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, }; var location = _locationRepository.QueryFirst(x => x.Id == stockInfo.LocationId); if (location == null) return null; location.LocationStatus = (int)LocationEnum.InStockDisable; _locationRepository.UpdateData(location); 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(); 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 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)) .OrderBy(x => x.OutboundTime) .FirstAsync(); if (stockInfo.IsNullOrEmpty()) throw new Exception($"CWSC3库内{station.productLine}无满足条件的库存可出库"); DtLocationInfo locationInfo = _locationRepository.QueryFirst(x => x.AreaId == 5 && x.LocationCode == stockInfo.LocationCode); Dt_StationManager OutStation = _stationManagerRepository.QueryFirst(x => x.stationPLC == "1005" && 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); _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("火警参数为空"); DtLocationInfo locationInfo = _locationRepository.QueryFirst(x => x.Row == emergencyTask.row && x.Column == emergencyTask.column && x.Layer == emergencyTask.layer && x.AreaId == emergencyTask.zone); if (locationInfo == null) { throw new Exception("未知库位"); } //查找消防站台 var station = _stationManagerRepository.QueryFirst(t => t.Roadway == locationInfo.RoadwayNo && t.stationType == (int)StationManager.FireStation /*&& t. == "Enable"*/); 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 == 500 && 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 = 1, Dispatchertime = DateTime.Now, PalletCode = barcode, Roadway = station.Roadway, SourceAddress = locationInfo.LocationCode, TaskState = (int)TaskOutStatusEnum.OutNew, TaskType = 500, TargetAddress = station.stationLocation, NextAddress = station.stationChildCode, 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 = 500, }; 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; } #endregion }