#include "mainwindow.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "core/his_core.h" #include "dialogs/department_detail_dialog.h" void MainWindow::setupDepartmentsTab() { departmentsTab_ = new QWidget(this); auto* layout = new QVBoxLayout(departmentsTab_); auto* toolBar = new QHBoxLayout(); departmentSearchBox_ = new QLineEdit(departmentsTab_); departmentSearchBox_->setPlaceholderText(tr("搜索科室...")); connect(departmentSearchBox_, &QLineEdit::textChanged, this, &MainWindow::onDepartmentSearch); departmentAddButton_ = new QPushButton(tr("添加科室"), departmentsTab_); departmentEditButton_ = new QPushButton(tr("编辑科室"), departmentsTab_); departmentRemoveButton_ = new QPushButton(tr("删除科室"), departmentsTab_); QPushButton* viewDetailButton = new QPushButton(tr("查看详情"), departmentsTab_); toolBar->addWidget(departmentSearchBox_); toolBar->addWidget(departmentAddButton_); toolBar->addWidget(departmentEditButton_); toolBar->addWidget(departmentRemoveButton_); toolBar->addWidget(viewDetailButton); toolBar->addStretch(1); layout->addLayout(toolBar); departmentTable_ = new QTableWidget(0, 3, departmentsTab_); departmentTable_->setHorizontalHeaderLabels({tr("科室ID"), tr("科室名称"), tr("描述")}); departmentTable_->setSelectionBehavior(QAbstractItemView::SelectRows); departmentTable_->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed); departmentTable_->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); departmentTable_->setSortingEnabled(true); layout->addWidget(departmentTable_); connect(departmentAddButton_, &QPushButton::clicked, this, &MainWindow::handleAddDepartment); connect(departmentEditButton_, &QPushButton::clicked, this, &MainWindow::handleEditDepartment); connect(departmentRemoveButton_, &QPushButton::clicked, this, &MainWindow::handleRemoveDepartment); connect(viewDetailButton, &QPushButton::clicked, this, &MainWindow::handleViewDepartmentDetail); connect(departmentTable_, &QTableWidget::cellDoubleClicked, this, &MainWindow::onDepartmentItemDoubleClicked); } void MainWindow::refreshDepartmentTable() { departmentTable_->blockSignals(true); departmentTable_->setSortingEnabled(false); // 【关键修复】 departmentTable_->setRowCount(0); int row = 0; core_.departmentService.for_eachDepartment([this, &row](const std::string&, const Department& dept) { departmentTable_->insertRow(row); departmentTable_->setItem(row, 0, new QTableWidgetItem(QString::fromStdString(dept.DepartmentID))); departmentTable_->setItem(row, 1, new QTableWidgetItem(QString::fromStdString(dept.Name))); departmentTable_->setItem(row, 2, new QTableWidgetItem(QString::fromStdString(dept.Description))); row++; }); departmentTable_->setSortingEnabled(true); // 【关键修复】 departmentTable_->blockSignals(false); } void MainWindow::onDepartmentSearch(const QString& text) { for (int i = 0; i < departmentTable_->rowCount(); ++i) { bool match = false; for (int j = 0; j < departmentTable_->columnCount(); ++j) { QTableWidgetItem* item = departmentTable_->item(i, j); if (item && item->text().contains(text, Qt::CaseInsensitive)) { match = true; break; } } departmentTable_->setRowHidden(i, !match); } } void MainWindow::handleAddDepartment() { QDialog* dialog = new QDialog(this); dialog->setWindowTitle(tr("添加科室")); dialog->setModal(true); dialog->resize(400, 250); //dialog->setAttribute(Qt::WA_DeleteOnClose); QFormLayout* form = new QFormLayout(dialog); form->setSpacing(10); form->setContentsMargins(20, 20, 20, 20); std::vector existingIds; core_.departmentService.for_eachDepartment([&existingIds](const std::string& id, const Department&) { existingIds.push_back(id); }); QString newDeptId = QString::fromStdString(Department::generateUniqueId()); QLabel* deptIdDisplay = new QLabel(newDeptId, dialog); deptIdDisplay->setEnabled(false); QLineEdit* nameEdit = new QLineEdit(dialog); nameEdit->setPlaceholderText(tr("请输入科室名称")); QTextEdit* descEdit = new QTextEdit(dialog); descEdit->setMaximumHeight(80); descEdit->setPlaceholderText(tr("请输入科室描述(可选)")); QLabel* infoLabel = new QLabel(tr("科室ID将自动生成"), dialog); infoLabel->setStyleSheet("color: gray; font-size: 11px;"); form->addRow(tr("科室ID (自动生成):"), deptIdDisplay); form->addRow(tr("科室名称:"), nameEdit); form->addRow(tr("描述:"), descEdit); 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, descEdit, newDeptId]() { if (nameEdit->text().isEmpty()) { QMessageBox::warning(this, tr("错误"), tr("请填写科室名称")); return; } Department dept(newDeptId.toStdString(), nameEdit->text().toStdString(), descEdit->toPlainText().toStdString()); if (!core_.departmentService.addDepartment(dept)) { QMessageBox::warning(this, tr("添加失败"), tr("科室 ID 已存在")); return; } // 记录详细日志 - 科室的完整信息 std::string deptDetails = "科室ID: " + newDeptId.toStdString() + " | 科室名: " + nameEdit->text().toStdString() + " | 描述: " + descEdit->toPlainText().toStdString(); logOperation(LogEntryType::SYSTEM_EVENT, "ADD_DEPARTMENT", deptDetails, newDeptId.toStdString()); QMessageBox::information(this, tr("成功"), tr("已添加科室: %1 (%2)").arg(newDeptId).arg(nameEdit->text())); refreshDepartmentTable(); refreshDashboard(); dialog->accept(); }); connect(cancelButton, &QPushButton::clicked, dialog, &QDialog::reject); dialog->exec(); } void MainWindow::handleEditDepartment() { QString deptId = safeCurrentTableId(departmentTable_); if (deptId.isEmpty()) { QMessageBox::warning(this, tr("编辑科室"), tr("请先选择科室")); return; } auto* d = core_.departmentService.findDepartment(deptId.toStdString()); if (!d) return; QDialog* dialog = new QDialog(this); dialog->setWindowTitle(tr("编辑科室 - %1").arg(deptId)); dialog->setModal(true); dialog->resize(400, 250); dialog->setAttribute(Qt::WA_DeleteOnClose); QFormLayout* form = new QFormLayout(dialog); QLabel* deptIdLabel = new QLabel(deptId, dialog); deptIdLabel->setEnabled(false); QLineEdit* nameEdit = new QLineEdit(QString::fromStdString(d->Name), dialog); QTextEdit* descEdit = new QTextEdit(QString::fromStdString(d->Description), dialog); descEdit->setMaximumHeight(80); form->addRow(tr("科室ID:"), deptIdLabel); form->addRow(tr("科室名称:"), nameEdit); form->addRow(tr("描述:"), descEdit); 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, deptId, dialog, d, nameEdit, descEdit]() { // 记录修改前的信息 std::string oldDetails = "修改前 - 科室名: " + d->Name + " | 描述: " + d->Description; if (nameEdit->text().isEmpty()) { QMessageBox::warning(this, tr("错误"), tr("请填写科室名称")); return; } Department dept(deptId.toStdString(), nameEdit->text().toStdString(), descEdit->toPlainText().toStdString()); if (!core_.departmentService.updateDepartment(deptId.toStdString(), dept)) { QMessageBox::warning(this, tr("编辑失败"), tr("更新失败")); return; } // 记录详细日志 - 修改后的信息 std::string newDetails = "修改后 - 科室名: " + nameEdit->text().toStdString() + " | 描述: " + descEdit->toPlainText().toStdString(); std::string fullDetails = "科室ID: " + deptId.toStdString() + " | " + oldDetails + "\n" + newDetails; logOperation(LogEntryType::SYSTEM_EVENT, "MODIFY_DEPARTMENT", fullDetails, deptId.toStdString()); QMessageBox::information(this, tr("成功"), tr("已成功更新科室 %1").arg(deptId)); refreshDepartmentTable(); dialog->accept(); }); connect(cancelButton, &QPushButton::clicked, dialog, &QDialog::reject); dialog->exec(); } void MainWindow::handleRemoveDepartment() { QString deptId = safeCurrentTableId(departmentTable_); if (deptId.isEmpty()) { QMessageBox::warning(this, tr("删除科室"), tr("请先选择科室")); return; } // 检查是否可以删除科室 if (!core_.departmentService.canDeleteDepartment(deptId.toStdString())) { size_t doctorCount = core_.departmentService.getDoctorCountInDepartment(deptId.toStdString()); size_t medicineCount = core_.departmentService.getMedicineCountInDepartment(deptId.toStdString()); size_t checkCount = core_.departmentService.getCheckCountInDepartment(deptId.toStdString()); QString message = tr("无法删除该科室,因为该科室下仍有:\n"); if (doctorCount > 0) { message += tr("• %1 名医生\n").arg(static_cast(doctorCount)); } if (medicineCount > 0) { message += tr("• %1 种药品\n").arg(static_cast(medicineCount)); } if (checkCount > 0) { message += tr("• %1 个检查项目\n").arg(static_cast(checkCount)); } message += tr("\n请先将医生和药品移出该科室后再尝试删除。"); QMessageBox::warning(this, tr("删除失败"), message); return; } // 获取科室完整信息用于日志记录和确认弹窗 auto* department = core_.departmentService.findDepartment(deptId.toStdString()); std::string deptDetails; QString deptName = tr("未知"); if (department) { deptName = QString::fromStdString(department->Name); deptDetails = "科室ID: " + department->DepartmentID + " | 科室名: " + department->Name + " | 描述: " + department->Description; } // 确认删除弹窗 QMessageBox::StandardButton reply = QMessageBox::question( this, tr("确认删除"), tr("确定要删除科室 \"%1\" (ID: %2) 吗?\n此操作无法撤销。").arg(deptName).arg(deptId), QMessageBox::Yes | QMessageBox::No); if (reply != QMessageBox::Yes) return; if (!core_.departmentService.removeDepartment(deptId.toStdString())) { QMessageBox::warning(this, tr("删除失败"), tr("无法删除科室")); return; } // 记录详细日志 - 包含被删除科室的完整信息 if (!deptDetails.empty()) { logOperation(LogEntryType::SYSTEM_EVENT, "REMOVE_DEPARTMENT", deptDetails, deptId.toStdString()); } refreshDepartmentTable(); refreshDashboard(); } void MainWindow::handleViewDepartmentDetail() { QString deptId = safeCurrentTableId(departmentTable_); if (deptId.isEmpty()) { QMessageBox::warning(this, tr("查看科室详情"), tr("请先选择一个科室")); return; } auto* dialog = new DepartmentDetailDialog(core_, deptId, this); dialog->exec(); delete dialog; } void MainWindow::onDepartmentItemDoubleClicked(int row, int column) { QTableWidgetItem* item = departmentTable_->item(row, 0); if (!item) return; QString deptId = item->text(); if (deptId.isEmpty()) return; auto* dialog = new DepartmentDetailDialog(core_, deptId, this); dialog->exec(); delete dialog; }