using System.ComponentModel; using WCS.Core; using WCS.Entity.Protocol.Station; namespace WCS.WorkEngineering.Systems { /// /// 分线计算09 /// //[BelongTo(typeof(NoInteractionWorld))] [Description("分线计算09")] public class 分线计算09 : DeviceSystem> { protected override bool ParallelDo => true; protected override bool SaveLogsToFile => true; public override void Do(Device obj) { //SqlSugarHelper.Do(_db => //{ // //获取所有待执行的任务 // var db = _db.Default; // var taskList = db.Queryable().Where(x => x.Status == TaskStatus.WaitingToExecute && x.Type == TaskType.SetPlate && x.AddrFrom == "Robot").Take(1).ToList(); // //开始对任务进行处理 // foreach (var taskInfo in taskList) // { // //TODO:暂时不来考虑动态计算可前往的目标 // var nextAdd = taskInfo.WarehouseCode switch // { // "1N" => "455", // "1S" => "455", // "2N" => "455", // "2S" => "455", // "3N" => "455", // "3S" => "455", // _ => "0" // }; // //获取这个地址的下一个地址集合 // var cacheLineDevList = Device.All.First(x => x.Code == nextAdd).Targets.Where(x => x.HasFlag(DeviceFlags.桁架缓存放行点)); // var cacheLineCodes = cacheLineDevList.Select(x => x.Code.ToShort()); // var cacheLineList = db.Queryable().Includes(x => x.Locations).ToList(); // #region 跟据缓存信息寻找可以到达的缓存点 // //找到当前任务可用的缓存线信息 // var cacheLine = cacheLineList.Where(x => x.Locations.Any(l => l is { InStock: false, IsEmpty: false })).FirstOrDefault(x => cacheLineCodes.Contains(x.LocationNo) && x.MatCodeList.Contains(taskInfo.MatCode) && !x.InStock); // if (cacheLine != null)//这个任务可以直接去一条线体,不需要新建缓存信息 // { // //找到这条线体中序号最小的一条位信息 非空置且无货 // var cacheLoc = cacheLine.Locations.Where(x => x is { InStock: false, IsEmpty: false }).MinBy(x => x.XYNo); // if (cacheLoc != null) // { // cacheLoc = db.Queryable().Single(x => x.Id == cacheLoc.Id); // cacheLoc.InStock = true; // cacheLoc.TaskId = taskInfo.ID; // cacheLoc.EditTime = DateTime.Now; // db.Updateable(cacheLoc).ExecuteCommand(); // //WCS任务相关信息 // taskInfo.Status = TaskStatus.FinishOfShunt; // taskInfo.AddrNext = cacheLine.LocationNo.ToString(); // taskInfo.EditWho = "WCS"; // taskInfo.EditTime = DateTime.Now; // taskInfo.AddWCS_TASK_DTL(_db, obj.Entity.Code, taskInfo.AddrNext, $"完成分库计算,目标地址:{cacheLine.LocationNo}"); // db.Updateable(taskInfo).ExecuteCommand(); // taskInfo.UpdateRedisHash(); // return; // } // } // #endregion 跟据缓存信息寻找可以到达的缓存点 // #region 初始化一个信息的缓存信息 // //找到所有当前轮子可以去的垛形 // var palletizingList = db.Queryable() // .Includes(x => x.Layers, r => r.Rows, l => l.Locs) // .Where(x => x.MatCodeList.Contains(taskInfo.MatCode) && !x.Finish).ToList().Where(x => x.Layers.SelectMany(x => x.Rows).Any(r => r.LineCode == null)).OrderBy(x => x.AddTime).ToList(); // //如果没有对应的垛形信息就初始化一个垛形信息 // if (palletizingList.Count <= 0) // { // taskInfo.InitStackStructure(); // return; // } // foreach (var palletizing in palletizingList) // { // //TODO:当前不考虑不按顺序码垛的情况 // //按码垛顺序找到一个最近的没有码垛成功的行, // //先找层:未空置、未结束 TODO:暂不考虑所有层全部结束,但是垛形信息未清除的情况 // var palletizingLayer = palletizing.Layers // .Where(x => !x.IsEmpty) // .Where(x => !x.Finish) // .Where(x => x.MatCodeList.Contains(taskInfo.MatCode)) // .Where(x => x.Rows.Any(r => r.CacheLineId == 0)) // .MinBy(x => x.LayerNo); // //如果没有哪一层需要这个物料号,就初始化一个新的垛形信息 // if (palletizingLayer == null) // { // taskInfo.InitStackStructure(); // return; // } // //再找行:未空置、未结束 // var palletizingRow = palletizingLayer.Rows.Where(x => x is { IsEmpty: false, Finish: false } && x.MatCodeList.Contains(taskInfo.MatCode) && x.CacheLineId == 0) // .MinBy(x => x.RowNo); // //如果没有哪一行需要这个物料号,就初始化一个新的垛形信息 // if (palletizingRow == null) // { // taskInfo.InitStackStructure(); // return; // } // //走到这一步就表示没有哪一段线体缓存了当前物料,需要选一段新的线体进行缓存 // //TODO:暂时不处理就近分线的逻辑 // //获取一个当前可以使用的分配锁 // var devCode = cacheLineDevList.Select(x => x.Code.ToShort()).FirstOrDefault(x => !cacheLineList.Select(s => s.LocationNo).Contains(x)); // if (devCode == 0) // { // World.Log($"无可用线体:{taskInfo.ID}"); // return; // } // //开始初始化缓存位信息 // cacheLine = new WCS_CacheLine() // { // LocationNo = devCode, // AddTime = DateTime.Now, // PalletizingRowId = palletizingRow.Id, // InStock = false, // Put = false, // MatCodeList = palletizingRow.MatCodeList // }; // var res = db.Insertable(cacheLine).ExecuteReturnEntity(); // palletizingRow = db.Queryable().Includes(x => x.Locs).Single(x => x.Id == palletizingRow.Id); // palletizingRow.Locs = palletizingRow.Locs.OrderBy(x => x.XYNo).ToList(); // palletizingRow.CacheLineId = res.Id; // palletizingRow.EditTime = DateTime.Now; // db.Updateable(palletizingRow).ExecuteCommand(); // for (var i = 0; i < palletizingRow.Locs.Count; i++) // { // var loc = new WCS_CacheLineLoc() // { // XYNo = palletizingRow.Locs[i].XYNo, // InStock = i == 0, // IsEmpty = palletizingRow.Locs[i].IsEmpty, // MatCode = palletizingRow.Locs[i].MatCode, // TaskId = i == 0 ? taskInfo.ID : 0, // CacheLineId = res.Id // }; // db.Insertable(loc).ExecuteCommand(); // } // taskInfo.Status = TaskStatus.FinishOfShunt; // taskInfo.AddrNext = devCode.ToString(); // taskInfo.EditWho = "WCS"; // taskInfo.EditTime = DateTime.Now; // taskInfo.AddWCS_TASK_DTL(_db, obj.Entity.Code, taskInfo.AddrNext, $"完成分库计算,目标地址:{cacheLine.LocationNo}"); // db.Updateable(taskInfo).ExecuteCommand(); // taskInfo.UpdateRedisHash(); // return; // } // #endregion 初始化一个信息的缓存信息 // } //}); } public override bool Select(Device dev) { return dev.Code == nameof(分线计算09); } } public class LineCache { /// /// 位置 /// public string Location { get; set; } /// /// 是否放行 /// public bool IsPut { get; set; } /// /// 具体缓存信息 /// public List LineInfos { get; set; } } /// /// 线体缓存组员 /// public class LineCacheInfo { /// /// 序号 /// public string Index { get; set; } /// /// 物料号 /// public string MatCode { get; set; } /// /// 任务号 /// public int TaskNumber { get; set; } /// /// 是否有货 /// public bool InStock { get; set; } /// /// 是否空置 /// public bool IsEmpty { get; set; } } }