From bfcd7f5b405e431a5c07fe3fa77d74c892d4e66b Mon Sep 17 00:00:00 2001
From: xiazhengtongxue <133085197+xiazhengtongxue@users.noreply.github.com>
Date: 星期四, 19 三月 2026 15:52:42 +0800
Subject: [PATCH] fix: 修复出入库冲突拦截,系统位置与实际位置的映射和修复

---
 项目代码/WMS/WIDESEA_WMSServer/WIDESEA_BasicService/LocationInfoService.cs |  302 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 291 insertions(+), 11 deletions(-)

diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS/WIDESEA_WMSServer/WIDESEA_BasicService/LocationInfoService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS/WIDESEA_WMSServer/WIDESEA_BasicService/LocationInfoService.cs"
index f3a3025..cc91e60 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS/WIDESEA_WMSServer/WIDESEA_BasicService/LocationInfoService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS/WIDESEA_WMSServer/WIDESEA_BasicService/LocationInfoService.cs"
@@ -1,4 +1,5 @@
 锘縰sing HslCommunication.WebSocket;
+using OfficeOpenXml.FormulaParsing.Excel.Functions.Math;
 using OfficeOpenXml.FormulaParsing.Excel.Functions.RefAndLookup;
 using OfficeOpenXml.FormulaParsing.Excel.Functions.Text;
 using SqlSugar;
@@ -10,6 +11,7 @@
 using WIDESEA_Common.CommonEnum;
 using WIDESEA_Common.LocationEnum;
 using WIDESEA_Common.StockEnum;
+using WIDESEA_Common.WareHouseEnum;
 using WIDESEA_Core;
 using WIDESEA_Core.BaseRepository;
 using WIDESEA_Core.BaseServices;
@@ -30,6 +32,9 @@
         private readonly IUnitOfWorkManage _unitOfWorkManage;
         private readonly IRepository<Dt_StockInfo> _stockInfoRepository;
         public IRepository<Dt_LocationInfo> Repository => BaseDal;
+        private readonly static object _locker = new object();
+
+        public static List<LocationCache> locationCaches = new List<LocationCache>();
 
         public LocationInfoService(IRepository<Dt_LocationInfo> BaseDal, IUnitOfWorkManage unitOfWorkManage, IRepository<Dt_StockInfo> stockInfoRepository) : base(BaseDal)
         {
@@ -153,24 +158,299 @@
                 return WebResponseContent.Instance.Error(ex.Message);
             }
         }
