2025-04-30 16:29:17 +08:00
|
|
|
|
#include "topologyView.h"
|
|
|
|
|
|
#include "ui_topologyView.h"
|
|
|
|
|
|
#include "tools.h"
|
2025-05-09 19:36:32 +08:00
|
|
|
|
#include "topologyTree.h"
|
2025-05-16 19:20:46 +08:00
|
|
|
|
#include "dataBase.h"
|
2025-05-23 10:30:52 +08:00
|
|
|
|
#include "basePropertyManager.h"
|
|
|
|
|
|
#include "baseProperty.h"
|
2026-03-02 20:15:22 +08:00
|
|
|
|
#include "structDataSource.h"
|
|
|
|
|
|
#include "extraPropertyManager.h"
|
2025-04-30 16:29:17 +08:00
|
|
|
|
#include <QStandardItemModel>
|
|
|
|
|
|
#include <QMenu>
|
|
|
|
|
|
#include <QUuid>
|
|
|
|
|
|
|
|
|
|
|
|
TopologyView::TopologyView(QWidget *parent)
|
|
|
|
|
|
: QDialog(parent)
|
|
|
|
|
|
, ui(new Ui::topologyView)
|
2026-03-02 20:15:22 +08:00
|
|
|
|
,_treeModel(nullptr)
|
2025-05-09 19:36:32 +08:00
|
|
|
|
,_treeView(nullptr)
|
2026-03-02 20:15:22 +08:00
|
|
|
|
,_pExtraProManager(nullptr)
|
2025-04-30 16:29:17 +08:00
|
|
|
|
{
|
|
|
|
|
|
ui->setupUi(this);
|
|
|
|
|
|
//setWindowFlags(windowFlags() | Qt::WindowMinMaxButtonsHint&Qt::WindowCloseButtonHint);
|
2026-03-02 20:15:22 +08:00
|
|
|
|
_treeModel = new QStandardItemModel(this);
|
2025-05-09 19:36:32 +08:00
|
|
|
|
_treeView = new TopologyTree(this);
|
|
|
|
|
|
ui->verticalLayout->addWidget(_treeView);
|
|
|
|
|
|
_treeView->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
|
|
|
|
|
2025-04-30 16:29:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TopologyView::~TopologyView()
|
|
|
|
|
|
{
|
|
|
|
|
|
delete ui;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TopologyView::initial()
|
|
|
|
|
|
{
|
2025-05-09 19:36:32 +08:00
|
|
|
|
connect(_treeView, &QTreeView::clicked, this, &TopologyView::onItemClicked);
|
2026-03-02 20:15:22 +08:00
|
|
|
|
connect(_treeModel, &QStandardItemModel::itemChanged, this, &TopologyView::onItemChanged);
|
2025-05-23 10:30:52 +08:00
|
|
|
|
|
2026-03-02 20:15:22 +08:00
|
|
|
|
m_dataSource = new StructDataSource(this);
|
|
|
|
|
|
_pExtraProManager = new ExtraPropertyManager(this);
|
|
|
|
|
|
_pExtraProManager->initial();
|
2025-04-30 16:29:17 +08:00
|
|
|
|
|
2026-03-02 20:15:22 +08:00
|
|
|
|
if(_pExtraProManager)
|
|
|
|
|
|
m_dataSource->loadExtrapro(_pExtraProManager->geAlltProperty());
|
2025-04-30 16:29:17 +08:00
|
|
|
|
|
2026-03-02 20:15:22 +08:00
|
|
|
|
_treeView->setHeaderHidden(true);
|
|
|
|
|
|
// 设置模型的列数
|
|
|
|
|
|
_treeModel->setColumnCount(1);
|
2025-05-16 19:20:46 +08:00
|
|
|
|
|
2025-04-30 16:29:17 +08:00
|
|
|
|
// 创建树视图
|
2026-03-02 20:15:22 +08:00
|
|
|
|
_treeView->setModel(_treeModel);
|
2025-04-30 16:29:17 +08:00
|
|
|
|
|
|
|
|
|
|
// 展开所有节点
|
2025-05-09 19:36:32 +08:00
|
|
|
|
_treeView->expandAll();
|
2025-04-30 16:29:17 +08:00
|
|
|
|
// 显示树视图
|
2025-05-09 19:36:32 +08:00
|
|
|
|
_treeView->setWindowTitle(QObject::tr("拓扑树"));
|
|
|
|
|
|
|
2026-03-02 20:15:22 +08:00
|
|
|
|
loadTopologyFromDB();
|
2025-04-30 16:29:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-02 20:15:22 +08:00
|
|
|
|
void TopologyView::loadTopologyFromDB()
|
2025-04-30 16:29:17 +08:00
|
|
|
|
{
|
2026-03-02 20:15:22 +08:00
|
|
|
|
if(_pExtraProManager)
|
2025-04-30 16:29:17 +08:00
|
|
|
|
{
|
2026-03-02 20:15:22 +08:00
|
|
|
|
//clearItems();
|
|
|
|
|
|
auto& mapExtra = m_dataSource->allProperties;
|
|
|
|
|
|
/*QStandardItem* root = _treeModel->invisibleRootItem();
|
|
|
|
|
|
for(auto& pro:mapExtra){
|
|
|
|
|
|
QStandardItem* propertyItem = new QStandardItem();
|
|
|
|
|
|
addItemToView(pro,"name",root,propertyItem);
|
|
|
|
|
|
}*/
|
|
|
|
|
|
QVector<ExtraProperty> vec = QVector<ExtraProperty>::fromList(mapExtra.values());
|
|
|
|
|
|
buildTreeStructure(_treeModel,vec);
|
|
|
|
|
|
|
|
|
|
|
|
_treeView->expandAll();
|
2025-04-30 16:29:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
{
|
2026-03-02 20:15:22 +08:00
|
|
|
|
QStandardItem* item = _treeModel->itemFromIndex(index);
|
2025-04-30 16:29:17 +08:00
|
|
|
|
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);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-05-23 10:30:52 +08:00
|
|
|
|
|
2026-03-02 20:15:22 +08:00
|
|
|
|
void TopologyView::onUpdateTopology(QList<RelationItem> lst,bool refresh)
|
2025-05-23 10:30:52 +08:00
|
|
|
|
{
|
2026-03-02 20:15:22 +08:00
|
|
|
|
if(refresh){
|
|
|
|
|
|
QStandardItem *root = _treeModel->invisibleRootItem();
|
|
|
|
|
|
int rowCount = root->rowCount();
|
|
|
|
|
|
if (rowCount > 0) {
|
|
|
|
|
|
_treeModel->removeRows(0, rowCount);
|
|
|
|
|
|
}
|
|
|
|
|
|
// 清空缓存
|
|
|
|
|
|
m_mapVoltageLevels.clear();
|
|
|
|
|
|
m_mapBayItems.clear();
|
|
|
|
|
|
}
|
2025-05-23 10:30:52 +08:00
|
|
|
|
|
2026-03-02 20:15:22 +08:00
|
|
|
|
// 第一阶段:处理间隔节点(nCategory == 1)
|
|
|
|
|
|
for(auto &info:lst){
|
|
|
|
|
|
auto curItem = info.item;
|
|
|
|
|
|
if(curItem.nCategory == 1){ // 间隔信息
|
|
|
|
|
|
// 获取间隔的电压层级
|
|
|
|
|
|
QString voltageLevel = curItem.sVoltageLevel;
|
|
|
|
|
|
if(voltageLevel.isEmpty()){
|
|
|
|
|
|
voltageLevel = "未知电压等级"; // 默认值
|
|
|
|
|
|
}
|
2025-05-23 10:30:52 +08:00
|
|
|
|
|
2026-03-02 20:15:22 +08:00
|
|
|
|
// 查找或创建电压层级节点
|
|
|
|
|
|
QStandardItem* pVoltageItem = findOrCreateVoltageLevel(voltageLevel);
|
2025-05-23 10:30:52 +08:00
|
|
|
|
|
2026-03-02 20:15:22 +08:00
|
|
|
|
// 创建间隔节点
|
|
|
|
|
|
QStandardItem* pBayItem = createBayItem(voltageLevel, curItem);
|
2025-05-23 10:30:52 +08:00
|
|
|
|
|
2026-03-02 20:15:22 +08:00
|
|
|
|
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);
|
2025-05-23 10:30:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-03-02 20:15:22 +08:00
|
|
|
|
|
|
|
|
|
|
// 展开所有节点
|
|
|
|
|
|
_treeView->expandAll();
|
2025-05-23 10:30:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-02 20:15:22 +08:00
|
|
|
|
void TopologyView::clearItems()
|
2025-05-23 10:30:52 +08:00
|
|
|
|
{
|
2026-03-02 20:15:22 +08:00
|
|
|
|
if(_treeModel){
|
|
|
|
|
|
QStandardItem *root = _treeModel->invisibleRootItem(); //先清空model
|
|
|
|
|
|
int rowCount = root->rowCount();
|
|
|
|
|
|
if (rowCount > 0) {
|
|
|
|
|
|
_treeModel->removeRows(0, rowCount);
|
2025-10-30 17:20:10 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-03-02 20:15:22 +08:00
|
|
|
|
}
|
2025-05-23 10:30:52 +08:00
|
|
|
|
|
2026-03-02 20:15:22 +08:00
|
|
|
|
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<ExtraProperty>& properties) {
|
|
|
|
|
|
// 清空模型
|
|
|
|
|
|
model->clear();
|
|
|
|
|
|
|
|
|
|
|
|
// 创建根节点
|
|
|
|
|
|
//QStandardItem* root = new QStandardItem("拓扑结构");
|
|
|
|
|
|
//model->appendRow(root);
|
|
|
|
|
|
QStandardItem* root = _treeModel->invisibleRootItem();
|
|
|
|
|
|
// 存储节点映射:路径 -> 节点
|
|
|
|
|
|
QMap<QString, QStandardItem*> 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;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-05-23 10:30:52 +08:00
|
|
|
|
}
|
2026-03-02 20:15:22 +08:00
|
|
|
|
|
|
|
|
|
|
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<ExtraProperty>());
|
|
|
|
|
|
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<ExtraProperty>());
|
|
|
|
|
|
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;
|
2025-05-23 10:30:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-03-02 20:15:22 +08:00
|
|
|
|
|
|
|
|
|
|
// 将属性添加到合适的节点
|
|
|
|
|
|
// 如果有设备,添加到设备节点;否则添加到间隔节点
|
|
|
|
|
|
QVariantMap targetNodeData = currentNode->data(Qt::UserRole + 1).toMap();
|
|
|
|
|
|
QVector<ExtraProperty> nodeProperties = targetNodeData["properties"].value<QVector<ExtraProperty>>();
|
|
|
|
|
|
|
|
|
|
|
|
// 检查属性是否已存在
|
|
|
|
|
|
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);
|
2025-05-23 10:30:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-03-02 20:15:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 简化的获取属性列表函数
|
|
|
|
|
|
QVector<ExtraProperty> 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<QVector<ExtraProperty>>();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return QVector<ExtraProperty>();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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];
|
2025-05-23 10:30:52 +08:00
|
|
|
|
}
|
2026-03-02 20:15:22 +08:00
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
|
|
m_mapVoltageLevels[voltageLevel] = pVoltageItem;
|
|
|
|
|
|
_treeModel->appendRow(pVoltageItem);
|
|
|
|
|
|
|
|
|
|
|
|
return pVoltageItem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 创建间隔节点
|
|
|
|
|
|
QStandardItem* TopologyView::createBayItem(const QString& voltageLevel, 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);
|
|
|
|
|
|
|
|
|
|
|
|
// 存储到缓存中,key 使用"电压层级|间隔名称"确保唯一
|
|
|
|
|
|
QString bayKey = QString("%1|%2").arg(voltageLevel).arg(bayInfo.sName);
|
|
|
|
|
|
m_mapBayItems[bayKey] = pBayItem;
|
|
|
|
|
|
|
|
|
|
|
|
return pBayItem;
|
2025-05-23 10:30:52 +08:00
|
|
|
|
}
|
2026-03-02 20:15:22 +08:00
|
|
|
|
|
|
|
|
|
|
// 在电压层级下查找间隔节点
|
|
|
|
|
|
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->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);
|
|
|
|
|
|
|
|
|
|
|
|
pParent->appendRow(pItem);
|
|
|
|
|
|
}
|
|
|
|
|
|
|