public async Task <ApiData> TakeOnline(int id, TakeOnlineArgs args) { Laneway laneway = await _session.GetAsync <Laneway>(id); if (laneway == null) { throw new InvalidOperationException("巷道不存在"); } if (laneway.Offline == false) { throw new InvalidOperationException($"巷道已处于联机状态。【{laneway.LanewayCode}】"); } laneway.Offline = false; laneway.TotalOfflineHours += DateTime.Now.Subtract(laneway.TakeOfflineTime).TotalHours; laneway.OfflineComment = args.Comment; await _session.UpdateAsync(laneway); _ = await _opHelper.SaveOpAsync($"巷道【{laneway.LanewayCode}】"); _logger.Information("已将巷道 {lanewayCode} 联机", laneway.LanewayCode); return(this.Success()); }
public async Task <ApiData> TakeOffline(int id, [FromBody] TakeOfflineArgs args) { Laneway laneway = await _session.GetAsync <Laneway>(id); if (laneway == null) { throw new InvalidOperationException("巷道不存在。"); } if (laneway.Offline == true) { throw new InvalidOperationException($"巷道已处于脱机状态。【{laneway.LanewayCode}】"); } laneway.Offline = true; laneway.TakeOfflineTime = DateTime.Now; laneway.OfflineComment = args.Comment; await _session.UpdateAsync(laneway); _ = await _opHelper.SaveOpAsync($"巷道【{laneway.LanewayCode}】,备注【{args.Comment}】"); _logger.Information("已将巷道 {lanewayCode} 脱机", laneway.LanewayCode); return(this.Success()); }
/// <summary> /// 在指定的巷道和分组中分配一个货位以供入库。 /// </summary> /// <param name="laneway">要在其中分配货位的巷道。</param> /// <param name="excludedIdList">要排除的货位。</param> /// <param name="excludedColumnList">要排除的列。</param> /// <param name="excludedLevelList">要排除的层。</param> /// <param name="cargoInfo">入库的货物信息。</param> /// <param name="orderBy">排序依据。这是 LocationUnit 类的属性名。</param> /// <returns> /// 从不返回 null。 /// </returns> public async Task <SResult> AllocateAsync( Laneway laneway, UnitloadStorageInfo cargoInfo, int[] excludedIdList = null, int[] excludedColumnList = null, int[] excludedLevelList = null, string orderBy = "i1") { if (laneway == null) { throw new ArgumentNullException(nameof(laneway)); } if (string.IsNullOrWhiteSpace(orderBy)) { throw new ArgumentException("参数 orderBy 不能为 null 或空字符串。"); } _logger.Debug("巷道 {lanewayCode}", laneway.LanewayCode); var rules = _rules.Where(x => x.DoubleDeep == laneway.DoubleDeep).OrderBy(x => x.Order); Stopwatch sw = new Stopwatch(); foreach (var rule in rules) { _logger.Debug("正在测试 {ruleName}", rule.Name); sw.Restart(); var loc = await rule.SelectAsync(laneway, cargoInfo, excludedIdList, excludedColumnList, excludedLevelList, orderBy).ConfigureAwait(false); sw.Stop(); //// TODO 涉及巷道过多时,会打开很多session,需优化 //ThreadPool.QueueUserWorkItem(state => //{ // using (ILifetimeScope scope = _lifetimeScope.BeginLifetimeScope()) // { // var ruleNames = _rules.Select(x => x.Name); // RuleStatHelper ruleStatHelper = scope.Resolve<RuleStatHelper>(TypedParameter.From(ruleNames)); // ruleStatHelper.Update(rule.Name, loc, DateTime.Now, sw.ElapsedMilliseconds); // } //}); if (loc != null) { _logger.Debug("{ruleName} 成功分配到货位 {locationCode}", rule.Name, loc.LocationCode); return(SResult.MakeSuccess(loc)); } else { _logger.Debug("{ruleName} 失败", rule.Name); } } return(SResult.Failure); }
public async Task <ApiData> SetPorts(int id, SetPortsArgs args) { Laneway laneway = await _session.GetAsync <Laneway>(id); if (laneway == null) { throw new InvalidOperationException("巷道不存在"); } laneway.Ports.Clear(); foreach (var portId in args.PortIdList) { Port port = await _session.GetAsync <Port>(portId); laneway.Ports.Add(port); } var op = await _opHelper.SaveOpAsync("巷道【{0}】,{1} 个出货口", laneway.LanewayCode, laneway.Ports.Count); _logger.Information("设置出货口成功,{lanewayCode} --> {ports}", laneway.LanewayCode, string.Join(",", laneway.Ports.Select(x => x.PortCode))); return(this.Success()); }
/// <summary> /// 在指定的巷道和分组中分配一个货位以供入库。 /// </summary> /// <param name="laneway">要在其中分配货位的巷道。</param> /// <param name="excludedIdList">要排除的货位。</param> /// <param name="excludedColumnList">要排除的列。</param> /// <param name="excludedLevelList">要排除的层。</param> /// <param name="storageInfo">入库货物信息。</param> /// <param name="orderBy">排序依据。这是 LocationUnit 类的属性名。</param> /// <returns></returns> public async Task <Location> SelectAsync(Laneway laneway, UnitloadStorageInfo storageInfo, int[] excludedIdList, int[] excludedColumnList, int[] excludedLevelList, string orderBy) { if (laneway == null) { throw new ArgumentNullException("laneway"); } if (storageInfo == null) { throw new ArgumentNullException("cargoInfo"); } if (string.IsNullOrWhiteSpace(orderBy)) { throw new ArgumentException("参数 orderBy 不能为 null 或空字符串。"); } if (laneway.DoubleDeep != this.DoubleDeep) { string msg = $"巷道类型不匹配,此规则适用于单深巷道,但传入的巷道是双深。【{laneway.LanewayCode}】。"; throw new InvalidOperationException(msg); } if (laneway.Offline) { _logger.Warning("巷道 {lanewayCode} 已离线", laneway.LanewayCode); return(null); } string queryString = $@" SELECT loc.LocationId FROM Location loc JOIN loc.Rack rack JOIN loc.Cell c WHERE rack.Laneway = :laneway AND loc.Exists = true AND loc.UnitloadCount = 0 AND loc.OutboundCount = 0 AND loc.InboundDisabled = false AND loc.InboundCount = 0 AND loc.WeightLimit >= :weight AND loc.HeightLimit >= :height AND loc.StorageGroup = :storageGroup AND loc.Specification = :locSpec {"AND loc.LocationId NOT IN (:excludedIdList)".If(excludedIdList)} {"AND loc.Column NOT IN (:excludedColumnList)".If(excludedColumnList)} {"AND loc.Level NOT IN (:excludedLevelList)".If(excludedLevelList)} ORDER BY loc.WeightLimit, loc.HeightLimit, c.$orderBy "; queryString = queryString.Replace("$orderBy", orderBy); IQuery q = _session .CreateQuery(queryString) .SetParameter("laneway", laneway) .SetParameter("weight", storageInfo.Weight) .SetParameter("height", storageInfo.Height) .SetParameter("storageGroup", storageInfo.StorageGroup) .SetParameter("locSpec", storageInfo.ContainerSpecification) .EmptySafeSetParameterList("excludedIdList", excludedIdList) .EmptySafeSetParameterList("excludedColumnList", excludedColumnList) .EmptySafeSetParameterList("excludedLevelList", excludedLevelList) .SetMaxResults(1); int?id = await q.UniqueResultAsync <int?>().ConfigureAwait(false); if (id == null) { return(null); } else { var loc = await _session.GetAsync <Location>(id.Value).ConfigureAwait(false); return(loc); } }
/// <summary> /// 在指定的巷道和分组中分配一个货位以供入库。 /// </summary> /// <param name="laneway">要在其中分配货位的巷道。</param> /// <param name="excludedIdList">要排除的货位。</param> /// <param name="excludedColumnList">要排除的列。</param> /// <param name="excludedLevelList">要排除的层。</param> /// <param name="storageInfo">入库货物信息。</param> /// <param name="orderBy">排序依据。这是 LocationUnit 类的属性名。</param> /// <returns></returns> public async Task <Location> SelectAsync(Laneway laneway, UnitloadStorageInfo storageInfo, int[] excludedIdList, int[] excludedColumnList, int[] excludedLevelList, string orderBy) { if (laneway == null) { throw new ArgumentNullException(nameof(laneway)); } if (storageInfo == null) { throw new ArgumentNullException("cargoInfo"); } if (string.IsNullOrWhiteSpace(orderBy)) { throw new ArgumentException("参数 orderBy 不能为 null 或空字符串。"); } if (laneway.DoubleDeep != this.DoubleDeep) { string msg = $"巷道类型不匹配,此规则适用于双深巷道,但传入的巷道是单深。【{laneway.LanewayCode}】。"; throw new InvalidOperationException(msg); } if (laneway.Offline) { _logger.Warning("巷道 {lanewayCode} 已离线", laneway.LanewayCode); return(null); } // 此规则向双深单元的一深分配 // 使双深单元的有货标记从 01| 变为 11| // 会考虑二深的出库标记和分配标记 string queryString = $@" SELECT loc1.LocationId FROM Location loc1 JOIN loc1.Rack rack1 JOIN loc1.Cell c, Location loc2 JOIN loc2.Rack rack2 WHERE rack1.Deep = 1 AND rack2.Deep = 2 AND loc1.Cell = loc2.Cell AND rack1.Laneway = :laneway AND loc2.Exists = true AND loc2.UnitloadCount > 0 AND loc2.OutboundCount = 0 AND loc2.InboundCount = 0 AND NOT EXISTS ( FROM Unitload WHERE CurrentLocation = loc2 AND (OutFlag <> :outFlag OR Allocated = true) ) AND loc1.Exists = true AND loc1.UnitloadCount = 0 AND loc1.OutboundCount = 0 AND loc1.InboundDisabled = false AND loc1.InboundCount = 0 AND loc1.WeightLimit >= :weight AND loc1.HeightLimit >= :height AND loc1.StorageGroup = :storageGroup AND loc1.Specification = :locSpec {"AND loc1.LocationId NOT IN (:excludedIdList)".If(excludedIdList)} {"AND loc1.Column NOT IN (:excludedColumnList)".If(excludedColumnList)} {"AND loc1.Level NOT IN (:excludedLevelList)".If(excludedLevelList)} ORDER BY loc1.WeightLimit, loc1.HeightLimit, c.$orderBy "; queryString = queryString.Replace("$orderBy", orderBy); IQuery q = _session .CreateQuery(queryString) .SetParameter("laneway", laneway) .SetParameter("outFlag", storageInfo.OutFlag) .SetParameter("weight", storageInfo.Weight) .SetParameter("height", storageInfo.Height) .SetParameter("storageGroup", storageInfo.StorageGroup) .SetParameter("locSpec", storageInfo.ContainerSpecification) .EmptySafeSetParameterList("excludedIdList", excludedIdList) .EmptySafeSetParameterList("excludedColumnList", excludedColumnList) .EmptySafeSetParameterList("excludedLevelList", excludedLevelList) .SetMaxResults(1); int?id = await q.UniqueResultAsync <int?>().ConfigureAwait(false); if (id == null) { return(null); } else { var loc = await _session.GetAsync <Location>(id.Value).ConfigureAwait(false); return(loc); } }