Files
HIS-GUI/README.md
2026-04-01 11:02:24 +08:00

11 KiB
Raw Permalink Blame History

HIS (Hospital Information System)

一个完整的医院信息管理系统使用C++20开发支持病患管理、医生管理、药品管理、病房管理、患者病例管理和操作日志记录。

系统概述

HIS系统采用模块化设计包含以下核心组件

  • 数据模型层: 定义所有业务实体和数据结构
  • 服务层: 提供业务逻辑和数据操作接口
  • 工具层: 提供日志记录、JSON序列化等通用功能
  • 用户界面层: 命令行shell界面支持交互式操作

系统架构

graph TB
    A[ReplShell] --> B[HisCore]
    B --> C[PatientCaseService]
    B --> D[HisContext]
    D --> E[LinkedList<Patient>]
    D --> F[LinkedList<Doctor>]
    D --> G[LinkedList<Medicine>]
    D --> H[LinkedList<Ward>]
    D --> I[LinkedList<PatientCase>]
    C --> I
    A --> J[Logger]

    style A fill:#e1f5fe
    style B fill:#f3e5f5
    style C fill:#e8f5e8
    style J fill:#fff3e0

数据结构分析

核心数据结构

LinkedList<T>

自定义链表实现,支持泛型存储和管理数据。

主要特性:

  • 泛型支持,支持任意数据类型
  • 键值对存储 (key-value pairs)
  • 高效的查找、插入、删除操作
  • 内存安全,无需手动管理内存

使用示例:

LinkedList<std::string, Patient> patients;
patients.insert("P001", patient);
Patient* p = patients.find("P001")->value;

E2hangJson

自定义JSON库用于数据序列化和反序列化。

主要特性:

  • 支持JSON对象、数组、字符串、数字、布尔值
  • 提供toJson()fromJson()方法
  • 支持嵌套结构
  • 用于数据持久化到文件

使用示例:

JsonValue json = patient.toJson();
std::string jsonStr = json.toString();
Patient p = Patient::fromJson(json);

模型类

基础模型

Patient (患者)
class Patient {
    std::string id;
    std::string name;
    int age;
    std::string gender;
    std::string contact;
    std::string medicalHistory;
};
Doctor (医生)
class Doctor {
    std::string id;
    std::string name;
    std::string specialty;
    std::string contact;
    std::vector<std::string> patients;
};
Medicine (药品)
class Medicine {
    std::string id;
    std::string name;
    std::string description;
    double price;
    int stock;
};
Ward (病房)
class Ward {
    std::string id;
    std::string name;
    int capacity;
    int occupied;
    std::vector<std::string> patients;
};

患者病例管理模型

DiagnosisRecord (诊断记录)
class DiagnosisRecord {
    std::string diagnosisId;
    time_t diagnosisTime;
    std::string doctorId;
    std::string diagnosis;
    std::string notes;
};
MedicineRecord (用药记录)
class MedicineRecord {
    std::string recordId;
    time_t prescriptionTime;
    std::string medicineId;
    int quantity;
    double unitPrice;
    std::string doctorId;
    std::string notes;
};
AdmissionRecord (入院记录)
class AdmissionRecord {
    std::string admissionId;
    time_t admissionTime;
    time_t dischargeTime;
    std::string wardId;
    std::string reason;
    std::string status; // "admitted", "discharged"
};
PatientCase (患者病例)
class PatientCase {
    std::string patientId;
    std::vector<DiagnosisRecord> diagnoses;
    std::vector<MedicineRecord> medicines;
    std::vector<AdmissionRecord> admissions;
};

服务层

PatientCaseService

患者病例管理服务类,提供病例的增删改查操作。

主要方法:

  • PatientCase* getOrCreateCase(const std::string& patientId): 获取或创建患者病例
  • bool addDiagnosisRecord(const std::string& patientId, const DiagnosisRecord& record): 添加诊断记录
  • bool addMedicineRecord(const std::string& patientId, const MedicineRecord& record): 添加用药记录
  • bool admitPatient(const std::string& patientId, const std::string& wardId, const std::string& reason): 入院患者
  • bool dischargePatient(const std::string& patientId): 出院患者
  • double getTotalMedicineCost(const std::string& patientId): 计算总用药费用

工具类

Logger

操作日志记录器,支持多种日志类型和格式化输出。

日志类型:

enum class LogEntryType {
    SHELL_COMMAND,      // Shell命令
    PATIENT_OPERATION,  // 患者操作
    DOCTOR_OPERATION,   // 医生操作
    MEDICINE_OPERATION, // 药品操作
    WARD_OPERATION,     // 病房操作
    CASE_OPERATION,     // 病例操作
    SYSTEM_INFO,        // 系统信息
    ERROR,              // 错误
    DEBUG               // 调试
};

主要方法:

  • void log(LogEntryType type, const std::string& command, const std::string& details): 记录日志
  • void logShellCommand(const std::string& command): 记录shell命令
  • bool exportToFile(const std::string& filename): 导出日志到文件
  • void setFormat(const std::string& fmt): 设置日志格式

上下文和核心类

HisContext

全局上下文类,持有所有系统数据。

主要成员:

class HisContext {
    LinkedList<std::string, Patient> patients;
    LinkedList<std::string, Doctor> doctors;
    LinkedList<std::string, Medicine> medicines;
    LinkedList<std::string, Ward> wards;
    LinkedList<std::string, PatientCase> patientCases;
};

HisCore

