| | |
| | | private readonly IRepository<Dt_Task> _taskRepository; |
| | | private readonly IRepository<Dt_StockInfo> _stockInfoRepository; |
| | | private readonly IRecordService _recordService; |
| | | private readonly IRepository<Dt_Warehouse> _warehouseRepository; |
| | | |
| | | /// <summary> |
| | | /// 构造函数 |
| | |
| | | IRepository<Dt_LocationInfo> baseDal, |
| | | IRepository<Dt_Task> taskRepository, |
| | | IRepository<Dt_StockInfo> stockInfoRepository, |
| | | IRepository<Dt_Warehouse> warehouseRepository, |
| | | IMapper mapper, |
| | | IRecordService recordService) : base(baseDal) |
| | | { |
| | |
| | | _stockInfoRepository = stockInfoRepository; |
| | | _mapper = mapper; |
| | | _recordService = recordService; |
| | | _warehouseRepository = warehouseRepository; |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | |
| | | /// <summary> |
| | | /// 根据巷道获取空闲货位信息 |
| | | /// 排序策略:深度优先(二深位优先),其次按层、列、行升序 |
| | | /// </summary> |
| | | /// <param name="roadwayNo">巷道编号</param> |
| | | /// <returns>空闲货位信息,如果未找到则返回null</returns> |
| | | /// <returns>空闲货位信息,如果空闲货位不足则返回null</returns> |
| | | public async Task<Dt_LocationInfo?> GetLocationInfo(string roadwayNo) |
| | | { |
| | | var locations = await BaseDal.QueryDataAsync(x => |
| | | x.EnableStatus == EnableStatusEnum.Normal.GetHashCode() && |
| | | x.RoadwayNo == roadwayNo && |
| | | x.LocationStatus == LocationStatusEnum.Free.GetHashCode()); |
| | | // HC 巷道使用 Capacity 类型,其他巷道使用 ShelfCapacity 类型 |
| | | var locationType = roadwayNo.Contains("HC") |
| | | ? (int)LocationTypeEnum.Capacity |
| | | : (int)LocationTypeEnum.ShelfCapacity; |
| | | |
| | | return locations? |
| | | var enableStatus = EnableStatusEnum.Normal.GetHashCode(); |
| | | var freeStatus = LocationStatusEnum.Free.GetHashCode(); |
| | | |
| | | // 数据库端 COUNT 检查空闲货位数量(仅返回一个数字,无数据传输开销) |
| | | var freeCount = await BaseDal.Db.Queryable<Dt_LocationInfo>() |
| | | .Where(x => x.EnableStatus == enableStatus |
| | | && x.RoadwayNo == roadwayNo |
| | | && x.LocationStatus == freeStatus |
| | | && x.LocationType == locationType) |
| | | .CountAsync(); |
| | | |
| | | // 空闲货位不足最低保留数量时返回null,避免将巷道分配耗尽 |
| | | const int minFreeLocationThreshold = 5; |
| | | if (freeCount < minFreeLocationThreshold) return null; |
| | | |
| | | // 数据库端排序取第一条(只传输单行数据) |
| | | return await BaseDal.Db.Queryable<Dt_LocationInfo>() |
| | | .Where(x => x.EnableStatus == enableStatus |
| | | && x.RoadwayNo == roadwayNo |
| | | && x.LocationStatus == freeStatus |
| | | && x.LocationType == locationType) |
| | | .OrderByDescending(x => x.Depth) |
| | | .OrderBy(x => x.Layer) |
| | | .ThenByDescending(x => x.Depth) |
| | | .ThenBy(x => x.Column) |
| | | .ThenBy(x => x.Row) |
| | | .FirstOrDefault(); |
| | | .OrderBy(x => x.Column) |
| | | .OrderBy(x => x.Row) |
| | | .FirstAsync(); |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | public async Task<Dt_LocationInfo> GetLocationInfoAsync(string locationCode) |
| | | { |
| | | return await BaseDal.QueryFirstAsync(x => x.LocationCode == locationCode); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 根据货位ID获取货位信息 |
| | | /// </summary> |
| | | /// <param name="id">货位id</param> |
| | | /// <returns>货位信息</returns> |
| | | public async Task<Dt_LocationInfo> GetLocationInfoAsync(int id) |
| | | { |
| | | return await BaseDal.QueryFirstAsync(x => x.Id == id); |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | // 判断该位置是否有库存 |
| | | var stockInfo = await _stockInfoRepository.QueryDataNavFirstAsync(x => |
| | | x.LocationCode == newLocationID && |
| | | x.StockStatus == StockStatusEmun.入库完成.GetHashCode() && |
| | | (x.StockStatus == StockStatusEmun.入库完成.GetHashCode() || x.StockStatus == StockStatusEmun.空托盘库存.GetHashCode()) && |
| | | x.LocationDetails.LocationStatus == LocationStatusEnum.InStock.GetHashCode()); |
| | | if (stockInfo == null) |
| | | { |
| | |
| | | /// <param name="layer">层数</param> |
| | | /// <param name="depth">深度</param> |
| | | /// <returns>货位信息对象</returns> |
| | | private static Dt_LocationInfo CreateLocationInfo(string roadwayNo, int row, int col, int layer, int depth) |
| | | private Dt_LocationInfo CreateLocationInfo(string roadwayNo, int row, int col, int layer, int depth) |
| | | { |
| | | var warehouse = _warehouseRepository.QueryData(x => x.WarehouseCode == roadwayNo).FirstOrDefault(); |
| | | |
| | | if (warehouse == null) |
| | | { |
| | | throw new InvalidOperationException($"未找到巷道编号为 {roadwayNo} 的仓库信息"); |
| | | } |
| | | |
| | | return new Dt_LocationInfo |
| | | { |
| | | WarehouseId = 0, |
| | | WarehouseId = warehouse.WarehouseId, |
| | | Row = row, |
| | | Column = col, |
| | | Layer = layer, |
| | |
| | | EnableStatus = EnableStatusEnum.Normal.GetHashCode(), |
| | | LocationStatus = LocationStatusEnum.Free.GetHashCode(), |
| | | LocationType = LocationTypeEnum.Undefined.GetHashCode(), |
| | | //LocationCode = $"{roadwayNo}-{row:D3}-{col:D3}-{layer:D3}", |
| | | LocationCode = $"{row:D3}-{col:D3}-{layer:D3}", |
| | | LocationName = $"{roadwayNo}巷道{row:D3}行{col:D3}列{layer:D3}层{depth:D2}深" |
| | | }; |
| | |
| | | |
| | | #endregion 私有方法 |
| | | } |
| | | } |
| | | } |