Files
HIS-GUI/gui/pages/role_page.cpp
2026-04-07 21:30:39 +08:00

377 lines
14 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "mainwindow.h"
#include <QAction>
#include <QComboBox>
#include <QCoreApplication>
#include <QDialog>
#include <QDir>
#include <QFileDialog>
#include <QFormLayout>
#include <QHBoxLayout>
#include <QHeaderView>
#include <QInputDialog>
#include <QLabel>
#include <QLineEdit>
#include <QListWidget>
#include <QMenuBar>
#include <QMessageBox>
#include <QPushButton>
#include <QSpinBox>
#include <QStackedWidget>
#include <QTabWidget>
#include <QTableWidget>
#include <QTableWidgetItem>
#include <QTextEdit>
#include <QToolBar>
#include <QTreeWidget>
#include <QTreeWidgetItem>
#include <QVBoxLayout>
#include <QGroupBox>
#include <QTextCursor>
#include <QDebug>
#include <QAbstractItemView>
#include <QFile>
#include <QTextStream>
#include <QDateTime>
#include <QSettings>
#include <QTimer>
#include <QHeaderView>
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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<ViewRole>(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 + "]");
}