#include "topologyView.h" #include "ui_topologyView.h" #include "tools.h" #include "topologyTree.h" #include "dataBase.h" #include "basePropertyManager.h" #include "baseProperty.h" #include "structDataSource.h" #include "extraPropertyManager.h" #include #include #include TopologyView::TopologyView(QWidget *parent) : QDialog(parent) , ui(new Ui::topologyView) ,_treeModel(nullptr) ,_treeView(nullptr) ,_pExtraProManager(nullptr) { ui->setupUi(this); //setWindowFlags(windowFlags() | Qt::WindowMinMaxButtonsHint&Qt::WindowCloseButtonHint); _treeModel = new QStandardItemModel(this); _treeView = new TopologyTree(this); ui->verticalLayout->addWidget(_treeView); _treeView->setContextMenuPolicy(Qt::CustomContextMenu); } TopologyView::~TopologyView() { delete ui; } void TopologyView::initial() { connect(_treeView, &QTreeView::clicked, this, &TopologyView::onItemClicked); connect(_treeModel, &QStandardItemModel::itemChanged, this, &TopologyView::onItemChanged); m_dataSource = new StructDataSource(this); _pExtraProManager = new ExtraPropertyManager(this); _pExtraProManager->initial(); if(_pExtraProManager) m_dataSource->loadExtrapro(_pExtraProManager->geAlltProperty()); _treeView->setHeaderHidden(true); // 设置模型的列数 _treeModel->setColumnCount(1); // 创建树视图 _treeView->setModel(_treeModel); // 展开所有节点 _treeView->expandAll(); // 显示树视图 _treeView->setWindowTitle(QObject::tr("拓扑树")); loadTopologyFromDB(); } void TopologyView::loadTopologyFromDB() { if(_pExtraProManager) { //clearItems(); auto& mapExtra = m_dataSource->allProperties; /*QStandardItem* root = _treeModel->invisibleRootItem(); for(auto& pro:mapExtra){ QStandardItem* propertyItem = new QStandardItem(); addItemToView(pro,"name",root,propertyItem); }*/ QVector vec = QVector::fromList(mapExtra.values()); buildTreeStructure(_treeModel,vec); _treeView->expandAll(); } } void TopologyView::onItemChanged(QStandardItem *item) { int nLevel = getLevel(item); QString str = item->text(); EntityInfo info; info.sName = str; info.sUuid = item->data(Qt::UserRole+1).toString(); info.eType = EntityType(item->data(Qt::UserRole+2).toInt()); emit entityChange(info); } void TopologyView::onItemClicked(const QModelIndex &index) { QStandardItem* item = _treeModel->itemFromIndex(index); if(item) { EntityType type = EntityType(item->data(Qt::UserRole+2).toInt()); if(type == EntityType::ConfigurationDiagram) { EntityInfo info; info.eType = EntityType::ConfigurationDiagram; info.sName = item->text(); info.sUuid = item->data(Qt::UserRole+1).toString(); info.sParentId = item->parent()->data(Qt::UserRole+1).toString(); emit entitySelected(info); } } } void TopologyView::onUpdateTopology(QList lst, bool refresh, bool bFull) { if(refresh){ QStandardItem *root = _treeModel->invisibleRootItem(); int rowCount = root->rowCount(); 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; if(curItem.nCategory == 1){ // 间隔信息 // 获取间隔的电压层级 QString voltageLevel = curItem.sVoltageLevel; if(voltageLevel.isEmpty()){ voltageLevel = "未知电压等级"; // 默认值 } // 查找或创建电压层级节点 QStandardItem* pVoltageItem = findOrCreateVoltageLevel(voltageLevel); // 创建间隔节点 QStandardItem* pBayItem = createBayItem(voltageLevel, curItem); pVoltageItem->appendRow(pBayItem); } } // 第二阶段:处理设备节点(nCategory == 0) for(auto &info:lst){ auto curItem = info.item; if(curItem.nCategory == 0){ // 设备信息 // 获取设备所属的间隔名称和电压层级 QString bayName = info.parent.sName; QString voltageLevel = info.parent.sVoltageLevel; // 从父间隔获取电压层级 if(!bayName.isEmpty() && !voltageLevel.isEmpty()){ // 查找对应的间隔节点 QStandardItem* pBayItem = findBayItem(voltageLevel, bayName); if(pBayItem){ // 创建设备节点 createDeviceItem(pBayItem, curItem); } } } } } 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() { if(_treeModel){ QStandardItem *root = _treeModel->invisibleRootItem(); //先清空model int rowCount = root->rowCount(); if (rowCount > 0) { _treeModel->removeRows(0, rowCount); } } } QString TopologyView::getLevelType(int index) { switch (index) { case 0: return "电网"; case 1: return "区域"; case 2: return "站点"; case 3: return "电压等级"; case 4: return "间隔"; case 5: return "设备"; case 6: return "分组"; default: return "未知层级"; } } void TopologyView::buildTreeStructure(QStandardItemModel* model, const QVector& properties) { // 清空模型 model->clear(); // 创建根节点 //QStandardItem* root = new QStandardItem("拓扑结构"); //model->appendRow(root); QStandardItem* root = _treeModel->invisibleRootItem(); // 存储节点映射:路径 -> 节点 QMap nodeMap; for (const auto& property : properties) { // 判断是否有设备信息 bool hasDevice = !property.component_uuid.isNull() && !property.component_name.isEmpty(); // 检查间隔信息(根据业务逻辑,间隔应该总是存在) QString bayDisplayName = property.bay_name.isEmpty() ? (property.bay_tag.isEmpty() ? "未命名间隔" : property.bay_tag) : property.bay_name; // 构建完整的节点路径 QStringList pathComponents; // 基本层级:电网、区域、站点、电压等级、间隔 pathComponents << property.grid_name; pathComponents << property.zone_name; pathComponents << property.station_name; pathComponents << property.currentLevel; pathComponents << bayDisplayName; // 如果有设备信息,添加设备层级 if (hasDevice) { QString deviceDisplayName = property.component_name.isEmpty() ? property.component_uuid.toString() : property.component_name; pathComponents << deviceDisplayName; } // 构建路径字符串作为唯一标识 QString pathKey = pathComponents.join("|"); // 查找或创建节点路径 QStandardItem* currentNode = root; QString currentPath = ""; for (int i = 0; i < pathComponents.size(); i++) { currentPath += (i > 0 ? "|" : "") + pathComponents[i]; // 查找是否已存在该节点 QStandardItem* existingNode = nodeMap.value(currentPath); if (!existingNode) { // 在当前父节点下查找 for (int row = 0; row < currentNode->rowCount(); row++) { QStandardItem* child = currentNode->child(row, 0); if (child && child->text() == pathComponents[i]) { QVariantMap childData = child->data(Qt::UserRole + 1).toMap(); QString childPath = childData.value("fullPath").toString(); if (childPath == currentPath) { existingNode = child; nodeMap[currentPath] = child; break; } } } } if (existingNode) { currentNode = existingNode; } else { // 创建新节点 QStandardItem* newNode = new QStandardItem(pathComponents[i]); // 确定节点类型和层级信息 QVariantMap nodeData; nodeData["fullPath"] = currentPath; nodeData["level"] = i; // 根据层级设置节点类型 QString nodeType; QString levelType; switch (i) { case 0: nodeType = "grid"; levelType = "电网"; break; case 1: nodeType = "zone"; levelType = "区域"; break; case 2: nodeType = "station"; levelType = "站点"; break; case 3: nodeType = "voltage"; levelType = "电压等级"; break; case 4: nodeType = "bay"; levelType = "间隔"; break; case 5: if (hasDevice) { nodeType = "device"; levelType = "设备"; // 创建设备节点时初始化属性列表 nodeData["properties"] = QVariant::fromValue(QVector()); nodeData["propertyCount"] = 0; nodeData["deviceId"] = property.component_uuid.toString(); nodeData["deviceName"] = property.component_name; //nodeData["deviceType"] = property.device_type; } break; } // 如果是间隔节点(第4层),也初始化属性列表(用于无设备的情况) if (i == 4) { nodeData["properties"] = QVariant::fromValue(QVector()); nodeData["propertyCount"] = 0; nodeData["bayName"] = property.bay_name; nodeData["bayTag"] = property.bay_tag; } nodeData["nodeType"] = nodeType; nodeData["levelType"] = levelType; newNode->setData(nodeData, Qt::UserRole + 1); currentNode->appendRow(newNode); currentNode = newNode; nodeMap[currentPath] = newNode; } } // 将属性添加到合适的节点 // 如果有设备,添加到设备节点;否则添加到间隔节点 QVariantMap targetNodeData = currentNode->data(Qt::UserRole + 1).toMap(); QVector nodeProperties = targetNodeData["properties"].value>(); // 检查属性是否已存在 bool propertyExists = false; for (const auto& existingProp : nodeProperties) { if (existingProp.code == property.code) { propertyExists = true; break; } } if (!propertyExists) { nodeProperties.append(property); targetNodeData["properties"] = QVariant::fromValue(nodeProperties); // 更新属性数量 int propertyCount = targetNodeData["propertyCount"].toInt() + 1; targetNodeData["propertyCount"] = propertyCount; // 更新节点显示文本 QString currentText = currentNode->text(); // 移除可能存在的数量后缀 currentText = currentText.replace(QRegularExpression("\\(\\d+\\)$"), "").trimmed(); currentNode->setText(QString("%1 (%2)").arg(currentText).arg(propertyCount)); // 更新工具提示 QString tooltip = QString("%1: %2").arg(targetNodeData["levelType"].toString()).arg(currentText); if (propertyCount > 0) { tooltip += QString("\n属性数量: %1").arg(propertyCount); } // 添加设备类型信息(如果是设备节点) if (targetNodeData["nodeType"].toString() == "device") { tooltip += QString("\n设备类型: %1").arg(targetNodeData["deviceType"].toString()); } currentNode->setToolTip(tooltip); // 保存更新后的数据 currentNode->setData(targetNodeData, Qt::UserRole + 1); } } } // 简化的获取属性列表函数 QVector TopologyView::getPropertiesForNode(QStandardItem* node) { QVariantMap nodeData = node->data(Qt::UserRole + 1).toMap(); QString nodeType = nodeData.value("nodeType").toString(); if (nodeType == "device" || nodeType == "bay") { return nodeData["properties"].value>(); } return QVector(); } QString TopologyView::getNodeInfo(QStandardItem* node) { QVariantMap nodeData = node->data(Qt::UserRole + 1).toMap(); QString nodeType = nodeData.value("nodeType").toString(); QString levelType = nodeData.value("levelType").toString(); QString name = node->text().replace(QRegularExpression("\\(\\d+\\)$"), "").trimmed(); int propertyCount = nodeData.value("propertyCount", 0).toInt(); if (nodeType == "device") { return QString("%1: %2 (设备类型: %3, 属性数: %4)") .arg(levelType) .arg(name) .arg(nodeData.value("deviceType").toString()) .arg(propertyCount); } else if (nodeType == "bay") { return QString("%1: %2 (属性数: %3)") .arg(levelType) .arg(name) .arg(propertyCount); } return QString("%1: %2").arg(levelType).arg(name); } // 查找或创建电压层级节点 QStandardItem* TopologyView::findOrCreateVoltageLevel(const QString& voltageLevel) { if(m_mapVoltageLevels.contains(voltageLevel)){ return m_mapVoltageLevels[voltageLevel]; } QStandardItem* pVoltageItem = new QStandardItem(voltageLevel); pVoltageItem->setData(-1, Qt::UserRole+1); // 特殊标识,表示电压层级 pVoltageItem->setData(-1, Qt::UserRole+2); pVoltageItem->setData(QString(), Qt::UserRole+3); m_mapVoltageLevels[voltageLevel] = pVoltageItem; _treeModel->appendRow(pVoltageItem); return pVoltageItem; } // 创建间隔节点 QStandardItem* TopologyView::createBayItem(const QString& cacheKey, const RelationSturctItem& bayInfo) { QStandardItem* pBayItem = new QStandardItem(bayInfo.sName); 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); // 存储完整路径 m_mapBayItems[cacheKey] = pBayItem; return pBayItem; } // 在电压层级下查找间隔节点 QStandardItem* TopologyView::findBayItem(const QString& voltageLevel, const QString& bayName) { QString bayKey = QString("%1|%2").arg(voltageLevel).arg(bayName); // 先从缓存查找 if(m_mapBayItems.contains(bayKey)){ return m_mapBayItems[bayKey]; } // 在对应电压层级下查找 if(m_mapVoltageLevels.contains(voltageLevel)){ QStandardItem* pVoltageItem = m_mapVoltageLevels[voltageLevel]; for(int i = 0; i < pVoltageItem->rowCount(); ++i){ QStandardItem* pItem = pVoltageItem->child(i); if(pItem->text() == bayName && pItem->data(Qt::UserRole+1).toInt() == 1){ m_mapBayItems[bayKey] = pItem; // 加入缓存 return pItem; } } } return nullptr; } // 创建设备节点 void TopologyView::createDeviceItem(QStandardItem* pParent, const RelationSturctItem& deviceInfo) { QStandardItem* pItem = new QStandardItem(deviceInfo.sName); pItem->setData(deviceInfo.nCategory, Qt::UserRole+1); pItem->setData(deviceInfo.nEquipType, Qt::UserRole+2); pItem->setData(deviceInfo.uid, Qt::UserRole+3); pParent->appendRow(pItem); }