#include "ProjectListDialog.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "Theme.hpp" namespace geopro::app { namespace { QString statusText(int s) { switch (s) { case 1: return QStringLiteral("未开始"); case 2: return QStringLiteral("进行中"); default: return QString::number(s); } } // 状态语义色(寻路):未开始=弱化中性、进行中=信息蓝(活动中);未知状态用中性灰。 const char* statusColorHex(int s) { switch (s) { case 1: return "#8A93A3"; // 未开始:弱化 case 2: return semantic::kInfo; // 进行中:活动中 default: return "#5A6B85"; // 未知:中性 } } } // namespace ProjectListDialog::ProjectListDialog(data::IProjectRepository& repo, QWidget* parent) : QDialog(parent), repo_(repo) { setWindowTitle(QStringLiteral("全部项目")); resize(980, 560); auto* root = new QVBoxLayout(this); auto* filter = new QHBoxLayout(); filter->addWidget(new QLabel(QStringLiteral("项目名称"), this)); nameEdit_ = new QLineEdit(this); nameEdit_->setPlaceholderText(QStringLiteral("输入项目名称")); nameEdit_->setFixedWidth(200); filter->addWidget(nameEdit_); filter->addSpacing(8); filter->addWidget(new QLabel(QStringLiteral("项目类型"), this)); typeCombo_ = new QComboBox(this); typeCombo_->setFixedWidth(160); filter->addWidget(typeCombo_); filter->addSpacing(8); auto* searchBtn = new QPushButton(QStringLiteral("搜索"), this); auto* resetBtn = new QPushButton(QStringLiteral("重置"), this); filter->addWidget(searchBtn); filter->addWidget(resetBtn); filter->addStretch(); root->addLayout(filter); table_ = new QTableWidget(this); table_->setColumnCount(8); table_->setHorizontalHeaderLabels(QStringList{ QStringLiteral("序号"), QStringLiteral("项目名称"), QStringLiteral("项目编号"), QStringLiteral("项目状态"), QStringLiteral("项目类型"), QStringLiteral("业主单位"), QStringLiteral("负责人"), QStringLiteral("创建时间")}); table_->setEditTriggers(QAbstractItemView::NoEditTriggers); table_->setSelectionBehavior(QAbstractItemView::SelectRows); table_->setSelectionMode(QAbstractItemView::SingleSelection); table_->verticalHeader()->setVisible(false); table_->horizontalHeader()->setStretchLastSection(true); table_->setColumnWidth(0, 50); table_->setColumnWidth(1, 260); root->addWidget(table_, 1); auto* bottom = new QHBoxLayout(); pageLabel_ = new QLabel(this); bottom->addWidget(pageLabel_); bottom->addStretch(); prevBtn_ = new QPushButton(QStringLiteral("上一页"), this); nextBtn_ = new QPushButton(QStringLiteral("下一页"), this); bottom->addWidget(prevBtn_); bottom->addWidget(nextBtn_); root->addLayout(bottom); fillTypeFilter(); QObject::connect(searchBtn, &QPushButton::clicked, this, [this]() { pageNo_ = 1; query(); }); QObject::connect(resetBtn, &QPushButton::clicked, this, [this]() { nameEdit_->clear(); typeCombo_->setCurrentIndex(0); pageNo_ = 1; query(); }); QObject::connect(prevBtn_, &QPushButton::clicked, this, [this]() { if (pageNo_ > 1) { --pageNo_; query(); } }); QObject::connect(nextBtn_, &QPushButton::clicked, this, [this]() { if (pageNo_ * pageSize_ < total_) { ++pageNo_; query(); } }); QObject::connect(table_, &QTableWidget::cellClicked, this, [this](int row, int col) { if (col != 1) return; // 仅"项目名称"列触发切换 auto* item = table_->item(row, 1); if (!item) return; const QString id = item->data(Qt::UserRole).toString(); if (id.isEmpty()) return; emit projectChosen(id, item->text()); accept(); }); query(); } void ProjectListDialog::fillTypeFilter() { typeCombo_->addItem(QStringLiteral("全部类型"), QString()); const auto r = repo_.listProjectTypes(); if (!r.ok) return; for (const auto& t : r.value) typeCombo_->addItem(QString::fromStdString(t.name), QString::fromStdString(t.id)); } void ProjectListDialog::query() { const std::string name = nameEdit_->text().trimmed().toStdString(); const std::string typeId = typeCombo_->currentData().toString().toStdString(); const auto r = repo_.pageProjects(name, typeId, pageNo_, pageSize_); if (!r.ok) { table_->setRowCount(0); pageLabel_->setText(QStringLiteral("加载失败:%1").arg(QString::fromStdString(r.error))); prevBtn_->setEnabled(false); nextBtn_->setEnabled(false); return; } total_ = r.value.total; const auto& rows = r.value.rows; table_->setRowCount(static_cast(rows.size())); for (int i = 0; i < static_cast(rows.size()); ++i) { const auto& p = rows[i]; auto set = [&](int col, const QString& text) { table_->setItem(i, col, new QTableWidgetItem(text)); }; set(0, QString::number((pageNo_ - 1) * pageSize_ + i + 1)); auto* nameItem = new QTableWidgetItem(QString::fromStdString(p.name)); nameItem->setData(Qt::UserRole, QString::fromStdString(p.id)); nameItem->setForeground(QColor("#2D6CB5")); table_->setItem(i, 1, nameItem); set(2, QString::fromStdString(p.code)); // 状态列语义着色:颜色承载“未开始/进行中”分类,进行中加粗强调(不只靠颜色)。 auto* statusItem = new QTableWidgetItem(statusText(p.status)); statusItem->setForeground(QColor(statusColorHex(p.status))); if (p.status == 2) { QFont f = statusItem->font(); f.setBold(true); statusItem->setFont(f); } table_->setItem(i, 3, statusItem); set(4, QString::fromStdString(p.typeName)); set(5, QString::fromStdString(p.ownerCompany)); set(6, QString::fromStdString(p.responsiblePerson)); set(7, QString::fromStdString(p.createTime)); } const int pages = total_ > 0 ? (total_ + pageSize_ - 1) / pageSize_ : 1; pageLabel_->setText(QStringLiteral("共 %1 条 第 %2 / %3 页").arg(total_).arg(pageNo_).arg(pages)); prevBtn_->setEnabled(pageNo_ > 1); nextBtn_->setEnabled(pageNo_ < pages); } } // namespace geopro::app