286 lines
11 KiB
C++
286 lines
11 KiB
C++
#include "mainwindow.h"
|
|
|
|
#include <QComboBox>
|
|
#include <QDialog>
|
|
#include <QDoubleSpinBox>
|
|
#include <QFormLayout>
|
|
#include <QHBoxLayout>
|
|
#include <QHeaderView>
|
|
#include <QLabel>
|
|
#include <QLineEdit>
|
|
#include <QMessageBox>
|
|
#include <QPushButton>
|
|
#include <QTableWidget>
|
|
#include <QTableWidgetItem>
|
|
#include <QVBoxLayout>
|
|
#include <QWidget>
|
|
|
|
void MainWindow::setupChecksTab() {
|
|
checksTab_ = new QWidget(this);
|
|
auto* layout = new QVBoxLayout(checksTab_);
|
|
|
|
auto* toolBar = new QHBoxLayout();
|
|
checkSearchBox_ = new QLineEdit(checksTab_);
|
|
checkSearchBox_->setPlaceholderText(tr("搜索检查..."));
|
|
connect(checkSearchBox_, &QLineEdit::textChanged, this, &MainWindow::onCheckSearch);
|
|
|
|
checkAddButton_ = new QPushButton(tr("添加检查"), checksTab_);
|
|
checkUpdateButton_ = new QPushButton(tr("更新检查"), checksTab_);
|
|
checkRemoveButton_ = new QPushButton(tr("删除检查"), checksTab_);
|
|
|
|
toolBar->addWidget(checkSearchBox_);
|
|
toolBar->addWidget(checkAddButton_);
|
|
toolBar->addWidget(checkUpdateButton_);
|
|
toolBar->addWidget(checkRemoveButton_);
|
|
toolBar->addStretch(1);
|
|
layout->addLayout(toolBar);
|
|
|
|
checkTable_ = new QTableWidget(0, 4, checksTab_);
|
|
checkTable_->setHorizontalHeaderLabels({tr("检查ID"), tr("名称"), tr("归属科室"), tr("价格")});
|
|
checkTable_->setSelectionBehavior(QAbstractItemView::SelectRows);
|
|
checkTable_->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed);
|
|
checkTable_->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
|
|
checkTable_->setSortingEnabled(true);
|
|
layout->addWidget(checkTable_);
|
|
|
|
connect(checkAddButton_, &QPushButton::clicked, this, &MainWindow::handleAddCheck);
|
|
connect(checkUpdateButton_, &QPushButton::clicked, this, &MainWindow::handleUpdateCheck);
|
|
connect(checkRemoveButton_, &QPushButton::clicked, this, &MainWindow::handleRemoveCheck);
|
|
}
|
|
|
|
void MainWindow::refreshCheckTable() {
|
|
checkTable_->blockSignals(true);
|
|
checkTable_->setSortingEnabled(false);
|
|
checkTable_->setRowCount(0);
|
|
|
|
int row = 0;
|
|
core_.checkService.for_eachCheck([this, &row](const std::string&, const Check& chk) {
|
|
checkTable_->insertRow(row);
|
|
checkTable_->setItem(row, 0, new QTableWidgetItem(QString::fromStdString(chk.CheckID)));
|
|
checkTable_->setItem(row, 1, new QTableWidgetItem(QString::fromStdString(chk.Name)));
|
|
|
|
QString deptName = QString::fromStdString(chk.DepartmentID);
|
|
auto* dept = core_.departmentService.findDepartment(chk.DepartmentID);
|
|
if (dept) {
|
|
deptName = QString::fromStdString(dept->Name);
|
|
}
|
|
checkTable_->setItem(row, 2, new QTableWidgetItem(deptName));
|
|
|
|
QTableWidgetItem* priceItem = new QTableWidgetItem();
|
|
priceItem->setData(Qt::DisplayRole, chk.Price);
|
|
checkTable_->setItem(row, 3, priceItem);
|
|
|
|
row++;
|
|
});
|
|
|
|
checkTable_->setSortingEnabled(true);
|
|
checkTable_->blockSignals(false);
|
|
}
|
|
|
|
void MainWindow::handleAddCheck() {
|
|
QDialog* dialog = new QDialog(this);
|
|
dialog->setWindowTitle(tr("添加检查"));
|
|
dialog->setModal(true);
|
|
dialog->resize(450, 300);
|
|
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
|
|
|
QFormLayout* form = new QFormLayout(dialog);
|
|
form->setSpacing(10);
|
|
form->setContentsMargins(20, 20, 20, 20);
|
|
|
|
QString newCheckId = QString::fromStdString(Check::generateUniqueId());
|
|
QLabel* checkIdDisplay = new QLabel(newCheckId, dialog);
|
|
checkIdDisplay->setEnabled(false);
|
|
|
|
QLineEdit* nameEdit = new QLineEdit(dialog);
|
|
QComboBox* deptCombo = new QComboBox(dialog);
|
|
deptCombo->addItem(tr("-- 请选择科室 --"));
|
|
core_.departmentService.for_eachDepartment([deptCombo](const std::string&, const Department& d) {
|
|
deptCombo->addItem(QString::fromStdString(d.Name), QString::fromStdString(d.DepartmentID));
|
|
});
|
|
QDoubleSpinBox* priceSpin = new QDoubleSpinBox(dialog);
|
|
priceSpin->setRange(0.0, 100000.0);
|
|
priceSpin->setDecimals(2);
|
|
|
|
QLabel* infoLabel = new QLabel(tr("检查ID将自动生成"), dialog);
|
|
infoLabel->setStyleSheet("color: gray; font-size: 11px;");
|
|
|
|
form->addRow(tr("检查ID (自动生成):"), checkIdDisplay);
|
|
form->addRow(tr("名称:"), nameEdit);
|
|
form->addRow(tr("选择科室:"), deptCombo);
|
|
form->addRow(tr("价格:"), priceSpin);
|
|
form->addRow(infoLabel);
|
|
|
|
auto* buttonLayout = new QHBoxLayout();
|
|
auto* okButton = new QPushButton(tr("添加"), dialog);
|
|
auto* cancelButton = new QPushButton(tr("取消"), dialog);
|
|
buttonLayout->addWidget(okButton);
|
|
buttonLayout->addWidget(cancelButton);
|
|
buttonLayout->addStretch();
|
|
form->addRow(buttonLayout);
|
|
|
|
connect(okButton, &QPushButton::clicked, [this, dialog, nameEdit, deptCombo, priceSpin, newCheckId]() {
|
|
if (nameEdit->text().isEmpty()) {
|
|
QMessageBox::warning(this, tr("错误"), tr("请填写检查名称"));
|
|
return;
|
|
}
|
|
if (deptCombo->currentIndex() == 0) {
|
|
QMessageBox::warning(this, tr("错误"), tr("请选择科室"));
|
|
return;
|
|
}
|
|
|
|
Check c(newCheckId.toStdString(), nameEdit->text().toStdString(),
|
|
deptCombo->currentData().toString().toStdString(), priceSpin->value());
|
|
if (!core_.checkService.addCheck(c)) {
|
|
QMessageBox::warning(this, tr("添加失败"), tr("检查 ID 已存在"));
|
|
return;
|
|
}
|
|
|
|
std::string checkDetails =
|
|
"检查ID: " + newCheckId.toStdString() +
|
|
" | 名称: " + nameEdit->text().toStdString() +
|
|
" | 科室: " + deptCombo->currentText().toStdString() +
|
|
" | 价格: " + std::to_string(priceSpin->value());
|
|
logOperation(LogEntryType::CHECK_OPERATION, "ADD_CHECK", checkDetails, newCheckId.toStdString());
|
|
|
|
QMessageBox::information(this, tr("成功"), tr("已添加检查: %1 (%2)").arg(newCheckId).arg(nameEdit->text()));
|
|
refreshCheckTable();
|
|
refreshDashboard();
|
|
dialog->accept();
|
|
});
|
|
|
|
connect(cancelButton, &QPushButton::clicked, dialog, &QDialog::reject);
|
|
dialog->exec();
|
|
}
|
|
|
|
void MainWindow::handleUpdateCheck() {
|
|
QString cid = safeCurrentTableId(checkTable_);
|
|
if (cid.isEmpty()) {
|
|
QMessageBox::warning(this, tr("更新检查"), tr("请先选择检查"));
|
|
return;
|
|
}
|
|
auto* c = core_.checkService.findCheck(cid.toStdString());
|
|
if (!c) return;
|
|
|
|
QDialog* dialog = new QDialog(this);
|
|
dialog->setWindowTitle(tr("更新检查 - %1").arg(cid));
|
|
dialog->setModal(true);
|
|
dialog->resize(450, 250);
|
|
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
|
|
|
QFormLayout* form = new QFormLayout(dialog);
|
|
|
|
QLabel* checkIdDisplay = new QLabel(cid, dialog);
|
|
checkIdDisplay->setEnabled(false);
|
|
|
|
QLineEdit* nameEdit = new QLineEdit(QString::fromStdString(c->Name), dialog);
|
|
QComboBox* deptCombo = new QComboBox(dialog);
|
|
deptCombo->addItem(tr("-- 请选择科室 --"));
|
|
core_.departmentService.for_eachDepartment([deptCombo](const std::string& id, const Department& d) {
|
|
deptCombo->addItem(QString::fromStdString(d.Name), QString::fromStdString(id));
|
|
});
|
|
// 设置当前选中的科室
|
|
for (int i = 1; i < deptCombo->count(); ++i) {
|
|
if (deptCombo->itemData(i).toString().toStdString() == c->DepartmentID) {
|
|
deptCombo->setCurrentIndex(i);
|
|
break;
|
|
}
|
|
}
|
|
QDoubleSpinBox* priceSpin = new QDoubleSpinBox(dialog);
|
|
priceSpin->setRange(0.0, 100000.0);
|
|
priceSpin->setDecimals(2);
|
|
priceSpin->setValue(c->Price);
|
|
|
|
form->addRow(tr("检查ID:"), checkIdDisplay);
|
|
form->addRow(tr("名称:"), nameEdit);
|
|
form->addRow(tr("选择科室:"), deptCombo);
|
|
form->addRow(tr("价格:"), priceSpin);
|
|
|
|
auto* buttonLayout = new QHBoxLayout();
|
|
auto* okButton = new QPushButton(tr("保存"), dialog);
|
|
auto* cancelButton = new QPushButton(tr("取消"), dialog);
|
|
buttonLayout->addWidget(okButton);
|
|
buttonLayout->addWidget(cancelButton);
|
|
buttonLayout->addStretch();
|
|
form->addRow(buttonLayout);
|
|
|
|
connect(okButton, &QPushButton::clicked, [this, cid, dialog, c, nameEdit, deptCombo, priceSpin]() {
|
|
if (deptCombo->currentIndex() == 0) {
|
|
QMessageBox::warning(this, tr("错误"), tr("请选择科室"));
|
|
return;
|
|
}
|
|
if (!core_.checkService.updateCheck(cid.toStdString(), nameEdit->text().toStdString(),
|
|
deptCombo->currentData().toString().toStdString(), priceSpin->value())) {
|
|
QMessageBox::warning(this, tr("更新失败"), tr("操作失败"));
|
|
return;
|
|
}
|
|
|
|
std::string checkDetails =
|
|
"检查ID: " + cid.toStdString() +
|
|
" | 修改后 - 名称: " + nameEdit->text().toStdString() +
|
|
" | 科室: " + deptCombo->currentText().toStdString() +
|
|
" | 价格: " + std::to_string(priceSpin->value());
|
|
logOperation(LogEntryType::CHECK_OPERATION, "MODIFY_CHECK", checkDetails, cid.toStdString());
|
|
|
|
QMessageBox::information(this, tr("成功"), tr("检查 %1 已更新").arg(cid));
|
|
refreshCheckTable();
|
|
dialog->accept();
|
|
});
|
|
|
|
connect(cancelButton, &QPushButton::clicked, dialog, &QDialog::reject);
|
|
dialog->exec();
|
|
}
|
|
|
|
void MainWindow::handleRemoveCheck() {
|
|
QString cid = safeCurrentTableId(checkTable_);
|
|
if (cid.isEmpty()) {
|
|
QMessageBox::warning(this, tr("删除检查"), tr("请先选择检查"));
|
|
return;
|
|
}
|
|
|
|
auto* check = core_.checkService.findCheck(cid.toStdString());
|
|
std::string checkDetails;
|
|
QString checkName = tr("未知");
|
|
if (check) {
|
|
checkName = QString::fromStdString(check->Name);
|
|
checkDetails =
|
|
"检查ID: " + check->CheckID +
|
|
" | 名称: " + check->Name +
|
|
" | 科室ID: " + check->DepartmentID +
|
|
" | 价格: " + std::to_string(check->Price);
|
|
}
|
|
|
|
QMessageBox::StandardButton reply = QMessageBox::question(
|
|
this, tr("确认删除"),
|
|
tr("确定要删除检查 \"%1\" (ID: %2) 吗?\n此操作无法撤销。").arg(checkName).arg(cid),
|
|
QMessageBox::Yes | QMessageBox::No);
|
|
if (reply != QMessageBox::Yes) return;
|
|
|
|
std::string err;
|
|
if (!core_.checkService.removeCheck(cid.toStdString(), err)) {
|
|
QMessageBox::warning(this, tr("删除失败"), tr("无法删除检查: ") + QString::fromStdString(err));
|
|
return;
|
|
}
|
|
|
|
if (!checkDetails.empty()) {
|
|
logOperation(LogEntryType::CHECK_OPERATION, "REMOVE_CHECK", checkDetails, cid.toStdString());
|
|
}
|
|
|
|
refreshCheckTable();
|
|
refreshDashboard();
|
|
}
|
|
|
|
void MainWindow::onCheckSearch(const QString& text) {
|
|
for (int i = 0; i < checkTable_->rowCount(); ++i) {
|
|
bool match = false;
|
|
for (int j = 0; j < checkTable_->columnCount(); ++j) {
|
|
QTableWidgetItem* item = checkTable_->item(i, j);
|
|
if (item && item->text().contains(text, Qt::CaseInsensitive)) {
|
|
match = true;
|
|
break;
|
|
}
|
|
}
|
|
checkTable_->setRowHidden(i, !match);
|
|
}
|
|
}
|