-    
-        
+
+
         public string AccessingTunnel(int WarehouseId, int LocationType)
         {
             List<Dt_LocationInfo> locationData = BaseDal.QueryData(x => x.WarehouseId == WarehouseId);
-            var roadwayGroups = locationData
-                .Where(x => x.LocationType == LocationType)
-                .GroupBy(x => x.RoadwayNo)
+            var roadwayGroups = locationData.Where(x => x.LocationType == LocationType && x.LocationStatus== (int)LocationStatusEnum.Free && x.EnableStatus== (int)EnableStatusEnum.Normal).GroupBy(x => x.RoadwayNo)
+            .Select(g => new
+            {
+                RoadwayNo = g.Key,
+                LocationCount = g.Count(),
+            }).OrderByDescending(g => g.LocationCount).ToList();
+
+            int minRequired = 15;
+            if(WarehouseId== (int)WarehouseEnum.YMYL)
+            {
+                if (LocationType == 2) minRequired = 6;
+
+                var selectedRoadway = roadwayGroups.FirstOrDefault(g => g.LocationCount >= minRequired);
+                if(selectedRoadway!=null) return selectedRoadway.RoadwayNo;
+
+            }
+            else
+            {
+                var selectedRoadway = roadwayGroups.FirstOrDefault(g => g.LocationCount >= minRequired);
+                if(selectedRoadway == null)
+                {
+                    selectedRoadway = roadwayGroups.FirstOrDefault(g => g.RoadwayNo == "5" && g.LocationCount != 0);
+
+                }
+                if(selectedRoadway != null) return selectedRoadway.RoadwayNo;
+            }
+
+            return "0";
+        }
+
+
+        public Dt_LocationInfo? ShallowGetLocation(string roadway, int Locationtype,int row ,int Layer, int Column)
+        {
+            return BaseDal.QueryData(x => x.RoadwayNo == roadway && x.LocationType == Locationtype && x.Row==row && x.Layer== Layer && x.Column== Column).FirstOrDefault();
+        }
+
+        public Dt_LocationInfo? FindStorageLocation(string LocationCode)
+        {
+            return BaseDal.QueryData(x => x.LocationCode == LocationCode).FirstOrDefault();
+        }
+
+
+        //鏌ユ壘鏂拌揣浣�
+        public Dt_LocationInfo? GetLocation(string roadway, int Locationtype)
+        {
+            lock (_locker)
+            {
+                List<LocationCache> removeItems = locationCaches.Where(x => (DateTime.Now - x.DateTime).TotalMinutes > 5).ToList();//鏌ヨ娣诲姞闈欐�佸彉閲忚秴杩�10鍒嗛挓鐨勮揣浣�
+                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 = null;
+                locationInfos = BaseDal.QueryData(x => x.RoadwayNo == roadway && x.LocationType == Locationtype && x.EnableStatus == (int)EnableStatusEnum.Normal);
+
+
+                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娣辫揣浣�
+                    {
+                        //鏌ヨ娣卞簱浣�
+                        //int emprow = emptyLocations[i].Row == 2 ? 1 : 4;
+                        int emprow = judgmentRow(emptyLocations[i].RoadwayNo,emptyLocations[i].Row);
+
+                        Dt_LocationInfo? sencondDepthLocationShen = emptyLocations.FirstOrDefault(x => x.Row == emprow && x.Layer == emptyLocations[i].Layer && x.Column == emptyLocations[i].Column);
+                        if (sencondDepthLocationShen != null && sencondDepthLocationShen.LocationStatus == LocationStatusEnum.Free.ObjToInt())
+                        {
+                            locationCaches.Add(new LocationCache { DateTime = DateTime.Now, LocationCode = sencondDepthLocationShen.LocationCode });
+                            return sencondDepthLocationShen;//1娣辫揣浣嶅強2娣辫揣浣嶉兘涓虹┖鐨勬儏鍐典笅,浼樺厛鍒嗛厤2娣辫揣浣�
+                        }
+                        else
+                        {
+                            Dt_LocationInfo? sencondDepthLo = locationInfos.FirstOrDefault(x => x.Row == emprow && x.Layer == emptyLocations[i].Layer && x.Column == emptyLocations[i].Column);
+                            if (sencondDepthLo != null && sencondDepthLo.LocationStatus != LocationStatusEnum.Lock.ObjToInt() && sencondDepthLo.LocationStatus == LocationStatusEnum.InStock.ObjToInt() && !lockLocations.Contains(sencondDepthLo.LocationCode))
+                            {
+                                locationCaches.Add(new LocationCache { DateTime = DateTime.Now, LocationCode = emptyLocations[i].LocationCode });
+                                return emptyLocations[i];
+                            }else if (emptyLocations[i].RoadwayNo=="5" && emptyLocations[i].LocationStatus == LocationStatusEnum.Free.ObjToInt())
+                            {
+                                locationCaches.Add(new LocationCache { DateTime = DateTime.Now, LocationCode = emptyLocations[i].LocationCode });
+                                return emptyLocations[i];
+                            }
+                        }
+                    }
+                    else
+                    {
+                        //鏌ヨ2娣辫揣浣嶅搴旂殑1娣辫揣浣嶆槸鍚︿负绌�
+                        //int emprow = emptyLocations[i].Row == 4 ? 3 : 2;
+                        int emprow = judgmentRow(emptyLocations[i].RoadwayNo, emptyLocations[i].Row);
+
+                        Dt_LocationInfo? sencondDepthLocationQian = emptyLocations.FirstOrDefault(x => x.Row == emprow && x.Layer == emptyLocations[i].Layer && x.Column == emptyLocations[i].Column);
+                        if (sencondDepthLocationQian != null && sencondDepthLocationQian.LocationStatus == LocationStatusEnum.Free.ObjToInt())
+                        {
+                            locationCaches.Add(new LocationCache { DateTime = DateTime.Now, LocationCode = emptyLocations[i].LocationCode });
+                            return emptyLocations[i];
+                        }
+                    }
+                }
+                return null;
+            }
+        }
+
+        public int judgmentRow(string RoadwayNo, int locrow)
+        {
+            if (RoadwayNo == "1" || RoadwayNo == "3")
+            {
+                if(locrow==1 || locrow == 4)
+                {
+                    return locrow == 1 ? 2 : 3;
+                }
+                else
+                {
+                    return locrow == 2 ? 1 : 4;
+                }
+               
+            }
+            else if (RoadwayNo == "2" || RoadwayNo == "4")
+            {
+                if (locrow == 5 || locrow == 8)
+                {
+                    return locrow == 5 ? 6 : 7;
+                }
+                else
+                {
+                    return locrow == 6 ? 5 : 8;
+                }
+                    
+            }
+            else
+            {
+                return 0;
+            }
+        }
+
+        public class LocationCache
+        {
+            public string LocationCode { get; set; }
+
+            public DateTime DateTime { get; set; }
+        }
+
+
+
+        public WebResponseContent GetArea()
+        {
+            // WarehouseId鍒嗙粍锛岀劧鍚庢槸RoadwayNo
+            var result = BaseDal.QueryData()
+                .GroupBy(x => x.WarehouseId)
+                .Select(g => new {
+                    WarehouseId = g.Key,
+                    RoadwayNo = g.Select(x => x.RoadwayNo).Distinct().ToList()
+                })
+                .ToList();
+            return WebResponseContent.Instance.OK("鎴愬姛", result);
+        }
+
+        public WebResponseContent GetLocationStatus(int WarehouseId, string RoadwayNo)
+        {
+            // 鏍煎紡{灞�,{杩欎竴灞傜殑鍒楁暟鎹畗}
+            var locations = BaseDal.QueryData(x => x.WarehouseId == WarehouseId && x.RoadwayNo == RoadwayNo)
+                .Select(x => new
+                {
+                    x.RoadwayNo,
+                    x.LocationCode,
+                    x.WarehouseId,
+                    x.Row,
+                    x.Column,
+                    x.Layer,
+                    x.Depth,
+                    x.LocationType,
+                    x.LocationStatus,
+                    x.EnableStatus
+                })
+                .ToList();
+
+            // 濡傛灉娌℃湁鎵惧埌鏁版嵁锛岃繑鍥炵┖鍒楄〃鑰屼笉鏄痭ull
+            if (locations == null || !locations.Any())
+            {
+                return WebResponseContent.Instance.OK("鏈壘鍒板搴斿贩閬撶殑璐т綅鏁版嵁", new List<object>());
+            }
+
+            // 淇敼涓哄眰涓嬮潰鏀炬墍鏈夊垪鐨勪俊鎭�
+            var result = locations
+                .GroupBy(x => x.Layer)  // 鎸夊眰鍒嗙粍
+                .Select(layerGroup => new
+                {
+                    layer = layerGroup.Key,
+                    columns = layerGroup.GroupBy(x => x.Column)  // 姣忓眰涓寜鍒楀垎缁�
+                                       .Select(columnGroup => new
+                                       {
+                                           column = columnGroup.Key,
+                                           depths = columnGroup.Select(d => new
+                                           {
+                                               row = d.Row,
+                                               LocationCode = d.LocationCode,
+                                               depth = d.Depth,
+                                               locationType = d.LocationType,
+                                               locationStatus = d.LocationStatus,
+                                               enableStatus = d.EnableStatus
+                                           }).ToList()
+                                       }).ToList()
+                }).ToList();
+
+            return WebResponseContent.Instance.OK("鎴愬姛", result);
+        }
+
+        public WebResponseContent GetWarehouseCapacity()
+        {
+            // 鏌ヨ鎵�鏈変粨搴撶殑璐т綅鏁版嵁
+            var allLocations = BaseDal.QueryData()
+                .Select(x => new
+                {
+                    x.WarehouseId,
+                    x.LocationStatus
+                })
+                .ToList();
+
+            // 濡傛灉娌℃湁鏁版嵁锛岃繑鍥炵┖鍒楄〃
+            if (allLocations == null || !allLocations.Any())
+            {
+                return WebResponseContent.Instance.OK("鏈壘鍒颁换浣曡揣浣嶆暟鎹�", new List<object>());
+            }
+
+            // 璁$畻姣忎釜浠撳簱鐨勫閲忎娇鐢ㄦ儏鍐�
+            var result = allLocations
+                .GroupBy(x => x.WarehouseId)
                 .Select(g => new
                 {
-                    RoadwayNo = g.Key,
-                    LocationCount = g.Count(),
-                    AllLocations = g.ToList()
+                    WarehouseId = g.Key,
+                    FreeLocations = g.Count(x => x.LocationStatus == 0),
+                    RemainingCapacityPercentage = (int)Math.Round((double)g.Count(x => x.LocationStatus == 0) / g.Count() * 100)
                 })
-                .OrderByDescending(g => g.LocationCount)  // 鏀逛负闄嶅簭鎺掑簭
-                .FirstOrDefault();  // 鍙栫涓�涓紙鏁伴噺鏈�澶氱殑锛�
+                .ToList();
 
-            return roadwayGroups.RoadwayNo;
+            return WebResponseContent.Instance.OK("鎴愬姛", result);
+        }
+
+        /// <summary>
+        /// 涓�閿惎鐢ㄥ贩閬撴墍鏈夎揣浣�
+        /// </summary>
+        /// <param name="warehouseId">浠撳簱ID</param>
+        /// <param name="roadwayNo">宸烽亾缂栧彿</param>
+        /// <returns></returns>
+        public WebResponseContent EnableAllLocationsInRoadway(string roadwayNo)
+        {
+            if (string.IsNullOrEmpty(roadwayNo))
+                return WebResponseContent.Instance.Error("宸烽亾缂栧彿涓嶈兘涓虹┖");
+
+            var locations = Repository.QueryData(x =>
+                x.RoadwayNo == roadwayNo &&
+                x.EnableStatus != EnableStatusEnum.Normal.ObjToInt());
+
+            if (locations == null || locations.Count == 0)
+                return WebResponseContent.Instance.OK("璇ュ贩閬撴病鏈夐渶瑕佸惎鐢ㄧ殑璐т綅");
+
+            locations.ForEach(x => x.EnableStatus = EnableStatusEnum.Normal.ObjToInt());
+            Repository.UpdateData(locations);
+
+            return WebResponseContent.Instance.OK($"鎴愬姛鍚敤宸烽亾[{roadwayNo}]鐨剓locations.Count}涓揣浣�");
+        }
+
+        /// <summary>
+        /// 涓�閿鐢ㄥ贩閬撴墍鏈夎揣浣�
+        /// </summary>
+        /// <param name="warehouseId">浠撳簱ID</param>
+        /// <param name="roadwayNo">宸烽亾缂栧彿</param>
+        /// <returns></returns>
+        public WebResponseContent DisableAllLocationsInRoadway(string roadwayNo)
+        {
+            if (string.IsNullOrEmpty(roadwayNo))
+                return WebResponseContent.Instance.Error("宸烽亾缂栧彿涓嶈兘涓虹┖");
+            var locations = Repository.QueryData(x =>
+                x.RoadwayNo == roadwayNo &&
+                x.EnableStatus != EnableStatusEnum.Disable.ObjToInt());
+            if (locations == null || locations.Count == 0)
+                return WebResponseContent.Instance.OK("璇ュ贩閬撴病鏈夐渶瑕佺鐢ㄧ殑璐т綅");
+            // 妫�鏌ヨ揣浣嶆槸鍚︽湁搴撳瓨
+            var locationIds = locations.Select(x => x.Id).ToList();
+            locations.ForEach(x => x.EnableStatus = EnableStatusEnum.Disable.ObjToInt());
+            Repository.UpdateData(locations);
+            return WebResponseContent.Instance.OK($"鎴愬姛绂佺敤宸烽亾[{roadwayNo}]鐨剓locations.Count}涓揣浣�");
         }
     }
 }

--
Gitblit v1.9.3