From af328bdb8ffd47fc40700064b7fb955dc6e98695 Mon Sep 17 00:00:00 2001 From: xingheng Date: Wed, 1 Oct 2025 23:35:57 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86homerun=E7=9A=84?= =?UTF-8?q?=E5=88=86=E9=85=8D=E9=80=BB=E8=BE=91=EF=BC=88=E4=B8=8D=E9=9C=80?= =?UTF-8?q?=E8=A6=81=E8=80=83=E8=99=91=E9=A2=84=E7=95=99=E7=A9=BA=E7=99=BD?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AppApi/IOModuleApiController.cs | 200 +++++++++++------- 1 file changed, 126 insertions(+), 74 deletions(-) diff --git a/Learun.Application.Web/AppApi/IOModuleApiController.cs b/Learun.Application.Web/AppApi/IOModuleApiController.cs index 9753552d..a7caf92b 100644 --- a/Learun.Application.Web/AppApi/IOModuleApiController.cs +++ b/Learun.Application.Web/AppApi/IOModuleApiController.cs @@ -625,8 +625,10 @@ namespace Learun.Application.Web.AppApi //1.2 流程图 分组原则为同一信号类型、同一系统的为一组 var cablesGrouped = cablesNeedAssigned.OrderBy(x => x.AssignedPanel?.PanelID).ThenBy(x => x.PreAssignIOType).ThenBy(x => x.System).ToList(); - cablesGrouped = cablesGrouped.Where(x => x.Sets != null && x.Sets.Count() > 0 && x.AssignedPanel != null).ToList();//过滤掉没有set的,或者没有找到箱子的 - cablesGrouped = cablesGrouped.Where(x => x.Sets.Where(xx => !string.IsNullOrEmpty(xx.PreAssignGroup_Desc)).Count() > 0).ToList();//过滤掉set没有分配信号的 + var cNotPanel = cablesGrouped.FindAll(x => x.AssignedPanel == null); + cablesGrouped = cablesNeedAssigned.FindAll(x => x.AssignedPanel != null); + //cablesGrouped = cablesGrouped.Where(x => x.Sets != null && x.Sets.Count() > 0 && x.AssignedPanel != null).ToList();//过滤掉没有set的,或者没有找到箱子的 + //cablesGrouped = cablesGrouped.Where(x => x.Sets.Where(xx => !string.IsNullOrEmpty(xx.PreAssignGroup_Desc)).Count() > 0).ToList();//过滤掉set没有分配信号的 var allPanelIds = cablesGrouped.Select(x => x.AssignedPanel).Select(x => x.PanelID).Distinct().ToList(); @@ -635,6 +637,15 @@ namespace Learun.Application.Web.AppApi .Where(x => allPanelIds.Contains(x.PanelID)) .GroupBy(x => x.PanelID) .ToDictionary(x => x.Key, x => x.ToList());//带出strip下的channel + + + foreach (var c in cNotPanel) + { + foreach (var set in c.Sets) + { + set.ConnectionInfo = "err:没有找到合适的采集箱"; + } + } foreach (var curPanelId in allPanelIds) { int newTSSeq = 10001; @@ -645,11 +656,6 @@ namespace Learun.Application.Web.AppApi var lastUsedStrip = (ec_PanelStripEntity)null; foreach (var cable in cablesOnThisPanel) { - if (cable.CableID == "8c8ebc52-1ae3-4074-af53-e914dd178e78") - { - Console.Write(""); - } - ; //1.2.2 分组原则为同一信号类型、同一系统的为一组,系统属性从电缆的from端上的设备中取设备的系统,同组的优先放到同一个箱子的同一个模块里面, //如果一组放完后发现模块还有多余的通道可以放则下一个系统继续从这个模块开始分配。 //???总感觉这句话,总结后:可以无脑用上一个模块,直到模块满了再用下一个模块。 @@ -659,7 +665,7 @@ namespace Learun.Application.Web.AppApi //{ // sameGroup = false;//换组了 //} - #endregion + #endregion //1.2 流程图 读取有提前选好箱子的信号 var setsSpared = cable.Sets.Where(x => string.IsNullOrEmpty(x.PreAssignGroup_Desc) || string.IsNullOrEmpty(x.PreAssignInOrOut)).ToList(); var setsIn = cable.Sets.Where(x => !string.IsNullOrEmpty(x.PreAssignGroup_Desc) && x.PreAssignInOrOut == SWS.Share.Enum.inOrOut.输入.ToString()).ToList(); @@ -669,8 +675,20 @@ namespace Learun.Application.Web.AppApi if (cable.PreAssignIOType.ToLower() == GlobalEnum.signalType.Digital.ToString().ToLower()) { - if (setsIn.Count > 0 && setsOut.Count > 0) continue; - //from cjj 25 09 23 wechat:一根电缆可能会出现既有输入也有输出,如果碰到就放到两个端子排里面,公共端不会出现一个输出,一个输入的 + if (setsIn.Count > 0 && setsOut.Count > 0) + { + foreach (var set in setsIn) + { + set.ConnectionInfo = "err:digital类型的电缆,无法同时配置输入和输出。"; + } + foreach (var set in setsOut) + { + set.ConnectionInfo = "err:digital类型的电缆,无法同时配置输入和输出。"; + } + continue; + //from cjj 25 09 23 wechat:一根电缆可能会出现既有输入也有输出,如果碰到就放到两个端子排里面,公共端不会出现一个输出,一个输入的 + } + } #endregion @@ -682,11 +700,23 @@ namespace Learun.Application.Web.AppApi #endregion #region output - if (setsOut.Count > 0) + else if (setsOut.Count > 0) { var resOut = AutoAssignCore(GlobalEnum.inOrOut.输出, setsOut); } + else + { + //all zero + foreach (var set in cable.Sets.Where(x => !setsSpared.Select(c => c.CableSetID).Contains(x.CableSetID))) + { + set.ConnectionInfo = "err:信号描述为空"; + } + foreach (var set in setsSpared) + { + set.ConnectionInfo = "err:电缆无任一set被分配"; + } + } #endregion @@ -763,14 +793,7 @@ namespace Learun.Application.Web.AppApi //1.2 流程图 箱子里是否已经存在端子排(io匹配) List usedChs = new List(); List notUsedChs = new List(); - if (cable.CableClass == SWS.Share.Enum.cableClass.homerun.ToString()) - { - //1.2.3(2)如果模块是通讯信号(像RS485这种就是通讯信号),则不用管预留空白通道这个事情,看到有空的通道就放。 - //当前这个端子排就是可用的 - //????????????????????????????????????? - - } #region 1.2 流程图 按规则先放几个信号进去(放不下就延到下一个模块) //if (cable.Sets.Count > 10) //{ @@ -1012,77 +1035,106 @@ namespace Learun.Application.Web.AppApi //被占用的(wt里有或者信号里或有),或者被锁定的,都算占用 usedChs = allCh.Where(x => allUsedCHBySignalOrSet.Contains(x.ChannelID) || x.lock_flg == 1).ToList(); notUsedChs = allCh.Where(x => !usedChs.Select(c => c.ChannelID).Contains(x.ChannelID)).ToList(); - //1.2 流程图 空的通道数够不够 - double sparedRate = notUsedChs.Count * 1.0 / allChCount * 1.0; - if (sparedRate < 0.05) - { - NeedNextTS = true; - //同时又是最后一个了 - if (idx == matchedStrips.Count - 1) - { - var newTS = CreatePanelStripByProfile2(projId, cable.AssignedPanel, newTSSeq++, ioTypeOnC); - if (newTS.Channels.Count() < setsSpared.Count + 1)//1代表至少要放一个set - { - //有问题了 panel的io模板,估计会导致无限循环了 - break; - } - matchedStrips.Add(newTS); - } - idx++; continue;//本模块可用的模块小于5% - } - //没有空闲通道 next - //或者空闲通道不够放下这个电缆的所有set - //算一下5%是多少个通道 - var trueAvailableChs =notUsedChs.Count- (allChCount- FindMaxNumberChannel(allChCount));//真正能用的(没接过的,然后去掉5%) + var ChNeedConn = 0; var SparedNeedConn = 0; - if (trueAvailableChs < sets.Count) + + if (cable.CableClass.ToLower() == SWS.Share.Enum.cableClass.homerun.ToString()) { - //case1,能顺利接完,set还有多,还要再do循环一次,多余的set和spared都要放到下一个模块 - NeedNextTS = true; - ChNeedConn = trueAvailableChs; SparedNeedConn = 0; - } - else if (trueAvailableChs == sets.Count) - { - //case3,刚好,只有spared可能多 - if (setsSpared.Count > 0) + //1.2.3(2)如果模块是通讯信号(像RS485这种就是通讯信号),则不用管预留空白通道这个事情,看到有空的通道就放。 + + if (allChCount < sets.Count) { - //自己的感觉(非客户word需求里的原话):spared不能自己单独占用一个模块 + //case1,能顺利接完,set还有多,还要再do循环一次,多余的set和spared都要放到下一个模块 NeedNextTS = true; - ChNeedConn = trueAvailableChs - 1;//留一个给spared - SparedNeedConn = 0; + ChNeedConn = allChCount; SparedNeedConn = 0; + } + else if (allChCount == sets.Count) + { + //case3,刚好,只有spared可能多 + ChNeedConn = allChCount; + SparedNeedConn = 0; //homerun不用考虑预留一个set去配合后续的spared } else - { - ChNeedConn = trueAvailableChs; SparedNeedConn = 0; + { + ChNeedConn = sets.Count; + SparedNeedConn = 0; } - } else { - //maxCh > sets.Count - //case2,占满可用通道后(或者没占满通道,预分配set已经没了),只剩下spared的set - if (setsSpared.Count == 0) + //1.2 流程图 空的通道数够不够 + double sparedRate = notUsedChs.Count * 1.0 / allChCount * 1.0; + if (sparedRate < 0.05) { - //ok - ChNeedConn = sets.Count; SparedNeedConn = 0; - } - //这种时候要确保spared也能放下 - else if (trueAvailableChs < sets.Count + setsSpared.Count) - { - //自己的感觉(非客户word需求里的原话):spared不能自己单独占用一个模块 - ChNeedConn = trueAvailableChs - 1;//留一个给spared NeedNextTS = true; - SparedNeedConn = 0; + //同时又是最后一个了 + if (idx == matchedStrips.Count - 1) + { + var newTS = CreatePanelStripByProfile2(projId, cable.AssignedPanel, newTSSeq++, ioTypeOnC); + if (newTS.Channels.Count() < setsSpared.Count + 1)//1代表至少要放一个set + { + //有问题了 panel的io模板,估计会导致无限循环了 + break; + } + matchedStrips.Add(newTS); + } + idx++; continue;//本模块可用的模块小于5% + } + //没有空闲通道 next + //或者空闲通道不够放下这个电缆的所有set + //算一下5%是多少个通道 + var trueAvailableChs = notUsedChs.Count - (allChCount - FindMaxNumberChannel(allChCount));//真正能用的(没接过的,然后去掉5%) + + if (trueAvailableChs < sets.Count) + { + //case1,能顺利接完,set还有多,还要再do循环一次,多余的set和spared都要放到下一个模块 + NeedNextTS = true; + ChNeedConn = trueAvailableChs; SparedNeedConn = 0; + } + else if (trueAvailableChs == sets.Count) + { + //case3,刚好,只有spared可能多 + if (setsSpared.Count > 0) + { + //自己的感觉(非客户word需求里的原话):spared不能自己单独占用一个模块 + NeedNextTS = true; + ChNeedConn = trueAvailableChs - 1;//留一个给spared + SparedNeedConn = 0; + } + else + { + ChNeedConn = trueAvailableChs; SparedNeedConn = 0; + } + } else { - //ok,set和spared都能放下 - ChNeedConn = sets.Count; - SparedNeedConn = setsSpared.Count; + //maxCh > sets.Count + //case2,占满可用通道后(或者没占满通道,预分配set已经没了),只剩下spared的set + if (setsSpared.Count == 0) + { + //ok + ChNeedConn = sets.Count; SparedNeedConn = 0; + } + //这种时候要确保spared也能放下 + else if (trueAvailableChs < sets.Count + setsSpared.Count) + { + //自己的感觉(非客户word需求里的原话):spared不能自己单独占用一个模块 + ChNeedConn = sets.Count - 1;//留一个给spared + NeedNextTS = true; + SparedNeedConn = 0; + } + else + { + //ok,set和spared都能放下 + ChNeedConn = sets.Count; + SparedNeedConn = setsSpared.Count; + } } } + //到这里,说明本模块至少都是可用的 TS.Channels = allCh.OrderBy(X => X.Channel_Seq).ToList();//不能像之前一样过滤掉,否则下一个电缆进来时,总数就不对了。 @@ -1133,12 +1185,12 @@ namespace Learun.Application.Web.AppApi #endregion //shi否要继续 - TS.ChannelsSpared = notUsedChs.Where(x=>x.lock_flg !=1).Count(); + TS.ChannelsSpared = notUsedChs.Where(x => x.lock_flg != 1).Count(); TS.ChannelsUsed = allChCount - TS.ChannelsSpared;// usedChs.Count + (notUsedChs.Where(x => x.lock_flg == 1).Count()); if (NeedNextTS) { sets = sets.Where(x => !x.IsConned ?? false).ToList();//移除已经分配过的set - //同时又是最后一个了 + //同时又是最后一个了 if (idx == matchedStrips.Count - 1) { var newTS = CreatePanelStripByProfile2(projId, cable.AssignedPanel, newTSSeq++, ioTypeOnC); @@ -1150,10 +1202,10 @@ namespace Learun.Application.Web.AppApi matchedStrips.Add(newTS); } idx++; continue;// 需要下一个模块接着放本电缆 - // 手动递增索引,避免无限循环 + // 手动递增索引,避免无限循环 } else - { + { break; } }