using Admin.NET.Application.Entity; using Microsoft.CodeAnalysis; namespace Admin.NET.Application { /// /// 寻找 空库位的处理类 /// public class FindEmptyPlaceServiceHandle { /// /// 是否正在执行方法 /// private static bool isRuning_Fun = false; private static SemaphoreSlim semaphoreSlim = new SemaphoreSlim(1, 1); protected readonly SqlSugarRepository _v_empty_placeRep; protected readonly SqlSugarRepository _wmsPlaceRep; private readonly SqlSugarRepository _wareTaskRep; protected List findEmptyPlaceList = null; /// /// 构造函数 /// /// /// /// public FindEmptyPlaceServiceHandle( SqlSugarRepository v_empty_placeRep, SqlSugarRepository wmsPlaceRep, SqlSugarRepository wareTaskRep ) { _v_empty_placeRep = v_empty_placeRep; _wmsPlaceRep = wmsPlaceRep; _wareTaskRep = wareTaskRep; } /// /// 主方法入口1:查询单个库位 /// ///* 原则: ///* 1、方法必须使用lock锁定,防止并发抢同一个库位 ///* 2、该库位如果所在的堆垛机被设定为 禁用,则不允许寻找该库位 ///* 3、入库-库存分摊原则(注意:此项按照客户约定规则,视情况而定) /// public async Task MainFindSingleEmptyLocation(FindEmptyPlaceInput input) { var findList = await MainFindMultiEmptyLocation(input); if (findList != null && findList.Count > 0) { return findList.First(); } return null; } /// /// 主方法入口2:查询多个库位 /// ///* 原则: ///* 1、方法必须使用lock锁定,防止并发抢同一个库位 ///* 2、该库位如果所在的堆垛机被设定为 禁用,则不允许寻找该库位 ///* 3、入库-库存分摊原则(注意:此项按照客户约定规则,视情况而定) /// public async Task> MainFindMultiEmptyLocation(FindEmptyPlaceInput input) { try { if (isRuning_Fun) { throw Oops.Oh("程序正忙,请稍后再试"); } await semaphoreSlim.WaitAsync(); isRuning_Fun = true; await QueryBaseEmptyLocationList(input); //查询所有的空闲库位 await EnableLaneFilter();//可用的堆垛机巷道 --筛选条件 await TaskOccupyFilter();//任务占用的库位 -- 筛选条件 DiyFilter();//自定义查询条件 -- 筛选条件 DataOrder();//数据排序 //返回结果 if (findEmptyPlaceList != null && findEmptyPlaceList.Count > 0) { var queryIds = findEmptyPlaceList.Select(x => x.Id).ToList(); return _wmsPlaceRep.GetList(x => queryIds.Contains(x.Id)); } return new List(); } catch (Exception) { throw; } finally { semaphoreSlim.Release(); isRuning_Fun = false; } } #region 虚方法 /// /// 查询最基础的空库位集合,即获取数据库数据源的入口 /// protected virtual async Task QueryBaseEmptyLocationList(FindEmptyPlaceInput input) { findEmptyPlaceList = await _v_empty_placeRep.GetListAsync(x => 1 == 1); if (input != null) { if (input.AreaList?.Count > 0) { findEmptyPlaceList = findEmptyPlaceList.Where(x => input.AreaList.Contains(x.AreaCode)).ToList(); } if (!string.IsNullOrEmpty(input.PalceNo)) { findEmptyPlaceList = findEmptyPlaceList.Where(x => x.PlaceCode == input.PalceNo).ToList(); } } } /// /// 可用的堆垛机巷道 -- 筛选条件 /// protected virtual async Task EnableLaneFilter() { if (findEmptyPlaceList != null && findEmptyPlaceList.Count > 0) { //该库位如果所在的堆垛机被设定为 禁用,则不允许寻找该库位 List enable_laneList = await GetEnableLaneList(); if (enable_laneList != null && enable_laneList.Count > 0) { findEmptyPlaceList = await _v_empty_placeRep.AsQueryable().Where(x => enable_laneList.Contains(x.LaneNo)).ToListAsync(); } } } /// /// 排除未终结的任务占用库位 -- 筛选条件 /// protected virtual async Task TaskOccupyFilter() { if (findEmptyPlaceList != null && findEmptyPlaceList.Count > 0) { List removeIdList = new List(); var noFinishTask = await _wareTaskRep.AsQueryable().Where(x => x.TaskStatus != TaskStatusEnum.已完成 && x.TaskStatus != TaskStatusEnum.已取消).ToListAsync(); var noFinishTask_Form = noFinishTask.Select(x => x.SourcePlaceCode).ToList(); var noFinishTask_To = noFinishTask.Select(x => x.ToPlaceCode).ToList(); //排除未结束任务占用的 findEmptyPlaceList = findEmptyPlaceList.Where(x => !noFinishTask_Form.Contains(x.PlaceCode) && !noFinishTask_To.Contains(x.PlaceCode)).ToList(); } } /// /// 自定义查询条件 -- 筛选条件 /// protected virtual void DiyFilter() { } /// /// 数据排序 /// protected virtual void DataOrder() { if (findEmptyPlaceList != null && findEmptyPlaceList.Count > 0) { findEmptyPlaceList = findEmptyPlaceList //先按照层,升序排列 .OrderBy(x => x.LayerNo) //再按照列,升序排列 .ThenBy(x => x.ColumnNo).ToList(); } } #endregion #region 公共方法 /// /// 获取可用的堆垛机所在的巷道集合 /// /// protected async Task> GetEnableLaneList() { //根据自己的项目自行判断 ////该库位如果所在的堆垛机被设定为 禁用,则不允许寻找该库位 //var eqType = _wareEquipmentTypeRep.FirstOrDefault(x => x.Code == EquipmentTypeEnum.Srm.ToString()); //if (eqType == null) //{ // throw Oops.Bah("没有找到类型是堆垛机的数据"); //} //var noramlEquipmentList = _wareEquipmentRep.Where(x => x.Status == 0 && x.EquipmentTypeId == eqType.Id).ToList();//查询所有可用的堆垛机列表 //if (noramlEquipmentList != null && noramlEquipmentList.Count > 0) //{ // return noramlEquipmentList.Where(x => x.Lane != null).Select(x => x.Lane).ToList(); //} return null; } #endregion } }