wanshenmean
2026-01-30 c75f62bad64e5b03c9cda9ba97c68aba7f09dd3d
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>返回下一个路由节点,如果没有则返回null</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>返回下一个路由节点,如果没有则返回null</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>返回下一个路由节点,优先返回朝向终点的路由,如果没有则返回null</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)
        {
            // 创建一个字符串列表,用于存储所有位置