diff --git a/BoardSetting.cpp b/BoardSetting.cpp index 33e34da..f888ec0 100644 --- a/BoardSetting.cpp +++ b/BoardSetting.cpp @@ -310,6 +310,14 @@ void CBoardSetting::PushData() file.open(QIODevice::WriteOnly); file.write(jsonDoc.toJson()); file.close(); + QString remotePath = QString("/CIDW/qtconfig/%1").arg("UnitBoardsInfo.json"); + ScpClient scp; + bool res = scp.connectToHost(IP, 22, "root", "@#cidw!@123456"); + if(!res){ + QMessageBox::information(nullptr, QStringLiteral("提示"), "连接失败!"); + return; + } + scp.upload(name, remotePath,"UnitBoardsInfo.json"); QString strMAC = MAC; QString taleName = "t_ChannelSetting"; @@ -467,7 +475,6 @@ void CBoardSetting::PushData() QString fileName = QCoreApplication::applicationDirPath() + "/config/UnitWorkConditionsInfo.json"; #endif - QFile file2(fileName); file2.open(QIODevice::WriteOnly); file2.write(jsonDoc2.toJson()); @@ -481,13 +488,7 @@ void CBoardSetting::PushData() strTablename = "t_TriggerConfig"; g_SqliteDB->DeleteData(strTablename); - QString remotePath = QString("/CIDW/qtconfig/%1").arg("UnitWorkConditionsInfo.json"); - ScpClient scp; - bool res = scp.connectToHost(IP, 22, "root", "@#cidw!@123456"); - if(!res){ - QMessageBox::information(nullptr, QStringLiteral("提示"), "连接失败!"); - return; - } + remotePath = QString("/CIDW/qtconfig/%1").arg("UnitWorkConditionsInfo.json"); scp.upload(fileName, remotePath,"UnitWorkConditionsInfo.json"); QJsonDocument jsonDocUnit; diff --git a/CopyDatFile.cpp b/CopyDatFile.cpp index fd6fc8c..3c9e460 100644 --- a/CopyDatFile.cpp +++ b/CopyDatFile.cpp @@ -3,33 +3,25 @@ #include #include "NetMgr.h" #include -#ifdef _WIN32 -#include -#include -#else -#include -#include -#include -#include -#endif -static const QString kUpItem = "__UP__"; + CCopyDatFile::CCopyDatFile(QWidget *parent) : QWidget(parent), ui(new Ui::CCopyDatFile) { ui->setupUi(this); ui -> treeWidget_fileList -> setRootIsDecorated(false); - ui -> treeWidget_fileList -> setHeaderLabels(QStringList() << tr("名字") << tr("大小(KB)") << tr("拥有者") << tr("所属组") << tr("时间")); - ui -> treeWidget_dist -> setHeaderLabels(QStringList() << tr("名字") << tr("大小(KB)") << tr("拥有者") << tr("所属组") << tr("时间")); + ui -> treeWidget_fileList -> setHeaderLabels(QStringList() << tr("名字") << tr("大小(KB)") << tr("类型")<< tr("权限") << tr("拥有者") << tr("所属组") << tr("时间")); + ui -> treeWidget_dist -> setHeaderLabels(QStringList() << tr("名字") << tr("大小(KB)") << tr("类型")<< tr("权限") << tr("拥有者") << tr("所属组") << tr("时间")); ui->treeWidget_fileList->header()->setSectionResizeMode(QHeaderView::ResizeToContents); ui -> treeWidget_fileList -> header() ->setStretchLastSection(false); ui->treeWidget_dist->header()->setSectionResizeMode(QHeaderView::ResizeToContents); ui -> treeWidget_dist -> header() ->setStretchLastSection(false); ui->treeWidget_fileList->setContextMenuPolicy(Qt::CustomContextMenu); QObject::connect(ui->treeWidget_fileList ,SIGNAL(customContextMenuRequested(const QPoint &)),this,SLOT(on_treeWidget_customContextMenuRequested(const QPoint &))); - connect(ui->treeWidget_dist, &QTreeWidget::itemActivated,this, &CCopyDatFile::processItem); connect(ui->treeWidget_fileList, &QTreeWidget::itemDoubleClicked, this, &CCopyDatFile::onItemDoubleClicked); + connect(ui->treeWidget_dist, &QTreeWidget::itemDoubleClicked, + this, &CCopyDatFile::onItemDoubleClickedDist); ui->label_path->setText("/run/media/"); connectToFtp(); @@ -43,54 +35,17 @@ CCopyDatFile::~CCopyDatFile() void CCopyDatFile::connectToFtp() { - bool res = scp.connectToHost("192.168.0.102", 22, "root", "@#cidw!@123456"); + bool res = scp.connectToHost(IP, 22, "root", "@#cidw!@123456"); if(!res){ QMessageBox::information(this, QStringLiteral("提示"), "连接失败!"); return; } - QString path = "/opt/"; - + QString path = "/run/media/"; QVector files ; scp.listRemoteDir(path,files); - fillTreeWidget(ui->treeWidget_fileList, files, path); - - } -void CCopyDatFile::ftpCommandFinished(int, bool error) -{ -// qDebug() << ftp->currentCommand() <currentCommand() == QFtp::ConnectToHost) -// { -// if (error) { - -// return; -// } -// else { - -// return; -// } -// } - -// if (ftp->currentCommand() == QFtp::Login){ -// qDebug() << "连接成功!" << endl; -// ftp -> cd("/var/www/html/cidwdat/"); -// ftp->list(); -// } - -// if (ftp->currentCommand() == QFtp::Get) { -// if (error) { - -// } else { - -// } - - -// } else if (ftp->currentCommand() == QFtp::List) { -// qDebug() << "List" << endl; -// } -} static QString permToString(uint perm) { QString s; @@ -112,33 +67,27 @@ void CCopyDatFile::fillTreeWidget( const QString ¤tPath) { tree->clear(); - QTreeWidgetItem *up = new QTreeWidgetItem; - up->setText(ColName, ".."); - up->setText(ColType, "Dir"); - up->setIcon(ColName, QIcon(":/icons/up.png")); - //up->setData(ColName, Qt::UserRole, kUpItem); - ui->treeWidget_fileList->addTopLevelItem(up); - for (const auto &f : files) { QTreeWidgetItem *item = new QTreeWidgetItem(tree); item->setText(ColName, f.name); - item->setText(ColSize, f.isDir ? "" : QString::number(f.size)); + if (f.isDir) { + item->setText(ColSize, ""); + } else { + item->setText(ColSize, QString::number((f.size + 1023) / 1024)); + item->setTextAlignment(1, Qt::AlignRight | Qt::AlignVCenter); + } item->setText(ColType, f.isDir ? "Dir" : "File"); item->setText(ColPerm, permToString(f.permissions)); item->setText(ColOwner, f.owner); item->setText(ColGroup, f.group); item->setText(ColModified, f.lastModified.toString("yyyy-MM-dd HH:mm:ss")); - item->setData(ColName, Qt::UserRole, f.name); + item->setData(ColName, Qt::UserRole + 1, f.name); // 📁 目录加图标 if (f.isDir) { item->setIcon(ColName, QApplication::style()->standardIcon(QStyle::SP_DirIcon)); - - // 标记可展开(即使还没加载) - item->setChildIndicatorPolicy( - QTreeWidgetItem::ShowIndicator); } else { item->setIcon(ColName, QApplication::style()->standardIcon(QStyle::SP_FileIcon)); @@ -156,41 +105,41 @@ void CCopyDatFile::fillTreeWidget( void CCopyDatFile::on_pushButton_refresh_clicked() { - QString path = "/opt/"; - - QVector files ; - scp.listRemoteDir(path,files); - - fillTreeWidget(ui->treeWidget_dist, files, path); - QString path_dist = "/run/media"; + QVector files ; + scp.listRemoteDir(path_dist,files); + fillTreeWidget(ui->treeWidget_dist, files, path_dist); + m_strDistPath = "/run/media"; } void CCopyDatFile::onItemDoubleClicked(QTreeWidgetItem *item, int column) { if (item->text(ColType) != "Dir") - return; + return; QString path = item->data(ColName, Qt::UserRole).toString(); - QVector files ; scp.listRemoteDir(path,files); - fillTreeWidget(ui->treeWidget_fileList, files, path); - ui->treeWidget_fileList->setProperty("currentPath", path); ui->label_path->setText(path); - + m_strFilePath = path; } +void CCopyDatFile::onItemDoubleClickedDist(QTreeWidgetItem *item, int column){ + if (item->text(ColType) != "Dir") + return; -void CCopyDatFile::processItem(QTreeWidgetItem *item, int /*column*/) -{ - + QString path = item->data(ColName, Qt::UserRole).toString(); + QVector files ; + scp.listRemoteDir(path,files); + fillTreeWidget(ui->treeWidget_dist, files, path); + ui->treeWidget_dist->setProperty("currentPath", path); + ui->label_path->setText(path); + m_strDistPath = path; } - void CCopyDatFile::slotCopyItem() { QTreeWidgetItem *item = ui->treeWidget_fileList->currentItem(); //获取光标所在位置的Item @@ -234,3 +183,25 @@ void CCopyDatFile::on_pushButton_exit_clicked() g_NetMgr->PostJson(req,allObj); } + +void CCopyDatFile::on_pushButton_up_1_clicked() +{ + QVector files ; + QString retPath; + scp.goUp(m_strFilePath,files,retPath); + fillTreeWidget(ui->treeWidget_fileList, files, retPath); + ui->treeWidget_fileList->setProperty("currentPath", retPath); + ui->label_path->setText(retPath); +} + + +void CCopyDatFile::on_pushButton_up_2_clicked() +{ + QVector files ; + QString retPath; + scp.goUp(m_strDistPath,files,retPath); + fillTreeWidget(ui->treeWidget_dist, files, retPath); + ui->treeWidget_fileList->setProperty("currentPath", retPath); + ui->label_path->setText(retPath); +} + diff --git a/CopyDatFile.h b/CopyDatFile.h index e61f0d4..58f27a9 100644 --- a/CopyDatFile.h +++ b/CopyDatFile.h @@ -34,27 +34,27 @@ public: ~CCopyDatFile(); private slots: - //void downloadFile(); - //void cancelDownload(); - - void ftpCommandFinished(int commandId, bool error); void on_pushButton_refresh_clicked(); - void processItem(QTreeWidgetItem *item, int column); void on_treeWidget_customContextMenuRequested(const QPoint &pos); void slotCopyItem(); void on_pushButton_exit_clicked(); void onItemDoubleClicked(QTreeWidgetItem *item, int column); + void onItemDoubleClickedDist(QTreeWidgetItem *item, int column); void fillTreeWidget( QTreeWidget *tree, const QVector &files, const QString ¤tPath); + void on_pushButton_up_1_clicked(); + + void on_pushButton_up_2_clicked(); + private: Ui::CCopyDatFile *ui; QHash isDirectory; void connectToFtp(); QFtp *ftp = nullptr; QStandardItemModel *model; - QString currentPath; + QString m_strFilePath; QString m_strDistPath; QAction *copyAction; ScpClient scp; diff --git a/CopyDatFile.ui b/CopyDatFile.ui index bc96b31..9f5d605 100644 --- a/CopyDatFile.ui +++ b/CopyDatFile.ui @@ -125,22 +125,88 @@ color: rgb(27, 30, 35); - - - - 1 - - - + + + + + + 96 + 28 + + + + + 96 + 28 + + + + #pushButton_up_1 { border-image: url(:/image/Btn/normal_Btn.png); + color:#1f5188 } +#pushButton_up_1:hover { border-image: url(:/image/Btn/normal_Btn_p.png); + color:#ffffff} +#pushButton_up_1:pressed { border-image: url(:/image/Btn/normal_Btn_p.png); + color:#ffffff} +#pushButton_up_1:checked { border-image: url(:/image/Btn/normal_Btn_p.png); + color:#ffffff} + + + 上一级 + + + + + + + + 1 + + + + + - - - - 1 - - - + + + + + + 96 + 28 + + + + + 96 + 28 + + + + #pushButton_up_2 { border-image: url(:/image/Btn/normal_Btn.png); + color:#1f5188 } +#pushButton_up_2:hover { border-image: url(:/image/Btn/normal_Btn_p.png); + color:#ffffff} +#pushButton_up_2:pressed { border-image: url(:/image/Btn/normal_Btn_p.png); + color:#ffffff} +#pushButton_up_2:checked { border-image: url(:/image/Btn/normal_Btn_p.png); + color:#ffffff} + + + 上一级 + + + + + + + + 1 + + + + + diff --git a/ViewTriggerConfig.cpp b/ViewTriggerConfig.cpp index 42c1512..1a516fc 100644 --- a/ViewTriggerConfig.cpp +++ b/ViewTriggerConfig.cpp @@ -130,13 +130,111 @@ void ViewTriggerConfig::LoadTriggerConfig(const QString& strWorkCondition) model->setData(model->index(i,11,QModelIndex()),"阈值"); else if(m_vecTriggerConfig[i].TriggerType == "DELTA") model->setData(model->index(i,12,QModelIndex()),"偏差"); - model->setData(model->index(i,13,QModelIndex()),m_vecTriggerConfig[i].ChannelID); + model->setData(model->index(i,1,QModelIndex()),m_vecTriggerConfig[i].ChannelID,Qt::UserRole); model->setData(model->index(i,14,QModelIndex()),m_vecTriggerConfig[i].WorkConditionID); } } } +void ViewTriggerConfig::populateTree(QStandardItem *parentItem, const QJsonObject &jsonObject) { + for (auto it = jsonObject.begin(); it != jsonObject.end(); ++it) { + QString key = it.key(); + QJsonValue value = it.value(); + if (key == "Combination") { + + } else if (key == "Inputs" && value.isArray()) { + // 解析 Inputs 数组 + QJsonArray inputsArray = value.toArray(); + for (const QJsonValue &inputValue : inputsArray) { + if (inputValue.isObject()) { + populateTree(parentItem, inputValue.toObject()); + } + } + } else if (key.startsWith("logic")) { + // 处理 logicAND 或 logicOR 节点 + QStandardItem *logicItem = new QStandardItem(key); + parentItem->appendRow(logicItem); + + if (value.isArray()) { + QJsonArray logicArray = value.toArray(); + for (const QJsonValue &logicValue : logicArray) { + if (logicValue.isObject()) { + QJsonObject logicCombination = logicValue["Combination"].toObject(); + int MinimumNumber =logicCombination["MinimumNumber"].toInt(); + qDebug() << "MinimumNumber" << MinimumNumber << endl; + logicItem->setData(MinimumNumber,Qt::UserRole+1); + if(key.contains("logicAND")) + logicItem->setText(QString("logicAND(%1)").arg(MinimumNumber)); + populateTree(logicItem, logicValue.toObject()); + } + } + } + } else if (value.isObject()) { + // 如果是嵌套对象 + QStandardItem *objectItem = new QStandardItem(key); + parentItem->appendRow(objectItem); + populateTree(objectItem, value.toObject()); + } else if (key == "displayTitle") { + // 叶子节点:展示 displayTitle + QStandardItem *leafItem = new QStandardItem(value.toString()); + parentItem->appendRow(leafItem); + }else if (key == "channelId") { + vecChannelID.append(value.toString()); + } + } +} +void ViewTriggerConfig::LoadConfiguration(const QString& strWorkConditonName){ +#ifdef Q_OS_WIN32 + QString name = QCoreApplication::applicationDirPath() + "\\config\\UnitConfigurations.json"; +#endif +#ifdef Q_OS_LINUX + QString name = QCoreApplication::applicationDirPath() + "/config/UnitConfigurations.json"; +#endif + QVector vecWorkConditionObj; + QFile loadFile(name); + if(!loadFile.open(QIODevice::ReadOnly)) + { + qDebug() << "could't open projects json"; + return; + } + QString value = loadFile.readAll(); + loadFile.close(); + QJsonParseError parseJsonErr; + QJsonDocument document = QJsonDocument::fromJson(value.toUtf8(), &parseJsonErr); + if (!(parseJsonErr.error == QJsonParseError::NoError)) { + QMessageBox::about(NULL, "提示", "读取文件错误!"); + return; + } + QJsonObject TriggerConfigObj = document.object(); + QJsonArray arrayConfig = TriggerConfigObj["WorkConditionConfiguraitons"].toArray(); + for (int i = 0; i < arrayConfig.size(); i++) { + vecWorkConditionObj.append(arrayConfig[i].toObject()); + } + for (int i = 0; i < vecWorkConditionObj.size(); i++) { + QJsonObject tempObj = vecWorkConditionObj[i]; + if(strWorkConditonName == tempObj["WorkConditionName"].toString()){ + QJsonArray tempArray = tempObj["Configuraitons"].toArray(); + QString strSecondDelaySeconds = tempObj["SecondDelaySeconds"].toString(); + for (int j = 0;j < tempArray.size() ;j++ ) { + QJsonArray tempArray2 = tempArray.at(j)["logicExpress"].toArray(); + // 递归解析 JSON 数据并填充到模型中 + for (int k = 0; k < tempArray2.size(); k++) { + QJsonObject tempObj2 = tempArray2[k].toObject(); + if (tempObj2.contains(QStringLiteral("logicOR"))){ + QJsonValue arrayValue = tempObj2.value(QStringLiteral("logicOR")); + QStandardItem *itemOr = new QStandardItem(QString("logicOR")); + QJsonArray array = arrayValue.toArray(); + for (int kk = 0; kk < array.size(); kk++) { + QJsonObject tempObj3 = array[k].toObject(); + populateTree(itemOr, tempObj3); + } + } + } + } + } + } +} void ViewTriggerConfig::on_pushButton_del_clicked() { int iRet = -1; @@ -155,9 +253,21 @@ void ViewTriggerConfig::on_pushButton_del_clicked() QModelIndex indexCheck = model->index(i,0); bool check = model->data(indexCheck, Qt::UserRole).toBool(); if(check){ + LoadConfiguration(ui->comboBox_workCondition->currentText()); + QString strChannelName = model->data(model->index(i,1)).toString(); QString strWorkConditionID = model->data(model->index(i,14)).toString(); QString strCharacteristic = model->data(model->index(i,2)).toString(); + QString strChannelID = model->data(model->index(i,1),Qt::UserRole).toString(); + if(vecChannelID.size()>0){ + for (int var = 0; var < vecChannelID.size(); var++) { + if(vecChannelID[var] == strChannelID){ + QString message = QString("请先删除“组态配置”中绑定的触发信息。\n通道名称: %1。").arg(strChannelName); + QMessageBox::warning(this, QStringLiteral("警告"), message); + return; + } + } + } QString strWhere = QString("where ChannelName = '%1' and WorkConditionID = %2 and Characteristic = '%3' ").arg(strChannelName).arg(m_WorkCondition[ii].SN).arg(strCharacteristic); QString tableName = "t_TriggerConfig "; QString strSql = QString(" set operate = 3 "); diff --git a/ViewTriggerConfig.h b/ViewTriggerConfig.h index 6188371..b026976 100644 --- a/ViewTriggerConfig.h +++ b/ViewTriggerConfig.h @@ -32,7 +32,10 @@ private: QString m_strWorkCondition; QVector m_WorkCondition; QVector m_vecTriggerConfig; + QVector vecChannelID; void LoadTriggerConfig(const QString& strWorkCondition); + void LoadConfiguration(const QString& strWorkConditonName); + void populateTree(QStandardItem *parentItem, const QJsonObject &jsonObject); }; diff --git a/WorkingCondition.cpp b/WorkingCondition.cpp index 95715d4..037b6c1 100644 --- a/WorkingCondition.cpp +++ b/WorkingCondition.cpp @@ -619,6 +619,14 @@ void CWorkingcondition::on_pushButton_del_clicked() return; } QString strIndex = model->data(model->index(row,0)).toString(); + //判断工况在触发和组态有没有配置 + QString whereCon = QString("WorkConditionID = %1").arg(strIndex); + QVector vecTriggerConfig = g_SqliteDB->GetTriggerConfig("t_TriggerConfig",whereCon); + if(vecTriggerConfig.size() > 0){ + QString message = QString("请先删除“触发配置”中绑定的工况信息。\n通道名称: %1。").arg(vecTriggerConfig[0].ChannelName); + QMessageBox::warning(this, QStringLiteral("提示"), message); + return; + } QString strTablename = "t_WorkCondition"; g_SqliteDB->DeleteData(strTablename,"WorkConditionID",strIndex); strTablename = "t_WorkConditionRules"; @@ -872,16 +880,17 @@ void CWorkingcondition::PushData() file.write(jsonDoc.toJson()); file.close(); - - QString remotePath = QString("ftp://%1/CIDW/qtconfig/%2").arg(IP).arg("UnitWorkConditionsInfo.json"); - + QString remotePath = QString("/CIDW/qtconfig/%1").arg("UnitWorkConditionsInfo.json"); ScpClient scp; bool res = scp.connectToHost(IP, 22, "root", "@#cidw!@123456"); if(!res){ - QMessageBox::information(this, QStringLiteral("提示"), "连接失败!"); + QMessageBox::information(nullptr, QStringLiteral("提示"), "连接失败!"); return; } scp.upload(fileName, remotePath,"UnitWorkConditionsInfo.json"); + scp.disconnectFromHost(); + disconnect(g_NetMgr,SIGNAL(sigNetMgr(QString, const QVariant&)), this, SLOT(slotNetMgr(QString,const QVariant&))); + } void CWorkingcondition::slotNetMgr(QString sAddr, const QVariant &msg) { diff --git a/mainwindow.cpp b/mainwindow.cpp index 6d4402d..d3aa5a4 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -29,7 +29,7 @@ MainWindow::MainWindow(QWidget *parent) : QDate buildDate = QLocale( QLocale::English ).toDate( QString(__DATE__).replace(" ", " 0"), "MMM dd yyyy"); QTime buildTime = QTime::fromString(__TIME__, "hh:mm:ss"); - g_strVersion = "SJ90C V1.2_" + buildDate.toString("yyyyMMdd"); + g_strVersion = "SJ90C V2.0_" + buildDate.toString("yyyyMMdd"); customLogMessageHandler(QtDebugMsg,g_strVersion + " " + buildTime.toString()); g_strProject = settingsread.value("main/Project").toString(); g_strFre = settingsread.value("main/Fre").toString(); diff --git a/scp_client.cpp b/scp_client.cpp index c6cdb34..d9ceb9b 100644 --- a/scp_client.cpp +++ b/scp_client.cpp @@ -5,15 +5,7 @@ #include #include #endif -#ifdef _WIN32 -#include -#include -#else -#include -#include -#include -#include -#endif + #include "NetMgr.h" #include #include @@ -304,7 +296,7 @@ QString ScpClient::gidToName(uint gid) } -void ScpClient::waitSocket(SOCKET sock) +void ScpClient::waitSocket(int sock) { fd_set fds; FD_ZERO(&fds); @@ -468,24 +460,21 @@ bool ScpClient::exec(const QString &cmd, QString &output) libssh2_channel_free(channel); return true; } -bool ScpClient::goUp() +bool ScpClient::goUp(QString& filePath, QVector &files,QString& retPath) { - if (m_currentPath.isEmpty() || m_currentPath == "/") - return true; // 已经在根目录,仍返回 true - - int idx = m_currentPath.lastIndexOf('/'); - if (idx <= 0) { - m_currentPath = "/"; + if (filePath.isEmpty() || filePath == "/") { + filePath = "/"; } else { - m_currentPath = m_currentPath.left(idx); + int idx = filePath.lastIndexOf('/'); + filePath = (idx <= 0) ? "/" : filePath.left(idx); } - // 测试能否列出目录,确保路径有效 - QString dummy; - QString cmd = QString("ls -l %1").arg(m_currentPath); - if (!exec(cmd, dummy)) + // 列出新路径内容 + files.clear(); + if (!listRemoteDir(filePath, files)) { return false; - + } + retPath = filePath; return true; } diff --git a/scp_client.h b/scp_client.h index 795e4d1..4e0d21f 100644 --- a/scp_client.h +++ b/scp_client.h @@ -3,7 +3,15 @@ #include #include #include - +#ifdef _WIN32 +#include +#include +#else +#include +#include +#include +#include +#endif #include #include #include @@ -60,8 +68,8 @@ public: bool removeRemoteDir(const QString &path); bool renameRemote(const QString &oldPath, const QString &newPath); bool exec(const QString &cmd, QString &output); - void waitSocket(SOCKET sock); - bool goUp(); + void waitSocket(int sock); + bool goUp(QString& filePath, QVector &outList,QString& retPath); QString m_currentPath;