using SqlSugar;
|
using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Text;
|
using System.Threading.Tasks;
|
using WIDESEAWCS_Common;
|
using WIDESEAWCS_Common.TaskEnum;
|
using WIDESEAWCS_Core;
|
using WIDESEAWCS_Core.BaseServices;
|
using WIDESEAWCS_Core.Enums;
|
using WIDESEAWCS_Core.Helper;
|
using WIDESEAWCS_DTO.BasicInfo;
|
using WIDESEAWCS_QuartzJob.Models;
|
using WIDESEAWCS_QuartzJob.Repository;
|
using ICacheService = WIDESEAWCS_Core.Caches.ICacheService;
|
|
namespace WIDESEAWCS_QuartzJob.Service
|
{
|
/// <summary>
|
/// 路由配置业务层
|
/// </summary>
|
public class RouterService : ServiceBase<Dt_Router, IRouterRepository>, IRouterService
|
{
|
private readonly IDeviceProtocolRepository _deviceProtocolRepository;
|
private readonly IDeviceInfoRepository _deviceInfoRepository;
|
private readonly ICacheService _cacheService;
|
|
/// <summary>
|
/// 路由配置业务层
|
/// </summary>
|
/// <param name="BaseDal"></param>
|
/// <param name="deviceProtocolRepository"></param>
|
/// <param name="deviceInfoRepository"></param>
|
public RouterService(IRouterRepository BaseDal, IDeviceProtocolRepository deviceProtocolRepository, IDeviceInfoRepository deviceInfoRepository, ICacheService cacheService) : base(BaseDal)
|
{
|
_deviceProtocolRepository = deviceProtocolRepository;
|
_deviceInfoRepository = deviceInfoRepository;
|
_cacheService = cacheService;
|
}
|
|
/// <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>
|
/// <param name="startPosi">起点/当前位置。</param>
|
/// <param name="endPosi">终点。</param>
|
/// <returns>返回路由实体集合。</returns>
|
public List<Dt_Router> QueryNextRoutes(string startPosi, string endPosi)
|
{
|
List<Dt_Router> routers = new List<Dt_Router>();
|
try
|
{
|
// 从缓存加载入口类型和出口类型的路由数据并合并(创建新列表,避免修改缓存引用)
|
List<Dt_Router> allRouters = GetAllRoutersFromCache(RouterInOutType.In.ObjToInt())
|
.Concat(GetAllRoutersFromCache(RouterInOutType.Out.ObjToInt()))
|
.ToList();
|
|
// 在内存中进行路径搜索
|
routers = FindRoutesInMemory(startPosi, endPosi, allRouters, null);
|
|
if (routers.Count == 0)
|
{
|
throw new Exception($"该路径未配置或配置错误,请检查设备路由信息,起点:【{startPosi}】,终点:【{endPosi}】");
|
}
|
}
|
catch (Exception ex)
|
{
|
// 记录错误信息
|
}
|
return routers;
|
}
|
|
/// <summary>
|
/// 根据起点/当前位置、终点获取下一个子节点。
|
/// </summary>
|
/// <param name="startPosi">起点/当前位置。</param>
|
/// <param name="endPosi">终点。</param>
|
/// <param name="routeType">路由类型。</param>
|
/// <returns>返回路由实体集合。</returns>
|
public List<Dt_Router> QueryNextRoutes(string startPosi, string endPosi, int routeType)
|
{
|
List<Dt_Router> routers = new List<Dt_Router>();
|
try
|
{
|
// 从缓存加载指定类型的所有路由数据
|
List<Dt_Router> allRouters = GetAllRoutersFromCache(routeType);
|
|
// 在内存中进行路径搜索
|
routers = FindRoutesInMemory(startPosi, endPosi, allRouters, routeType);
|
|
if (routers.Count == 0)
|
{
|
throw new Exception($"该路径未配置或配置错误,请检查设备路由信息,起点:【{startPosi}】,终点:【{endPosi}】");
|
}
|
}
|
catch (Exception ex)
|
{
|
// 记录错误信息
|
}
|
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
|
{
|
// 从缓存获取入口类型的所有路由数据,基于起点筛选后按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();
|
}
|
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
|
{
|
// 从缓存获取指定类型的所有路由数据,筛选起点后按IsEnd降序排列
|
List<Dt_Router> routes = GetAllRoutersFromCache(routeType)
|
.Where(x => x.StartPosi == startPosi)
|
.ToList();
|
routes = routes.OrderByDescending(x => x.IsEnd).ToList();
|
|
// 返回第一个路由
|
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
|
{
|
// 从缓存获取指定类型的所有路由数据,筛选起点后按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;
|
|
// 优先选择直接指向终点的路由
|
Dt_Router directRoute = routes.FirstOrDefault(x => x.NextPosi == endPosi || x.ChildPosi == endPosi);
|
if (directRoute != null)
|
return directRoute;
|
|
// 如果没有直接路由,使用缓存中的全量路由数据查找朝向终点的路由
|
List<Dt_Router> allRouters = GetAllRoutersFromCache(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>
|
/// <returns>返回下一个路由节点,优先返回朝向终点的路由,如果没有则返回null</returns>
|
public Dt_Router QueryNextRoute(string startPosi, string endPosi)
|
{
|
try
|
{
|
// 从缓存获取入口和出口类型的所有路由数据,筛选起点后按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;
|
|
// 优先选择直接指向终点的路由
|
Dt_Router directRoute = routes.FirstOrDefault(x => x.NextPosi == endPosi || x.ChildPosi == endPosi);
|
if (directRoute != null)
|
return directRoute;
|
|
// 如果都不能到达终点,返回第一个路由
|
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>
|
/// 根据设备编号获取对应的路由点位编号(输送线站台编号)信息
|
/// </summary>
|
/// <param name="deviceCode">设备编号</param>
|
/// <returns>返回路由点位编号(输送线站台编号)集合</returns>
|
public List<string> QueryAllPositions(string deviceCode)
|
{
|
// 创建一个字符串列表,用于存储所有位置
|
List<string> positions = new List<string>();
|
var device = _cacheService.Get<List<string>>($"{RedisPrefix.System}:{RedisName.DevicePositions}:{deviceCode}");
|
if (device.IsNullOrEmpty())
|
{
|
try
|
{
|
// 查询所有进入路由器的位置
|
List<string> inRouterPositions = BaseDal.QueryData(x => x.ChildPosiDeviceCode == deviceCode && x.InOutType == RouterInOutType.In.ObjToInt()).GroupBy(x => x.StartPosi).Select(x => x.Key).ToList();
|
|
// 查询所有离开路由器的位置
|
List<string> outRouterPositions = BaseDal.QueryData(x => x.ChildPosiDeviceCode == deviceCode && x.InOutType == RouterInOutType.Out.ObjToInt()).GroupBy(x => x.ChildPosi).Select(x => x.Key).ToList();
|
|
// 将进入和离开路由器的位置添加到列表中
|
positions.AddRange(inRouterPositions);
|
positions.AddRange(outRouterPositions);
|
// 返回去重后的位置列表
|
return positions.GroupBy(x => x).Select(x => x.Key).ToList();
|
}
|
catch (Exception ex)
|
{
|
ConsoleHelper.WriteErrorLine($"RouterService.QueryAllPositions 查询失败: {ex.Message}");
|
}
|
finally
|
{
|
_cacheService.TryAdd($"{RedisPrefix.System}:{RedisName.DevicePositions}:{deviceCode}", positions);
|
}
|
}
|
else
|
positions = device;
|
// 返回位置列表
|
return positions;
|
}
|
/// <summary>
|
/// 获取路由表中所有完整的路由信息(前端调用展示数据)。
|
/// </summary>
|
/// <returns>匿名对象集合。</returns>
|
public List<object> GetAllWholeRouters()
|
{
|
List<object> data = new List<object>();
|
// 从缓存加载入口类型和出口类型的全量路由数据并合并
|
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();
|
|
// 遍历所有结束的路由
|
foreach (var item in dt_Routers)
|
{
|
// 获取所有可能的完整路径
|
List<List<string>> allPaths = GetAllPaths(item.StartPosi, item.NextPosi, allRouters, item.InOutType);
|
|
// 为每条独立路径生成结果
|
foreach (var path in allPaths)
|
{
|
// 如果当前路由是入口
|
if (item.InOutType == RouterInOutType.In.ObjToInt())
|
{
|
object obj = new { type = RouterInOutType.In, routes = path };
|
data.Add(obj);
|
}
|
// 如果当前路由是出口
|
else
|
{
|
object obj = new { type = RouterInOutType.Out, routes = path };
|
data.Add(obj);
|
}
|
}
|
}
|
|
// 返回data
|
return data;
|
}
|
|
/// <summary>
|
/// 获取从起点到终点的所有完整路径
|
/// </summary>
|
/// <param name="startPosi">当前起始位置</param>
|
/// <param name="endPosi">终点位置</param>
|
/// <param name="allRouters">所有路由数据</param>
|
/// <param name="routerType">路由类型</param>
|
/// <returns>所有完整路径列表,每条路径是从起点到终点的位置列表</returns>
|
private List<List<string>> GetAllPaths(string startPosi, string endPosi, List<Dt_Router> allRouters, int routerType)
|
{
|
List<List<string>> result = new List<List<string>>();
|
|
// 从终点开始反向查找所有路径
|
List<List<string>> reversePaths = new List<List<string>>();
|
BuildReversePaths(startPosi, new List<string> { endPosi, startPosi }, allRouters, routerType, reversePaths);
|
|
// 将反向路径转为正向(从起点到终点)
|
foreach (var reversePath in reversePaths)
|
{
|
result.Add(reversePath.AsEnumerable().Reverse().ToList());
|
}
|
|
return result;
|
}
|
|
/// <summary>
|
/// 递归构建反向路径(从终点向起点查找)
|
/// </summary>
|
/// <param name="currentStartPosi">当前节点的起始位置</param>
|
/// <param name="currentPath">当前已构建的路径(反向,从终点开始)</param>
|
/// <param name="allRouters">所有路由数据</param>
|
/// <param name="routerType">路由类型</param>
|
/// <param name="result">收集所有完整路径</param>
|
private void BuildReversePaths(string currentStartPosi, List<string> currentPath, List<Dt_Router> allRouters, int routerType, List<List<string>> result)
|
{
|
// 查找当前节点的前置节点(NextPosi等于当前StartPosi的路由)
|
List<Dt_Router> preRouters = allRouters.Where(x => x.NextPosi == currentStartPosi && x.InOutType == routerType).ToList();
|
|
// 如果没有前置节点,说明已经到达路径起点,保存当前路径
|
if (preRouters.Count == 0)
|
{
|
result.Add(new List<string>(currentPath));
|
return;
|
}
|
|
// 对每个前置节点,创建新的路径分支
|
foreach (var preRouter in preRouters)
|
{
|
// 创建新的路径副本
|
List<string> newPath = new List<string>(currentPath);
|
newPath.Add(preRouter.StartPosi);
|
|
// 递归查找前置节点
|
BuildReversePaths(preRouter.StartPosi, newPath, allRouters, routerType, result);
|
}
|
}
|
|
/// <summary>
|
/// 添加完整路由信息(前端调用配置路由信息)。
|
/// </summary>
|
/// <param name="routersAddDTOs">设备路由配置添加DTO</param>
|
/// <param name="routerType">路由类型</param>
|
/// <returns>返回处理结果</returns>
|
public WebResponseContent AddRouters(List<RoutersAddDTO> routersAddDTOs, int routerType)
|
{
|
WebResponseContent content = new WebResponseContent();
|
try
|
{
|
// 检查子位置编号是否重复
|
if (routersAddDTOs.GroupBy(x => x.ChildPositionCode).Where(x => !string.IsNullOrEmpty(x.Key)).Select(x => x.Count()).Any(x => x > 1))
|
{
|
return content = WebResponseContent.Instance.Error("子位置编号重复");
|
}
|
|
// 检查根位置编号是否重复
|
if (routersAddDTOs.GroupBy(x => x.PositionCode).Select(x => x.Count()).Any(x => x > 1))
|
{
|
return content = WebResponseContent.Instance.Error("根位置编号重复");
|
}
|
// 查询设备信息
|
List<dynamic> deviceCode = _deviceInfoRepository.QueryTabs<Dt_DeviceInfo, Dt_DeviceProtocol, dynamic>((a, b) => new object[] { JoinType.Inner, a.Id == b.DeviceId }, (a, b) => new { b.DeviceChildCode, a.DeviceCode }, (a, b) => true, x => true).Distinct().ToList();
|
|
List<Dt_Router> routers = new List<Dt_Router>();
|
// 遍历routersAddDTOs,生成Dt_Router对象
|
for (int i = 0; i < routersAddDTOs.Count - 1; i++)
|
{
|
dynamic obj = deviceCode.FirstOrDefault(x => x.DeviceChildCode == routersAddDTOs[i + 1].PositionCode || x.DeviceChildCode == routersAddDTOs[i + 1].ChildPositionCode);
|
Dt_Router router = new Dt_Router()
|
{
|
ChildPosi = routersAddDTOs[i + 1].PositionCode,
|
ChildPosiDeviceCode = obj.DeviceCode,
|
Depth = 1,
|
InOutType = routerType,
|
NextPosi = routersAddDTOs[i + 1].PositionCode,
|
SrmColumn = string.IsNullOrEmpty(routersAddDTOs[i].SCColumn) ? int.TryParse(routersAddDTOs[i + 1].SCColumn, out int col) ? col : null : int.TryParse(routersAddDTOs[i].SCColumn, out int col2) ? col2 : null,
|
SrmLayer = string.IsNullOrEmpty(routersAddDTOs[i].SCLayer) ? int.TryParse(routersAddDTOs[i + 1].SCLayer, out int lay) ? lay : null : int.TryParse(routersAddDTOs[i].SCLayer, out int lay2) ? lay2 : null,
|
SrmRow = string.IsNullOrEmpty(routersAddDTOs[i].SCRow) ? int.TryParse(routersAddDTOs[i + 1].SCRow, out int row) ? row : null : int.TryParse(routersAddDTOs[i].SCRow, out int row2) ? row2 : null,
|
StartPosi = routersAddDTOs[i].PositionCode,
|
IsEnd = false
|
};
|
// 如果是最后一个元素,设置终点位置编号
|
if (i == routersAddDTOs.Count - 2)
|
{
|
if (routerType == (int)RouterInOutType.Out)
|
router.ChildPosi = routersAddDTOs[i + 1].ChildPositionCode;
|
router.IsEnd = true;
|
}
|
routers.Add(router);
|
}
|
// 检查起点位置编号与子位置编号是否相同
|
if (routers.Any(x => x.StartPosi == x.ChildPosi))
|
{
|
return content = WebResponseContent.Instance.Error("输入数据起点位置编号与子位置编号相同");
|
}
|
// 检查起点位置编号与终点位置编号是否相同
|
if (routers.Any(x => x.StartPosi == x.NextPosi))
|
{
|
return content = WebResponseContent.Instance.Error("输入数据起点位置编号与终点位置编号相同");
|
}
|
// 查询数据库中已有的路由信息
|
List<Dt_Router> dt_Routers = BaseDal.QueryData(x => x.InOutType == routerType);
|
|
// 移除重复的路由信息
|
dt_Routers.ForEach(x =>
|
{
|
var t = routers.FirstOrDefault(v => v.StartPosi == x.StartPosi && v.NextPosi == x.NextPosi);
|
if (t != null)
|
{
|
routers.Remove(t);
|
}
|
var r = routers.FirstOrDefault(v => v.StartPosi == x.StartPosi && v.ChildPosi == x.ChildPosi);
|
if (r != null)
|
{
|
routers.Remove(r);
|
}
|
});
|
|
// 添加新的路由信息
|
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)
|
{
|
content = WebResponseContent.Instance.Error(ex.Message);
|
}
|
return content;
|
}
|
}
|
}
|