using JSMachine.WMS.App.Dto; using JSMachine.WMS.App.Dto.Enum; using JSMachine.WMS.App.IService; using JSMachine.WMS.Domain.Entity; using JSMachine.WMS.Domain.IRepository; using JSMachine.WMS.Infrastructure; using JSMachine.WMS.Infrastructure.Helper; using SqlSugar; using static JSMachine.WMS.App.Dto.StorageRackDto; namespace JSMachine.WMS.App.ServiceImpl { public class StorageRackService : BaseService, IStorageRackService { private IStorageRackRepository _storageRackRepository; public StorageRackService(IStorageRackRepository repository) : base(repository) { _storageRackRepository = repository; } /// /// 根据库位号查询库位信息 /// /// /// public async Task GetByStorageRackNo(string storageRackNo) { return await GetSingalByExpression(p => p.StorageRackNo == storageRackNo); } /// /// 根据批次号计算目标存储区库位 /// /// /// //public async Task CalculateDestWarehouse(string materiaBatch, FloorEnum floor) //{ // //如果某一列有一个库位被锁定,说明该列有未完成的任务(任务完成会解锁库位),因此该列不可以再生成新的任务 // //获取楼层的所有库位 // List wareHouses = await GetListByExpression(p => // p.Floor == floor && p.Transport == TransportEnum.NormalArea); // if (wareHouses.IsNullOrEmpty()) // { // LogHelper.Warn($"{floor} 层没有空余库位"); // return null; // } // wareHouses = wareHouses.OrderBy(p => p.AreaNumSort).OrderBy(p => p.ReservoirAreaColumnId).ToList(); // List sameBatchWarehouses = wareHouses.Where(p => p.MateriaBatch == materiaBatch).ToList(); // StorageRackDto destStorageRack = null; // //没有相同批次则任选一个空白的列 // if (sameBatchWarehouses.IsNullOrEmpty()) // { // var groupByColumn = wareHouses.GroupBy(p => p.ReservoirAreaColumnId); // foreach (var columnGroup in groupByColumn) // { // bool emptyColumn = columnGroup.All(p => !p.IsLock && !p.IsDisabled && string.IsNullOrEmpty(p.BarCode)); // if (emptyColumn) // { // destStorageRack = columnGroup.OrderByDescending(p => p.NumSort).First(); // break; // } // } // } // else //存在相同批次则搜寻该批次所在的列下是否还有空库位 // { // foreach (StorageRackDto sameBatchWarehous in sameBatchWarehouses) // { // var sameColumnWarehouse = wareHouses.Where(p => p.ReservoirAreaColumnId == sameBatchWarehous.ReservoirAreaColumnId); // //同批次的列中也不能有任何库位被锁定 // if (sameColumnWarehouse.All(p => !p.IsLock && !p.IsDisabled)) // { // destStorageRack = sameColumnWarehouse // .OrderByDescending(p => p.NumSort) // .FirstOrDefault(p => string.IsNullOrEmpty(p.BarCode)); // if (destStorageRack != null) // break; // } // } // //如果同批次下都没有合适的库位,则需要找空列 // if (destStorageRack == null) // { // List remain = wareHouses.Except(sameBatchWarehouses, new StorageRackDtoIEqualityComparer()).ToList(); // if (remain.IsNullOrEmpty()) // { // LogHelper.Warn("排除相同批次库位后没有剩余可用库位"); // return null; // } // var groupByColumn = remain.GroupBy(p => p.ReservoirAreaColumnId); // foreach (var columnGroup in groupByColumn) // { // bool emptyColumn = columnGroup.All(p => !p.IsLock && !p.IsDisabled && string.IsNullOrEmpty(p.BarCode)); // if (emptyColumn) // { // destStorageRack = columnGroup.OrderByDescending(p => p.NumSort).First(); // break; // } // } // } // } // return destStorageRack; //} /// /// 根据批次号判断是否存在空余库位 /// /// /// //public async Task HasEmptyWareHouse(string materiaBatch, TaskTypeEnum taskType, FloorEnum floor) //{ // //直接调用目标库位计算方法,能够计算出目标库位则有库位,否则就是没有 // //一楼采用完全不混放模式 // //二楼视配置 //} /// /// 获取可用的提升机库位 /// /// /// public async Task> GetUsableElevatorWareHouse(FloorEnum floor) { List reservoirAreaIds = floor == FloorEnum.FirstFloor ? [1091, 1092] : [2091, 2092]; List elevatorWarehouse = await GetListByExpression(p => reservoirAreaIds.Contains(p.ReservoirAreaId) && !p.IsLock && !p.IsDisabled ); return elevatorWarehouse; } /// /// 根据提升机编号和通道号获取提所属库位信息 /// /// /// /// public async Task GetElevatorWareHouse(int elevatorNo, int channel) { string nameMatch = elevatorNo == 1 ? "1号" : "2号"; StorageRackDto storageRack = await GetSingalByExpression(p => p.ElevatorChannel == channel && p.StorageRackName.Contains(nameMatch)); return storageRack; } public async Task Lock(StorageRackDto storageRack) { storageRack.IsLock = true; LogHelper.Info($"锁定库位{storageRack.StorageRackNo}"); return await base.EditSingalWithSpecificCols(storageRack, ["IsLock"]); } public async Task Unlock(StorageRackDto storageRack) { storageRack.IsLock = false; LogHelper.Info($"解锁库位{storageRack.StorageRackNo}"); return await base.EditSingalWithSpecificCols(storageRack, ["IsLock"]); } public Task UpdateLockStatus(Guid id, bool isLock) { return base.ExcuteSql($"update StorageRack set IsLock = {isLock} where Id = '{id}'"); } public Task UpdateDisableStatus(Guid id, bool isDisable) { return base.ExcuteSql($"update StorageRack set IsDisabled = {isDisable} where Id = '{id}'"); } private static readonly SemaphoreSlim SemaphoreSlim = new(1,1); public async Task GetUsableTransferStorageRack() { await SemaphoreSlim.WaitAsync(); StorageRackDto storageRackDto = await base.GetSingalByExpression(p => p.Transport == TransportEnum.TransitArea && !p.IsLock && !p.IsDisabled && string.IsNullOrEmpty(p.BarCode)); if (storageRackDto != null) await Lock(storageRackDto); SemaphoreSlim.Release(); return storageRackDto; } //public async Task PreCalUsableStorageRackCount(FloorEnum floor) //{ // //1. 一楼不混放,需要查找同批次,或者空白列 // //2.二楼可以混放,仅需要查找到一个空库位即可 //} } }