#include "mainwindow.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include bool MainWindow::loadDataFromFiles() { QStringList possiblePaths = { QDir(QCoreApplication::applicationDirPath()).absoluteFilePath("../data"), "/home/e2hang/code/HIS-GUI/data", QDir::currentPath() + "/../data", QDir::currentPath() + "/data" }; QString dataPath; for (const QString& path : possiblePaths) { if (QDir(path).exists() && QFile::exists(path + "/patients.txt")) { dataPath = path; break; } } if (dataPath.isEmpty()) { QMessageBox::warning(this, tr("数据文件夹未找到"), tr("无法找到数据文件夹。")); return false; } dataFolder_ = dataPath; qDebug() << "Using data folder:" << dataFolder_; std::vector wardKeys; core_.ctx_.wards.for_each([&wardKeys](const std::string& k, const Ward&) { wardKeys.push_back(k); }); for (const auto& k : wardKeys) core_.ctx_.wards.remove(k); std::vector patientKeys; core_.ctx_.patients.for_each([&patientKeys](const std::string& k, const Patient&) { patientKeys.push_back(k); }); for (const auto& k : patientKeys) core_.ctx_.patients.remove(k); std::vector doctorKeys; core_.ctx_.doctors.for_each([&doctorKeys](const std::string& k, const Doctor&) { doctorKeys.push_back(k); }); for (const auto& k : doctorKeys) core_.ctx_.doctors.remove(k); std::vector medicineKeys; core_.ctx_.medicines.for_each([&medicineKeys](const std::string& k, const Medicine&) { medicineKeys.push_back(k); }); for (const auto& k : medicineKeys) core_.ctx_.medicines.remove(k); std::vector caseKeys; core_.ctx_.patientCases.for_each([&caseKeys](const std::string& k, const PatientCase&) { caseKeys.push_back(k); }); for (const auto& k : caseKeys) core_.ctx_.patientCases.remove(k); std::vector departmentKeys; core_.ctx_.departments.for_each([&departmentKeys](const std::string& k, const Department&) { departmentKeys.push_back(k); }); for (const auto& k : departmentKeys) core_.ctx_.departments.remove(k); std::vector checkKeys; core_.ctx_.checks.for_each([&checkKeys](const std::string& k, const Check&) { checkKeys.push_back(k); }); for (const auto& k : checkKeys) core_.ctx_.checks.remove(k); std::vector paymentKeys; core_.ctx_.payments.for_each([&paymentKeys](const std::string& k, const Payment&) { paymentKeys.push_back(k); }); for (const auto& k : paymentKeys) core_.ctx_.payments.remove(k); std::vector settlementKeys; core_.ctx_.settlements.for_each([&settlementKeys](const std::string& k, const Settlement&) { settlementKeys.push_back(k); }); for (const auto& k : settlementKeys) core_.ctx_.settlements.remove(k); std::string err; if (!core_.loadDataFromFolder(dataFolder_.toStdString(), err)) { qWarning("Failed to load data from folder: %s", err.c_str()); QMessageBox::warning(this, tr("数据加载失败"), tr("无法加载数据: ") + QString::fromStdString(err)); return false; } return true; } void MainWindow::handleReloadAction() { wardTreeView_->clear(); patientTable_->setRowCount(0); doctorTable_->setRowCount(0); medicineTable_->setRowCount(0); checkTable_->setRowCount(0); departmentTable_->setRowCount(0); patientCaseDetail_->setText(tr("正在重新加载数据...")); summaryLabel_->setText(tr("正在重新加载数据...")); logDisplay_->clear(); if (!loadDataFromFiles()) { QMessageBox::warning(this, tr("重载失败"), tr("数据重新加载失败")); return; } refreshDashboard(); refreshWardTable(); refreshPatientTable(); refreshDoctorTable(); refreshMedicineTable(); refreshCheckTable(); refreshDepartmentTable(); QMessageBox::information(this, tr("重载成功"), tr("数据已重新加载")); } void MainWindow::handleSaveData() { if (dataFolder_.isEmpty()) { QMessageBox::warning(this, tr("保存失败"), tr("数据文件夹路径未设置。请先重新加载数据。")); return; } std::string err; if (!core_.wardService.saveToFile((dataFolder_ + "/wards.txt").toStdString(), err)) { QMessageBox::warning(this, tr("保存失败"), tr("病房保存失败: ") + QString::fromStdString(err)); return; } err.clear(); if (!FileManager::savePatientListToFile( (dataFolder_ + "/patients.txt").toStdString(), core_.ctx_.patients, err)) { QMessageBox::warning(this, tr("保存失败"), tr("患者保存失败: ") + QString::fromStdString(err)); return; } err.clear(); if (!FileManager::saveDoctorListToFile( (dataFolder_ + "/doctors.txt").toStdString(), core_.ctx_.doctors, err)) { QMessageBox::warning(this, tr("保存失败"), tr("医生保存失败: ") + QString::fromStdString(err)); return; } err.clear(); if (!FileManager::saveMedicineListToFile( (dataFolder_ + "/medicines.txt").toStdString(), core_.ctx_.medicines, err, 2)) { QMessageBox::warning(this, tr("保存失败"), tr("药品保存失败: ") + QString::fromStdString(err)); return; } err.clear(); if (!FileManager::savePatientCaseListToFile( (dataFolder_ + "/patient_cases.txt").toStdString(), core_.ctx_.patientCases, err, 2)) { QMessageBox::warning(this, tr("保存失败"), tr("病例保存失败: ") + QString::fromStdString(err)); return; } // 保存支付记录 err.clear(); if (!FileManager::savePaymentListToFile( (dataFolder_ + "/payments.txt").toStdString(), core_.ctx_.payments, err)) { QMessageBox::warning(this, tr("保存失败"), tr("支付记录保存失败: ") + QString::fromStdString(err)); return; } // 保存结算单 err.clear(); if (!FileManager::saveSettlementListToFile( (dataFolder_ + "/settlements.txt").toStdString(), core_.ctx_.settlements, err)) { QMessageBox::warning(this, tr("保存失败"), tr("结算单保存失败: ") + QString::fromStdString(err)); return; } // 保存科室 err.clear(); if (!FileManager::saveDepartmentListToFile( (dataFolder_ + "/departments.txt").toStdString(), core_.ctx_.departments, err)) { QMessageBox::warning(this, tr("保存失败"), tr("科室保存失败: ") + QString::fromStdString(err)); return; } // 保存检查项目 err.clear(); if (!FileManager::saveCheckListToFile( (dataFolder_ + "/checks.txt").toStdString(), core_.ctx_.checks, err)) { QMessageBox::warning(this, tr("保存失败"), tr("检查项目保存失败: ") + QString::fromStdString(err)); return; } QMessageBox::information(this, tr("保存成功"), tr("所有数据已保存到文件: ") + dataFolder_); } void MainWindow::onRoleChanged(int index) { currentRole_ = static_cast(roleComboBox_->currentData().toInt()); updateUIForRole(); } void MainWindow::updateUIForRole() { bool isAdmin = (currentRole_ == ViewRole::Admin); bool isPatient = (currentRole_ == ViewRole::Patient); bool isMedical = (currentRole_ == ViewRole::Medical); // 根据视角显示/隐藏不同的标签页 // Dashboard - 所有视角都可以看到 int dashboardIndex = navList_->row(navList_->item(0)); // Wards - 管理视角和医护视角可以看到 int wardsIndex = navList_->row(navList_->item(1)); navList_->item(1)->setHidden(!isAdmin && !isMedical); // Patients - 管理视角和医护视角可以看到 int patientsIndex = navList_->row(navList_->item(2)); navList_->item(2)->setHidden(!isAdmin && !isMedical); // Doctors - 所有视角都可以看到 int doctorsIndex = navList_->row(navList_->item(3)); // Medicines - 只有管理视角可以看到 int medicinesIndex = navList_->row(navList_->item(4)); navList_->item(4)->setHidden(!isAdmin); // Departments - 所有视角都可以看到(新增:病人可以查看科室) int departmentsIndex = navList_->row(navList_->item(5)); navList_->item(5)->setHidden(false); // 如果当前选中的标签页被隐藏,切换到第一个可见的标签页 bool switched = false; for (int i = 0; i < navList_->count(); ++i) { if (!navList_->item(i)->isHidden()) { if (navList_->item(i)->isSelected() || !switched) { navList_->setCurrentRow(i); switched = true; } } } // 根据视角设置按钮可见性 // 病房相关按钮 - 管理视角和医护视角 wardAddButton_->setEnabled(isAdmin || isMedical); wardEditButton_->setEnabled(isAdmin || isMedical); wardDeleteButton_->setEnabled(isAdmin || isMedical); wardAddBedButton_->setEnabled(isAdmin || isMedical); wardDeleteBedButton_->setEnabled(isAdmin || isMedical); wardOccupancyButton_->setEnabled(isAdmin || isMedical); // 患者相关按钮 - 管理视角和医护视角 patientAddButton_->setEnabled(isAdmin || isMedical); patientEditButton_->setEnabled(isAdmin || isMedical); patientRemoveButton_->setEnabled(isAdmin); patientViewCaseButton_->setEnabled(isAdmin || isMedical); patientAdmitButton_->setEnabled(isAdmin || isMedical); patientDischargeButton_->setEnabled(isAdmin || isMedical); patientAddDiagnosisButton_->setEnabled(isAdmin || isMedical); patientAddMedicineRecordButton_->setEnabled(isAdmin || isMedical); // ============ 问题3 权限控制 ============ // 设置患者表格编辑权限 if (isPatient) { // 病人视角:完全不可编辑 patientTable_->setEditTriggers(QAbstractItemView::NoEditTriggers); doctorTable_->setEditTriggers(QAbstractItemView::NoEditTriggers); wardTreeView_->setEditTriggers(QAbstractItemView::NoEditTriggers); medicineTable_->setEditTriggers(QAbstractItemView::NoEditTriggers); departmentTable_->setEditTriggers(QAbstractItemView::NoEditTriggers); // 病人视角:禁用所有修改按钮 wardAddButton_->setEnabled(false); wardEditButton_->setEnabled(false); wardDeleteButton_->setEnabled(false); wardAddBedButton_->setEnabled(false); wardDeleteBedButton_->setEnabled(false); wardOccupancyButton_->setEnabled(false); // 医生编辑按钮禁用 doctorEditButton_->setEnabled(false); patientAddButton_->setEnabled(false); patientEditButton_->setEnabled(false); patientRemoveButton_->setEnabled(false); patientAdmitButton_->setEnabled(false); patientDischargeButton_->setEnabled(false); patientAddDiagnosisButton_->setEnabled(false); patientAddMedicineRecordButton_->setEnabled(false); // 病人视角:科室修改按钮禁用,但查看详情按钮可用 departmentAddButton_->setEnabled(false); departmentEditButton_->setEnabled(false); departmentRemoveButton_->setEnabled(false); } else if (isMedical) { // 医护视角:患者ID列不可编辑,其他列可编辑 patientTable_->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed); // 第0列是患者ID,设置为不可编辑 for (int i = 0; i < patientTable_->rowCount(); ++i) { QTableWidgetItem* item = patientTable_->item(i, 0); if (item) { item->setFlags(item->flags() & ~Qt::ItemIsEditable); } } doctorTable_->setEditTriggers(QAbstractItemView::NoEditTriggers); medicineTable_->setEditTriggers(QAbstractItemView::NoEditTriggers); } else { // 管理视角:全部可编辑 patientTable_->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed); doctorTable_->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed); medicineTable_->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed); } // 医生相关按钮 - 只有管理视角可以添加/编辑/删除 doctorAddButton_->setEnabled(isAdmin); doctorEditButton_->setEnabled(isAdmin); doctorRemoveButton_->setEnabled(isAdmin); // 药品相关按钮 - 只有管理视角 medicineAddButton_->setEnabled(isAdmin); medicineUpdateButton_->setEnabled(isAdmin); medicineRemoveButton_->setEnabled(isAdmin); medicineIncreaseStockButton_->setEnabled(isAdmin); medicineDecreaseStockButton_->setEnabled(isAdmin); // 科室相关按钮 - 管理视角可以添加/编辑/删除 departmentAddButton_->setEnabled(isAdmin); departmentEditButton_->setEnabled(isAdmin); departmentRemoveButton_->setEnabled(isAdmin); // 更新窗口标题以显示当前视角 QString roleText; switch (currentRole_) { case ViewRole::Admin: roleText = tr("管理视角"); break; case ViewRole::Patient: roleText = tr("病人视角"); break; case ViewRole::Medical: roleText = tr("医护视角"); break; } setWindowTitle(tr("HIS GUI") + " - " + tr("医院信息系统") + " [" + roleText + "]"); }