| 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, 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; | 
|         } | 
|     } | 
| } |