From 7252d5ade2830d9d331d95120abe1802e5ca4548 Mon Sep 17 00:00:00 2001 From: baiYue Date: Fri, 6 Mar 2026 19:00:26 +0800 Subject: [PATCH] optimize topology level info --- common/include/global.h | 9 + diagramCavas/include/diagramCavas.h | 7 +- .../graphicsDataModel/diagramEditorModel.h | 4 +- .../graphicsDataModel/fixedPortsModel.h | 4 +- diagramCavas/include/monitorPanel.h | 2 +- diagramCavas/source/diagramCavas.cpp | 46 +--- .../source/diagramEditor/editPanel.cpp | 4 +- diagramCavas/source/drawingPanel.cpp | 179 +++++++------- .../graphicsDataModel/diagramEditorModel.cpp | 125 +++++++++- .../graphicsDataModel/fixedPortsModel.cpp | 91 +++++--- diagramCavas/source/monitorPanel.cpp | 124 +++++----- diagramUtils/source/projectModelManager.cpp | 1 + include/topologyView.h | 24 +- source/mainwindow.cpp | 1 + source/topologyView.cpp | 221 ++++++++++++++++-- 15 files changed, 605 insertions(+), 237 deletions(-) diff --git a/common/include/global.h b/common/include/global.h index 0e8225e..0feb7b6 100644 --- a/common/include/global.h +++ b/common/include/global.h @@ -1226,6 +1226,9 @@ struct RelationSturctItem //层级关系结构item int nEquipType; //设备类别 QString sName; //名称 QUuid uid; //id + QString grid; //电网 + QString zone; //区域 + QString station; //电站 QJsonObject toJson() const { QJsonObject obj; @@ -1234,6 +1237,9 @@ struct RelationSturctItem //层级关系结构item obj["nEquipType"] = nEquipType; obj["sName"] = sName; obj["uid"] = uid.toString(); + obj["grid"] = grid; + obj["zone"] = zone; + obj["station"] = station; return obj; } @@ -1244,6 +1250,9 @@ struct RelationSturctItem //层级关系结构item nEquipType = json["nEquipType"].toInt(); sName = json["sName"].toString(); uid = QUuid::fromString(json["uid"].toString()); + grid = json["grid"].toString(); + zone = json["zone"].toString(); + station = json["station"].toString(); } // 检查有效性 diff --git a/diagramCavas/include/diagramCavas.h b/diagramCavas/include/diagramCavas.h index a2747b9..05ef722 100644 --- a/diagramCavas/include/diagramCavas.h +++ b/diagramCavas/include/diagramCavas.h @@ -50,7 +50,9 @@ signals: void updateMonitorList(QString,QPair,int nMode = 0); //0新增1删除 void createdMonitorItems(QList); //创建的监控中item个数 void selectTarget(QObject*); - void prepareUpdateTopology(QList,bool refresh); //更新层级数 + void prepareUpdateTopology(QList,bool refresh,bool showFull); //更新层级数 refresh:刷新标志,showFull:显示全部层级 + + void updateMonitorTopology(QList); public slots: void onSignal_addDrawingPanel(PowerEntity* p,DiagramMode = DM_edit,QString parent = QString()); //parent:派生运行时的page void onSignal_addGraphicsItem(modelStateInfo&); @@ -82,7 +84,7 @@ public slots: void onCreateTestBaseModelDiagram(); //生成测试基模图 /****************************拓扑关系(层级关系)******************************/ - void onSignal_updateTopology(QList,bool); //更新拓扑列表 + void onSignal_updateTopology(QList,bool,bool); //更新拓扑列表 /******************************生成组态***********************************/ void onSignal_createEditPanel(QString,QUuid); void onSignal_prepareOpenSetting(QString); @@ -105,6 +107,7 @@ public slots: void onSignal_saveMonitor(QList>); //保存选中的监控 void updateMonitorListFromDB(int dest = 0); //从数据库更新监控列表 0更新外部lst 1更新内部lst + void onSignal_updateMonitorTopology(QList); //通知tree更新monitor拓扑 QMap> getMapDraw() {return m_mapDrawPanel;} QMap> getMapEdit() {return m_mapEditPanel;} diff --git a/diagramCavas/include/graphicsDataModel/diagramEditorModel.h b/diagramCavas/include/graphicsDataModel/diagramEditorModel.h index fcd133b..bd06dad 100644 --- a/diagramCavas/include/graphicsDataModel/diagramEditorModel.h +++ b/diagramCavas/include/graphicsDataModel/diagramEditorModel.h @@ -61,7 +61,7 @@ public: void generateItemByModel(QStandardItemModel* pModel,DiagramEditorBaseBlock* pBlock,int nFrom = 0,QPoint delta = QPoint(0,0)); //0间隔1变压器 QList generateItemByInfo(QMap mapRoute,QMap mapCompo,QPointF delta = QPointF(0,0),DiagramEditorBaseBlock* pParent = nullptr); //根据data生成item parent:生成的对象添加到parent下(非拓扑计算) - QMultiMap generateOutConnection(QList,int nTypeTransCon,int nPos = 0,DiagramEditorBaseBlock* pParent = nullptr); //生成外部连接(手动bind的连接) nTypeTransCon变压器连线类型,1中性点连接2外部连接,nPos中性点连接时的位置 + QMultiMap generateOutConnection(QList,QList&,int nTypeTransCon,int nPos = 0,DiagramEditorBaseBlock* pParent = nullptr); //生成外部连接(手动bind的连接)relation:层级关系引用 nTypeTransCon变压器连线类型,1中性点连接2外部连接,nPos中性点连接时的位置 QRectF updateTarget(QMap&,QMap&,int nLayout,int nSource,bool saveToModel = true); //更新位置 nLayout主次朝向:8421,8421 上下左右,上下左右 nSource:0间隔1变压器 regenerate重新生成标志 saveToModel:生成到模型或map void clearCompoDir(QMap&,QMap&,int nSource); //清空component中的dir(updateTarget前调用) @@ -70,7 +70,7 @@ public: QByteArray getWizardInfo(); //返回二进制wizard设置 void setWizardInfo(const QByteArray&); //二进制设置wizard signals: - void updateTopologyItems(QList,bool); //更新当前拓扑列表 <连接关系,是否刷新> + void updateTopologyItems(QList,bool,bool); //更新当前拓扑列表 <连接关系,是否刷新,显示全部层级> private: void bulidAndLinkComponent(QList,QMap,DiagramEditorBaseBlock* pParent = nullptr); //生成并连接线路上的设备 lst,mapComponents(从map中获取正确数据) QByteArray serializeWizardData(const DiagramEditorProjectInfo &data); //序列化eidtor向导设置数据 diff --git a/diagramCavas/include/graphicsDataModel/fixedPortsModel.h b/diagramCavas/include/graphicsDataModel/fixedPortsModel.h index 441cf2d..aa5b195 100644 --- a/diagramCavas/include/graphicsDataModel/fixedPortsModel.h +++ b/diagramCavas/include/graphicsDataModel/fixedPortsModel.h @@ -75,6 +75,7 @@ public: void insertProjectModelName(QString,QString); //插入工程模类型(生成工程模时调用) void showProjectIconSettingDlg(GraphicsProjectModelItem*); //显示工程模图标设置(设置使用图标) void updateItemIcon(QString sMeta,QString sModel,QMap,QString sIndex = ""); //更新指定模型的图标 sIndex:索引下标,为空全部更新 + void saveProject(); //保存工程模组态 /********************baseModel相关**********************/ QMap& allBaseItems(); //获取所有基模对象 QVector allBaseConnections(); @@ -135,7 +136,8 @@ Q_SIGNALS: void monitorCreated(QString,QPair); //监控创建信号 <工程page,<监控page,page_uid>> void monitorItems(QList); //发送创建成功的Items void dataUpdated(); //数据更新通知 - void updateTopologyItems(QList,bool); //更新当前拓扑列表 <连接关系,是否刷新> + void updateTopologyItems(QList,bool,bool); //更新当前拓扑列表 <连接关系,是否刷新,显示全部层级> + void notifyUpdateMonitorTopology(QList); //使用列表中的item id更新总拓扑 public: void setPageName(QString s) {_pageName = s;} //设置表名称 QString pageName() const {return _pageName;} diff --git a/diagramCavas/include/monitorPanel.h b/diagramCavas/include/monitorPanel.h index d0731db..f42a03e 100644 --- a/diagramCavas/include/monitorPanel.h +++ b/diagramCavas/include/monitorPanel.h @@ -63,7 +63,7 @@ private: QToolBar* _toolBar; MonitorSideBarDlg* _sideBar; MonitorConfigDlg* _pConfigDlg; - QStandardItemModel* _itemListmodel; + QStandardItemModel* _itemListmodel; //通用的序列模型(暂时) MonitorDetailAttributeDlg* _detailAttributeDlg; MonitorDisplaySettingDlg* _displaySettingDlg; QMenu* _menuSetting; diff --git a/diagramCavas/source/diagramCavas.cpp b/diagramCavas/source/diagramCavas.cpp index fa7e3e0..2967404 100644 --- a/diagramCavas/source/diagramCavas.cpp +++ b/diagramCavas/source/diagramCavas.cpp @@ -198,6 +198,7 @@ void DiagramCavas::onSignal_addDrawingPanel(PowerEntity* pItem,DiagramMode mode, connect(pModel,&FixedPortsModel::updateCurrentItems,this,&DiagramCavas::onSignal_updateCurItems); connect(pModel,&FixedPortsModel::updateTopologyItems,this,&DiagramCavas::onSignal_updateTopology); connect(pModel,&FixedPortsModel::itemSelected,this,&DiagramCavas::onSignal_selectedItems); + connect(pModel,&FixedPortsModel::notifyUpdateMonitorTopology,this,&DiagramCavas::onSignal_updateMonitorTopology); connect(pPanel,&DrawingPanel::panelDelete,this,&DiagramCavas::onSignal_panelDelete); } else if(mode == DM_run){ @@ -264,7 +265,7 @@ void DiagramCavas::onSignal_savePage() } else if(pPanel->getMode() == DM_edit) { - auto pDrawPanel = dynamic_cast(pPanel); + auto pDrawPanel = dynamic_cast(pPanel); _curPage = pPanel->pageName(); QMessageBox msgBox; msgBox.setText(QString::fromWCharArray(L"提示")); @@ -274,38 +275,9 @@ void DiagramCavas::onSignal_savePage() int ret = msgBox.exec(); switch (ret) { - case QMessageBox::Save: //todo:已存在更新 + case QMessageBox::Save: { - QMap map = pPanel->getModelController()->allItems(); - QList updatedModel; //更新过图标的模型 - for(auto pItem:map) - { - BaseProperty* pData = dynamic_cast(pItem->getProperty()); - if(pData){ - QString sMeta = pData->metaModelName(); - QString sModel = pData->modelName(); - if(!updatedModel.contains(sModel)){ - ProjectModelManager::instance().updateSetting(sMeta,sModel,true); //更新使用的图标数据 - updatedModel.append(sModel); - } - - if(pItem->itemChanged() || pData->dataChanged()) - { - pItem->updateConnectData(); //更新连接状态 - pItem->setItemChanged(false); - } - } - } - - auto context = pPanel->getDiagramInfo(); - - if(DataBase::GetInstance()->getPageIdByName(_curPage) == -1) //不存在,创建 - DataBase::GetInstance()->insertPage(_curPage,_curPage,QJsonObject(),context,QString("page"),1); - else - DataBase::GetInstance()->updatePage(_curPage,_curPage,context); - int pageId = DataBase::GetInstance()->getPageIdByName(_curPage); - pPanel->saveNodes(pageId); - + pPanel->getModelController()->saveProject(); } break; case QMessageBox::Cancel: @@ -609,9 +581,9 @@ void DiagramCavas::onTargetSelected(QObject* obj) } /****************************************************/ -void DiagramCavas::onSignal_updateTopology(QList lst,bool refresh) +void DiagramCavas::onSignal_updateTopology(QList lst,bool refresh,bool showFull) { - emit prepareUpdateTopology(lst,refresh); + emit prepareUpdateTopology(lst,refresh,showFull); } /*******************************************************/ @@ -747,6 +719,7 @@ void DiagramCavas::onSignal_generate(QString sPage,QList lst) QWidget* pWindow= currentSubWindow()->widget(); DrawingPanel* pPanel = dynamic_cast(pWindow); if(pPanel){ + pPanel->getModelController()->saveProject(); //生成运行时之前先保存工程项目 pPanel->getModelController()->generateMonitor(sPage,lst); } } @@ -820,3 +793,8 @@ void DiagramCavas::updateMonitorListFromDB(int dest) } } } + +void DiagramCavas::onSignal_updateMonitorTopology(QList lst) +{ + emit updateMonitorTopology(lst); +} diff --git a/diagramCavas/source/diagramEditor/editPanel.cpp b/diagramCavas/source/diagramEditor/editPanel.cpp index 266801b..8952fb4 100644 --- a/diagramCavas/source/diagramEditor/editPanel.cpp +++ b/diagramCavas/source/diagramEditor/editPanel.cpp @@ -299,8 +299,8 @@ void EditPanel::initByWizardInfo() } } _widgetLayout->addStretch(); - emit _pModel->updateTopologyItems(lstBay,true); - emit _pModel->updateTopologyItems(lstItem,false); + emit _pModel->updateTopologyItems(lstBay,true,false); + emit _pModel->updateTopologyItems(lstItem,false,false); QTimer::singleShot(300, [&]() { // 1000 毫秒 = 1 秒 qDebug() << "一次性定时器触发!"; initBlockConnection(); diff --git a/diagramCavas/source/drawingPanel.cpp b/diagramCavas/source/drawingPanel.cpp index 345f199..2654500 100644 --- a/diagramCavas/source/drawingPanel.cpp +++ b/diagramCavas/source/drawingPanel.cpp @@ -222,106 +222,105 @@ void DrawingPanel::loadNodes(QJsonObject obj) } if(_pModel){ + QString sG; + QString sZ; + QString sS; + for(auto& pBaseItem:_pModel->getProjectItems()) //取grid_zone_station(间隔不含这些内容) + { + BaseProperty* pBase = dynamic_cast(pBaseItem->getProperty()); + if(sG.isEmpty()) + sG = pBase->grid(); + if(sZ.isEmpty()) + sZ = pBase->zone(); + if(sS.isEmpty()) + sS = pBase->station(); + break; + } + QList lstFirst; - for(auto& pBaseItem:_pModel->getProjectItems()) //首次循环添加母线及独立设备(变压器等),更新列表显示使用 + + for(auto& pOtherItem:_pModel->getProjectBayItems()) { - BaseProperty* pBase = dynamic_cast(pBaseItem->getProperty()); - if(pBase->type() == 1){ //母线添加子间隔 - RelationItem info; - info.item.nEquipType = pBase->type(); - info.item.nCategory = 0; - info.item.sName = pBase->name(); - info.item.uid = pBase->uuid(); + BayProperty* pBay = dynamic_cast(pOtherItem->getProperty()); + if(pBay){ + // 创建间隔项 + RelationItem bayInfo; + bayInfo.item.nEquipType = 0; // 间隔的设备类型为0 + bayInfo.item.nCategory = 1; // 类别为1表示间隔 + bayInfo.item.sName = pBay->tag(); + bayInfo.item.uid = pBay->uuid(); + bayInfo.item.sVoltageLevel = QString::number(pBay->getVoltage()); + bayInfo.item.grid = sG; + bayInfo.item.zone = sZ; + bayInfo.item.station = sS; - for(auto& subPair:pBase->getSubList()){ - RelationSturctItem subStruct; - - BayProperty* pTargetBay = nullptr; - for(auto& pOtherItem:_pModel->getProjectBayItems()) - { - BayProperty* pBay = dynamic_cast(pOtherItem->getProperty()); - if(pBay){ - if(pBay->uuid() == subPair.second){ //从所有间隔中找到sublist中的间隔 - pTargetBay = pBay; - break; - } - } - } - - if(pTargetBay){ - subStruct.nEquipType = 0; - subStruct.nCategory = 1; - subStruct.sName = pTargetBay->tag(); - subStruct.uid = pTargetBay->uuid(); - info.subList.append(subStruct); - } - } - lstFirst.append(info); - } - else if(pBase->type() == 15 || pBase->type() == 16){ - RelationItem info; - info.item.nEquipType = pBase->type(); - info.item.nCategory = 0; - info.item.sName = pBase->name(); - info.item.uid = pBase->uuid(); - - for(auto& subPair:pBase->getSubList()){ - RelationSturctItem subStruct; - - ModelProperty* pPro = nullptr; - for(auto& item:_pModel->getProjectItems()){ - auto p = item->getProperty(); - if(p->uuid() == subPair.second){ - pPro = p; - } - } - - if(pPro){ - subStruct.nEquipType = pPro->type(); - subStruct.nCategory = 0; - subStruct.sName = pPro->name(); - subStruct.uid = pPro->uuid(); - info.subList.append(subStruct); - } - } - - lstFirst.append(info); + lstFirst.append(bayInfo); } } - emit _pModel->updateCurrentItems(lstFirst,true); + emit _pModel->updateCurrentItems(lstFirst, true); + emit _pModel->updateTopologyItems(lstFirst, true,true); + + // 第二阶段:处理所有设备 QList lstSecond; - for(auto& pBaseItem:_pModel->getProjectItems()) //二次循环添加间隔内设备(更新列表显示使用) + + // 建立间隔UUID到间隔标签的映射,提高查找效率 + QHash bayUuidToTag; + for(auto& pOtherItem:_pModel->getProjectBayItems()) { - BaseProperty* pBase = dynamic_cast(pBaseItem->getProperty()); - if(pBase->type() != 1 && pBase->type() != 15 && pBase->type() != 16){ //设备添加 - RelationItem info; - info.item.nEquipType = pBase->type(); - info.item.nCategory = 0; - info.item.sName = pBase->name(); - info.item.uid = pBase->uuid(); - - BayProperty* pTargetBay = nullptr; - for(auto& pOtherItem:_pModel->getProjectBayItems()) - { - BayProperty* pBay = dynamic_cast(pOtherItem->getProperty()); - if(pBay){ - QString bayTag = pBay->tag(); - QString parentTag = pBase->getBay(); - if(bayTag == parentTag){ //将bay添加到parent - info.parent.nEquipType = 0; - info.parent.nCategory = 1; - info.parent.sName = pBay->tag(); - info.parent.uid = pBay->uuid(); - break; - } - } - } - - lstSecond.append(info); + BayProperty* pBay = dynamic_cast(pOtherItem->getProperty()); + if(pBay){ + bayUuidToTag[pBay->uuid().toString()] = pBay->tag(); } } - emit _pModel->updateCurrentItems(lstSecond,false); + + for(auto& pBaseItem:_pModel->getProjectItems()) + { + BaseProperty* pBase = dynamic_cast(pBaseItem->getProperty()); + + RelationItem info; + info.item.nEquipType = pBase->type(); + info.item.nCategory = 0; // 类别为0表示设备 + info.item.sName = pBase->name(); + info.item.uid = pBase->uuid(); + + // 查找设备所属的间隔 + QString bayTag; + QString bayUuid; + QString sVoltage; + + // 通过间隔标签直接查找 + bayTag = pBase->getBay(); + + // 如果需要间隔UUID,可以反向查找 + if(!bayTag.isEmpty()){ + for(auto& pOtherItem:_pModel->getProjectBayItems()){ + BayProperty* pBay = dynamic_cast(pOtherItem->getProperty()); + if(pBay && pBay->tag() == bayTag){ + bayUuid = pBay->uuid().toString(); + sVoltage = QString::number(pBay->getVoltage()); + break; + } + } + } + + if(!bayTag.isEmpty()){ + // 设置父间隔信息 + info.parent.nEquipType = 0; + info.parent.nCategory = 1; + info.parent.sName = bayTag; + info.parent.uid = QUuid(bayUuid); + info.parent.sVoltageLevel = sVoltage; + info.parent.grid = sG; + info.parent.zone = sZ; + info.parent.station = sS; + } + + lstSecond.append(info); + } + + emit _pModel->updateCurrentItems(lstSecond, false); + emit _pModel->updateTopologyItems(lstSecond, false,true); } } diff --git a/diagramCavas/source/graphicsDataModel/diagramEditorModel.cpp b/diagramCavas/source/graphicsDataModel/diagramEditorModel.cpp index 6dbeffa..6778d98 100644 --- a/diagramCavas/source/graphicsDataModel/diagramEditorModel.cpp +++ b/diagramCavas/source/graphicsDataModel/diagramEditorModel.cpp @@ -677,7 +677,6 @@ void DiagramEditorModel::generatePreview(bool bVisible) } for(auto iter = baysCompo.begin();iter != baysCompo.end();++iter){ //与间隔相连的线路都被计入间隔 - //QMultiMap mapId = generateOutConnection(iter.value(),2); QList lstFrom; //处理进出链接 QList lstTo; @@ -688,7 +687,10 @@ void DiagramEditorModel::generatePreview(bool bVisible) DiagramEditorBayBlock* pBay = dynamic_cast(p.data()); if(pBay){ if(pBay->getName() == iter.key()){ //相同间隔 - QMultiMap mapId = generateOutConnection(iter.value(),2,0,pBay); //type为2时pos不启用 + QList lstTemp; //外部连线的层级关系 + QMultiMap mapId = generateOutConnection(iter.value(),lstTemp,2,0,pBay); //type为2时pos不启用 + if(!lstTemp.isEmpty()) + lstItem.append(lstItem); switch (pBay->getBayType()) { case BayType::busSectionBay:{ QList values = mapId.values(1); @@ -767,15 +769,18 @@ void DiagramEditorModel::generatePreview(bool bVisible) DiagramEditorTransformerBlock* pTrans = dynamic_cast(p.data()); if(pTrans){ if(pTrans->getName() == iter.key()){ - generateOutConnection(it.value(),1,it.key(),pTrans); + QList lstTemp; //外部连线的层级关系 + generateOutConnection(it.value(),lstTemp,1,it.key(),pTrans); + if(!lstTemp.isEmpty()) + lstItem.append(lstItem); } } } } } } - emit updateTopologyItems(lstBay,true); - emit updateTopologyItems(lstItem,false); + emit updateTopologyItems(lstBay,true,false); + emit updateTopologyItems(lstItem,false,false); } } @@ -1230,7 +1235,7 @@ QList DiagramEditorModel::generateItemByInfo(QMap DiagramEditorModel::generateOutConnection(QList lstBind,int nTypeTransCon,int nPos,DiagramEditorBaseBlock* pParent) +QMultiMap DiagramEditorModel::generateOutConnection(QList lstBind,QList& lstRelation,int nTypeTransCon,int nPos,DiagramEditorBaseBlock* pParent) { QMultiMap bindId; //返回关联的对象id<类型,id> for(auto& compo:lstBind){ //遍历关联外部的item,进行连线 @@ -1256,8 +1261,35 @@ QMultiMap DiagramEditorModel::generateOutConnection(QListid()); if(!_previewItem.contains(lineId)){ //connectdata已存在,item未绘制 auto pLine = generateLine(lineId,strCable,1,pParent); //重新绘制 - if(pLine) + if(pLine){ establishConnection(pSrc,pTarget,pLine,ModelFunctionType::EditorModel); + + //层级关系 + RelationItem info; + info.item.nEquipType = compo.nType; + info.item.nCategory = 0; // 类别为0表示设备 + info.item.sName = strCable; + info.item.uid = lineId; + + // 查找设备所属的间隔 + QString bayTag; + QString bayUuid; + QString sVoltageLevel; + + bayTag = pParent->getName(); + bayUuid = pParent->getId().toString(); + sVoltageLevel = QString::number(pParent->getVoltage()); + + if(!bayTag.isEmpty()){ + // 设置父间隔信息 + info.parent.nEquipType = 0; + info.parent.nCategory = 1; + info.parent.sName = bayTag; + info.parent.uid = QUuid(bayUuid); + info.parent.sVoltageLevel = sVoltageLevel; + } + lstRelation.append(info); + } } else{ //已绘制,略过 } @@ -1265,8 +1297,35 @@ QMultiMap DiagramEditorModel::generateOutConnection(QListgetName(); + bayUuid = pParent->getId().toString(); + sVoltageLevel = QString::number(pParent->getVoltage()); + + if(!bayTag.isEmpty()){ + // 设置父间隔信息 + info.parent.nEquipType = 0; + info.parent.nCategory = 1; + info.parent.sName = bayTag; + info.parent.uid = QUuid(bayUuid); + info.parent.sVoltageLevel = sVoltageLevel; + } + lstRelation.append(info); + } } bindId.insert(nType,uId); if(pParent){ @@ -1298,6 +1357,31 @@ QMultiMap DiagramEditorModel::generateOutConnection(QListgetName(); + bayUuid = pParent->getId().toString(); + sVoltageLevel = QString::number(pParent->getVoltage()); + + if(!bayTag.isEmpty()){ + // 设置父间隔信息 + info.parent.nEquipType = 0; + info.parent.nCategory = 1; + info.parent.sName = bayTag; + info.parent.uid = QUuid(bayUuid); + info.parent.sVoltageLevel = sVoltageLevel; + } + lstRelation.append(info); } } else{ //已绘制,略过 @@ -1311,6 +1395,31 @@ QMultiMap DiagramEditorModel::generateOutConnection(QListgetName(); + bayUuid = pParent->getId().toString(); + sVoltageLevel = QString::number(pParent->getVoltage()); + + if(!bayTag.isEmpty()){ + // 设置父间隔信息 + info.parent.nEquipType = 0; + info.parent.nCategory = 1; + info.parent.sName = bayTag; + info.parent.uid = QUuid(bayUuid); + info.parent.sVoltageLevel = sVoltageLevel; + } + lstRelation.append(info); } } bindId.insert(nType,uId); diff --git a/diagramCavas/source/graphicsDataModel/fixedPortsModel.cpp b/diagramCavas/source/graphicsDataModel/fixedPortsModel.cpp index 812556b..c59d44d 100644 --- a/diagramCavas/source/graphicsDataModel/fixedPortsModel.cpp +++ b/diagramCavas/source/graphicsDataModel/fixedPortsModel.cpp @@ -1982,6 +1982,41 @@ void FixedPortsModel::updateItemIcon(QString sMeta,QString sModel,QMap map = allItems(); + QList updatedModel; //更新过图标的模型 + for(auto pItem:map) + { + BaseProperty* pData = dynamic_cast(pItem->getProperty()); + if(pData){ + QString sMeta = pData->metaModelName(); + QString sModel = pData->modelName(); + if(!updatedModel.contains(sModel)){ + ProjectModelManager::instance().updateSetting(sMeta,sModel,true); //更新使用的图标数据 + updatedModel.append(sModel); + } + + if(pItem->itemChanged() || pData->dataChanged()) + { + pItem->updateConnectData(); //更新连接状态 + pItem->setItemChanged(false); + } + } + } + auto pPanel = dynamic_cast(_widget); + QString sPage = pPanel->pageName(); + + auto context = pPanel->getDiagramInfo(); + + if(DataBase::GetInstance()->getPageIdByName(sPage) == -1) //不存在,创建 + DataBase::GetInstance()->insertPage(sPage,sPage,QJsonObject(),context,QString("page"),1); + else + DataBase::GetInstance()->updatePage(sPage,sPage,context); + int pageId = DataBase::GetInstance()->getPageIdByName(sPage); + pPanel->saveNodes(pageId); +} /*********************baseModel**********************/ QMap& FixedPortsModel::allBaseItems() @@ -2132,12 +2167,17 @@ void FixedPortsModel::generateProjectModel(const QString& sPageName,QListtag(); bayInfo.item.uid = pBay->uuid(); + bayInfo.item.sVoltageLevel = QString::number(pBay->getVoltage()); + bayInfo.item.grid = sG; + bayInfo.item.zone = sZ; + bayInfo.item.station = sS; lstFirst.append(bayInfo); } } emit updateCurrentItems(lstFirst, true); + emit updateTopologyItems(lstFirst, true,true); // 第二阶段:处理所有设备 QList lstSecond; @@ -2165,6 +2205,7 @@ void FixedPortsModel::generateProjectModel(const QString& sPageName,QListgetBay(); @@ -2175,6 +2216,7 @@ void FixedPortsModel::generateProjectModel(const QString& sPageName,QList(pOtherItem->getProperty()); if(pBay && pBay->tag() == bayTag){ bayUuid = pBay->uuid().toString(); + sVoltage = QString::number(pBay->getVoltage()); break; } } @@ -2186,12 +2228,17 @@ void FixedPortsModel::generateProjectModel(const QString& sPageName,QList mapIte } } } - emit updateTopologyItems(lstBay,true); - emit updateTopologyItems(lstItem,false); + emit updateTopologyItems(lstBay,true,false); + emit updateTopologyItems(lstItem,false,false); } void FixedPortsModel::addProjectItemByBaseData(DrawingPanel* pPanel,GraphicsBaseModelItem* pItem,BaseProperty* pPro,QString sGrid,QString sZone,QString sStation) @@ -3361,6 +3408,21 @@ void FixedPortsModel::generateMonitor(QString sPage,QList lst) pPanel->setParentPage(_pageName); //生成页记录被哪个组态生成 QList lstFirst; + QList lstSecond; + for(auto& itemInfo:lst) //第一次循环处理间隔 + { + if(itemInfo.item.nCategory == 1){ //间隔 + if(_bayItem.contains(itemInfo.item.uid)){ + auto pBay = _bayItem.value(itemInfo.item.uid); + BayProperty* pPro = dynamic_cast(pBay->getProperty()); + if(pPro){ + pPanel->getModelController()->addBayByData(pPro); + } + } + lstFirst.append(itemInfo); //在lst插入时判断重复 + } + } + for(auto& itemInfo:lst) { if(itemInfo.item.nCategory == 0){ //设备 @@ -3386,30 +3448,7 @@ void FixedPortsModel::generateMonitor(QString sPage,QList lst) pPanel->getScene()->addItem(pNewItem); //绑定模型 } } - - if(itemInfo.item.nEquipType == 1 || itemInfo.item.nEquipType == 15 || itemInfo.item.nEquipType == 16){ //先添加母线及独立设备 - - lstFirst.append(itemInfo); - } - } - } - } - - QList lstSecond; - for(auto& itemInfo:lst) //第二次循环处理间隔 - { - if(itemInfo.item.nCategory == 1){ //间隔 - if(_bayItem.contains(itemInfo.item.uid)){ - auto pBay = _bayItem.value(itemInfo.item.uid); - BayProperty* pPro = dynamic_cast(pBay->getProperty()); - if(pPro){ - pPanel->getModelController()->addBayByData(pPro); - } - } - } - else{ - if(itemInfo.item.nEquipType != 1 && itemInfo.item.nEquipType != 15 && itemInfo.item.nEquipType != 16){ - lstSecond.append(itemInfo); + lstSecond.append(itemInfo); } } } diff --git a/diagramCavas/source/monitorPanel.cpp b/diagramCavas/source/monitorPanel.cpp index d4253fb..82401d6 100644 --- a/diagramCavas/source/monitorPanel.cpp +++ b/diagramCavas/source/monitorPanel.cpp @@ -196,6 +196,7 @@ void MonitorPanel::loadNodes(QJsonObject obj) QJsonArray nodesJsonArray = obj["nodes"].toArray(); QList> lst; + QList lstId; //通知外部拓扑列表使用 for (QJsonValueRef nodeJson : nodesJsonArray) { QJsonObject node = nodeJson.toObject(); @@ -211,6 +212,7 @@ void MonitorPanel::loadNodes(QJsonObject obj) QString sName = _pModel->addNodeItem(QUuid(uuid),QPointF(dX,dY),dWidth,dHeight,dRotate); if(sName != "err"){ lst.append(qMakePair(sName,QUuid(uuid))); + lstId.append(QUuid(uuid)); } } } @@ -238,6 +240,7 @@ void MonitorPanel::loadNodes(QJsonObject obj) QString sName = _pModel->addConnectLline(id,QUuid(srcItemId),QUuid(destItemId),srcPortId,destPortId); if(sName != "err"){ lst.append(qMakePair(sName,QUuid(id))); + lstId.append(QUuid(id)); } } } @@ -247,6 +250,8 @@ void MonitorPanel::loadNodes(QJsonObject obj) } } + emit getModelController()->notifyUpdateMonitorTopology(lstId); + QJsonArray bayArr = obj["bays"].toArray(); for(QJsonValueRef bayJson:bayArr) { @@ -287,26 +292,23 @@ void MonitorPanel::loadNodes(QJsonObject obj) if(resRel){ QList lstFirst; if(_pModel){ - auto pItems = _pModel->getProjectItems(); - for(auto& itemInfo:lstRelation) + auto pItems = _pModel->getProjectItems(); + auto pBays = _pModel->getProjectBayItems(); + for(auto& itemInfo:lstRelation) //首次循环间隔 { - if(itemInfo.item.nCategory == 0){ //设备 - if(pItems.contains(itemInfo.item.uid)){ - if(itemInfo.item.nEquipType == 1 || itemInfo.item.nEquipType == 15 || itemInfo.item.nEquipType == 16){ //先添加母线及独立设备 - lstFirst.append(itemInfo); - } + if(itemInfo.item.nCategory == 1){ //间隔 + if(pBays.contains(itemInfo.item.uid)){ + lstFirst.append(itemInfo); } } } QList lstSecond; - for(auto& itemInfo:lstRelation) //第二次循环处理间隔内设备 + for(auto& itemInfo:lstRelation) //第二次循环设备 { if(itemInfo.item.nCategory == 0){ //间隔 if(pItems.contains(itemInfo.item.uid)){ - if(itemInfo.item.nEquipType != 1 && itemInfo.item.nEquipType != 15 && itemInfo.item.nEquipType != 16){ - lstSecond.append(itemInfo); - } + lstSecond.append(itemInfo); } } } @@ -335,56 +337,74 @@ void MonitorPanel::updateSelectedItems(QList lst,bool val) } } - for(auto &info:lst){ + // 第一次循环:创建第一层间隔层(nCategory == 1) + QHash intervalItems; // 用于存储间隔项,方便后续查找 + + for (auto &info : lst) { auto curItem = info.item; - if(curItem.nCategory == 0){ - if(curItem.nEquipType == 1 || curItem.nEquipType == 15 || curItem.nEquipType == 16){ //母线与变压器等间隔外设备并列第一层 - QStandardItem *pItem = new QStandardItem(curItem.sName); - pItem->setData(curItem.nCategory,Qt::UserRole+1); - pItem->setData(curItem.nEquipType,Qt::UserRole+2); - pItem->setData(curItem.uid,Qt::UserRole+3); + // 只处理间隔层(nCategory == 1) + if (curItem.nCategory == 1) { + // 创建间隔项 + QStandardItem *pInterval = new QStandardItem(curItem.sName); + pInterval->setData(curItem.nCategory, Qt::UserRole + 1); + pInterval->setData(curItem.nEquipType, Qt::UserRole + 2); + pInterval->setData(curItem.uid, Qt::UserRole + 3); - for(auto& subInfo:info.subList){ //母线挂接间隔,变压器挂接设备 - QStandardItem *pSub = new QStandardItem(subInfo.sName); - pSub->setData(subInfo.nCategory,Qt::UserRole+1); - pSub->setData(subInfo.nEquipType,Qt::UserRole+2); - pSub->setData(subInfo.uid,Qt::UserRole+3); - pItem->appendRow(pSub); + // 添加到模型 + _itemListmodel->appendRow(pInterval); + + // 存储到哈希表,方便第二次循环查找 + intervalItems.insert(curItem.sName, pInterval); + } + } + + // 第二次循环:处理设备(nCategory == 0),统一添加到相应的间隔下 + for (auto &info : lst) { + auto curItem = info.item; + + // 只处理设备(nCategory == 0) + if (curItem.nCategory == 0) { + // 创建设备项 + QStandardItem *pDevice = new QStandardItem(curItem.sName); + pDevice->setData(curItem.nCategory, Qt::UserRole + 1); + pDevice->setData(curItem.nEquipType, Qt::UserRole + 2); + pDevice->setData(curItem.uid, Qt::UserRole + 3); + + // 查找父间隔 + if (!info.parent.sName.isEmpty()) { + // 有父间隔的设备 + QStandardItem *pParentInterval = intervalItems.value(info.parent.sName, nullptr); + + if (pParentInterval) { + // 找到父间隔,直接挂接 + pParentInterval->appendRow(pDevice); + } else { + // 父间隔不存在,创建新的间隔 + QStandardItem *pNewInterval = new QStandardItem(info.parent.sName); + pNewInterval->setData(info.parent.nCategory, Qt::UserRole + 1); + pNewInterval->setData(info.parent.nEquipType, Qt::UserRole + 2); + pNewInterval->setData(info.parent.uid, Qt::UserRole + 3); + _itemListmodel->appendRow(pNewInterval); + pNewInterval->appendRow(pDevice); + intervalItems.insert(info.parent.sName, pNewInterval); } - _itemListmodel->appendRow(pItem); + } else { + // 无父间隔的设备 - 直接添加到顶层 + _itemListmodel->appendRow(pDevice); } - else{ //其他设备挂接在母线下的间隔中 - if(!info.parent.sName.isEmpty()){ //有父,在间隔内 - QStandardItem *pItem = new QStandardItem(curItem.sName); - pItem->setData(curItem.nCategory,Qt::UserRole+1); - pItem->setData(curItem.nEquipType,Qt::UserRole+2); - pItem->setData(curItem.uid,Qt::UserRole+3); - auto pParent = findStandardItemAtLevel(_itemListmodel,1,info.parent.sName,nullptr,0); //查找父间隔所在item - if(pParent){ - pParent->appendRow(pItem); - } - else{ //一层没找到父 - QStandardItem *pPar = nullptr; - pPar = findStandardItemAtLevel(_itemListmodel,0,info.parent.sName,nullptr,0); - if(pPar){ //顶层中找到 - pPar->appendRow(pItem); //将自己挂到父下 - } - else{ //顶层未找到,新建 - pPar = new QStandardItem(info.parent.sName); - pPar->setData(info.parent.nCategory,Qt::UserRole+1); - pPar->setData(info.parent.nEquipType,Qt::UserRole+2); - pPar->setData(info.parent.uid,Qt::UserRole+3); - _itemListmodel->appendRow(pPar); - pPar->appendRow(pItem); //将自己挂到父下 - } - - } - } + // 添加子设备(如果有) + for (auto &subInfo : info.subList) { + QStandardItem *pSub = new QStandardItem(subInfo.sName); + pSub->setData(subInfo.nCategory, Qt::UserRole + 1); + pSub->setData(subInfo.nEquipType, Qt::UserRole + 2); + pSub->setData(subInfo.uid, Qt::UserRole + 3); + pDevice->appendRow(pSub); } } } + _sideBar->getItemsDlg()->updateItems(); _pConfigDlg->updateSelectedItems(); } diff --git a/diagramUtils/source/projectModelManager.cpp b/diagramUtils/source/projectModelManager.cpp index bb675ec..fdbb345 100644 --- a/diagramUtils/source/projectModelManager.cpp +++ b/diagramUtils/source/projectModelManager.cpp @@ -500,6 +500,7 @@ QPair ProjectModelManager::combinePropertySql(const QStandardIt QString defaultValue = pItem->data(DefaultValue).toString(); QString valueRange = pItem->data(ValueRange).toString(); int isNotNull = pItem->data(IsNotNull).toInt(); + QString attributeName = pItem->data(AttributeName).toString(); bool needsQuotes = stringDataTypes.contains(dataType); // 处理数据类型及其长度精度 diff --git a/include/topologyView.h b/include/topologyView.h index d1665a5..55e192a 100644 --- a/include/topologyView.h +++ b/include/topologyView.h @@ -31,7 +31,8 @@ signals: public slots: void onItemChanged(QStandardItem *item); void onItemClicked(const QModelIndex &index); - void onUpdateTopology(QList lst,bool refresh); + void onUpdateTopology(QList lst,bool refresh,bool bFull); + void onMonitorUpdate(QList); //更新运行时 private: void clearItems(); QString getLevelType(int index); @@ -40,16 +41,31 @@ private: QString getNodeInfo(QStandardItem* node); QStandardItem* findBayItem(const QString& voltageLevel, const QString& bayName); QStandardItem* findOrCreateVoltageLevel(const QString& voltageLevel); // 查找或创建电压层级节点 - QStandardItem* createBayItem(const QString& voltageLevel, const RelationSturctItem& bayInfo); + QStandardItem* createBayItem(const QString& cacheKey, const RelationSturctItem& bayInfo); void createDeviceItem(QStandardItem* pParent, const RelationSturctItem& deviceInfo); // 创建设备节点 + + void onUpdateTopologyFull(QList lst, bool refresh); + void onUpdateTopologySimple(QList lst, bool refresh); + + QStandardItem* findOrCreateTopLevelItem(const QString& name, int level, QHash& cache); //// 查找或创建顶级节点(电网) + QStandardItem* findOrCreateChildItem(QStandardItem* pParent, const QString& name, const QString& cacheKey, int level,QHash& cache);// 查找或创建子节点 + QStandardItem* findBayItemInFullTree(const QString& grid, const QString& zone, const QString& station, const QString& voltageLevel, const QString& bayName);// 在完整树中查找间隔节点 private: Ui::topologyView *ui; QStandardItemModel* _treeModel; ExtraPropertyManager* _pExtraProManager; StructDataSource* m_dataSource; TopologyTree* _treeView; - QHash m_mapVoltageLevels; // 存储电压层级名称到树节点的映射 - QHash m_mapBayItems; // 存储间隔节点,key格式为"电压层级|间隔名称" + // 完整层级结构缓存 + QHash m_mapGrids; // 电网节点 + QHash m_mapZones; // 区域节点 + QHash m_mapStations; // 变电站节点 + QHash m_mapVoltageLevels; // 电压层级节点 + QHash m_mapBayItems; // 间隔节点 + + // 原简化层级缓存 + QHash m_simpleVoltageLevels; // 只用于简化模式 + QHash m_simpleBayItems; // 只用于简化模式 }; #endif diff --git a/source/mainwindow.cpp b/source/mainwindow.cpp index 63afcf0..4b2f480 100644 --- a/source/mainwindow.cpp +++ b/source/mainwindow.cpp @@ -186,6 +186,7 @@ void CMainWindow::initializeAction() connect(m_pDiagramCavas,&DiagramCavas::prepareSelectItems,m_pMonitorItemsDlg,&MonitorItemsDlg::onSelectItems); connect(m_pDiagramCavas,&DiagramCavas::updateMonitorList,m_pMonitorPagesDlg,&MonitorPagesDlg::onMonitorCreated); connect(m_pDiagramCavas,&DiagramCavas::createdMonitorItems,m_pMonitorItemsDlg,&MonitorItemsDlg::onMonitorCreated); + connect(m_pDiagramCavas,&DiagramCavas::updateMonitorTopology,m_pTopologyView,&TopologyView::onMonitorUpdate); connect(m_pMonitorItemsDlg,&MonitorItemsDlg::generateMonitor,m_pDiagramCavas,&DiagramCavas::onSignal_generate); connect(m_pMonitorPagesDlg,&MonitorPagesDlg::monitorSelected,m_pDiagramCavas,&DiagramCavas::onSignal_monitorSelected); diff --git a/source/topologyView.cpp b/source/topologyView.cpp index 6df3a4c..554e242 100644 --- a/source/topologyView.cpp +++ b/source/topologyView.cpp @@ -72,7 +72,6 @@ void TopologyView::loadTopologyFromDB() }*/ QVector vec = QVector::fromList(mapExtra.values()); buildTreeStructure(_treeModel,vec); - _treeView->expandAll(); } } @@ -106,7 +105,7 @@ void TopologyView::onItemClicked(const QModelIndex &index) } } -void TopologyView::onUpdateTopology(QList lst,bool refresh) +void TopologyView::onUpdateTopology(QList lst, bool refresh, bool bFull) { if(refresh){ QStandardItem *root = _treeModel->invisibleRootItem(); @@ -114,11 +113,122 @@ void TopologyView::onUpdateTopology(QList lst,bool refresh) if (rowCount > 0) { _treeModel->removeRows(0, rowCount); } - // 清空缓存 + // 清空所有缓存 + m_mapGrids.clear(); + m_mapZones.clear(); + m_mapStations.clear(); m_mapVoltageLevels.clear(); m_mapBayItems.clear(); } + if(bFull){ + // 完整层级结构:grid -> zone -> station -> voltage -> bay -> device + onUpdateTopologyFull(lst, refresh); + } else { + // 简化层级结构:voltage -> bay -> device(现有逻辑) + onUpdateTopologySimple(lst, refresh); + } + + // 展开所有节点 + _treeView->expandAll(); +} + +void TopologyView::onMonitorUpdate(QList lst) +{ + clearItems(); + auto& mapExtra = m_dataSource->allProperties; + QVector vec = QVector::fromList(mapExtra.values()); + + QVector filteredVec; + for (const auto& property : vec) { + if (lst.contains(property.component_uuid)) { + filteredVec.append(property); + } + } + + buildTreeStructure(_treeModel,filteredVec); + _treeView->expandAll(); +} + +void TopologyView::onUpdateTopologyFull(QList lst, bool refresh) +{ + // 第一阶段:处理间隔节点(nCategory == 1) + for(auto &info:lst){ + auto curItem = info.item; + if(curItem.nCategory == 1){ // 间隔信息 + // 获取各级参数 + QString grid = curItem.grid; + QString zone = curItem.zone; + QString station = curItem.station; + QString voltageLevel = curItem.sVoltageLevel; + + // 设置默认值 + if(grid.isEmpty()) grid = "未指定电网"; + if(zone.isEmpty()) zone = "未指定区域"; + if(station.isEmpty()) station = "未指定变电站"; + if(voltageLevel.isEmpty()) voltageLevel = "未知电压等级"; + + // 查找或创建电网节点 + QStandardItem* pGridItem = findOrCreateTopLevelItem(grid, 0, m_mapGrids); + + // 查找或创建区域节点 + QString zoneKey = QString("%1|%2").arg(grid).arg(zone); + QStandardItem* pZoneItem = findOrCreateChildItem(pGridItem, zone, zoneKey, 1, m_mapZones); + + // 查找或创建变电站节点 + QString stationKey = QString("%1|%2|%3").arg(grid).arg(zone).arg(station); + QStandardItem* pStationItem = findOrCreateChildItem(pZoneItem, station, stationKey, 2, m_mapStations); + + // 查找或创建电压层级节点 + QString voltageKey = QString("%1|%2|%3|%4").arg(grid).arg(zone).arg(station).arg(voltageLevel); + QStandardItem* pVoltageItem = findOrCreateChildItem(pStationItem, voltageLevel, voltageKey, 3, m_mapVoltageLevels); + + // 创建间隔节点 + QString bayKey = QString("%1|%2|%3|%4|%5").arg(grid).arg(zone).arg(station).arg(voltageLevel).arg(curItem.sName); + QStandardItem* pBayItem = createBayItem(bayKey, curItem); + + pVoltageItem->appendRow(pBayItem); + } + } + + // 第二阶段:处理设备节点(nCategory == 0) + for(auto &info:lst){ + auto curItem = info.item; + if(curItem.nCategory == 0){ // 设备信息 + // 获取父间隔的参数 + QString grid = info.parent.grid; + QString zone = info.parent.zone; + QString station = info.parent.station; + QString voltageLevel = info.parent.sVoltageLevel; + QString bayName = info.parent.sName; + + if(!grid.isEmpty() && !zone.isEmpty() && !station.isEmpty() && + !voltageLevel.isEmpty() && !bayName.isEmpty()){ + + // 构建间隔节点的缓存key + QString bayKey = QString("%1|%2|%3|%4|%5").arg(grid).arg(zone).arg(station).arg(voltageLevel).arg(bayName); + + // 查找对应的间隔节点 + QStandardItem* pBayItem = nullptr; + if(m_mapBayItems.contains(bayKey)){ + pBayItem = m_mapBayItems[bayKey]; + } else { + // 如果没有在缓存中,需要从树中查找 + pBayItem = findBayItemInFullTree(grid, zone, station, voltageLevel, bayName); + } + + if(pBayItem){ + // 创建设备节点 + createDeviceItem(pBayItem, curItem); + } + } + } + } +} + +void TopologyView::onUpdateTopologySimple(QList lst, bool refresh) +{ + // 现有逻辑,只显示 voltage -> bay -> device // 第一阶段:处理间隔节点(nCategory == 1) for(auto &info:lst){ auto curItem = info.item; @@ -158,9 +268,97 @@ void TopologyView::onUpdateTopology(QList lst,bool refresh) } } } +} - // 展开所有节点 - _treeView->expandAll(); +QStandardItem* TopologyView::findOrCreateTopLevelItem(const QString& name, int level, QHash& cache) +{ + if(cache.contains(name)){ + return cache[name]; + } + + QStandardItem* pItem = new QStandardItem(name); + pItem->setData(level, Qt::UserRole+1); // 存储层级 + pItem->setData(-1, Qt::UserRole+2); // 特殊标识 + pItem->setData(name, Qt::UserRole+3); // 存储名称 + + cache[name] = pItem; + _treeModel->appendRow(pItem); + + return pItem; +} + +QStandardItem* TopologyView::findOrCreateChildItem(QStandardItem* pParent, const QString& name, + const QString& cacheKey, int level, + QHash& cache) +{ + if(cache.contains(cacheKey)){ + return cache[cacheKey]; + } + + // 在父节点下查找 + for(int i = 0; i < pParent->rowCount(); ++i){ + QStandardItem* pChild = pParent->child(i); + if(pChild->text() == name){ + cache[cacheKey] = pChild; + return pChild; + } + } + + // 创建新节点 + QStandardItem* pItem = new QStandardItem(name); + pItem->setData(level, Qt::UserRole+1); + pItem->setData(-1, Qt::UserRole+2); + pItem->setData(cacheKey, Qt::UserRole+3); + + cache[cacheKey] = pItem; + pParent->appendRow(pItem); + + return pItem; +} + +QStandardItem* TopologyView::findBayItemInFullTree(const QString& grid, const QString& zone, + const QString& station, const QString& voltageLevel, + const QString& bayName) +{ + // 构建完整的缓存key + QString bayKey = QString("%1|%2|%3|%4|%5").arg(grid).arg(zone).arg(station).arg(voltageLevel).arg(bayName); + + // 如果缓存中有,直接返回 + if(m_mapBayItems.contains(bayKey)){ + return m_mapBayItems[bayKey]; + } + + // 遍历树查找 + for(int i = 0; i < _treeModel->rowCount(); ++i){ + QStandardItem* pGridItem = _treeModel->item(i); + if(pGridItem->text() != grid) continue; + + for(int j = 0; j < pGridItem->rowCount(); ++j){ + QStandardItem* pZoneItem = pGridItem->child(j); + if(pZoneItem->text() != zone) continue; + + for(int k = 0; k < pZoneItem->rowCount(); ++k){ + QStandardItem* pStationItem = pZoneItem->child(k); + if(pStationItem->text() != station) continue; + + for(int l = 0; l < pStationItem->rowCount(); ++l){ + QStandardItem* pVoltageItem = pStationItem->child(l); + if(pVoltageItem->text() != voltageLevel) continue; + + for(int m = 0; m < pVoltageItem->rowCount(); ++m){ + QStandardItem* pBayItem = pVoltageItem->child(m); + if(pBayItem->text() == bayName && + pBayItem->data(Qt::UserRole+1).toInt() == 4){ // 间隔层级 + m_mapBayItems[bayKey] = pBayItem; // 加入缓存 + return pBayItem; + } + } + } + } + } + } + + return nullptr; } void TopologyView::clearItems() @@ -399,8 +597,6 @@ QStandardItem* TopologyView::findOrCreateVoltageLevel(const QString& voltageLeve } QStandardItem* pVoltageItem = new QStandardItem(voltageLevel); - //pVoltageItem->setCheckable(true); - //pVoltageItem->setCheckState(Qt::Unchecked); pVoltageItem->setData(-1, Qt::UserRole+1); // 特殊标识,表示电压层级 pVoltageItem->setData(-1, Qt::UserRole+2); pVoltageItem->setData(QString(), Qt::UserRole+3); @@ -412,18 +608,15 @@ QStandardItem* TopologyView::findOrCreateVoltageLevel(const QString& voltageLeve } // 创建间隔节点 -QStandardItem* TopologyView::createBayItem(const QString& voltageLevel, const RelationSturctItem& bayInfo) +QStandardItem* TopologyView::createBayItem(const QString& cacheKey, const RelationSturctItem& bayInfo) { QStandardItem* pBayItem = new QStandardItem(bayInfo.sName); - //pBayItem->setCheckable(true); - //pBayItem->setCheckState(Qt::Unchecked); pBayItem->setData(bayInfo.nCategory, Qt::UserRole+1); pBayItem->setData(bayInfo.nEquipType, Qt::UserRole+2); pBayItem->setData(bayInfo.uid, Qt::UserRole+3); + pBayItem->setData(cacheKey, Qt::UserRole+4); // 存储完整路径 - // 存储到缓存中,key 使用"电压层级|间隔名称"确保唯一 - QString bayKey = QString("%1|%2").arg(voltageLevel).arg(bayInfo.sName); - m_mapBayItems[bayKey] = pBayItem; + m_mapBayItems[cacheKey] = pBayItem; return pBayItem; } @@ -457,8 +650,6 @@ QStandardItem* TopologyView::findBayItem(const QString& voltageLevel, const QStr void TopologyView::createDeviceItem(QStandardItem* pParent, const RelationSturctItem& deviceInfo) { QStandardItem* pItem = new QStandardItem(deviceInfo.sName); - //pItem->setCheckable(true); - //pItem->setCheckState(Qt::Unchecked); pItem->setData(deviceInfo.nCategory, Qt::UserRole+1); pItem->setData(deviceInfo.nEquipType, Qt::UserRole+2); pItem->setData(deviceInfo.uid, Qt::UserRole+3);