wanshenmean
7 天以前 37acb8358f5602a9013ee29c04a45e33483c2329
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Service/RouterService.cs
@@ -1,9 +1,5 @@
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WIDESEAWCS_Common;
using WIDESEAWCS_Core;
using WIDESEAWCS_Core.BaseServices;
using WIDESEAWCS_Core.Enums;
@@ -11,7 +7,6 @@
using WIDESEAWCS_DTO.BasicInfo;
using WIDESEAWCS_QuartzJob.Models;
using WIDESEAWCS_QuartzJob.Repository;
using WIDESEAWCS_Common;
using ICacheService = WIDESEAWCS_Core.Caches.ICacheService;
namespace WIDESEAWCS_QuartzJob.Service
@@ -39,6 +34,137 @@
        }
        /// <summary>
        /// 从缓存获取指定类型的全量路由数据,缓存不存在时自动从数据库加载并写入缓存
        /// </summary>
        /// <param name="routeType">路由类型(入口/出口)</param>
        /// <returns>该类型的全部路由列表</returns>
        private List<Dt_Router> GetAllRoutersFromCache(int routeType)
        {
            // 根据路由类型构建缓存Key,In类型对应"In",Out类型对应"Out"
            string cacheKey = $"Router:AllRouters:{(routeType == RouterInOutType.In.ObjToInt() ? "In" : "Out")}";
            // 通过缓存服务获取数据,缓存未命中时调用工厂方法从数据库查询并写入缓存
            return _cacheService.GetOrAdd(
                cacheKey,
                _ => BaseDal.QueryData(x => x.InOutType == routeType)
            );
        }
        /// <summary>
        /// 清除所有路由缓存(入口和出口类型)
        /// </summary>
        public void ClearRouterCache()
        {
            _cacheService.Remove("Router:AllRouters:In");
            _cacheService.Remove("Router:AllRouters:Out");
        }
        /// <summary>
        /// 根据设备编号查询经过该设备的所有路由(合并入口+出口类型)
        /// </summary>
        /// <param name="deviceCode">设备编号</param>
        /// <returns>经过该设备的路由列表</returns>
        public List<Dt_Router> QueryRoutersByDeviceCode(string deviceCode)
        {
            // 从缓存获取入口类型和出口类型的全量路由数据
            List<Dt_Router> inRouters = GetAllRoutersFromCache(RouterInOutType.In.ObjToInt());
            List<Dt_Router> outRouters = GetAllRoutersFromCache(RouterInOutType.Out.ObjToInt());
            // 合并后筛选出经过指定设备的路由(ChildPosiDeviceCode匹配)
            return inRouters.Concat(outRouters)
                .Where(x => x.ChildPosiDeviceCode == deviceCode)
                .ToList();
        }
        /// <summary>
        /// 判断两点之间是否存在路由(全类型)
        /// </summary>
        public bool ExistsRouter(string startPosi, string endPosi)
        {
            // 从缓存获取入口类型和出口类型的全量路由数据并合并
            List<Dt_Router> inRouters = GetAllRoutersFromCache(RouterInOutType.In.ObjToInt());
            List<Dt_Router> outRouters = GetAllRoutersFromCache(RouterInOutType.Out.ObjToInt());
            var allRouters = inRouters.Concat(outRouters).ToList();
            // 在内存中查找从起点到终点的路由
            var routes = FindRoutesInMemory(startPosi, endPosi, allRouters, null);
            return routes.Count > 0;
        }
        /// <summary>
        /// 判断两点之间是否存在指定类型的路由
        /// </summary>
        public bool ExistsRouter(string startPosi, string endPosi, int routeType)
        {
            // 从缓存获取指定类型的全量路由数据
            List<Dt_Router> allRouters = GetAllRoutersFromCache(routeType);
            // 在内存中查找从起点到终点的路由
            var routes = FindRoutesInMemory(startPosi, endPosi, allRouters, routeType);
            return routes.Count > 0;
        }
        /// <summary>
        /// 获取全量路由数量(入口+出口合计)
        /// </summary>
        public int GetRouterCount()
        {
            // 分别获取入口类型和出口类型的路由数量并相加
            int inCount = GetAllRoutersFromCache(RouterInOutType.In.ObjToInt()).Count;
            int outCount = GetAllRoutersFromCache(RouterInOutType.Out.ObjToInt()).Count;
            return inCount + outCount;
        }
        /// <summary>
        /// 获取指定类型路由数量
        /// </summary>
        public int GetRouterCount(int routeType)
        {
            // 获取指定类型的全量路由数据并返回数量
            return GetAllRoutersFromCache(routeType).Count;
        }
        /// <summary>
        /// 批量删除指定ID的路由,删除后同步清除对应类型的缓存
        /// </summary>
        /// <param name="routerIds">待删除的路由ID列表</param>
        /// <returns>返回处理结果</returns>
        public WebResponseContent DeleteRouters(List<long> routerIds)
        {
            WebResponseContent content = new WebResponseContent();
            try
            {
                if (routerIds == null || routerIds.Count == 0)
                {
                    return content = WebResponseContent.Instance.Error("待删除的路由ID列表不能为空");
                }
                // 查询待删除路由的类型(用于后续清除缓存)
                var routersToDelete = BaseDal.QueryData(x => routerIds.Contains(x.Id));
                if (routersToDelete.Count == 0)
                {
                    return content = WebResponseContent.Instance.Error("未找到待删除的路由");
                }
                // 记录涉及的类型(去重)
                var affectedTypes = routersToDelete.Select(x => x.InOutType).Distinct().ToList();
                // 执行批量删除
                BaseDal.DeleteData(routersToDelete);
                // 清除受影响类型的缓存
                foreach (var routeType in affectedTypes)
                {
                    string cacheKey = $"Router:AllRouters:{(routeType == RouterInOutType.In.ObjToInt() ? "In" : "Out")}";
                    _cacheService.Remove(cacheKey);
                }
                content = WebResponseContent.Instance.OK();
            }
            catch (Exception ex)
            {
                content = WebResponseContent.Instance.Error(ex.Message);
            }
            return content;
        }
        /// <summary>
        /// 根据起点/当前位置、终点获取下一个子节点。
        /// </summary>
        /// <param name="startPosi">起点/当前位置。</param>
