using SqlSugar; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; 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; namespace WIDESEAWCS_QuartzJob.Service { /// /// 路由配置业务层 /// public class RouterService : ServiceBase, IRouterService { private readonly IDeviceProtocolRepository _deviceProtocolRepository; private readonly IDeviceInfoRepository _deviceInfoRepository; /// /// 路由配置业务层 /// /// /// /// public RouterService(IRouterRepository BaseDal, IDeviceProtocolRepository deviceProtocolRepository, IDeviceInfoRepository deviceInfoRepository) : base(BaseDal) { _deviceProtocolRepository = deviceProtocolRepository; _deviceInfoRepository = deviceInfoRepository; } /// /// 根据起点/当前位置、终点获取下一个子节点。 /// /// 起点/当前位置。 /// 终点。 /// 返回路由实体集合。 public List QueryNextRoutes(string startPosi, string endPosi) { //todo 方法需优化 List routers = new List(); try { //查询下一个路由信息 List dt_Routers = BaseDal.QueryData(x => (x.NextPosi == endPosi || x.ChildPosi == endPosi), new Dictionary { { nameof(Dt_Router.IsEnd), OrderByType.Desc } }); if (dt_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 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; } /// /// 根据起点/当前位置、终点获取下一个子节点。 /// /// 起点/当前位置。 /// 终点。 /// 路由类型。 /// 返回路由实体集合。 public List QueryNextRoutes(string startPosi, string endPosi, int routeType) { //todo 方法需优化 List routers = new List(); try { //查询下一个路由信息 List dt_Routers = BaseDal.QueryData(x => (x.NextPosi == endPosi || x.ChildPosi == endPosi) && x.InOutType == routeType, new Dictionary { { nameof(Dt_Router.IsEnd), OrderByType.Desc } }); if (dt_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 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; } /// /// 根据设备编号获取对应的路由点位编号(输送线站台编号)信息 /// /// 设备编号 /// 返回路由点位编号(输送线站台编号)集合 // 根据设备编码查询所有位置 public List QueryAllPositions(string deviceCode) { // 创建一个字符串列表,用于存储所有位置 List positions = new List(); try { // 查询所有进入路由器的位置 List inRouterPositions = BaseDal.QueryData(x => x.ChildPosiDeviceCode == deviceCode && x.InOutType == RouterInOutType.In.ObjToInt()).GroupBy(x => x.StartPosi).Select(x => x.Key).ToList(); // 查询所有离开路由器的位置 List 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 { } // 返回位置列表 return positions; } /// /// 获取路由表中所有完整的路由信息(前端调用展示数据)。 /// /// 匿名对象集合。 public List GetAllWholeRouters() { List data = new List(); // 查询所有路由 List allRouters = BaseDal.QueryData(x => true); // 查询所有结束的路由,并按Id排序 List dt_Routers = allRouters.Where(x => x.IsEnd).OrderBy(x => x.Id).ToList(); // 遍历所有结束的路由 foreach (var item in dt_Routers) { // 获取当前路由的子路由 string routes = $"{item.ChildPosi},"; // 获取当前路由的父路由 string str = GetPreviousRoutes(item.StartPosi, allRouters, item.InOutType); // 如果父路由不为空 if (!string.IsNullOrEmpty(str)) { // 去掉最后一个逗号 if (str.EndsWith(",")) str = str.Substring(0, str.Length - 1); // 将父路由添加到子路由中 routes += str; } // 如果当前路由是入口 if (item.InOutType == RouterInOutType.In.ObjToInt()) { // 将子路由反转并添加到data中 List itemRouters = routes.Split(",").Reverse().ToList(); object obj = new { type = RouterInOutType.In, routes = itemRouters }; data.Add(obj); } // 如果当前路由是出口 else { // 将子路由反转并添加到data中 List itemRouters = routes.Split(",").Reverse().ToList(); object obj = new { type = RouterInOutType.Out, routes = itemRouters }; data.Add(obj); } } // 返回data return data; } private string GetPreviousRoutes(string startPosi, List allRouters, int routerType) { // 定义一个空字符串routers string routers = string.Empty; // 判断startPosi是否为空 if (!string.IsNullOrEmpty(startPosi)) { // 判断routers是否以逗号结尾 if (!routers.EndsWith(",")) // 如果不是,则将startPosi添加到routers中,并在后面加上逗号 routers += $"{startPosi},"; else // 如果是,则将startPosi添加到routers中 routers += $"{startPosi}"; } // 从allRouters中筛选出NextPosi等于startPosi且InOutType等于routerType的元素,并转换为List List preRouters = allRouters.Where(x => x.NextPosi == startPosi && x.InOutType == routerType).ToList(); // 遍历preRouters中的每个元素 foreach (var item in preRouters) { // 调用GetPreviousRoutes方法,传入item.StartPosi、allRouters和routerType,并将返回值赋给str string str = GetPreviousRoutes(item.StartPosi, allRouters, routerType); // 判断str是否为空 if (!string.IsNullOrEmpty(str)) { // 判断routers是否以逗号结尾 if (routers.EndsWith(",")) // 如果是,则将str添加到routers中 routers += $"{str}"; else // 如果不是,则将str添加到routers中,并在后面加上逗号 routers += $"{str},"; } } // 返回routers return routers; } /// /// 添加完整路由信息(前端调用配置路由信息)。 /// /// 设备路由配置添加DTO /// 路由类型 /// 返回处理结果 public WebResponseContent AddRouters(List 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 deviceCode = _deviceInfoRepository.QueryTabs((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 routers = new List(); // 遍历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_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); content = WebResponseContent.Instance.OK(); } catch (Exception ex) { content = WebResponseContent.Instance.Error(ex.Message); } return content; } } }