#include "panels/chart/ExceptionDetailDialog.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "FormKit.hpp" #include "Theme.hpp" #include "repo/IDatasetCommandRepository.hpp" namespace geopro::app { ExceptionDetailDialog::ExceptionDetailDialog(geopro::data::IDatasetCommandRepository* repo, const geopro::core::Anomaly& anomaly, QWidget* parent) : QDialog(parent), repo_(repo), anomaly_(anomaly) { setWindowTitle(QStringLiteral("异常详情")); setModal(true); resize(420, 460); lineColor_ = QString::fromStdString(anomaly_.lineColor); if (lineColor_.isEmpty()) lineColor_ = QStringLiteral("#000000"); auto* root = formkit::dialogRoot(this); auto* card = formkit::formCard(this); auto* cardLay = formkit::cardBody(card); auto* form = formkit::makeEditForm(); nameEdit_ = new QLineEdit(QString::fromStdString(anomaly_.name), this); formkit::capField(nameEdit_); form->addRow(formkit::editLabel(QStringLiteral("名称")), nameEdit_); auto* typeLabel = new QLabel(QString::fromStdString(anomaly_.typeName), this); form->addRow(formkit::editLabel(QStringLiteral("异常类型")), typeLabel); // 图例:线色 / 线宽 / 线型(对照原版 legend.polyline*)。 colorBtn_ = new QPushButton(lineColor_, this); colorBtn_->setStyleSheet(QStringLiteral("background:%1;").arg(lineColor_)); connect(colorBtn_, &QPushButton::clicked, this, [this]() { const QColor c = QColorDialog::getColor(QColor(lineColor_), this, QStringLiteral("线色")); if (c.isValid()) { lineColor_ = c.name(); colorBtn_->setText(lineColor_); colorBtn_->setStyleSheet(QStringLiteral("background:%1;").arg(lineColor_)); } }); formkit::capField(colorBtn_); form->addRow(formkit::editLabel(QStringLiteral("线色")), colorBtn_); widthSpin_ = new QDoubleSpinBox(this); widthSpin_->setRange(0.1, 20.0); widthSpin_->setSingleStep(0.5); widthSpin_->setValue(anomaly_.lineWidth > 0 ? anomaly_.lineWidth : 1.0); formkit::capField(widthSpin_); form->addRow(formkit::editLabel(QStringLiteral("线宽")), widthSpin_); shapeCombo_ = new QComboBox(this); shapeCombo_->addItem(QStringLiteral("实线"), QStringLiteral("solid")); shapeCombo_->addItem(QStringLiteral("虚线"), QStringLiteral("dash")); shapeCombo_->setCurrentIndex(anomaly_.dashed ? 1 : 0); formkit::capField(shapeCombo_); form->addRow(formkit::editLabel(QStringLiteral("线型")), shapeCombo_); remarkEdit_ = new QPlainTextEdit(QString::fromStdString(anomaly_.remark), this); remarkEdit_->setFixedHeight(geopro::app::scaledPx(60)); formkit::capField(remarkEdit_); form->addRow(formkit::editLabel(QStringLiteral("备注")), remarkEdit_); cardLay->addLayout(form); root->addWidget(card); // 坐标(只读展示,对照原版坐标信息 tab)。 root->addWidget(new QLabel(QStringLiteral("坐标:"), this)); auto* coordTable = new QTableWidget(static_cast(anomaly_.localPts.size()), 2, this); coordTable->setHorizontalHeaderLabels({QStringLiteral("x"), QStringLiteral("y")}); coordTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); coordTable->setEditTriggers(QAbstractItemView::NoEditTriggers); for (int r = 0; r < static_cast(anomaly_.localPts.size()); ++r) { coordTable->setItem(r, 0, new QTableWidgetItem(QString::number(anomaly_.localPts[r].x, 'f', 7))); coordTable->setItem(r, 1, new QTableWidgetItem(QString::number(anomaly_.localPts[r].y, 'f', 7))); } root->addWidget(coordTable, 1); auto* btnLay = new QHBoxLayout(); btnLay->addStretch(); auto* cancelBtn = new QPushButton(QStringLiteral("取消"), this); okBtn_ = new QPushButton(QStringLiteral("确定"), this); okBtn_->setDefault(true); btnLay->addWidget(cancelBtn); btnLay->addWidget(okBtn_); root->addLayout(btnLay); connect(cancelBtn, &QPushButton::clicked, this, &QDialog::reject); connect(okBtn_, &QPushButton::clicked, this, &ExceptionDetailDialog::onConfirm); } void ExceptionDetailDialog::onConfirm() { if (!repo_ || anomaly_.id.empty()) { reject(); return; } const QString name = nameEdit_->text().trimmed(); if (name.isEmpty()) { QMessageBox::warning(this, windowTitle(), QStringLiteral("请输入名称")); return; } // 原版详情抽屉「改名称/备注」走 PUT /business/exception 的局部更新, // 仅发 {id, exceptionName, remark}(线样式是另一条独立 PUT,且抽屉里样式控件 disabled)。 // 对齐原版 contourPage.vue onOk:不合并/不重发 legend。 QJsonObject body{ {QStringLiteral("id"), QString::fromStdString(anomaly_.id)}, {QStringLiteral("exceptionName"), name}, {QStringLiteral("remark"), remarkEdit_->toPlainText()}, }; okBtn_->setEnabled(false); QPointer self(this); repo_->updateException(body, [self](bool ok, QString msg) { if (!self) return; self->okBtn_->setEnabled(true); if (ok) { self->accept(); } else { QMessageBox::warning(self, self->windowTitle(), msg.isEmpty() ? QStringLiteral("更新失败") : msg); } }); } } // namespace geopro::app