using Newtonsoft.Json; using PlcSiemens.Core.Extension; using ServiceCenter.Extensions; using ServiceCenter.Logs; using ServiceCenter.SqlSugars; using SqlSugar; using System.ComponentModel; using WCS.Core; using WCS.Entity; using WCS.Entity.Protocol.Station; using WCS.WorkEngineering.Extensions; using WCS.WorkEngineering.Model.WMS; using WCS.WorkEngineering.WebApi.Controllers; using WCS.WorkEngineering.WebApi.Models.WMS.Request; using WCS.WorkEngineering.Worlds; using DeviceFlags = WCS.WorkEngineering.Extensions.DeviceFlags; using TaskStatus = WCS.Entity.TaskStatus; namespace WCS.WorkEngineering.Systems { /// /// 无交互系统 /// [BelongTo(typeof(NoInteractionWorld))] [Description("无交互系统")] public class NoInteractionSystems : DeviceSystem> { protected override bool ParallelDo => true; public override void Do(Device obj) { var taskInfos = new List(); var sqlSugar = new SqlSugarHelper(); SqlSugarHelper.Do(db => { //获取所有的新建任务,组盘任务不需要 taskInfos = db.Default.Queryable().NoLock().Where(x => x.Status == 0).ToList() .Where(x => x.Type != TaskType.SetPlate || (x.Type == TaskType.SetPlate && x.AddrFrom != "Robot") && x.BusType!="芯股用空托盘入库" && !x.BarCode.Contains("Error")).Select(x => x.ID).ToList(); var time = DateTime.Now.AddMinutes(-20); var time1 = DateTime.Now.AddMinutes(-40); var timeOut = db.Default.Queryable().NoLock().Count(x => x.BusType == "车间叫料" && x.Status < TaskStatus.StackerExecution && x.AddTime < time); if (timeOut > 0) World.Log($"共有{timeOut}个车间叫料任务超过二十分钟未执行,请检查相关相关任务对应的堆垛机是否正常、堆垛机放货点是否卡任务等", LogLevelEnum.High); var timeOut1 = db.Default.Queryable().NoLock().Count(x => x.BusType == "车间叫料" && x.Status < TaskStatus.StackerExecution && x.AddTime < time1); if (timeOut1 > 0) World.Log($"共有{timeOut1}个车间叫料任务超过四十分钟未执行,请检查相关相关任务对应的堆垛机是否正常、堆垛机放货点是否卡任务等", LogLevelEnum.High); var timeOut2 = db.Default.Queryable().NoLock().Count(x => x.BusType == "皮盘入库" && x.Status < TaskStatus.StackerExecution && x.AddTime < time); if (timeOut2 > 0) World.Log($"共有{timeOut2}个皮盘入库任务超过二十分钟未执行,请检查相关相关任务及对应agv设备", LogLevelEnum.High); var timeOut3 = db.Default.Queryable().NoLock().Count(x => x.BusType == "皮盘入库" && x.Status < TaskStatus.StackerExecution && x.AddTime < time1); if (timeOut3 > 0) World.Log($"共有{timeOut3}个皮盘入库任务超过四十分钟未执行,请检查相关相关任务及对应agv设备", LogLevelEnum.High); var time3 = DateTime.Now.AddHours(-24); var timeOut4 = db.Default.Queryable().NoLock().Count(x => x.AddTime < time3 && x.ContGrpBarCode.Contains("TPB")); if (timeOut4 > 0) World.Log($"共有{timeOut4}个库存信息超过24小时未执行,请检查相关库存信息并处理", LogLevelEnum.High); var time4 = DateTime.Now.AddHours(-12); var timeOut5 = db.Default.Queryable().NoLock().Where(x => x.AddTime < time4 && !x.Finish).ToList(); if (timeOut5.Count > 0) World.Log($"共有{timeOut5.Count}个桁架码垛信息超过12小时未结束,请检查相关码垛信息并处理,具体在{JsonConvert.SerializeObject(timeOut5.Select(x=>x.PalletizingStation).ToList())}", LogLevelEnum.High); }); if (!taskInfos.Any()) { return; } var isEnd = false; //每个周期只处理一个任务 foreach (var item in taskInfos) { if (isEnd) return; try { SqlSugarHelper.Do(db => { var task = db.Default.Queryable().RowLock().Where(t => t.ID == item && t.Status== TaskStatus.NewBuild).First(); switch (task.Type) { case TaskType.SetPlate: if (task.AddrFrom != "Robot") { //更新任务状态 task.Status = TaskStatus.WaitingToExecute; db.Default.UpdateableRowLock(task).UpdateColumns(x => new { x.Status }).ExecuteCommand(); task.AddWCS_TASK_DTL(db.Default, task.Device, $"初始化入库任务信息"); isEnd = true; } break; case TaskType.EnterDepot: if (task.LastInteractionPoint == "2") { var sta = GetAgvStation(task, db); var agv = new WCS_AgvTaskInfo() { ID = db.GetAgvTaskId(), TaskType = AGVTaskType.EnterDepot, Status = AGVTaskStatus.NewBuild, TaskId = task.ID, Position = task.WorkBench, Station = sta, AddWho = "WCS", AddTime = DateTime.Now }; db.Default.InsertableRowLock(agv).SplitTable().ExecuteCommand(); task.AgvTaskID = agv.ID; task.Status = Entity.TaskStatus.WaitingToExecute; db.Default.UpdateableRowLock(task).UpdateColumns(x => new { x.Status, x.AgvTaskID }).ExecuteCommand(); task.AddWCS_TASK_DTL(db.Default, task.Device, $"初始化单独返皮盘任务"); } else if (task.BusType == TaskBusType.芯股用空托盘入库.GetDescription()) return; else if (task.BusType == TaskBusType.人工满托入库.GetDescription()) { var agv = new WCS_AgvTaskInfo() { ID = db.GetAgvTaskId(), TaskType = AGVTaskType.EnterDepot, Status = AGVTaskStatus.NewBuild, TaskId = task.ID, Position = task.WorkBench, Station = task.WarehouseCode switch { "1N" => "2535", "1S" => "2735", "2N" => "2935", "2S" => "3135", _ => "2535" }, AddWho = "WCS", AddTime = DateTime.Now }; db.Default.InsertableRowLock(agv).SplitTable().ExecuteCommand(); task.AgvTaskID = agv.ID; task.Device = task.WarehouseCode switch { "1N" => "TY1", "1S" => "TY2", "2N" => "TY3", "2S" => "TY4", _ => "TY1" }; task.Height = 1; task.Status = Entity.TaskStatus.WaitingToExecute; db.Default.UpdateableRowLock(task).UpdateColumns(x => new { x.Status, x.AgvTaskID, x.Device, x.Height }).ExecuteCommand(); task.AddWCS_TASK_DTL(db.Default, task.Device, $"初始化人工满托入库任务"); } else if (task.BusType == TaskBusType.UT人工满托入库.GetDescription()) { var agv = new WCS_AgvTaskInfo() { ID = db.GetAgvTaskId(), TaskType = AGVTaskType.EnterDepot, Status = AGVTaskStatus.NewBuild, TaskId = task.ID, Position = task.WorkBench, Station = task.WarehouseCode switch { "1N" => "2533", "1S" => "2733", "2N" => "2933", "2S" => "3133", _ => "2533" }, AddWho = "WCS", AddTime = DateTime.Now }; db.Default.InsertableRowLock(agv).SplitTable().ExecuteCommand(); task.AgvTaskID = agv.ID; task.Device = task.WarehouseCode switch { "1N" => "TY1", "1S" => "TY2", "2N" => "TY3", "2S" => "TY4", _ => "TY1" }; task.Height = 1; task.Status = Entity.TaskStatus.WaitingToExecute; db.Default.UpdateableRowLock(task).UpdateColumns(x => new { x.Status, x.AgvTaskID, x.Device, x.Height }).ExecuteCommand(); task.AddWCS_TASK_DTL(db.Default, task.Device, $"初始化UT人工满托入库任务"); } else if (task.BusType == TaskBusType.重绕满托入库.GetDescription()) { task.Status = Entity.TaskStatus.WaitingToExecute; db.Default.UpdateableRowLock(task).UpdateColumns(x => new { x.Status }).ExecuteCommand(); task.AddWCS_TASK_DTL(db.Default, task.Device, $"初始化入库任务信息"); } else if (task.BusType == TaskBusType.帘线退料重绕.GetDescription()) { var agv = new WCS_AgvTaskInfo() { ID = db.GetAgvTaskId(), TaskType = AGVTaskType.EnterDepot, Status = AGVTaskStatus.NewBuild, TaskId = task.ID, Position = task.WorkBench, WorkShop = 222, Station = "9001", AddWho = "WCS", AddTime = DateTime.Now }; db.Default.InsertableRowLock(agv).SplitTable().ExecuteCommand(); task.Status = Entity.TaskStatus.WaitingToExecute; task.AgvTaskID = agv.ID; task.AddrTo = agv.Station; db.Default.UpdateableRowLock(task).UpdateColumns(x => new { x.Status,x.AgvTaskID,x.AddrTo }).ExecuteCommand(); task.AddWCS_TASK_DTL(db.Default, task.Device, $"初始化入库任务信息"); } else { //更新任务状态 task.Status = Entity.TaskStatus.WaitingToExecute; task.Device = task.WarehouseCode switch { "1N" => "SRM1", "1S" => "SRM2", "2N" => "SRM3", "2S" => "SRM4", "3N" => "SRM5", "3S" => "SRM6", _ => task.Device }; task.Device = task.AddrFrom switch { "1666" or "1661" => "SRM1", "1681" or "1676" => "SRM2", "1696" or "1691" => "SRM3", "1711" or "1706" => "SRM4", "1726" or "1721" => "SRM5", "1741" or "1736" => "SRM6", _ => task.Device }; //计算下一个地址 var path1 = DevicePath.GetPath(task.AddrFrom, task.Device); task.AddrNext = path1.Points[1].Code; //var des1 = task.AddrNext; //var des2 = "1"; ////分拣一 //if (task.AddrNext == "1604") //{ // des2 = "1606"; //} ////else if (task.AddrNext == "1614") ////{ //// des2 = "1616"; ////} //var num1 = db.Default.Queryable().RowLock().Where(t => t.WorkBench == des1 && t.Status < TaskStatus.Finish && t.Type == TaskType.EnterDepot).Count(); //var num2 = db.Default.Queryable().RowLock().Where(t => t.WorkBench == des2 && t.Status < TaskStatus.Finish && t.Type == TaskType.EnterDepot).Count(); //if (task.AddrNext == "1604") //{ // task.AddrNext = num1 <= num2 ? des2 : des1; //} //task.WorkBench = task.AddrNext; task.SrmStation = task.BarCode.Contains("TPA") || task.BarCode.Contains("TPB") ? task.AddrFrom : path1.Points[2].Code; db.Default.UpdateableRowLock(task).UpdateColumns(x => new { x.Status, x.Device, x.AddrNext, x.SrmStation, x.WorkBench }).ExecuteCommand(); task.AddWCS_TASK_DTL(db.Default, task.Device, $"初始化入库任务信息"); } isEnd = true; break; case TaskType.OutDepot: { if (task.Device.Contains("Robot")) //机器人任务 { var lastTask = db.Default.Queryable().NoLock().First(x => x.Type == TaskType.OutDepot && x.AddrTo == task.AddrTo && x.Status > TaskStatus.WaitingToExecute && x.Status < TaskStatus.Finish); if (lastTask != null) { World.Log($"等待任务结束:{task.AddrTo}上一组码垛任务未结束,等待{lastTask.ID}任务完成后开始初始化当前任务{task.ID}"); return; } var pos = task.AddrFrom.Split("-"); task.Status = Entity.TaskStatus.WaitingToExecute; task.Line = pos[0].ToShort(); task.Col = pos[1].ToShort(); task.Layer = pos[2].ToShort(); task.Depth = pos[3].ToShort(); db.Default.UpdateableRowLock(task).UpdateColumns(x => new { x.Status, x.Line, x.Col, x.Layer, x.Depth }).ExecuteCommand(); task.AddWCS_TASK_DTL(db.Default, task.Device, $"初始化出库任务信息,放货站台:{task.SrmStation}"); isEnd = true; } else if (task.Device == "FJXG") //芯股仓库的任务 { if (task.LastInteractionPoint != "3") //车间叫料任务,此值为3时是单独取满任务 { var sta = GetAgvStation(task, db); //芯股任务,取货站台就是芯股站台 var agv = new WCS_AgvTaskInfo() { ID = db.GetAgvTaskId(), TaskType = AGVTaskType.EnterDepot, Status = AGVTaskStatus.NewBuild, TaskId = task.ID, Position = task.WorkBench, Station = sta, AddWho = "WCS", AddTime = DateTime.Now }; db.Default.InsertableRowLock(agv).SplitTable().ExecuteCommand(); } var agvId = DateTime.Now.GetFormat(GetFormatterEnum.only) + task.ID; var agvTask = new WCS_AgvTaskInfo() { ID = db.GetAgvTaskId(), TaskType = AGVTaskType.CallMaterial, Status = AGVTaskStatus.NewBuild, TaskId = task.ID, Position = task.WorkBench, Station = task.AddrFrom, AddWho = "WCS", AddTime = DateTime.Now, AgvID = agvId }; //开始处理车间叫料AGV任务任务 db.Default.InsertableRowLock(agvTask).SplitTable().ExecuteCommand(); agvTask = db.Default.Queryable().RowLock().SplitTable(x => x.Take(2)).Single(x => x.TaskId == task.ID && x.TaskType == AGVTaskType.CallMaterial); if (agvTask.Status != AGVTaskStatus.NewBuild) { World.Log($"AGV任务{agvTask.ID}状态不是新建", LogLevelEnum.High); return; } agvId = agvTask.AgvID; agvTask.Status = AGVTaskStatus.Confirm; agvTask.AgvStatus = AGVTaskStatus.Confirm; db.Default.UpdateableRowLock(agvTask).UpdateColumns(x => new { x.AgvID, x.Status, x.AgvStatus }).SplitTable(x => x.Take(2)).ExecuteCommand(); task.Status = TaskStatus.AGVExecution; task.AgvTaskID = agvTask.ID; task.EditTime = DateTime.Now; task.EditWho = "WCS"; db.Default.Updateable(task).UpdateColumns(x => new { x.Status, x.AgvTaskID, x.EditTime, x.EditWho }).ExecuteCommand(); task.AddWCS_TASK_DTL(db.Default, task.AddrFrom, "AGV", $"任务下发至AGV{agvId}"); var res = AgvApi.机台叫料(task.AddrFrom, task.WorkBench, agvId); isEnd = true; } else if (task.BusType == TaskBusType.芯股站台送空托.GetDescription()) { if (task.SrmStation == "1") { var srmStation = new string[2]; switch (task.Device) { case "SRM1": srmStation[0] = "2534"; srmStation[1] = "2533"; break; case "SRM2": srmStation[0] = "2734"; srmStation[1] = "2733"; break; case "SRM3": srmStation[0] = "2934"; srmStation[1] = "2933"; break; case "SRM4": srmStation[0] = "3134"; srmStation[1] = "3133"; break; case "SRM5": srmStation[0] = "3334"; srmStation[1] = "3333"; break; case "SRM6": srmStation[0] = "3534"; srmStation[1] = "3533"; break; } //开始计算当前这个任务要从哪个站台出 //计算两个站台小于取货完成数量的AGV任务 var agv1 = db.Default.Queryable().NoLock().Where(x => x.Status <= TaskStatus.StackerExecution && x.AddrTo == srmStation[0]).Count(); var agv2 = db.Default.Queryable().NoLock().Where(x => x.Status <= TaskStatus.StackerExecution && x.AddrTo == srmStation[1]).Count(); task.SrmStation = ""; //if (srmStation[0] == "2534"/* || srmStation[0] == "2934"*/) //{ // task.AddrTo = srmStation[0]; //} //else { task.AddrTo = agv1 > agv2 ? srmStation[1] : srmStation[0]; } } if (task.SrmStation.IsNullOrEmpty()) //如果没有指定放货站台 { if (task.Device.IsNullOrEmpty()) { task.Device = "SRM" + task.Tunnel.GetLastDigit(); } //获取堆垛机到目标地址的路径信息 var path = DevicePath.GetPath(task.Device, task.AddrTo); task.SrmStation = path.Points[1].Code; } //更新任务状态 task.Status = Entity.TaskStatus.WaitingToExecute; db.Default.UpdateableRowLock(task).UpdateColumns(x => new { x.SrmStation, x.AddrTo, x.Status }).ExecuteCommand(); task.AddWCS_TASK_DTL(db.Default, task.Device, $"初始化出库任务信息,放货站台:{task.SrmStation}"); isEnd = true; } else if (task.Device == "CR") { if (task.LastInteractionPoint != "3") //车间叫料任务,此值为3时是单独取满任务 { //var sta = GetAgvStation(task, db); var agv = new WCS_AgvTaskInfo() { ID = db.GetAgvTaskId(), TaskType = AGVTaskType.EnterDepot, Status = AGVTaskStatus.NewBuild, TaskId = task.ID, Position = task.WorkBench, Station = "2501",//默认去分拣一 AddWho = "WCS", AddTime = DateTime.Now }; db.Default.InsertableRowLock(agv).SplitTable().ExecuteCommand(); } //更新任务状态 task.Status = Entity.TaskStatus.WaitingToExecute; task.AddrTo = task.WorkBench; db.Default.UpdateableRowLock(task).UpdateColumns(x => new {x.Status , x.AddrTo }).ExecuteCommand(); task.AddWCS_TASK_DTL(db.Default, task.Device, $"初始化出库任务信息,重绕组盘区{task.AddrFrom}"); isEnd = true; break; } else //立库出库任务 { if (task.SrmStation == "1") { var srmStation = new string[2]; switch (task.Device) { case "SRM1": srmStation[0] = "2534"; srmStation[1] = "2533"; break; case "SRM2": srmStation[0] = "2734"; srmStation[1] = "2733"; break; case "SRM3": srmStation[0] = "2934"; srmStation[1] = "2933"; break; case "SRM4": srmStation[0] = "3134"; srmStation[1] = "3133"; break; case "SRM5": srmStation[0] = "3334"; srmStation[1] = "3333"; break; case "SRM6": srmStation[0] = "3534"; srmStation[1] = "3533"; break; } //开始计算当前这个任务要从哪个站台出 //计算两个站台小于取货完成数量的AGV任务 var agv1 = db.Default.Queryable().NoLock().Where(x => x.Status <= TaskStatus.StackerExecution && x.AddrTo == srmStation[0]).Count(); var agv2 = db.Default.Queryable().NoLock().Where(x => x.Status <= TaskStatus.StackerExecution && x.AddrTo == srmStation[1]).Count(); task.SrmStation = ""; //if (srmStation[0] == "2534"/* || srmStation[0] == "2934"*/) //{ // task.AddrTo = srmStation[0]; //} //else { task.AddrTo = agv1 > agv2 ? srmStation[1] : srmStation[0]; } } if (task.SrmStation.IsNullOrEmpty()) //如果没有指定放货站台 { if (task.Device.IsNullOrEmpty()) { task.Device = "SRM" + task.Tunnel.GetLastDigit(); } //获取堆垛机到目标地址的路径信息 var path = DevicePath.GetPath(task.Device, task.AddrTo); task.SrmStation = path.Points[1].Code; } var devs = Device.All.Where(x => x.HasFlag(DeviceFlags.AGV取货站台口)).Select(x => x.Code); if (devs.Contains(task.SrmStation) && task.LastInteractionPoint != "3") //车间叫料任务,此值为3时是单独取满任务 { var sta = GetAgvStation(task, db); var agv = new WCS_AgvTaskInfo() { ID = db.GetAgvTaskId(), TaskType = AGVTaskType.EnterDepot, Status = AGVTaskStatus.NewBuild, TaskId = task.ID, Position = task.WorkBench, Station = sta, AddWho = "WCS", AddTime = DateTime.Now }; db.Default.InsertableRowLock(agv).SplitTable().ExecuteCommand(); } //更新任务状态 task.Status = Entity.TaskStatus.WaitingToExecute; db.Default.UpdateableRowLock(task).UpdateColumns(x => new { x.SrmStation, x.AddrTo, x.Status }).ExecuteCommand(); task.AddWCS_TASK_DTL(db.Default, task.Device, $"初始化出库任务信息,放货站台:{task.SrmStation}"); isEnd = true; } break; } case TaskType.Delivery: break; case TaskType.EmptyInit: break; } }); } catch (Exception ex) { if (ex.Message.Contains("Index")) World.Log($"{ex.Message}:{ex.StackTrace}"); if (ex.Message.Contains("SqlTransaction")) World.Log($"{ex.Message}:{ex.StackTrace}"); World.Log(ex.Message, LogLevelEnum.Mid); } } } public override bool Select(Device dev) { return dev.Code == nameof(NoInteractionSystems); } /// /// 获取AGV的目标站台 /// /// 任务信息 /// 数据库操作对象 /// 目标站台 private string GetAgvStation(WCS_TaskInfo task, SqlSugarHelper db) { // 默认站台 var defaultStation = "2701"; var sta = defaultStation; // 定义仓库与站台的映射关系 var stationMap = new Dictionary { ["1"] = ("2501", "2701"), ["2"] = ("2901", "3101"), ["3"] = ("3301", "3501") }; var oldWarehouseCode = task.WarehouseCode; // 检查是否需要更新 warehouseCode if (task.BusType == TaskBusType.皮盘入库.GetDescription() || task.BusType == TaskBusType.车间叫料.GetDescription()) { task.WarehouseCode = task.MaterialCode switch { "分拣库1北" => "1N", "分拣库1南" => "1S", "分拣库2北" => "2N", "分拣库2南" => "2S", "分拣库3北" => "3N", "分拣库3南" => "3S", _ => task.WarehouseCode }; } // 确定站台初始值 if (stationMap.TryGetValue(task.WarehouseCode[0].ToString(), out var stationPair)) sta = task.WarehouseCode.Contains("N") ? stationPair.N : stationPair.S; // 配置值获取 var num = db.Default.Queryable() .NoLock() .First(x => x.Code == "SameSideTaskNum")?.SContent.ToInt() ?? 5; // 判断当前侧任务数量是否超出限制 var currentTaskCount = GetStationTaskCount(db, sta); if (currentTaskCount > num) { // 同一分拣库的两侧均分任务 if (task.WarehouseCode.StartsWith("1") || task.WarehouseCode.StartsWith("2") || task.WarehouseCode.StartsWith("3")) { var (northCount, southCount) = GetNorthAndSouthTaskCounts(db, stationPair); sta = southCount > northCount ? stationPair.N : stationPair.S; } else { return defaultStation; } } // 配置值获取 num = db.Default.Queryable() .NoLock() .First(x => x.Code == "TasksInSameWarehouse")?.SContent.ToInt() ?? 10; // 判断是否需要在三个分拣中心中选取任务数量较少的一侧进行分配 currentTaskCount = GetStationTaskCount(db, sta); var otherSide = stationMap.First(x => x.Value.N == sta || x.Value.S == sta); currentTaskCount += GetStationTaskCount(db, otherSide.Value.N==sta ? otherSide.Value.S : otherSide.Value.N); if (currentTaskCount > num) { sta = db.Default.Queryable() .NoLock() .Where(v => v.Status >= AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.Complete1 && v.TaskType == AGVTaskType.EnterDepot && (v.Station != "2535" && v.Station != "2735" && v.Station != "2935" && v.Station != "3135" && !v.Station.StartsWith("9"))) .SplitTable(v => v.Take(2)) .ToList() .GroupBy(x => x.Station) .Select(g => new { Station = g.Key, Count = g.Count() }) .OrderBy(x => x.Count) .FirstOrDefault()?.Station ?? defaultStation; } task.WarehouseCode = oldWarehouseCode; return sta; } /// /// 获取指定站台的任务数量 /// private int GetStationTaskCount(SqlSugarHelper db, string station) { return db.Default.Queryable() .NoLock() .Where(v => v.Status >= AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.Complete1 && v.TaskType == AGVTaskType.EnterDepot && v.Station == station) .SplitTable(v => v.Take(2)) .Count(); } /// /// 获取北侧和南侧的任务数量 /// private (int NorthCount, int SouthCount) GetNorthAndSouthTaskCounts(SqlSugarHelper db, (string N, string S) stationPair) { var northCount = GetStationTaskCount(db, stationPair.N); var southCount = GetStationTaskCount(db, stationPair.S); return (northCount, southCount); } /// /// 获取AGV的目标站台 /// /// /// /// private string GetAgvStation1(WCS_TaskInfo task, SqlSugarHelper db) { string sta = ""; var n = 0; var s = 0; var warehouseCode = task.WarehouseCode; if (task.BusType == TaskBusType.皮盘入库.GetDescription() || task.BusType == TaskBusType.车间叫料.GetDescription()) { warehouseCode = task.MaterialCode switch { "分拣库1北" => "1N", "分拣库1南" => "1S", "分拣库2北" => "2N", "分拣库2南" => "2S", "分拣库3北" => "3N", "分拣库3南" => "3S", _ => task.WarehouseCode }; } #region 判断是否需要在同一分拣库的两侧进行均分 //获取配置值 var num = 5; var config = db.Default.Queryable().NoLock().First(x => x.Code == "SameSideTaskNum"); if (config != null) { num = config.SContent.ToInt(); } sta = warehouseCode switch { "1N" => "2501", "1S" => "2701", "2N" => "2901", "2S" => "3101", "3N" => "3301", "3S" => "3501", _ => "2501", }; //获取当前侧的已有任务数量 var staNumber = db.Default.Queryable().NoLock().Where(v => v.Status >= AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.Complete1 && v.TaskType == AGVTaskType.EnterDepot && v.Station == sta) .SplitTable(v => v.Take(2)).Count(); //当前侧任务数量已大于配置任务数量 if (staNumber > num) { //同侧之间均分 if (warehouseCode.Contains("1")) { n = db.Default.Queryable().NoLock().Where(v => v.Status >= AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.Complete1 && v.TaskType == AGVTaskType.EnterDepot && v.Station=="2501") .SplitTable(v => v.Take(2)).Count(); s = db.Default.Queryable().NoLock().Where(v => v.Status >= AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.Complete1 && v.TaskType == AGVTaskType.EnterDepot && v.Station=="2701") .SplitTable(v => v.Take(2)).Count(); sta = n > s ? "2701" : "2501"; } else if (warehouseCode.Contains("2")) { n = db.Default.Queryable().NoLock().Where(v => v.Status >= AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.Complete1 && v.TaskType == AGVTaskType.EnterDepot && v.Station=="2901") .SplitTable(v => v.Take(2)).Count(); s = db.Default.Queryable().NoLock().Where(v => v.Status >= AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.Complete1 && v.TaskType == AGVTaskType.EnterDepot && v.Station=="3101") .SplitTable(v => v.Take(2)).Count(); sta = n > s ? "3101" : "2901"; } else if (warehouseCode.Contains("3")) { n = db.Default.Queryable().NoLock().Where(v => v.Status >= AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.Complete1 && v.TaskType == AGVTaskType.EnterDepot && v.Station=="3301") .SplitTable(v => v.Take(2)).Count(); s = db.Default.Queryable().NoLock().Where(v => v.Status >= AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.Complete1 && v.TaskType == AGVTaskType.EnterDepot && v.Station=="3501") .SplitTable(v => v.Take(2)).Count(); sta = n > s ? "3501" : "3301"; } else { return default; } } #endregion #region 判断是否需要在三个分拣中心中选取任务数量较少的一侧进行分配 staNumber = db.Default.Queryable().NoLock().Where(v => v.Status >= AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.Complete1 && v.TaskType == AGVTaskType.EnterDepot && v.Station == sta) .SplitTable(v => v.Take(2)).Count(); num = 10; config = db.Default.Queryable().NoLock().First(x => x.Code == "TasksInSameWarehouse"); if (config != null) { num = config.SContent.ToInt(); } if (staNumber > num) { sta = db.Default.Queryable().NoLock().Where(v => v.Status >= AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.Complete1 && v.TaskType == AGVTaskType.EnterDepot && (v.Station != "2535" && v.Station != "2735" && v.Station != "2935" && v.Station != "3135" && !v.Station.StartsWith("9")))//过滤掉人工满托入库和重绕区任务 .SplitTable(v => v.Take(2)).ToList().GroupBy(x => x.Station).Select(x => new { x.Key, Count = x.Count() }).MinBy(x => x.Count).Key; } #endregion return sta; } /// /// 获取AGV返空可用目标站台 /// /// 仓库 /// 需要获取的方向 /// 目标站台列表 public List GetAgvStation(string warehouseCode, string direction) { // 定义方向和仓库与站台的映射关系 var stationMap = new Dictionary>> { ["N"] = new() { ["1"] = new List { "2501", "2505", "2509", "2513" }, ["2"] = new List { "2901", "2905", "2909", "2913" }, ["3"] = new List { "3301", "3305", "3309", "3313" } }, ["S"] = new() { ["1"] = new List { "2701", "2705", "2709", "2713" }, ["2"] = new List { "3101", "3105", "3109", "3113" }, ["3"] = new List { "3501", "3505", "3509", "3513" } } }; // 查找方向和仓库对应的站台 if (stationMap.TryGetValue(direction, out var warehouseStations)) { var warehouseKey = warehouseStations.Keys.FirstOrDefault(warehouseCode.Contains); if (warehouseKey != null) return warehouseStations[warehouseKey]; } // 如果没有找到匹配的站台,则返回空列表 return new List(); } } }