geopro/src/app/ProjectListDialog.cpp

182 lines
6.7 KiB
C++

#include "ProjectListDialog.hpp"
#include <QAbstractItemView>
#include <QColor>
#include <QComboBox>
#include <QFont>
#include <QHBoxLayout>
#include <QHeaderView>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QStringList>
#include <QTableWidget>
#include <QTableWidgetItem>
#include <QVBoxLayout>
#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);
}
}
// 状态语义色(寻路):未开始=弱化中性、进行中=信息蓝(活动中);未知状态用中性灰。
QColor statusColor(int s) {
switch (s) {
case 1: return tokenColor("text/tertiary"); // 未开始:弱化
case 2: return tokenColor("accent/primary"); // 进行中:活动中
default: return tokenColor("text/secondary"); // 未知:中性
}
}
} // 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); // Ela item 版表格(继承 QTableWidget),直替
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<int>(rows.size()));
for (int i = 0; i < static_cast<int>(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(tokenColor("accent/primary"));
table_->setItem(i, 1, nameItem);
set(2, QString::fromStdString(p.code));
// 状态列语义着色:颜色承载“未开始/进行中”分类,进行中加粗强调(不只靠颜色)。
auto* statusItem = new QTableWidgetItem(statusText(p.status));
statusItem->setForeground(statusColor(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