From c75f62bad64e5b03c9cda9ba97c68aba7f09dd3d Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期五, 30 一月 2026 10:54:00 +0800
Subject: [PATCH] 添加化成分容堆垛机调度,优化路由查找

---
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Service/RouterService.cs |  304 ++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 241 insertions(+), 63 deletions(-)

diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Service/RouterService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Service/RouterService.cs
index 2feada3..4bf89ae 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Service/RouterService.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Service/RouterService.cs
@@ -42,46 +42,23 @@
         /// <returns>杩斿洖璺敱瀹炰綋闆嗗悎銆�</returns>
         public List<Dt_Router> QueryNextRoutes(string startPosi, string endPosi)
         {
-            //todo 鏂规硶闇�浼樺寲
             List<Dt_Router> routers = new List<Dt_Router>();
             try
             {
-                //鏌ヨ涓嬩竴涓矾鐢变俊鎭�
-                List<Dt_Router> dt_Routers = BaseDal.QueryData(x => (x.NextPosi == endPosi || x.ChildPosi == endPosi), new Dictionary<string, OrderByType> { { nameof(Dt_Router.IsEnd), OrderByType.Desc } });
-                if (dt_Routers.Count > 0)
+                // 涓�娆℃�ф煡璇㈡墍鏈夎矾鐢辨暟鎹埌鍐呭瓨
+                List<Dt_Router> allRouters = BaseDal.QueryData(x => true);
+                
+                // 鍦ㄥ唴瀛樹腑杩涜璺緞鎼滅储
+                routers = FindRoutesInMemory(startPosi, endPosi, allRouters, null);
+                
+                if (routers.Count == 0)
                 {
-                    foreach (var item in dt_Routers)
-                    {
-                        //濡傛灉涓嬩竴涓矾鐢辩殑璧风偣鍜岀粓鐐归兘鍖归厤锛屽垯娣诲姞鍒拌矾鐢卞垪琛ㄤ腑
-                        if (item.StartPosi == startPosi && !routers.Any(x => x.Id == item.Id))
-                        {
-                            routers.Add(item);
-                        }
-                        else
-                        {
-                            //鍚﹀垯锛岄�掑綊鏌ヨ涓嬩竴涓矾鐢辩殑璧风偣
-                            List<Dt_Router> tempRouters = QueryNextRoutes(startPosi, item.StartPosi);
-                            foreach (var router in tempRouters)
-                            {
-                                //濡傛灉涓嬩竴涓矾鐢辩殑璧风偣鍜岀粓鐐归兘鍖归厤锛屽垯娣诲姞鍒拌矾鐢卞垪琛ㄤ腑
-                                if (router.StartPosi == startPosi && !routers.Any(x => x.Id == router.Id))
-                                {
-                                    routers.Add(router);
-                                }
-                            }
-                        }
-                    }
-                }
-                else
-                {
-                    //濡傛灉鏌ヨ涓嶅埌涓嬩竴涓矾鐢变俊鎭紝鍒欐姏鍑哄紓甯�
                     throw new Exception($"璇ヨ矾寰勬湭閰嶇疆鎴栭厤缃敊璇�,璇锋鏌ヨ澶囪矾鐢变俊鎭�,璧风偣:銆恵startPosi}銆�,缁堢偣:銆恵endPosi}銆�");
                 }
             }
             catch (Exception ex)
             {
-                //throw new Exception(ex.Message);
-                //璁板綍閿欒淇℃伅
+                // 璁板綍閿欒淇℃伅
             }
             return routers;
         }
