From 4ac3f08f416685db0e218df55750d94556030330 Mon Sep 17 00:00:00 2001
From: HuBingJie <3146306518@qq.com>
Date: 星期四, 06 十一月 2025 20:25:17 +0800
Subject: [PATCH] 1
---
项目代码/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/WIDESEA_BasicService/LocationInfoService.cs | 307 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 307 insertions(+), 0 deletions(-)
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/WIDESEA_BasicService/LocationInfoService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/WIDESEA_BasicService/LocationInfoService.cs"
index 16c743a..cc5eca5 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/WIDESEA_BasicService/LocationInfoService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/WIDESEA_BasicService/LocationInfoService.cs"
@@ -153,5 +153,312 @@
return WebResponseContent.Instance.Error(ex.Message);
}
}
+
+ private readonly static object _locker = new object();
+ static List<LocationCache> locationCaches = new List<LocationCache>();
+ /// <summary>
+ /// 鍒嗛厤璐т綅
+ /// </summary>
+ /// <param name="roadwayNo"></param>
+ /// <param name="palletType"></param>
+ /// <param name="warehouseId"></param>
+ /// <param name="beRelocationCode"></param>
+ /// <param name="heightType"></param>
+ /// <returns></returns>
+ /// <exception cref="Exception"></exception>
+ public Dt_LocationInfo? AssignLocation(string roadwayNo, int warehouseId, string beRelocationCode = "")
+ {
+
+ lock (_locker)
+ {
+ List<LocationCache> removeItems = locationCaches.Where(x => (DateTime.Now - x.DateTime).TotalMinutes > 5).ToList();
+ int count = removeItems.Count;
+ for (int i = 0; i < count; i++)
+ {
+ locationCaches.Remove(removeItems[i]);
+ }
+
+ List<string> lockLocationCodes = locationCaches.Select(x => x.LocationCode).ToList();
+
+ List<Dt_LocationInfo> locationInfos = Repository.QueryData(x => x.RoadwayNo == roadwayNo);
+ if (locationInfos == null || locationInfos.Count == 0)
+ {
+ throw new Exception($"鏈壘鍒拌宸烽亾鐨勮揣浣嶄俊鎭�,宸烽亾鍙�:{roadwayNo}");
+ }
+
+ if (!string.IsNullOrEmpty(beRelocationCode))
+ {
+ Dt_LocationInfo? beRelocation = locationInfos.FirstOrDefault(x => x.LocationCode == beRelocationCode);
+ if (beRelocation == null)
+ {
+ throw new Exception($"鏈壘鍒拌揣浣嶄俊鎭�");
+ }
+ int maxDepth = locationInfos.Max(x => x.Depth);
+ int mathCurrentRow = beRelocation.Row - Convert.ToInt32(Math.Ceiling(beRelocation.Row / maxDepth / 2.0)) * maxDepth * 2;
+ if (mathCurrentRow <= maxDepth)
+ {
+ locationInfos = locationInfos.Where(x => x.Row - Convert.ToInt32(Math.Ceiling(x.Row / maxDepth / 2.0)) * maxDepth * 2 <= maxDepth).ToList();
+ }
+ else
+ {
+ locationInfos = locationInfos.Where(x => x.Row - Convert.ToInt32(Math.Ceiling(x.Row / maxDepth / 2.0)) * maxDepth * 2 > maxDepth).ToList();
+ }
+ }
+
+
+ //鏈畾涔夌被鍨嬬殑绌鸿揣浣�
+ List<Dt_LocationInfo> undefinedTypeEmptyLocations = locationInfos.Where(x => (x.EnableStatus == EnableStatusEnum.Normal.ObjToInt() || x.EnableStatus == EnableStatusEnum.OnlyIn.ObjToInt()) && x.LocationStatus == LocationStatusEnum.Free.ObjToInt() && x.LocationType == LocationTypeEnum.Undefined.ObjToInt() && !lockLocationCodes.Contains(x.LocationCode)).OrderByDescending(x => x.Depth).ThenBy(x => x.Layer).ThenBy(x => x.Column).ThenBy(x => x.Row).ToList();
+
+ List<Dt_LocationInfo> definedTypeEmptyLocations = locationInfos.Where(x => (x.EnableStatus == EnableStatusEnum.Normal.ObjToInt() || x.EnableStatus == EnableStatusEnum.OnlyIn.ObjToInt()) && x.LocationStatus == LocationStatusEnum.Free.ObjToInt() && !lockLocationCodes.Contains(x.LocationCode)).OrderByDescending(x => x.Depth).ThenBy(x => x.Layer).ThenBy(x => x.Column).ThenBy(x => x.Row).ToList();
+
+ if (definedTypeEmptyLocations.Any())
+ {
+ for (int i = 0; i < definedTypeEmptyLocations.Count; i++)
+ {
+ Dt_LocationInfo definedTypeEmptyLocation = definedTypeEmptyLocations[i];
+ Dt_LocationInfo? locationInfo = GetUsableLocation_BC(locationInfos, definedTypeEmptyLocation);
+ //鍒ゆ柇璐т綅涓ゆ繁鍙婁互涓婃槸鍚﹀瓨鍦ㄥ嚭搴撻攣瀹氳揣浣�
+ if (locationInfo?.Depth == 1)
+ {
+ Dt_LocationInfo? IsBebusyLocation = locationInfos.Where(x => x.Row == (locationInfo?.Row == 2 ? locationInfo?.Row - 1 : locationInfo?.Row + 1) && x.Column == locationInfo?.Column && x.Layer == locationInfo?.Layer).FirstOrDefault();
+ if (IsBebusyLocation != null && (IsBebusyLocation.LocationStatus <= LocationStatusEnum.InStock.ObjToInt()))
+ {
+ continue;
+ }
+ }
+ if (locationInfo != null)
+ {
+ locationCaches.Add(new LocationCache { LocationCode = locationInfo.LocationCode, DateTime = DateTime.Now });
+ return locationInfo;
+ }
+ }
+ }
+ if ((undefinedTypeEmptyLocations.Any()))//濡傛灉宸插畾涔夌被鍨嬭揣浣嶆湭瓒呰繃姣斾緥锛屼笖鏈夋湭瀹氫箟绫诲瀷鐨勮揣浣�
+ {
+ Dt_LocationInfo undefinedTypeEmptyLocation = undefinedTypeEmptyLocations.FirstOrDefault();
+ Dt_LocationInfo? locationInfo = GetUsableLocation_BC(locationInfos, undefinedTypeEmptyLocation);
+ locationCaches.Add(new LocationCache { LocationCode = locationInfo.LocationCode, DateTime = DateTime.Now });
+ return locationInfo;
+ }
+ return null;
+ }
+ }
+
+
+ /// <summary>
+ /// 搴撲綅鍒嗛厤,鏃犲贩閬撳彿杩涜鍒嗛厤鍙�
+ /// </summary>
+ /// <returns></returns>
+ public Dt_LocationInfo? GetLocationInfo()
+ {
+ lock (_locker)
+ {
+ List<LocationCache> removeItems = locationCaches.Where(x => (DateTime.Now - x.DateTime).TotalMinutes > 20).ToList();//鏌ヨ娣诲姞闈欐�佸彉閲忚秴杩�5鍒嗛挓鐨勮揣浣�
+ int count = removeItems.Count;
+ for (int i = 0; i < count; i++)
+ {
+ locationCaches.Remove(removeItems[i]);//绉婚櫎鏌ヨ娣诲姞闈欐�佸彉閲忚秴杩�5鍒嗛挓鐨勮揣浣�
+ }
+
+ List<string> lockLocations = locationCaches.Select(x => x.LocationCode).ToList();
+
+ List<Dt_LocationInfo> locationInfos = BaseDal.QueryData();//鏌ヨ宸烽亾鎵�鏈夎揣浣嶄俊鎭�
+ List<Dt_LocationInfo> emptyLocations = locationInfos.Where(x => x.LocationStatus == LocationStatusEnum.Free.ObjToInt() && !lockLocations.Contains(x.LocationCode)).OrderBy(x => x.Layer).ThenBy(x => x.Column).ThenByDescending(x => x.Depth).ThenBy(x => x.Row).ToList();//鏌ヨ绌鸿揣浣嶄俊鎭苟鎺掗櫎5鍒嗛挓鍐呭垎閰嶇殑璐т綅,鏍规嵁灞傘�佸垪銆佹繁搴︺�佽鎺掑簭
+
+
+ for (int i = 0; i < emptyLocations.Count; i++)
+ {
+ if (emptyLocations[i].Depth == 1)//鍒ゆ柇鏄惁1娣辫揣浣�
+ {
+ Dt_LocationInfo? sencondDepthLocation = locationInfos.FirstOrDefault(x => Math.Abs(x.Row - emptyLocations[i].Row) == 1 && x.Layer == emptyLocations[i].Layer && x.Column == emptyLocations[i].Column);//鏌ヨ2娣辫揣浣嶅搴旂殑1娣辫揣浣嶆槸鍚︿负绌�,闃叉鍑虹幇鍒嗛厤1娣辫揣浣嶈��2娣辫揣浣嶄负绌虹殑鎯呭喌
+ if (sencondDepthLocation != null && sencondDepthLocation.LocationStatus == LocationStatusEnum.Free.ObjToInt())
+ {
+ locationCaches.Add(new LocationCache { DateTime = DateTime.Now, LocationCode = sencondDepthLocation.LocationCode });
+ return sencondDepthLocation;//1娣辫揣浣嶅強2娣辫揣浣嶉兘涓虹┖鐨勬儏鍐典笅,浼樺厛鍒嗛厤2娣辫揣浣�
+ }
+ else
+ {
+ locationCaches.Add(new LocationCache { DateTime = DateTime.Now, LocationCode = emptyLocations[i].LocationCode });
+ return emptyLocations[i];
+ }
+ }
+ else
+ {
+ Dt_LocationInfo? sencondDepthLocation = locationInfos.FirstOrDefault(x => Math.Abs(x.Row - emptyLocations[i].Row) == 1 && x.Layer == emptyLocations[i].Layer && x.Column == emptyLocations[i].Column);//鏌ヨ2娣辫揣浣嶅搴旂殑1娣辫揣浣嶆槸鍚︿负绌�
+ if (sencondDepthLocation != null && sencondDepthLocation.LocationStatus == LocationStatusEnum.Free.ObjToInt())
+ {
+ locationCaches.Add(new LocationCache { DateTime = DateTime.Now, LocationCode = emptyLocations[i].LocationCode });
+ return emptyLocations[i];
+ }
+ }
+ }
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// 鍒ゆ柇宸烽亾鍐呯Щ搴�,鑾峰彇璐т綅
+ /// </summary>
+ /// <param name="roadway"></param>
+ /// <returns></returns>
+ public Dt_LocationInfo? GetLocation(string roadway)
+ {
+ lock (_locker)
+ {
+ List<LocationCache> removeItems = locationCaches.Where(x => (DateTime.Now - x.DateTime).TotalMinutes > 20).ToList();//鏌ヨ娣诲姞闈欐�佸彉閲忚秴杩�20鍒嗛挓鐨勮揣浣�
+ int count = removeItems.Count;
+ for (int i = 0; i < count; i++)
+ {
+ locationCaches.Remove(removeItems[i]);//绉婚櫎鏌ヨ娣诲姞闈欐�佸彉閲忚秴杩�5鍒嗛挓鐨勮揣浣�
+ }
+
+ List<string> lockLocations = locationCaches.Select(x => x.LocationCode).ToList();
+
+ List<Dt_LocationInfo> locationInfos = BaseDal.QueryData(x => x.RoadwayNo == roadway && x.LocationStatus == LocationStatusEnum.Free.ObjToInt() && !lockLocations.Contains(x.LocationCode));//鏌ヨ宸烽亾鎵�鏈夎揣浣嶄俊鎭�
+
+
+ List<Dt_LocationInfo> emptyLocations = locationInfos.Where(x => x.LocationStatus == LocationStatusEnum.Free.ObjToInt() && !lockLocations.Contains(x.LocationCode)).OrderBy(x => x.Layer).ThenBy(x => x.Column).ThenByDescending(x => x.Depth).ThenBy(x => x.Row).ToList();//鏌ヨ绌鸿揣浣嶄俊鎭苟鎺掗櫎20鍒嗛挓鍐呭垎閰嶇殑璐т綅,鏍规嵁灞傘�佸垪銆佹繁搴︺�佽鎺掑簭
+
+
+ for (int i = 0; i < emptyLocations.Count; i++)
+ {
+ if (emptyLocations[i].Depth == 1)//鍒ゆ柇鏄惁1娣辫揣浣�
+ {
+ Dt_LocationInfo? sencondDepthLocation = locationInfos.FirstOrDefault(x => Math.Abs(x.Row - emptyLocations[i].Row) == 1 && x.Layer == emptyLocations[i].Layer && x.Column == emptyLocations[i].Column);//鏌ヨ2娣辫揣浣嶅搴旂殑1娣辫揣浣嶆槸鍚︿负绌�,闃叉鍑虹幇鍒嗛厤1娣辫揣浣嶈��2娣辫揣浣嶄负绌虹殑鎯呭喌
+ if (sencondDepthLocation != null && sencondDepthLocation.LocationStatus == LocationStatusEnum.Free.ObjToInt())
+ {
+ locationCaches.Add(new LocationCache { DateTime = DateTime.Now, LocationCode = sencondDepthLocation.LocationCode });
+ return sencondDepthLocation;//1娣辫揣浣嶅強2娣辫揣浣嶉兘涓虹┖鐨勬儏鍐典笅,浼樺厛鍒嗛厤2娣辫揣浣�
+ }
+ else
+ {
+ if (sencondDepthLocation != null && sencondDepthLocation.LocationStatus != LocationStatusEnum.Lock.ObjToInt()) //鍒ゆ柇浜屾繁鏃犱换鍔�
+ {
+ locationCaches.Add(new LocationCache { DateTime = DateTime.Now, LocationCode = emptyLocations[i].LocationCode });
+ return emptyLocations[i];
+ }
+ }
+ }
+ else
+ {
+ Dt_LocationInfo? sencondDepthLocation = locationInfos.FirstOrDefault(x => Math.Abs(x.Row - emptyLocations[i].Row) == 1 && x.Layer == emptyLocations[i].Layer && x.Column == emptyLocations[i].Column);//鏌ヨ2娣辫揣浣嶅搴旂殑1娣辫揣浣嶆槸鍚︿负绌�
+
+ if (sencondDepthLocation != null && sencondDepthLocation.LocationStatus == LocationStatusEnum.Free.ObjToInt())
+ {
+ locationCaches.Add(new LocationCache { DateTime = DateTime.Now, LocationCode = emptyLocations[i].LocationCode });
+ return emptyLocations[i];
+ }
+ }
+ }
+ return null;
+ }
+ }
+
+
+
+ /// <summary>
+ /// 鑾峰彇鍙敤璐т綅
+ /// </summary>
+ /// <param name="locationInfos"></param>
+ /// <param name="emptyLocation"></param>
+ /// <param name="palletType"></param>
+ /// <returns></returns>
+ private Dt_LocationInfo? GetUsableLocation_BC(List<Dt_LocationInfo> locationInfos, Dt_LocationInfo emptyLocation)
+ {
+
+ //Dt_LocationInfo? nearLocation = null;
+ //if (emptyLocation.Column % 2 == 1)
+ // nearLocation = locationInfos.FirstOrDefault(x => x.Row == emptyLocation.Row && x.Layer == emptyLocation.Layer && x.Depth == emptyLocation.Depth && x.Column == emptyLocation.Column - 1);
+ //else if (emptyLocation.Column % 2 == 0)
+ // nearLocation = locationInfos.FirstOrDefault(x => x.Row == emptyLocation.Row && x.Layer == emptyLocation.Layer && x.Depth == emptyLocation.Depth && x.Column == emptyLocation.Column + 1);
+ //if (nearLocation != null && DepthLocationIsEmpty_BC(locationInfos, nearLocation) != null)
+ //{
+ Dt_LocationInfo? locationInfo = DepthLocationIsEmpty_BC(locationInfos, emptyLocation);
+ if (locationInfo != null)
+ {
+ return locationInfo;
+ }
+ //}
+
+ return null;
+ }
+
+
+ /// <summary>
+ /// 鍒ゆ柇涓嶅悓娣卞害鐨勫悓缁勮揣浣嶇姸鎬佹槸鍚︿负绌洪棽绌轰綅
+ /// </summary>
+ /// <param name="locationInfos"></param>
+ /// <param name="emptyLocation"></param>
+ /// <returns></returns>
+ private Dt_LocationInfo? DepthLocationIsEmpty_BC(List<Dt_LocationInfo> locationInfos, Dt_LocationInfo emptyLocation)
+ {
+ List<Dt_LocationInfo> locations = GetGroupLocations(locationInfos, emptyLocation);
+
+ bool moreDepthFlag = false;
+ bool littleDepthFlag = false;
+
+ if (emptyLocation.LocationType == 0)
+ {
+ List<Dt_LocationInfo> moreDepth = locations.Where(x => x.Depth > emptyLocation.Depth).ToList();
+ moreDepthFlag = moreDepth.FirstOrDefault(x => x.LocationStatus != LocationStatusEnum.InStock.ObjToInt() && (x.EnableStatus == EnableStatusEnum.OnlyIn.ObjToInt() || x.EnableStatus == EnableStatusEnum.Normal.ObjToInt()) && x.LocationType != 0) == null;//鏌ヨ澶т簬褰撳墠璐т綅娣卞害鐨勯泦鍚堥噷鏄惁鏈夌姸鎬佷笉涓烘湁璐х殑璐т綅锛屽鏋滄槸true锛屽垯琛ㄧず娣辫揣浣嶆湁鏈浣跨敤鐨勬儏鍐�
+
+ List<Dt_LocationInfo> littleDepth = locations.Where(x => x.Depth <= emptyLocation.Depth).ToList();
+ littleDepthFlag = littleDepth.FirstOrDefault(x => x.LocationStatus != LocationStatusEnum.Free.ObjToInt() && (x.EnableStatus == EnableStatusEnum.OnlyIn.ObjToInt() || x.EnableStatus == EnableStatusEnum.Normal.ObjToInt()) && x.LocationType != 0) == null; //鏌ヨ灏忎簬褰撳墠璐т綅娣卞害鐨勯泦鍚堥噷鏄惁鏈夌姸鎬佷笉涓虹┖锛屼笖绂佺敤鐘舵�佷笉涓虹鐢ㄤ互鍙婂彧鍏ョ殑璐т綅锛屽鏋滄槸true锛屽垯琛ㄧず娴呰揣浣嶈浣跨敤鎴栬�呰绂佺敤鐨勬儏鍐�
+ }
+ else
+ {
+ List<Dt_LocationInfo> moreDepth = locations.Where(x => x.Depth > emptyLocation.Depth).ToList();
+ moreDepthFlag = moreDepth.FirstOrDefault(x => x.LocationStatus != LocationStatusEnum.InStock.ObjToInt() && (x.EnableStatus == EnableStatusEnum.OnlyIn.ObjToInt() || x.EnableStatus == EnableStatusEnum.Normal.ObjToInt()) && x.LocationType != emptyLocation.LocationType) == null;//鏌ヨ澶т簬褰撳墠璐т綅娣卞害鐨勯泦鍚堥噷鏄惁鏈夌姸鎬佷笉涓烘湁璐х殑璐т綅锛屽鏋滄槸true锛屽垯琛ㄧず娣辫揣浣嶆湁鏈浣跨敤鐨勬儏鍐�
+
+ List<Dt_LocationInfo> littleDepth = locations.Where(x => x.Depth <= emptyLocation.Depth).ToList();
+ littleDepthFlag = littleDepth.FirstOrDefault(x => x.LocationStatus != LocationStatusEnum.Free.ObjToInt() && (x.EnableStatus == EnableStatusEnum.OnlyIn.ObjToInt() || x.EnableStatus == EnableStatusEnum.Normal.ObjToInt()) && x.LocationType != emptyLocation.LocationType) == null; //鏌ヨ灏忎簬褰撳墠璐т綅娣卞害鐨勯泦鍚堥噷鏄惁鏈夌姸鎬佷笉涓虹┖锛屼笖绂佺敤鐘舵�佷笉涓虹鐢ㄤ互鍙婂彧鍏ョ殑璐т綅锛屽鏋滄槸true锛屽垯琛ㄧず娴呰揣浣嶈浣跨敤鎴栬�呰绂佺敤鐨勬儏鍐�
+ }
+ if (moreDepthFlag && littleDepthFlag)
+ {
+ return emptyLocation;
+ }
+
+ return null;
+ }
+ /// <summary>
+ /// 鑾峰彇涓嶅悓娣卞害鐨勫悓缁勮揣浣嶄俊鎭�
+ /// </summary>
+ /// <param name="locationInfos"></param>
+ /// <param name="location"></param>
+ /// <returns></returns>
+ public List<Dt_LocationInfo> GetGroupLocations(List<Dt_LocationInfo> locationInfos, Dt_LocationInfo location)
+ {
+ List<Dt_LocationInfo> groupLocations = new List<Dt_LocationInfo>() { location };
+ int maxDepth = locationInfos.Max(x => x.Depth);
+ int row = location.Row;
+ for (int j = location.Depth + 1; j <= maxDepth; j++)
+ {
+ row += 1;
+ Dt_LocationInfo? locationInfo = locationInfos.FirstOrDefault(x => x.Depth == j && x.Column == location.Column && x.Layer == location.Layer && x.Row == row);
+ if (locationInfo != null)
+ {
+ groupLocations.Add(locationInfo);
+ }
+ }
+
+ for (int j = location.Depth - 1; j >= 1; j--)
+ {
+ row -= 1;
+ Dt_LocationInfo? locationInfo = locationInfos.FirstOrDefault(x => x.Depth == j && x.Column == location.Column && x.Layer == location.Layer && x.Row == row);
+ if (locationInfo != null)
+ {
+ groupLocations.Add(locationInfo);
+ }
+ }
+ return groupLocations;
+ }
+
+
+ public class LocationCache
+ {
+ public string LocationCode { get; set; }
+
+ public DateTime DateTime { get; set; }
+ }
}
}
--
Gitblit v1.9.3