@@ -49,8 +175,10 @@
            List<Dt_Router> routers = new List<Dt_Router>();
            try
            {
                // 一次性查询所有路由数据到内存
                List<Dt_Router> allRouters = BaseDal.QueryData(x => true);
                // 从缓存加载入口类型和出口类型的路由数据并合并(创建新列表,避免修改缓存引用)
                List<Dt_Router> allRouters = GetAllRoutersFromCache(RouterInOutType.In.ObjToInt())
                    .Concat(GetAllRoutersFromCache(RouterInOutType.Out.ObjToInt()))
                    .ToList();
                // 在内存中进行路径搜索
                routers = FindRoutesInMemory(startPosi, endPosi, allRouters, null);
@@ -79,8 +207,8 @@
            List<Dt_Router> routers = new List<Dt_Router>();
            try
            {
                // 一次性查询指定类型的所有路由数据到内存
                List<Dt_Router> allRouters = BaseDal.QueryData(x => x.InOutType == routeType);
                // 从缓存加载指定类型的所有路由数据
                List<Dt_Router> allRouters = GetAllRoutersFromCache(routeType);
                // 在内存中进行路径搜索
                routers = FindRoutesInMemory(startPosi, endPosi, allRouters, routeType);
@@ -189,9 +317,11 @@
        {
            try
            {
                // 查询从起点出发的所有路由
                List<Dt_Router> routes = BaseDal.QueryData(x => x.StartPosi == startPosi,
                    new Dictionary<string, OrderByType> { { nameof(Dt_Router.IsEnd), OrderByType.Desc } });
                // 从缓存获取入口类型的所有路由数据,基于起点筛选后按IsEnd降序排序
                List<Dt_Router> routes = GetAllRoutersFromCache(RouterInOutType.In.ObjToInt())
                    .Where(x => x.StartPosi == startPosi)
                    .ToList();
                routes = routes.OrderByDescending(x => x.IsEnd).ToList();
                // 返回第一个路由
                return routes.FirstOrDefault();
@@ -213,9 +343,11 @@
        {
            try
            {
                // 查询从起点出发的指定类型路由
                List<Dt_Router> routes = BaseDal.QueryData(x => x.StartPosi == startPosi && x.InOutType == routeType,
                    new Dictionary<string, OrderByType> { { nameof(Dt_Router.IsEnd), OrderByType.Desc } });
                // 从缓存获取指定类型的所有路由数据,筛选起点后按IsEnd降序排列
                List<Dt_Router> routes = GetAllRoutersFromCache(routeType)
                    .Where(x => x.StartPosi == startPosi)
                    .ToList();
                routes = routes.OrderByDescending(x => x.IsEnd).ToList();
                // 返回第一个路由
                return routes.FirstOrDefault();
@@ -238,9 +370,11 @@
        {
            try
            {
                // 查询从起点出发的指定类型路由
                List<Dt_Router> routes = BaseDal.QueryData(x => x.StartPosi == startPosi && x.InOutType == routeType,
                    new Dictionary<string, OrderByType> { { nameof(Dt_Router.IsEnd), OrderByType.Desc } });
                // 从缓存获取指定类型的所有路由数据,筛选起点后按IsEnd降序排列
                List<Dt_Router> routes = GetAllRoutersFromCache(routeType)
                    .Where(x => x.StartPosi == startPosi)
                    .ToList();
                routes = routes.OrderByDescending(x => x.IsEnd).ToList();
                if (routes.Count == 0)
                    return null;
@@ -250,8 +384,8 @@
                if (directRoute != null)
                    return directRoute;
                // 如果没有直接路由,使用查找算法找到朝向终点的路由
                List<Dt_Router> allRouters = BaseDal.QueryData(x => x.InOutType == routeType);
                // 如果没有直接路由,使用缓存中的全量路由数据查找朝向终点的路由
                List<Dt_Router> allRouters = GetAllRoutersFromCache(routeType);
                foreach (var route in routes)
                {
                    // 检查从这个路由的下一个位置是否能到达终点
@@ -280,9 +414,13 @@
        {
            try
            {
                // 查询从起点出发的指定类型路由
                List<Dt_Router> routes = BaseDal.QueryData(x => x.StartPosi == startPosi,
                    new Dictionary<string, OrderByType> { { nameof(Dt_Router.IsEnd), OrderByType.Desc } });
                // 从缓存获取入口和出口类型的所有路由数据,筛选起点后按IsEnd降序排序
                List<Dt_Router> inRoutes = GetAllRoutersFromCache(RouterInOutType.In.ObjToInt());
                List<Dt_Router> outRoutes = GetAllRoutersFromCache(RouterInOutType.Out.ObjToInt());
                List<Dt_Router> routes = inRoutes.Concat(outRoutes)
                    .Where(x => x.StartPosi == startPosi)
                    .ToList();
                routes = routes.OrderByDescending(x => x.IsEnd).ToList();
                if (routes.Count == 0)
                    return null;
@@ -291,16 +429,6 @@
                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();
@@ -390,20 +518,21 @@
                    // 返回去重后的位置列表
                    return positions.GroupBy(x => x).Select(x => x.Key).ToList();
                }
                catch
                catch (Exception ex)
                {
                    ConsoleHelper.WriteErrorLine($"RouterService.QueryAllPositions 查询失败: {ex.Message}");
                }
                finally
                {
                    _cacheService.TryAdd($"{RedisPrefix.System}:{RedisName.DevicePositions}:{deviceCode}", positions);
                }
            }
            else
            else
                positions = device;
            // 返回位置列表
            return positions;
        }
        /// <summary>
        /// 获取路由表中所有完整的路由信息(前端调用展示数据)。
        /// </summary>
@@ -411,8 +540,10 @@
        public List<object> GetAllWholeRouters()
        {
            List<object> data = new List<object>();
            // 查询所有路由
            List<Dt_Router> allRouters = BaseDal.QueryData(x => true);
            // 从缓存加载入口类型和出口类型的全量路由数据并合并
            List<Dt_Router> inRouters = GetAllRoutersFromCache(RouterInOutType.In.ObjToInt());
            List<Dt_Router> outRouters = GetAllRoutersFromCache(RouterInOutType.Out.ObjToInt());
            List<Dt_Router> allRouters = inRouters.Concat(outRouters).ToList();
            // 查询所有结束的路由,并按Id排序
            List<Dt_Router> dt_Routers = allRouters.Where(x => x.IsEnd).OrderBy(x => x.Id).ToList();
@@ -583,6 +714,20 @@
                // 添加新的路由信息
                BaseDal.AddData(routers);
                // 重新查询全量路由(此时才包含新增的路由),再写入缓存
                List<Dt_Router> updatedRouters = BaseDal.QueryData(x => x.InOutType == routerType);
                string cacheKey = $"Router:AllRouters:{(routerType == RouterInOutType.In.ObjToInt() ? "In" : "Out")}";
                try
                {
                    _cacheService.AddOrUpdate(cacheKey, updatedRouters);
                }
                catch
                {
                    // 缓存更新失败时静默忽略,下次查询会从DB自动重建缓存
                }
                content = WebResponseContent.Instance.OK();
            }
            catch (Exception ex)
@@ -592,4 +737,4 @@
            return content;
        }
    }
}
}