@@ -95,48 +72,250 @@
         /// <returns>杩斿洖璺敱瀹炰綋闆嗗悎銆�</returns>
         public List<Dt_Router> QueryNextRoutes(string startPosi, string endPosi, int routeType)
         {
-            //todo 鏂规硶闇�浼樺寲
             List<Dt_Router> routers = new List<Dt_Router>();
             try
             {
-                //鏌ヨ涓嬩竴涓矾鐢变俊鎭�
-                List<Dt_Router> dt_Routers = BaseDal.QueryData(x => (x.NextPosi == endPosi || x.ChildPosi == endPosi) && x.InOutType == routeType, new Dictionary<string, OrderByType> { { nameof(Dt_Router.IsEnd), OrderByType.Desc } });
-                if (dt_Routers.Count > 0)
+                // 涓�娆℃�ф煡璇㈡寚瀹氱被鍨嬬殑鎵�鏈夎矾鐢辨暟鎹埌鍐呭瓨
+                List<Dt_Router> allRouters = BaseDal.QueryData(x => x.InOutType == routeType);
+                
+                // 鍦ㄥ唴瀛樹腑杩涜璺緞鎼滅储
+                routers = FindRoutesInMemory(startPosi, endPosi, allRouters, routeType);
+                
+                if (routers.Count == 0)
                 {
-                    foreach (var item in dt_Routers)
-                    {
-                        //濡傛灉涓嬩竴涓矾鐢辩殑璧风偣鍜岀粓鐐归兘鍖归厤锛屽垯娣诲姞鍒拌矾鐢卞垪琛ㄤ腑
-                        if (item.StartPosi == startPosi && !routers.Any(x => x.Id == item.Id))
-                        {
-                            routers.Add(item);
-                        }
-                        else
-                        {
-                            //鍚﹀垯锛岄�掑綊鏌ヨ涓嬩竴涓矾鐢辩殑璧风偣
-                            List<Dt_Router> tempRouters = QueryNextRoutes(startPosi, item.StartPosi, routeType);
-                            foreach (var router in tempRouters)
-                            {
-                                //濡傛灉涓嬩竴涓矾鐢辩殑璧风偣鍜岀粓鐐归兘鍖归厤锛屽垯娣诲姞鍒拌矾鐢卞垪琛ㄤ腑
-                                if (router.StartPosi == startPosi && !routers.Any(x => x.Id == router.Id))
-                                {
-                                    routers.Add(router);
-                                }
-                            }
-                        }
-                    }
-                }
-                else
-                {
-                    //濡傛灉鏌ヨ涓嶅埌涓嬩竴涓矾鐢变俊鎭紝鍒欐姏鍑哄紓甯�
                     throw new Exception($"璇ヨ矾寰勬湭閰嶇疆鎴栭厤缃敊璇�,璇锋鏌ヨ澶囪矾鐢变俊鎭�,璧风偣:銆恵startPosi}銆�,缁堢偣:銆恵endPosi}銆�");
                 }
             }
             catch (Exception ex)
             {
-                //throw new Exception(ex.Message);
-                //璁板綍閿欒淇℃伅
+                // 璁板綍閿欒淇℃伅
             }
             return routers;
+        }
+
+        /// <summary>
+        /// 鍦ㄥ唴瀛樹腑鏌ユ壘浠庤捣鐐瑰埌缁堢偣鐨勬墍鏈夎矾鐢�
+        /// </summary>
+        /// <param name="startPosi">璧风偣浣嶇疆</param>
+        /// <param name="endPosi">缁堢偣浣嶇疆</param>
+        /// <param name="allRouters">鎵�鏈夎矾鐢辨暟鎹�</param>
+        /// <param name="routeType">璺敱绫诲瀷锛堝彲閫夛級</param>
+        /// <returns>绗﹀悎鏉′欢鐨勮矾鐢卞垪琛�</returns>
+        private List<Dt_Router> FindRoutesInMemory(string startPosi, string endPosi, List<Dt_Router> allRouters, int? routeType)
+        {
+            List<Dt_Router> result = new List<Dt_Router>();
+            HashSet<int> addedIds = new HashSet<int>();
+
+            // 鏋勫缓绱㈠紩锛氫互 NextPosi 鍜� ChildPosi 涓洪敭鐨勫瓧鍏革紝鍔犻�熸煡鎵�
+            var routersByNext = allRouters
+                .GroupBy(r => r.NextPosi)
+                .ToDictionary(g => g.Key, g => g.ToList());
+            
+            var routersByChild = allRouters
+                .GroupBy(r => r.ChildPosi)
+                .ToDictionary(g => g.Key, g => g.ToList());
+
+            // 鎵惧埌鎵�鏈夋寚鍚戠粓鐐圭殑璺敱锛堢粓鐐圭殑鐖惰妭鐐癸級
+            List<Dt_Router> endRouters = new List<Dt_Router>();
+            if (routersByNext.ContainsKey(endPosi))
+                endRouters.AddRange(routersByNext[endPosi]);
+            if (routersByChild.ContainsKey(endPosi))
+                endRouters.AddRange(routersByChild[endPosi].Where(r => !endRouters.Any(e => e.Id == r.Id)));
+
+            // 鎸� IsEnd 闄嶅簭鎺掑簭
+            endRouters = endRouters.OrderByDescending(r => r.IsEnd).ToList();
+
+            // 浣跨敤闃熷垪杩涜骞垮害浼樺厛鎼滅储
+            Queue<(Dt_Router router, List<Dt_Router> path)> queue = new Queue<(Dt_Router, List<Dt_Router>)>();
+            
+            // 灏嗘墍鏈夌粓鐐硅矾鐢卞姞鍏ラ槦鍒�
+            foreach (var endRouter in endRouters)
+            {
+                queue.Enqueue((endRouter, new List<Dt_Router> { endRouter }));
+            }
+
+            // 骞垮害浼樺厛鎼滅储
+            while (queue.Count > 0)
+            {
+                var (currentRouter, currentPath) = queue.Dequeue();
+
+                // 濡傛灉褰撳墠璺敱鐨勮捣鐐瑰氨鏄洰鏍囪捣鐐癸紝鎵惧埌瀹屾暣璺緞
+                if (currentRouter.StartPosi == startPosi)
+                {
+                    // 灏嗚矾寰勪腑鐨勬墍鏈夎矾鐢辨坊鍔犲埌缁撴灉涓紙鍘婚噸锛�
+                    foreach (var router in currentPath)
+                    {
+                        if (!addedIds.Contains(router.Id))
+                        {
+                            result.Add(router);
+                            addedIds.Add(router.Id);
+                        }
+                    }
+                    continue;
+                }
+
+                // 鏌ユ壘褰撳墠璺敱璧风偣鐨勭埗璺敱
+                List<Dt_Router> parentRouters = new List<Dt_Router>();
+                if (routersByNext.ContainsKey(currentRouter.StartPosi))
+                    parentRouters.AddRange(routersByNext[currentRouter.StartPosi]);
+                if (routersByChild.ContainsKey(currentRouter.StartPosi))
+                    parentRouters.AddRange(routersByChild[currentRouter.StartPosi].Where(r => !parentRouters.Any(p => p.Id == r.Id)));
+
+                // 灏嗙埗璺敱鍔犲叆闃熷垪
+                foreach (var parentRouter in parentRouters)
+                {
+                    // 閬垮厤寰幆寮曠敤
+                    if (!currentPath.Any(p => p.Id == parentRouter.Id))
+                    {
+                        var newPath = new List<Dt_Router>(currentPath) { parentRouter };
+                        queue.Enqueue((parentRouter, newPath));
+                    }
+                }
+            }
+
+            return result;
+        }
+
+        /// <summary>
+        /// 鏍规嵁璧风偣鑾峰彇涓嬩竴涓崟涓瓙鑺傜偣璺敱
+        /// </summary>
+        /// <param name="startPosi">璧风偣/褰撳墠浣嶇疆</param>
+        /// <returns>杩斿洖涓嬩竴涓矾鐢辫妭鐐癸紝濡傛灉娌℃湁鍒欒繑鍥瀗ull</returns>
+        public Dt_Router QueryNextRoute(string startPosi)
+        {
+            try
+            {
+                // 鏌ヨ浠庤捣鐐瑰嚭鍙戠殑鎵�鏈夎矾鐢�
+                List<Dt_Router> routes = BaseDal.QueryData(x => x.StartPosi == startPosi, 
+                    new Dictionary<string, OrderByType> { { nameof(Dt_Router.IsEnd), OrderByType.Desc } });
+                
+                // 杩斿洖绗竴涓矾鐢�
+                return routes.FirstOrDefault();
+            }
+            catch (Exception ex)
+            {
+                // 璁板綍閿欒淇℃伅
+                return null;
+            }
+        }
+
+        /// <summary>
+        /// 鏍规嵁璧风偣鍜岃矾鐢辩被鍨嬭幏鍙栦笅涓�涓崟涓瓙鑺傜偣璺敱
+        /// </summary>
+        /// <param name="startPosi">璧风偣/褰撳墠浣嶇疆</param>
+        /// <param name="routeType">璺敱绫诲瀷</param>
+        /// <returns>杩斿洖涓嬩竴涓矾鐢辫妭鐐癸紝濡傛灉娌℃湁鍒欒繑鍥瀗ull</returns>
+        public Dt_Router QueryNextRoute(string startPosi, int routeType)
+        {
+            try
+            {
+                // 鏌ヨ浠庤捣鐐瑰嚭鍙戠殑鎸囧畾绫诲瀷璺敱
+                List<Dt_Router> routes = BaseDal.QueryData(x => x.StartPosi == startPosi && x.InOutType == routeType, 
+                    new Dictionary<string, OrderByType> { { nameof(Dt_Router.IsEnd), OrderByType.Desc } });
+                
+                // 杩斿洖绗竴涓矾鐢�
+                return routes.FirstOrDefault();
+            }
+            catch (Exception ex)
+            {
+                // 璁板綍閿欒淇℃伅
+                return null;
+            }
+        }
+
+        /// <summary>
+        /// 鏍规嵁璧风偣銆佺粓鐐规柟鍚戝拰璺敱绫诲瀷鑾峰彇涓嬩竴涓崟涓瓙鑺傜偣璺敱锛堟櫤鑳介�夋嫨鏈濆悜缁堢偣鐨勮矾鐢憋級
+        /// </summary>
+        /// <param name="startPosi">璧风偣/褰撳墠浣嶇疆</param>
+        /// <param name="endPosi">缁堢偣浣嶇疆锛堢敤浜庢柟鍚戝垽鏂級</param>
+        /// <param name="routeType">璺敱绫诲瀷</param>
+        /// <returns>杩斿洖涓嬩竴涓矾鐢辫妭鐐癸紝浼樺厛杩斿洖鏈濆悜缁堢偣鐨勮矾鐢憋紝濡傛灉娌℃湁鍒欒繑鍥瀗ull</returns>
+        public Dt_Router QueryNextRoute(string startPosi, string endPosi, int routeType)
+        {
+            try
+            {
+                // 鏌ヨ浠庤捣鐐瑰嚭鍙戠殑鎸囧畾绫诲瀷璺敱
+                List<Dt_Router> routes = BaseDal.QueryData(x => x.StartPosi == startPosi && x.InOutType == routeType, 
+                    new Dictionary<string, OrderByType> { { nameof(Dt_Router.IsEnd), OrderByType.Desc } });
+                
+                if (routes.Count == 0)
+                    return null;
+
+                // 浼樺厛閫夋嫨鐩存帴鎸囧悜缁堢偣鐨勮矾鐢�
+                Dt_Router directRoute = routes.FirstOrDefault(x => x.NextPosi == endPosi || x.ChildPosi == endPosi);
+                if (directRoute != null)
+                    return directRoute;
+
+                // 濡傛灉娌℃湁鐩存帴璺敱锛屼娇鐢ㄦ煡鎵剧畻娉曟壘鍒版湞鍚戠粓鐐圭殑璺敱
+                List<Dt_Router> allRouters = BaseDal.QueryData(x => x.InOutType == routeType);
+                foreach (var route in routes)
+                {
+                    // 妫�鏌ヤ粠杩欎釜璺敱鐨勪笅涓�涓綅缃槸鍚﹁兘鍒拌揪缁堢偣
+                    var pathToEnd = FindRoutesInMemory(route.NextPosi, endPosi, allRouters, routeType);
+                    if (pathToEnd.Count > 0)
+                        return route;
+                }
+
+                // 濡傛灉閮戒笉鑳藉埌杈剧粓鐐癸紝杩斿洖绗竴涓矾鐢�
+                return routes.FirstOrDefault();
+            }
+            catch (Exception ex)
+            {
+                // 璁板綍閿欒淇℃伅
+                return null;
+            }
+        }
+
+        /// <summary>
+        /// 鑾峰彇浠庤捣鐐瑰埌缁堢偣鐨勫畬鏁磋矾寰勶紙鎸夐『搴忚繑鍥炴瘡涓瓙鑺傜偣璺敱锛�
+        /// </summary>
+        /// <param name="startPosi">璧风偣浣嶇疆</param>
+        /// <param name="endPosi">缁堢偣浣嶇疆</param>
+        /// <param name="routeType">璺敱绫诲瀷</param>
+        /// <returns>杩斿洖鏈夊簭鐨勮矾鐢卞垪琛紝濡傛灉鎵句笉鍒拌矾寰勫垯杩斿洖绌哄垪琛�</returns>
+        public List<Dt_Router> QueryRoutePath(string startPosi, string endPosi, int routeType)
+        {
+            List<Dt_Router> path = new List<Dt_Router>();
+            string currentPosi = startPosi;
+            HashSet<string> visitedPositions = new HashSet<string>();
+            
+            try
+            {
+                while (currentPosi != endPosi)
+                {
+                    if (visitedPositions.Contains(currentPosi))
+                    {
+                        break;
+                    }
+                    visitedPositions.Add(currentPosi);
+
+                    Dt_Router nextRoute = QueryNextRoute(currentPosi, endPosi, routeType);
+                    
+                    if (nextRoute == null)
+                    {
+                        break;
+                    }
+                    
+                    path.Add(nextRoute);
+                    currentPosi = nextRoute.NextPosi;
+                    
+                    if (path.Count > 1000)
+                    {
+                        break;
+                    }
+                }
+                
+                if (currentPosi != endPosi)
+                {
+                    return new List<Dt_Router>();
+                }
+            }
+            catch (Exception ex)
+            {
+                return new List<Dt_Router>();
+            }
+            
+            return path;
         }
 
         /// <summary>
@@ -144,7 +323,6 @@
         /// </summary>
         /// <param name="deviceCode">璁惧缂栧彿</param>
         /// <returns>杩斿洖璺敱鐐逛綅缂栧彿(杈撻�佺嚎绔欏彴缂栧彿)闆嗗悎</returns>
-        // 鏍规嵁璁惧缂栫爜鏌ヨ鎵�鏈変綅缃�
         public List<string> QueryAllPositions(string deviceCode)
         {
             // 鍒涘缓涓�涓瓧绗︿覆鍒楄〃锛岀敤浜庡瓨鍌ㄦ墍鏈変綅缃�

--
Gitblit v1.9.3