blastopepage.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  1. #include "blastopepage.h"
  2. #include "ui_blastopepage.h"
  3. #include "countdownwidget.h"
  4. #include <QFont>
  5. BlastOpePage::BlastOpePage(QWidget *parent) :
  6. QWidget(parent),
  7. ui(new Ui::BlastOpePage),
  8. dao(DatabaseManager::getInstance().getDatabase())
  9. {
  10. ui->setupUi(this);
  11. initPagination();
  12. //InitFace();
  13. }
  14. void BlastOpePage::showDownWidget(QString uuid,const QString &topic,const QString &message){
  15. CountdownWidget *countdownWidget = new CountdownWidget(this);
  16. countdownWidget->resize(200, 200);
  17. int x = (this->width() - countdownWidget->width()) / 2;
  18. int y = (this->height() - countdownWidget->height()) / 2;
  19. countdownWidget->move(x, y);
  20. countdownWidget->show();
  21. firingWidget *widget = uuidWidgetMap.value(uuid);
  22. if (widget) {
  23. connect(countdownWidget, &CountdownWidget::countdownFinished, widget, [widget,topic,message,countdownWidget](){
  24. widget->onCountdownFinished(topic,message);
  25. }, Qt::SingleShotConnection);
  26. }
  27. }
  28. void BlastOpePage::InitFace()
  29. {
  30. layout = new QVBoxLayout(this);
  31. view = new QWebEngineView(this);
  32. view->setAttribute(Qt::WA_OpaquePaintEvent);
  33. QWebEnginePage *page = view->page();
  34. QJsonObject metaInfo = getMetaInfo();
  35. QObject::connect(page, &QWebEnginePage::featurePermissionRequested, [this,page](const QUrl &securityOrigin, QWebEnginePage::Feature feature) {
  36. handleFeaturePermission(page, securityOrigin, feature);
  37. });
  38. QUrl postUrl("http://192.168.0.255:8000/api/v1/h-face-verify/pc");
  39. QJsonObject response = sendPostRequest(postUrl, metaInfo);
  40. QString certifyUrl;
  41. if (response.contains("data") && response["data"].isObject()) {
  42. QJsonObject dataObject = response["data"].toObject();
  43. if (dataObject.contains("ResultObject") && dataObject["ResultObject"].isObject()) {
  44. QJsonObject resultObject = dataObject["ResultObject"].toObject();
  45. if (resultObject.contains("CertifyId") && resultObject["CertifyId"].isString()) {
  46. certifyId= resultObject["CertifyId"].toString();
  47. }
  48. if (resultObject.contains("CertifyUrl") && resultObject["CertifyUrl"].isString()) {
  49. certifyUrl = resultObject["CertifyUrl"].toString();
  50. }
  51. }
  52. }
  53. if (!certifyUrl.isEmpty()) {
  54. view->load(QUrl(certifyUrl));
  55. layout->addWidget(view);
  56. layout->setStretchFactor(view, 1);
  57. QObject::connect(page, &QWebEnginePage::urlChanged, this, &BlastOpePage::onUrlChanged);
  58. } else {
  59. qDebug() << "Failed to get certifyUrl.";
  60. }
  61. }
  62. void BlastOpePage::closeWebViewAndRestoreUI()
  63. {
  64. //TODO: crash
  65. if (view) {
  66. layout->removeWidget(view);
  67. delete view;
  68. view = nullptr;
  69. }
  70. if (layout) {
  71. delete layout;
  72. layout = nullptr;
  73. }
  74. }
  75. // 槽函数:处理 URL 改变事件
  76. void BlastOpePage::onUrlChanged(const QUrl &newUrl) {
  77. if (newUrl.scheme() == "https" && newUrl.host() == "www.baidu.com") {
  78. closeWebViewAndRestoreUI();
  79. QNetworkAccessManager manager;
  80. QUrl requestUrl(QString("http://192.168.0.255:8000/api/v1/h-face-verify/certifyId/%1").arg(certifyId));
  81. QNetworkRequest request(requestUrl);
  82. QNetworkReply *reply = manager.get(request);
  83. QEventLoop loop;
  84. QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
  85. loop.exec();
  86. if (reply->error() == QNetworkReply::NoError) {
  87. QByteArray responseData = reply->readAll();
  88. QJsonDocument jsonDoc = QJsonDocument::fromJson(responseData);
  89. if (!jsonDoc.isNull() && jsonDoc.isObject()) {
  90. QJsonObject rootObj = jsonDoc.object();
  91. QJsonObject dataObj = rootObj["data"].toObject();
  92. QString message = dataObj["Message"].toString();
  93. QJsonObject resultObj = dataObj["ResultObject"].toObject();
  94. if (resultObj.isEmpty()) {
  95. int ret = QMessageBox::information(nullptr, "提示", message+" ,请重新认证!");
  96. if (ret == QMessageBox::Ok) {
  97. InitFace();
  98. }
  99. } else {
  100. QString passed = resultObj["Passed"].toString();
  101. if (passed == "T") {
  102. QMessageBox::information(nullptr, "提示", "操作成功!");
  103. ui->setupUi(this);
  104. initPagination();
  105. } else if (passed == "F") {
  106. int ret = QMessageBox::critical(nullptr, "提示", "操作失败,请重新认证!");
  107. if (ret == QMessageBox::Ok) {
  108. InitFace();
  109. }
  110. }
  111. }
  112. }
  113. } else {
  114. qDebug() << "Request failed:" << reply->errorString();
  115. }
  116. reply->deleteLater();
  117. }
  118. }
  119. BlastOpePage::~BlastOpePage()
  120. {
  121. delete ui;
  122. if (view) {
  123. delete view;
  124. }
  125. if (layout) {
  126. delete layout;
  127. }
  128. }
  129. QJsonObject BlastOpePage::sendPostRequest(const QUrl &url, const QJsonObject &data) {
  130. QNetworkAccessManager manager;
  131. QNetworkRequest request(url);
  132. request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
  133. QJsonDocument doc(data);
  134. QByteArray postData = doc.toJson();
  135. QNetworkReply *reply = manager.post(request, postData);
  136. QEventLoop loop;
  137. QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
  138. loop.exec();
  139. QJsonObject responseJson;
  140. if (reply->error() == QNetworkReply::NoError) {
  141. QByteArray responseData = reply->readAll();
  142. QJsonDocument responseDoc = QJsonDocument::fromJson(responseData);
  143. if (!responseDoc.isNull() && responseDoc.isObject()) {
  144. responseJson = responseDoc.object();
  145. }
  146. } else {
  147. qDebug() << "Error fetching content: " << reply->errorString();
  148. }
  149. reply->deleteLater();
  150. return responseJson;
  151. }
  152. void BlastOpePage::handleFeaturePermission(QWebEnginePage *page, const QUrl &securityOrigin, QWebEnginePage::Feature feature)
  153. {
  154. if (feature == QWebEnginePage::MediaAudioCapture ||
  155. feature == QWebEnginePage::MediaAudioVideoCapture ||
  156. feature == QWebEnginePage::MediaVideoCapture) {
  157. page->setFeaturePermission(securityOrigin, feature, QWebEnginePage::PermissionGrantedByUser);
  158. } else {
  159. page->setFeaturePermission(securityOrigin, feature, QWebEnginePage::PermissionDeniedByUser);
  160. }
  161. }
  162. QJsonObject BlastOpePage::getMetaInfo() {
  163. QJsonObject metaInfo;
  164. metaInfo["certName"] = "wangyao";
  165. metaInfo["certNo"] = "";
  166. return metaInfo;
  167. }
  168. void BlastOpePage::initPagination(){
  169. pageWidget= new PageWidget;
  170. connect(pageWidget, &PageWidget::currentPageChanged, this, &BlastOpePage::PageChanged);
  171. connect(pageWidget->getComboBox(), QOverload<int>::of(&QComboBox::currentIndexChanged), this, &BlastOpePage::onComboBoxIndexChanged);
  172. ui->verticalLayout_4->addWidget(pageWidget);;
  173. pageSize = 10;
  174. currentPage = 1;
  175. RefreshData();
  176. }
  177. void BlastOpePage::RefreshData()
  178. {
  179. loadDataFromSource(currentPage,pageSize);
  180. }
  181. void BlastOpePage::loadDataFromSource(int currentPage, int pageSize)
  182. {
  183. PaginatedHProjectResult result =dao.getAllHProjectsByOpera(currentPage,pageSize);
  184. QList<QSharedPointer<HProject>> projectList = result.projects;
  185. totalCount = result.totalCount;
  186. pageWidget->setMaxPage(ceil(static_cast<double>(totalCount)/pageSize));
  187. model = new QStandardItemModel(this);
  188. headers = {
  189. {"选择", ""}, // 新增选择列
  190. {"工程名称", "name"},
  191. {"操作员", "operatorName"},
  192. {"爆破员", "blasterName"},
  193. {"井下地址", "addressUuid"},
  194. {"雷管数量", "detSum"},
  195. {"起爆器数量", "blastCount"},
  196. {"起爆状态", "blastStatus"},
  197. {"进度", ""},
  198. {"操作",""},
  199. };
  200. int headerCount = headers.size();
  201. QStringList headerLabels;
  202. QMap<int, QString> propMap;
  203. for (int i = 0; i < headers.size(); ++i) {
  204. headerLabels << headers[i].label;
  205. propMap[i] = headers[i].prop;
  206. }
  207. model->setHorizontalHeaderLabels(headerLabels);
  208. for (int row = 0; row < projectList.size(); ++row) {
  209. HProject& HProject = *projectList.at(row).data();
  210. QStandardItem* uuidItem = new QStandardItem();
  211. uuidItem->setData(HProject.getUuid(), Qt::UserRole);
  212. model->setItem(row, headerCount, uuidItem);
  213. for (int col = 0; col < headerCount; ++col) {
  214. QString prop = propMap[col];
  215. QStandardItem* item = nullptr;
  216. if(col ==0){
  217. item = new QStandardItem();
  218. item->setCheckable(true);
  219. item->setCheckState(Qt::Unchecked);
  220. item->setText("");
  221. }
  222. if (!prop.isEmpty()) {
  223. QMetaProperty metaProp = HProject.metaObject()->property(HProject.metaObject()->indexOfProperty(prop.toUtf8()));
  224. QVariant value = metaProp.read(&HProject);
  225. if (prop == "blastStatus") {
  226. QString statusText;
  227. if (value.toString() == "1") {
  228. statusText = "未 注 册";
  229. item = new QStandardItem(statusText);
  230. item->setForeground(QColor("#e7c66b"));
  231. } else if (value.toString() == "2") {
  232. statusText = "待 起 爆";
  233. item = new QStandardItem(statusText);
  234. item->setForeground(QColor("#f3a361"));
  235. } else if (value.toString() == "3") {
  236. statusText = "起 爆 完 成";
  237. item = new QStandardItem(statusText);
  238. item->setForeground(QColor("#90d543"));
  239. } else {
  240. item = new QStandardItem(value.toString());
  241. }
  242. } else {
  243. item = new QStandardItem(value.toString());
  244. }
  245. }
  246. if (item) {
  247. item->setTextAlignment(Qt::AlignCenter); // 设置文本居中对齐
  248. model->setItem(row, col, item);
  249. }
  250. }
  251. }
  252. ui->tableView->setModel(model);
  253. connectionItem = QObject::connect(model, &QStandardItemModel::itemChanged, this, &BlastOpePage::onItemChanged);
  254. ui->tableView->setColumnWidth(0, 30);
  255. for (int i = 1; i < headerCount; ++i) {
  256. if (i == 8) { // Column: 进度
  257. ui->tableView->horizontalHeader()->setSectionResizeMode(i, QHeaderView::Custom);
  258. ui->tableView->setColumnWidth(i, 180);
  259. } else {
  260. ui->tableView->horizontalHeader()->setSectionResizeMode(i, QHeaderView::Stretch);
  261. }
  262. }
  263. ui->tableView->setColumnHidden(headerCount, true);
  264. ui->tableView->setAlternatingRowColors(true);
  265. ui->tableView->verticalHeader()->setDefaultSectionSize(50);
  266. for (int row = 0; row < projectList.size(); ++row) {
  267. int progressCol = headers.size() - 2; //
  268. QProgressBar *progressBar1 = new QProgressBar(ui->tableView);
  269. progressBar1->setRange(0, 100); // 设置范围为0到100
  270. progressBar1->setValue(0);
  271. progressBar1->setAlignment(Qt::AlignCenter);
  272. progressBar1->setStyleSheet("QProgressBar { border: 1px solid grey; border-radius: 5px; background-color: #EEEEEE; height: 10px; }"
  273. "QProgressBar::chunk { background-color: #05B8CC; width: 2px; margin: 0.5px; border - radius: 10px; }");
  274. progressBar1->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
  275. QProgressBar *progressBar2 = new QProgressBar(ui->tableView);
  276. progressBar2->setRange(0, 100); // 设置范围为0到100
  277. progressBar2->setValue(0);
  278. progressBar2->setAlignment(Qt::AlignCenter);
  279. progressBar2->setStyleSheet("QProgressBar { border: 1px solid grey; border-radius: 5px; background-color: #EEEEEE; height: 20px; }"
  280. "QProgressBar::chunk { background-color: #05B8CC; width: 20px; margin: 0.5px; border - radius: 10px; }");
  281. progressBar2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
  282. QProgressBar *progressBar3 = new QProgressBar(ui->tableView);
  283. progressBar3->setRange(0, 100); // 设置范围为0到100
  284. progressBar3->setValue(0);
  285. progressBar3->setAlignment(Qt::AlignCenter);
  286. progressBar3->setStyleSheet("QProgressBar { border: 1px solid grey; border-radius: 5px; background-color: #EEEEEE; height: 20px; }"
  287. "QProgressBar::chunk { background-color: #05B8CC; width: 20px; margin: 0.5px; border - radius: 10px; }");
  288. progressBar3->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
  289. progressBars.append(ProgressBarTriple(progressBar1, progressBar2,progressBar3));
  290. QHBoxLayout *progressBarLayout = new QHBoxLayout;
  291. progressBarLayout->addWidget(progressBar1);
  292. progressBarLayout->addWidget(progressBar2);
  293. progressBarLayout->addWidget(progressBar3);
  294. progressBarLayout->setAlignment(Qt::AlignCenter);
  295. progressBarLayout->setContentsMargins(0, 0, 0, 0);
  296. progressBarLayout->setSpacing(0); // 设置进度条之间的间距为0
  297. QWidget *progressBarContainer = new QWidget(ui->tableView);
  298. progressBarContainer->setLayout(progressBarLayout);
  299. QModelIndex progressIndex = model->index(row, progressCol);
  300. if (progressIndex.isValid()) {
  301. ui->tableView->setIndexWidget(progressIndex, progressBarContainer);
  302. }
  303. int col = headers.size() - 1;
  304. // 创建一个按钮
  305. QWidget* widget = new QWidget(ui->tableView);
  306. QPushButton* button = new QPushButton(widget);
  307. button->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
  308. QModelIndex statusIndex = model->index(row, propMap.key("blastStatus"));
  309. if (statusIndex.isValid()) {
  310. QString blastStatus = model->data(statusIndex).toString();
  311. if (blastStatus == "起 爆 完 成") {
  312. // 为按钮添加图标,这里假设图标文件名为 icon.png,你需要根据实际情况修改
  313. QIcon icon(":/icons/icons/svg/blast.svg");
  314. button->setIcon(icon);
  315. button->setIconSize(QSize(32, 32)); // 设置图标大小
  316. button->setStyleSheet("QPushButton {"
  317. " padding: 0px;"
  318. " border: none;"
  319. " background-color: transparent;"
  320. "}"
  321. );
  322. }else{
  323. button->setText("开启起爆流程");
  324. }
  325. }
  326. QHBoxLayout* layout = new QHBoxLayout(widget);
  327. layout->addWidget(button);
  328. layout->setAlignment(Qt::AlignCenter);
  329. layout->setContentsMargins(0, 0, 0, 0);
  330. widget->setLayout(layout);
  331. QModelIndex index = model->index(row, col);
  332. if (index.isValid()) {
  333. ui->tableView->setIndexWidget(index, widget);
  334. connect(button, &QPushButton::clicked, [this, row,button]() {
  335. handleButtonClick(row,button);
  336. });
  337. }
  338. }
  339. }
  340. // 切换页数
  341. void BlastOpePage::PageChanged(int page)
  342. {
  343. currentPage = page;
  344. loadDataFromSource(currentPage,pageSize);
  345. }
  346. void BlastOpePage::onComboBoxIndexChanged(int index) {
  347. QVariant variant = pageWidget->getComboBox()->itemData(index);
  348. int value = variant.toInt();
  349. pageSize = value;
  350. currentPage = 1;
  351. loadDataFromSource(currentPage,pageSize);
  352. }
  353. void BlastOpePage::updateProgressBar(int value, int row)
  354. {
  355. if (!progressBars.isEmpty()) {
  356. QProgressBar *progressBar1 = progressBars[row].bar1;
  357. QProgressBar *progressBar2 = progressBars[row].bar2;
  358. QProgressBar *progressBar3 = progressBars[row].bar3;
  359. switch (value) {
  360. case 1:
  361. //检查状态
  362. progressBar1->setRange(0, 0); // 设置范围为0到100
  363. progressBar1->setValue(0);
  364. break;
  365. case 2:
  366. // 检查完成
  367. progressBar1->setRange(0, 100); // 设置范围为0到100
  368. progressBar1->setValue(100);
  369. break;
  370. case 3:
  371. // 充电开始
  372. progressBar2->setRange(0, 0); // 设置范围为0到100
  373. progressBar2->setValue(0);
  374. break;
  375. case 4:
  376. //充电完成
  377. progressBar2->setRange(0, 100); // 设置范围为0到100
  378. progressBar2->setValue(100);
  379. break;
  380. case 5:
  381. //起爆中
  382. progressBar3->setRange(0, 0); // 设置范围为0到100
  383. progressBar3->setValue(0);
  384. break;
  385. case 6:
  386. //充电完成
  387. progressBar3->setRange(0, 100); // 设置范围为0到100
  388. progressBar3->setValue(100);
  389. break;
  390. case 0:
  391. progressBar1->setRange(0, 100);
  392. progressBar1->setValue(0);
  393. progressBar2->setRange(0, 100);
  394. progressBar2->setValue(0);
  395. progressBar3->setRange(0, 100);
  396. progressBar3->setValue(0);
  397. break;
  398. default:
  399. break;
  400. }
  401. }
  402. }
  403. void BlastOpePage::onUpdateBlastStatus(int status ,int row)
  404. {
  405. QModelIndex index = model->index(row, 7);
  406. if (index.isValid()) {
  407. QColor customColor;
  408. QFont boldFont;
  409. boldFont.setBold(true);
  410. switch (status) {
  411. case 1:
  412. model->setData(index, "组 网 中 ...");
  413. customColor= QColor("#44035b");
  414. model->setData(index, customColor, Qt::ForegroundRole);
  415. model->setData(index, boldFont, Qt::FontRole);
  416. break;
  417. case 2:
  418. model->setData(index, "组 网 完 成");
  419. customColor = QColor("#404185");
  420. model->setData(index, customColor, Qt::ForegroundRole);
  421. break;
  422. case 3:
  423. model->setData(index, "充 电 中 ...");
  424. customColor = QColor("#31688e");
  425. model->setData(index, customColor, Qt::ForegroundRole);
  426. break;
  427. case 4:
  428. model->setData(index, "充 电 完 成");
  429. customColor = QColor("#1f918d");
  430. model->setData(index, customColor, Qt::ForegroundRole);
  431. break;
  432. case 5:
  433. model->setData(index, "起 爆 中 ...");
  434. customColor = QColor("#38b775");
  435. model->setData(index, customColor, Qt::ForegroundRole);
  436. break;
  437. case 6:
  438. model->setData(index, "起 爆 完 成");
  439. customColor = QColor("#90d543");
  440. model->setData(index, customColor, Qt::ForegroundRole);
  441. break;
  442. case 0:
  443. model->setData(index, "已 注 册");
  444. customColor = QColor("#8e620");
  445. model->setData(index, customColor, Qt::ForegroundRole);
  446. break;
  447. case 10:
  448. model->setData(index, "按 下 双 建 起 爆 ...");
  449. customColor = QColor("#8e620");
  450. model->setData(index, customColor, Qt::ForegroundRole);
  451. break;
  452. default:
  453. break;
  454. }
  455. }
  456. }
  457. void BlastOpePage::handleButtonClick(int row,QPushButton *button){
  458. QStandardItem *uuidItem = model->item(row, 10);
  459. QString uuid;
  460. if (uuidItem) {
  461. QVariant uuidVariant = uuidItem->data(Qt::UserRole);
  462. if (uuidVariant.isValid()) {
  463. uuid = uuidVariant.toString();
  464. }
  465. }
  466. if (button->text() == "开启起爆流程") {
  467. button->setText("取消起爆流程");
  468. firingWidget *widget = new firingWidget(row,false,uuid);
  469. connect(widget, &firingWidget::progressChanged, this, &BlastOpePage::updateProgressBar);
  470. connect(widget, &firingWidget::updateBlastStatus, this, &BlastOpePage::onUpdateBlastStatus);
  471. connect(widget,&firingWidget::updateButton,this,&BlastOpePage::changeButByMqtt);
  472. connect(widget,&firingWidget::countdown,this,&BlastOpePage::showDownWidget);
  473. connect(widget,&firingWidget::updateProjectStatus,this,&BlastOpePage::updateProject);
  474. connect(widget,&firingWidget::closeFiring,this,&BlastOpePage::destroyFiringWidget);
  475. widget->show();
  476. widget->setAttribute(Qt::WA_DeleteOnClose);
  477. uuidWidgetMap.insert(uuid, widget);
  478. } else if (button->text() == "取消起爆流程") {
  479. firingWidget *widget = uuidWidgetMap.value(uuid);
  480. if (widget) {
  481. widget->cancelBlasting();
  482. }
  483. }
  484. }
  485. void BlastOpePage::changeButByMqtt(int status ,int row){
  486. qDebug() << "statusButton:"<<status;
  487. QModelIndex index = model->index(row, 8);
  488. if (index.isValid()) {
  489. QWidget *widget = ui->tableView->indexWidget(index);
  490. if (widget) {
  491. QPushButton *button = widget->findChild<QPushButton*>();
  492. if (button) {
  493. // 使用样式表设置图标居中
  494. button->setStyleSheet("QPushButton {"
  495. " padding: 0px;"
  496. " border: none;"
  497. " background-color: transparent;"
  498. "}"
  499. );
  500. // 添加图标,假设图标文件名为 blast.svg,并且该文件存在于项目资源中
  501. QIcon icon(":/icons/icons/svg/blast.svg");
  502. button->setText("");
  503. button->setIcon(icon);
  504. button->setIconSize(QSize(32, 32));
  505. }
  506. }
  507. }
  508. }
  509. void BlastOpePage::updateProject(QString uuid){
  510. dao.updateBlastStatusByUuid(uuid,"3");
  511. }
  512. void BlastOpePage::destroyFiringWidget(const QString& uuid)
  513. {
  514. firingWidget *widget = uuidWidgetMap.value(uuid);
  515. if (widget) {
  516. widget->close(); // 关闭窗口
  517. widget->deleteLater(); // 释放内存
  518. uuidWidgetMap.remove(uuid); // 从映射中移除
  519. }
  520. }
  521. // 槽函数,当 item 状态改变时触发
  522. void BlastOpePage::onItemChanged(QStandardItem *item) {
  523. if (item->column() == 0) { // 仅处理第一列的勾选状态改变
  524. if (item->checkState() == Qt::Checked) {
  525. QStandardItem *uuidItem = model->item(item->row(), 10);
  526. if (uuidItem) {
  527. QVariant uuidVariant = uuidItem->data(Qt::UserRole);
  528. if (uuidVariant.isValid()) {
  529. QString uuid = uuidVariant.toString();
  530. uuidMap[item->row()] = uuid;
  531. }
  532. }
  533. } else if (item->checkState() == Qt::Unchecked) {
  534. QStandardItem *uuidItem = model->item(item->row(), 10);
  535. if (uuidItem) {
  536. // 从 item 中获取 uuid 数据
  537. QVariant uuidVariant = uuidItem->data(Qt::UserRole);
  538. if (uuidVariant.isValid()) {
  539. QString uuid = uuidVariant.toString();
  540. // 从数组中移除该 uuid
  541. uuidMap.remove(item->row());
  542. }
  543. }
  544. }
  545. }
  546. }
  547. void BlastOpePage::on_btnSelect_clicked()
  548. {
  549. // 禁用表格第一列的选项
  550. for (int row = 0; row < model->rowCount(); ++row) {
  551. QStandardItem *item = model->item(row, 0);
  552. if (item) {
  553. Qt::ItemFlags flags = item->flags();
  554. flags &= ~Qt::ItemIsEnabled;
  555. item->setFlags(flags);
  556. }
  557. }
  558. for (auto it = uuidMap.begin(); it != uuidMap.end(); ++it) {
  559. int row = it.key();
  560. QString uuid = it.value();
  561. firingWidget *widgetSelect = new firingWidget(row,true,uuid);
  562. QModelIndex index = model->index(row, 9);
  563. if (index.isValid()) {
  564. QWidget *widgetButton = ui->tableView->indexWidget(index);
  565. if (widgetButton) {
  566. QPushButton *button = widgetButton->findChild<QPushButton*>();
  567. button->setText("取消起爆流程");
  568. }
  569. }
  570. // 信号连接
  571. connect(widgetSelect, &firingWidget::progressChanged, this, &BlastOpePage::updateProgressBar);
  572. connect(widgetSelect, &firingWidget::updateBlastStatus, this, &BlastOpePage::onUpdateBlastStatus);
  573. connect(widgetSelect, &firingWidget::selectSignal, this, &BlastOpePage::handleSelect);
  574. connect(widgetSelect, &firingWidget::updateButton, this, &BlastOpePage::changeButByMqtt);
  575. connect(widgetSelect, &firingWidget::updateProjectStatus, this, &BlastOpePage::updateProject);
  576. connect(widgetSelect, &firingWidget::closeFiring, this, &BlastOpePage::destroyFiringWidgetSelect);
  577. widgetSelect->show();
  578. widgetSelect->setAttribute(Qt::WA_DeleteOnClose);
  579. uuidWidgetSMap.insert(uuid, widgetSelect);
  580. }
  581. }
  582. //完成充电
  583. void BlastOpePage::handleSelect(QString uuid){
  584. selectedUuids.insert(uuid);
  585. bool isSame = checkUuidsSame();
  586. if (isSame) {
  587. bool successSelect;
  588. serialTool = SerialTool::getInstance(nullptr, &successSelect);
  589. connect(serialTool, &SerialTool::buttonPressedReceived,this,&BlastOpePage::showDownWidgetSelect, Qt::SingleShotConnection);
  590. if(serialTool){
  591. QByteArray data = "\r\nENABLE_BUTTON\r\n";
  592. bool success = serialTool->sendData(data);
  593. if (success) {
  594. qDebug() << "Data sent successfully";
  595. } else {
  596. qDebug() << "Failed to send data";
  597. }
  598. connect(serialTool, &SerialTool::enableButtonReceived,this, [this]() {
  599. for (const auto& row : uuidMap.keys()) {
  600. qDebug() << "Key:" << row;
  601. onUpdateBlastStatus(10,row);
  602. }
  603. }, Qt::SingleShotConnection);
  604. }else {
  605. qDebug() << "serialTool Not fond.";
  606. }
  607. } else {
  608. qDebug() << "The uuids in selectedUuids and uuidMap are different.";
  609. }
  610. }
  611. // 检查 selectedUuids 和 uuidMap 中的 uuid 是否相同
  612. bool BlastOpePage::checkUuidsSame() {
  613. QSet<QString> mapUuids;
  614. for (const auto& value : uuidMap) {
  615. qDebug()<<"value"<<value;
  616. mapUuids.insert(value);
  617. }
  618. return selectedUuids == mapUuids;
  619. }
  620. void BlastOpePage::showDownWidgetSelect()
  621. {
  622. QByteArray data = "\r\nDISABLE_BUTTON\r\n";
  623. bool success = serialTool->sendData(data);
  624. if (success) {
  625. qDebug() << "Data sent successfully";
  626. } else {
  627. qDebug() << "Failed to send data";
  628. }
  629. serialTool->releaseInstance();
  630. CountdownWidget *countdownWidgetSelect = new CountdownWidget(this);
  631. countdownWidgetSelect->resize(200, 200);
  632. int x = (this->width() - countdownWidgetSelect->width()) / 2;
  633. int y = (this->height() - countdownWidgetSelect->height()) / 2;
  634. countdownWidgetSelect->move(x, y);
  635. countdownWidgetSelect->show();
  636. connect(countdownWidgetSelect, &CountdownWidget::countdownFinished, this,&BlastOpePage::selectBlasting,Qt::SingleShotConnection);
  637. }
  638. void BlastOpePage::selectBlasting(){
  639. for (auto it = uuidWidgetSMap.begin(); it != uuidWidgetSMap.end(); ++it) {
  640. QString uuid = it.key();
  641. firingWidget* widget = it.value();
  642. QString topic = "hxgc/"+uuid+"/P";
  643. QString message = "起爆";
  644. widget->onCountdownFinished(topic,message);
  645. }
  646. }
  647. void BlastOpePage::destroyFiringWidgetSelect(const QString& uuid)
  648. {
  649. firingWidget *widget = uuidWidgetSMap.value(uuid);
  650. if (widget) {
  651. widget->close();
  652. widget->deleteLater();
  653. uuidWidgetSMap.remove(uuid);
  654. }
  655. for (int row = 0; row < model->rowCount(); ++row) {
  656. QStandardItem *item = model->item(row, 0);
  657. if (item) {
  658. Qt::ItemFlags flags = item->flags();
  659. flags &= ~Qt::ItemIsEnabled; // 去除 ItemIsEnabled 标志位
  660. item->setFlags(flags);
  661. }
  662. }
  663. }