using Masuit.Tools; 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_DTO.BasicInfo; using WIDESEAWCS_QuartzJob.Models; using WIDESEAWCS_QuartzJob.Repository; using WIDESEAWCS_QuartzJob.Service; namespace WIDESEAWCS_BasicInfoService { public class RouterService : ServiceBase<Dt_Router, IRouterRepository>, IRouterService { private readonly IDeviceProtocolRepository _deviceProtocolRepository; private readonly IDeviceInfoRepository _deviceInfoRepository; public RouterService(IRouterRepository BaseDal, IDeviceProtocolRepository deviceProtocolRepository, IDeviceInfoRepository deviceInfoRepository) : base(BaseDal) { _deviceProtocolRepository = deviceProtocolRepository; _deviceInfoRepository = deviceInfoRepository; } /// <summary> /// æ ¹æ®èµ·ç‚¹/当å‰ä½ç½®ã€ç»ˆç‚¹èŽ·å–下一个å节点。 /// </summary> /// <param name="startPosi">起点/当å‰ä½ç½®ã€‚</param> /// <param name="endPosi">终点。</param> /// <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) // { // 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; //} /// <summary> /// æ ¹æ®èµ·ç‚¹/当å‰ä½ç½®ã€ç»ˆç‚¹èŽ·å–下一个å节点。 /// </summary> /// <param name="startPosi">起点/当å‰ä½ç½®ã€‚</param> /// <param name="endPosi">终点。</param> /// <returns>返回路由实体集åˆã€‚</returns> public List<Dt_Router> QueryNextRoutes(string startPosi, string endPosi) { // 用于记录已ç»è®¿é—®è¿‡çš„起点和终点组åˆï¼Œé¿å…é‡å¤è®¿é—®è¿›å…¥æ»å¾ªçޝ HashSet<string> visitedRoutes = new HashSet<string>(); return QueryNextRoutesInternal(startPosi, endPosi, visitedRoutes); } private List<Dt_Router> QueryNextRoutesInternal(string startPosi, string endPosi, HashSet<string> visitedRoutes) { List<Dt_Router> routers = new List<Dt_Router>(); try { // æž„å»ºä¸€ä¸ªå”¯ä¸€æ ‡è¯†å½“å‰èµ·ç‚¹å’Œç»ˆç‚¹ç»„åˆçš„å—符串 string routeKey = $"{startPosi}_{endPosi}"; if (visitedRoutes.Contains(routeKey)) { // 如果已ç»è®¿é—®è¿‡ï¼Œç›´æŽ¥è¿”回空列表,é¿å…é‡å¤è¿›å…¥ç›¸åŒçš„递归分支 return routers; } visitedRoutes.Add(routeKey); List<Dt_Router> dt_Routers = BaseDal.QueryData(x => (x.NextPosi == endPosi || x.ChildPosi == endPosi) && x.StartPosi == startPosi, new Dictionary<string, OrderByType> { { nameof(Dt_Router.IsEnd), OrderByType.Desc } }); if (dt_Routers.IsNullOrEmpty()) { 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) { 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 = QueryNextRoutesInternal(startPosi, item.StartPosi, visitedRoutes); 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="deviceCode">设备编å·</param> /// <returns>返回路由点ä½ç¼–å·(输é€çº¿ç«™å°ç¼–å·)集åˆ</returns> public List<string> QueryAllPositions(string deviceCode) { List<string> positions = new List<string>(); try { List<string> inRouterPositions = BaseDal.QueryData(x => x.ChildPosiDeviceCode == deviceCode && x.InOutType == RouterInOutType.In).GroupBy(x => x.StartPosi).Select(x => x.Key).ToList(); List<string> outRouterPositions = BaseDal.QueryData(x => x.ChildPosiDeviceCode == deviceCode && x.InOutType == RouterInOutType.Out).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; } /// <summary> /// 获å–è·¯ç”±è¡¨ä¸æ‰€æœ‰å®Œæ•´çš„路由信æ¯(å‰ç«¯è°ƒç”¨å±•示数æ®)。 /// </summary> /// <returns>匿å对象集åˆã€‚</returns> public List<object> GetAllWholeRouters() { List<object> data = new List<object>(); List<Dt_Router> allRouters = BaseDal.QueryData(x => true); List<Dt_Router> 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) { List<string> itemRouters = routes.Split(",").Reverse().ToList(); object obj = new { type = RouterInOutType.In, routes = itemRouters }; data.Add(obj); } else { List<string> itemRouters = routes.Split(",").Reverse().ToList(); object obj = new { type = RouterInOutType.Out, routes = itemRouters }; data.Add(obj); } } return data; } private string GetPreviousRoutes(string startPosi, List<Dt_Router> allRouters, RouterInOutType routerType) { string routers = string.Empty; if (!string.IsNullOrEmpty(startPosi)) { if (!routers.EndsWith(",")) routers += $"{startPosi},"; else routers += $"{startPosi}"; } List<Dt_Router> preRouters = allRouters.Where(x => x.NextPosi == startPosi && x.InOutType == routerType).ToList(); foreach (var item in preRouters) { string str = GetPreviousRoutes(item.StartPosi, allRouters, routerType); if (!string.IsNullOrEmpty(str)) { if (routers.EndsWith(",")) routers += $"{str}"; else routers += $"{str},"; } } return routers; } /// <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>(); 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 = (RouterInOutType)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 == (RouterInOutType)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; } /// <summary> /// æ ¹æ®è®¾å¤‡ç¼–å·èŽ·å–å‡ºåº“è·¯ç”±ç‚¹ä½ /// </summary> /// <param name="deviceCode"></param> /// <returns></returns> public List<string> QueryOutDeviceCodes(string deviceCode) { List<string> positions = new List<string>(); try { List<string> outRouterPositions = BaseDal.QueryData(x => x.ChildPosiDeviceCode == deviceCode && x.InOutType == RouterInOutType.Out).GroupBy(x => x.ChildPosi).Select(x => x.Key).ToList(); positions.AddRange(outRouterPositions); return positions.GroupBy(x => x).Select(x => x.Key).ToList(); } catch { } return positions; } } }