Files
ww-jst/wmsjst/JSMachine.WMS.Application/ServiceImpl/StorageRackService.cs
T

216 lines
8.7 KiB
C#
Raw Normal View History

2026-09-02 16:31:50 +08:00
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<StorageRackDto, StorageRack>, IStorageRackService
{
private IStorageRackRepository _storageRackRepository;
public StorageRackService(IStorageRackRepository repository) : base(repository)
{
_storageRackRepository = repository;
}
/// <summary>
/// 根据库位号查询库位信息
/// </summary>
/// <param name="storageRackNo"></param>
/// <returns></returns>
public async Task<StorageRackDto> GetByStorageRackNo(string storageRackNo)
{
return await GetSingalByExpression(p => p.StorageRackNo == storageRackNo);
}
/// <summary>
/// 根据批次号计算目标存储区库位
/// </summary>
/// <param name="materiaBatch"></param>
/// <returns></returns>
//public async Task<StorageRackDto> CalculateDestWarehouse(string materiaBatch, FloorEnum floor)
//{
// //如果某一列有一个库位被锁定,说明该列有未完成的任务(任务完成会解锁库位),因此该列不可以再生成新的任务
// //获取楼层的所有库位
// List<StorageRackDto> 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<StorageRackDto> 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<StorageRackDto> 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;
//}
/// <summary>
/// 根据批次号判断是否存在空余库位
/// </summary>
/// <param name="materialBatch"></param>
/// <returns></returns>
//public async Task<bool> HasEmptyWareHouse(string materiaBatch, TaskTypeEnum taskType, FloorEnum floor)
//{
// //直接调用目标库位计算方法,能够计算出目标库位则有库位,否则就是没有
// //一楼采用完全不混放模式
// //二楼视配置
//}
/// <summary>
/// 获取可用的提升机库位
/// </summary>
/// <param name="floor"></param>
/// <returns></returns>
public async Task<List<StorageRackDto>> GetUsableElevatorWareHouse(FloorEnum floor)
{
List<long?> reservoirAreaIds = floor == FloorEnum.FirstFloor ? [1091, 1092] : [2091, 2092];
List<StorageRackDto> elevatorWarehouse = await
GetListByExpression(p =>
reservoirAreaIds.Contains(p.ReservoirAreaId)
&&
!p.IsLock && !p.IsDisabled
);
return elevatorWarehouse;
}
/// <summary>
/// 根据提升机编号和通道号获取提所属库位信息
/// </summary>
/// <param name="elevatorNo"></param>
/// <param name="channel"></param>
/// <returns></returns>
public async Task<StorageRackDto> 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<bool> Lock(StorageRackDto storageRack)
{
storageRack.IsLock = true;
LogHelper.Info($"锁定库位{storageRack.StorageRackNo}");
return await base.EditSingalWithSpecificCols(storageRack, ["IsLock"]);
}
public async Task<bool> Unlock(StorageRackDto storageRack)
{
storageRack.IsLock = false;
LogHelper.Info($"解锁库位{storageRack.StorageRackNo}");
return await base.EditSingalWithSpecificCols(storageRack, ["IsLock"]);
}
public Task<bool> UpdateLockStatus(Guid id, bool isLock)
{
return base.ExcuteSql($"update StorageRack set IsLock = {isLock} where Id = '{id}'");
}
public Task<bool> 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<StorageRackDto> 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<int> PreCalUsableStorageRackCount(FloorEnum floor)
//{
// //1. 一楼不混放,需要查找同批次,或者空白列
// //2.二楼可以混放,仅需要查找到一个空库位即可
//}
}
}