组合根类,组装所有服务和上下文。

主要成员:

class HisCore {
    HisContext ctx_;
    PatientCaseService patientCaseService;
    // 其他服务...
};

ReplShell

命令行交互shell处理用户输入和命令执行。

支持的命令:

  • 患者管理: add_patient, list_patients, find_patient, update_patient, delete_patient
  • 医生管理: add_doctor, list_doctors, find_doctor, update_doctor, delete_doctor
  • 药品管理: add_medicine, list_medicines, find_medicine, update_medicine, delete_medicine
  • 病房管理: add_ward, list_wards, find_ward, update_ward, delete_ward
  • 病例管理: add_diagnosis, add_medicine_record, admit_patient, discharge_patient, show_case, case_cost
  • 日志管理: show_logs, export_logs, clear_logs
  • 系统命令: help, exit, save, load

使用指南

编译和运行

编译

mkdir -p build
cd build
cmake ..
make -j4

运行

# 交互式 Shell
cd build
./his

# 在命令行中执行脚本批处理(适合测试)
cd build
printf "patient load ../data/patients.txt\ndoctor load ../data/doctors.txt\ncase view p1001\nexit\n" | ./his

推荐数据文件路径

  • data/patients.txt
  • data/doctors.txt
  • data/medicines.txt
  • data/wards.txt

核心命令

病人管理
  • patient add <patientId> <name> <age> <gender> <contact> [Outpatient|Inpatient|Discharged]
  • patient update <patientId> <name> <age> <gender> <contact>
  • patient rm <patientId>
  • patient list
  • patient search id <patientId_keyword>
  • patient search name <name_keyword>
  • patient search phone <contact_keyword>
  • patient search <keyword>(兼容旧版,优先 id -> name -> phone
  • patient load [file_path]
  • patient save [file_path]
  • patient admit <wardId> <patientId>
  • patient release bed <wardId> <bedId>
  • patient release patient <wardId> <patientId>
医生管理
  • doctor add <doctorId> <name> <departmentId> <Chief|AssociateChief|Attending|Resident> <schedule>
  • doctor rm <doctorId>
  • doctor list
  • doctor list dept <departmentId>
  • doctor search <keyword>(兼容旧版,任一字段包含匹配)
  • doctor search name <name_keyword>
  • doctor search dept <departmentId_keyword>(模糊匹配、大小写不敏感)
  • doctor search title <title_keyword>
  • doctor search schedule <schedule_keyword>
  • doctor load [file_path]
  • doctor save [file_path]
药品管理
  • medicine add <id> <genericName> <brandName> <departmentId> <stock> <unitPrice>
  • medicine list
  • medicine stock inc <id> <amount>
  • medicine stock dec <id> <amount>
  • medicine find <keyword>(通用模糊搜索)
  • medicine load [file_path]
  • medicine save [file_path]
病房管理
  • ward add <wardId> <departmentId> <Normal|Special|ICU> <maxBeds>
  • ward rm <wardId>
  • ward list
  • ward show <wardId>
  • ward bed add <wardId> <bedId>
  • ward bed rm <wardId> <bedId>
病例管理
  • case diagnosis add <patientId> <doctorId> <diagnosis> [prescription] [remarks]
  • case medicine add <patientId> <medicineId> <medicineName> <quantity> <usage> <unitPrice>
  • case admission add <patientId> <wardId> <bedId> [reason]
  • case discharge <patientId> [summary]
  • case appointment add <patientId> <doctorId> <date> [notes]
  • case view <patientId>
  • case stats <patientId>
日志管理
  • log view <num>
  • log export <path>
  • log clear

本次新增点

  • patient search id:按 patientId 模糊、大小写不敏感匹配
  • doctor search dept:科室支持模糊匹配(不区分大小写)
  • 所有 search 已统一为不区分大小写匹配

交互模式

./his

无shell模式

./his --noshell


### 数据文件

系统使用JSON文件进行数据持久化
- `data/patients.txt`: 患者数据
- `data/doctors.txt`: 医生数据
- `data/medicines.txt`: 药品数据
- `data/wards.txt`: 病房数据

### Shell命令使用

#### 患者病例管理示例

```bash
# 添加诊断记录
add_diagnosis P001 D001 "肺炎" "需要抗生素治疗"

# 添加用药记录
add_medicine_record P001 M001 5 25.0 D001 "每日三次"

# 入院患者
admit_patient P001 W001 "肺炎治疗"

# 出院患者
discharge_patient P001

# 查看患者病例
show_case P001

# 计算用药总费用
case_cost P001

日志管理示例

# 查看日志
show_logs

# 导出日志
export_logs logs/session.log

# 清除日志
clear_logs

数据结构使用最佳实践

  1. 内存管理: LinkedList自动管理内存无需手动释放
  2. 数据一致性: 通过服务层进行所有数据操作,确保业务规则
  3. 日志记录: 所有重要操作都会自动记录到日志系统
  4. 数据持久化: 使用save命令保存数据到文件,load命令从文件加载
  5. 错误处理: 系统提供完善的错误处理和用户提示

扩展开发

添加新的数据模型

  1. include/models/下定义新类
  2. 实现toJson()fromJson()方法
  3. HisContext中添加对应的LinkedList成员
  4. 在服务层添加业务逻辑
  5. ReplShell中添加相应的命令处理

添加新的日志类型

LogEntryType枚举中添加新类型,然后在相应位置调用logger.log()方法。

许可证

本项目采用MIT许可证。