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