# HIS 医院信息管理系统 - 完整文档 ## 一、系统概述 HIS(Hospital Information System)是一个完整的医院信息管理系统,使用 C++20 开发,采用 Qt6 框架构建图形界面。系统支持患者管理、医生管理、药品管理、病房管理、检查项目管理、科室管理、患者病例管理、支付结算管理和操作日志记录等核心功能。 ### 1.1 系统特点 - **双界面支持**:同时提供 CLI 命令行界面和 Qt6 GUI 图形界面 - **模块化设计**:数据模型层、服务层、工具层和用户界面层清晰分离 - **数据持久化**:支持 JSON 格式的文件存储和加载 - **完整日志系统**:记录所有关键操作,支持导出和查询 - **支付结算系统**:支持多种支付方式、医保结算和账单生成 - **多角色视角**:GUI 支持管理视角、病人视角和医护视角 ### 1.2 技术栈 - **编程语言**:C++20 - **构建系统**:CMake 3.16+ - **GUI 框架**:Qt6 (Widgets, Charts) - **数据格式**:JSON(自定义 E2hangJson 库) - **数据结构**:自定义泛型双向链表(LinkedList) --- ## 二、系统架构 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 用户界面层 │ │ ┌─────────────────────┐ ┌──────────────────────┐ │ │ │ CLI (ReplShell) │ │ GUI (MainWindow) │ │ │ │ - 命令行交互 │ │ - Qt6 Widgets │ │ │ │ - 表格打印 │ │ - Qt6 Charts │ │ │ └─────────────────────┘ └──────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ 核心业务层 │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ HisCore (组合根) │ │ │ │ ┌────────────┐ ┌────────────┐ ┌────────────────────┐ │ │ │ │ │ HisContext │ │ 各种服务 │ │ Logger (日志系统) │ │ │ │ │ │ (数据上下文)│ │ (Services) │ │ │ │ │ │ │ └────────────┘ └────────────┘ └────────────────────┘ │ │ │ └──────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ 数据模型层 │ │ Patient │ Doctor │ Medicine │ Ward │ Check │ Department │ │ │ PatientCase │ Payment │ Settlement │ 各种记录结构体 │ └─────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ 工具层 │ │ LinkedList │ FileManager │ Logger │ UUID │ E2hangJson │ └─────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ 数据持久化 │ │ JSON 文件 (patients.txt, doctors.txt, medicines.txt, ...) │ └─────────────────────────────────────────────────────────────────┘ ``` --- ## 三、数据结构(模型层) ### 3.1 基础实体模型 #### 3.1.1 Patient(患者) | 字段名 | 类型 | 说明 | |--------|------|------| | PatientID | string | 患者唯一标识(UUID) | | Name | string | 姓名 | | Age | int | 年龄 | | Gender | string | 性别 | | Contact | string | 联系方式 | | Status | PatientStatus | 患者状态 | **患者状态枚举 (PatientStatus)**: - `Outpatient`:门诊患者 - `Inpatient`:住院患者 - `Discharged`:已出院 - `Visited`:已就诊(门诊已完成诊断和用药) **主要方法**: - `updateBasicInfo()`:更新基本信息 - `canBeRemoved()`:检查是否可删除(住院中禁止删除) - `nameMatches()`:姓名模糊匹配 - `generateUniqueId()`:生成 UUID #### 3.1.2 Doctor(医生) | 字段名 | 类型 | 说明 | |--------|------|------| | DoctorID | string | 医生唯一标识(UUID) | | Name | string | 姓名 | | DepartmentID | string | 所属科室 ID | | Title | DoctorTitle | 职称 | | Schedule | string | 出诊时间安排 | **医生职称枚举 (DoctorTitle)**: - `Chief`:主任医师 - `AssociateChief`:副主任医师 - `Attending`:主治医师 - `Resident`:住院医师 #### 3.1.3 Medicine(药品) | 字段名 | 类型 | 说明 | |--------|------|------| | MedicineID | string | 药品唯一标识(UUID) | | GenericName | string | 通用名 | | BrandName | string | 商品名 | | Aliases | vector | 别名列表 | | StockQuantity | int | 当前库存数量 | | DepartmentID | string | 所属科室 ID | | UnitPrice | double | 单价 | **主要方法**: - `updateBasicInfo()`:更新药品信息 - `nameMatches()`:名称模糊匹配(通用名/商品名/别名) - `decreaseStock()`:减少库存(库存不足时失败) #### 3.1.4 Ward(病房)与 Bed(床位) **Ward 字段**: | 字段名 | 类型 | 说明 | |--------|------|------| | WardID | string | 病房唯一标识(UUID) | | DepartmentID | string | 所属科室 ID | | Type | WardType | 病房类型 | | MaxBeds | int | 最大床位数 | | Beds | vector | 床位列表 | **Bed 字段**: | 字段名 | 类型 | 说明 | |--------|------|------| | BedID | string | 床位唯一标识(UUID) | | WardID | string | 所属病房 ID | | Status | BedStatus | 床位状态 | | PatientID | string | 占用患者 ID(空闲时为空) | **病房类型枚举 (WardType)**: - `Normal`:普通病房 - `Special`:特殊病房 - `ICU`:重症监护室 **床位状态枚举 (BedStatus)**: - `Free`:空闲 - `Occupied`:占用 **主要方法**: - `getFreeBedID()`:获取第一个空闲床位 - `admitPatient()`:为患者分配床位 - `releaseBed()` / `releasePatient()`:释放床位 - `addBed()` / `removeBed()`:增减床位 - `freeBedCount()` / `occupiedBedCount()`:床位统计 - `occupancyRate()`:床位使用率 #### 3.1.5 Check(检查项目) | 字段名 | 类型 | 说明 | |--------|------|------| | CheckID | string | 检查项目唯一标识(UUID) | | Name | string | 检查名称 | | DepartmentID | string | 所属科室 ID | | Price | double | 检查价格 | #### 3.1.6 Department(科室) | 字段名 | 类型 | 说明 | |--------|------|------| | DepartmentID | string | 科室唯一标识(UUID) | | Name | string | 科室名称 | | Description | string | 科室描述 | ### 3.2 病例相关模型 #### 3.2.1 DiagnosisRecord(诊断记录) | 字段名 | 类型 | 说明 | |--------|------|------| | DoctorID | string | 诊断医生 ID | | Diagnosis | string | 诊断内容 | | Prescription | string | 处方(可选) | | Remarks | string | 备注 | | Timestamp | time_t | 诊断时间 | #### 3.2.2 MedicineRecord(用药记录) | 字段名 | 类型 | 说明 | |--------|------|------| | MedicineID | string | 药品 ID | | MedicineName | string | 药品名称 | | Quantity | int | 数量 | | Usage | string | 用法(如:一日三次,饭后服用) | | UnitPrice | double | 单价 | | DoctorID | string | 开药医生 ID | | Timestamp | time_t | 开药时间 | **计算方法**: - `getTotalPrice()`:返回 `Quantity * UnitPrice` #### 3.2.3 CheckRecord(检查记录) | 字段名 | 类型 | 说明 | |--------|------|------| | CheckID | string | 检查 ID | | CheckName | string | 检查名称 | | DepartmentID | string | 归属科室 ID | | Price | double | 检查价格 | | DoctorID | string | 开单医生 ID | | Timestamp | time_t | 开单时间 | #### 3.2.4 AdmissionRecord(住院记录) | 字段名 | 类型 | 说明 | |--------|------|------| | WardID | string | 病房 ID | | BedID | string | 床位 ID | | AdmissionTime | time_t | 入院时间 | | DischargeTime | time_t | 出院时间(0 表示未出院) | | Reason | string | 住院原因 | | DischargeSummary | string | 出院小结 | **判断方法**: - `isCurrentlyAdmitted()`:返回 `DischargeTime == 0` #### 3.2.5 AppointmentRecord(预约记录) | 字段名 | 类型 | 说明 | |--------|------|------| | DoctorID | string | 医生 ID | | PatientID | string | 患者 ID | | AppointmentDate | string | 预约日期(YYYY-MM-DD) | | Notes | string | 备注 | | Timestamp | time_t | 预约时间 | #### 3.2.6 PatientCase(患者病例) | 字段名 | 类型 | 说明 | |--------|------|------| | PatientID | string | 患者 ID | | DiagnosisRecords | vector | 诊断记录列表 | | MedicineRecords | vector | 用药记录列表 | | CheckRecords | vector | 检查记录列表 | | AdmissionRecords | vector | 住院记录列表 | | AppointmentRecords | vector | 预约记录列表 | | CreatedTime | time_t | 创建时间 | | LastModifiedTime | time_t | 最后修改时间 | **主要方法**: - `addDiagnosisRecord()` / `addMedicineRecord()` / `addCheckRecord()` / `addAdmissionRecord()` / `addAppointmentRecord()`:添加各类记录 - `getLatestDiagnosis()` / `getLatestAdmission()` / `getLatestAppointment()`:获取最新记录 - `getCurrentAdmission()`:获取当前住院记录(如果未出院) - `dischargeFromLatestAdmission()`:出院处理 - `getTotalMedicineCost()`:计算总用药费用 - `getTotalCheckCost()`:计算总检查费用 ### 3.3 支付结算模型 #### 3.3.1 Payment(支付记录) | 字段名 | 类型 | 说明 | |--------|------|------| | PaymentID | string | 支付唯一标识(UUID) | | PatientID | string | 患者 ID | | Amount | double | 支付金额 | | Method | PaymentMethod | 支付方式 | | PaymentType | string | 支付类型(如"挂号"、"检查"、"用药"等) | | OperationID | string | 关联的操作 ID | | PaymentTime | time_t | 支付时间 | | Status | string | 支付状态("Pending", "Completed", "Failed", "Refunded") | | Description | string | 支付描述 | **支付方式枚举 (PaymentMethod)**: - `Cash`:现金 - `CreditCard`:信用卡 - `MobilePayment`:移动支付(微信/支付宝) - `HealthInsurance`:医保 #### 3.3.2 SettlementItem(结算单明细项) | 字段名 | 类型 | 说明 | |--------|------|------| | ItemName | string | 项目名称 | | ItemType | string | 项目类型 | | OperationID | string | 关联的操作 ID | | Quantity | double | 数量 | | UnitPrice | double | 单价 | | Amount | double | 金额 | | PaymentMethod | string | 支付方式 | #### 3.3.3 Settlement(结算单) | 字段名 | 类型 | 说明 | |--------|------|------| | SettlementID | string | 结算单唯一标识(UUID) | | PatientID | string | 患者 ID | | PatientName | string | 患者姓名 | | DischargeDate | string | 出院日期 | | SettlementTime | time_t | 结算时间 | | Items | vector | 费用明细列表 | | TotalAmount | double | 医疗总费用 | | InsurancePaid | double | 医保支付金额 | | PatientPaid | double | 患者自付金额 | | Status | string | 结算状态("Pending", "Completed", "Settled") | | Notes | string | 备注 | **主要方法**: - `addItem()`:添加费用项 - `calculateTotals()`:计算总金额 ### 3.4 工具数据结构 #### 3.4.1 LinkedList(自定义泛型双向链表) ```cpp template class LinkedList { // 内部使用双向链表 + unordered_map 索引 ListNode* head; // 哨兵头节点 ListNode* tail; // 哨兵尾节点 std::unordered_map*> mp; // 快速查找索引 size_t sz; // 元素数量 }; ``` **特性**: - 泛型支持,支持任意 Key-Value 对 - 双向链表结构,支持高效插入和删除 - 使用 `unordered_map` 作为索引,O(1) 查找 - 哨兵节点设计,简化边界处理 - 自动内存管理 **主要方法**: - `insert_front(key, value)`:在头部插入(如果 key 已存在则忽略) - `remove(key)`:删除指定 key 的节点 - `find(key)`:查找节点 - `move_to_front(key)`:将节点移到头部(LRU 风格) - `remove_tail()`:删除尾部节点 - `size()`:返回元素数量 - `for_each(visitor)`:遍历所有节点 #### 3.4.2 LogEntry(日志条目) | 字段名 | 类型 | 说明 | |--------|------|------| | Timestamp | time_t | 时间戳 | | Type | LogEntryType | 日志类型 | | Command | string | 命令或操作标识 | | Details | string | 详细内容 | | UserID | string | 用户 ID | | OperationID | string | 操作涉及的对象 ID | **日志类型枚举 (LogEntryType)**: - `SHELL_COMMAND`:Shell 命令 - `PATIENT_OPERATION`:患者操作 - `DOCTOR_OPERATION`:医生操作 - `MEDICINE_OPERATION`:药品操作 - `WARD_OPERATION`:病房操作 - `DIAGNOSIS_RECORD`:诊断记录 - `MEDICINE_RECORD`:药房记录 - `ADMISSION_RECORD`:住院记录 - `DISCHARGE_RECORD`:出院记录 - `CHECK_OPERATION`:检查操作 - `CHECK_RECORD`:检查记录 - `SYSTEM_EVENT`:系统事件 #### 3.4.3 UUID(唯一标识符生成器) - `generate()`:生成标准 UUID v4(格式:`xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`) - `generateShort()`:生成简短 UUID(无连字符) - `isValid()`:检查 UUID 格式 - `toShort()` / `fromShort()`:格式转换 --- ## 四、服务层 ### 4.1 核心组件 #### 4.1.1 HisContext(全局数据上下文) 持有所有系统数据的内存存储,使用 `LinkedList` 管理各类实体: ```cpp class HisContext { LinkedList wards; // 病房列表 LinkedList patients; // 患者列表 LinkedList doctors; // 医生列表 LinkedList medicines; // 药品列表 LinkedList checks; // 检查项目列表 LinkedList patientCases; // 患者病例列表 LinkedList departments; // 科室列表 LinkedList payments; // 支付记录列表 LinkedList settlements; // 结算单列表 }; ``` #### 4.1.2 HisCore(组合根) 组装所有服务和上下文,是系统的入口点: ```cpp class HisCore { HisContext ctx_; WardService wardService; PatientService patientService; PatientCaseService patientCaseService; ReportService reportService; DoctorService doctorService; MedicineService medicineService; CheckService checkService; DepartmentService departmentService; PaymentService paymentService; SettlementService settlementService; PaymentManagementService paymentManagementService; }; ``` **主要方法**: - `loadDataFromFolder()`:从指定文件夹加载所有数据 - `fixDepartmentReferences()`:修复科室 ID 引用(将名称转换为 ID) ### 4.2 业务服务 #### 4.2.1 PatientService(患者服务) | 方法 | 说明 | |------|------| | `patientCount()` | 获取患者数量 | | `findPatient(id)` | 查找患者 | | `addPatient(patient)` | 添加患者 | | `updatePatient(...)` | 更新患者信息 | | `removePatient(id)` | 删除患者 | | `for_eachPatient(visitor)` | 遍历所有患者 | | `findByName(keyword)` | 按姓名模糊搜索 | | `findByPatientId(keyword)` | 按 ID 模糊搜索 | | `findByContact(keyword)` | 按手机号模糊搜索 | | `admitPatient(wardId, patientId)` | 入院患者(分配床位) | | `releaseBed(wardId, bedId)` | 释放指定床位 | | `releasePatient(wardId, patientId)` | 释放患者占用的床位 | | `createPatient(...)` | 创建患者(自动生成 UUID) | #### 4.2.2 DoctorService(医生服务) | 方法 | 说明 | |------|------| | `doctorCount()` | 获取医生数量 | | `findDoctor(id)` | 查找医生 | | `for_eachDoctor(visitor)` | 遍历所有医生 | | `for_eachDoctorInDept(deptId, visitor)` | 按科室遍历医生 | | `searchDoctors(keyword)` | 模糊搜索(姓名/科室/职称/排班) | | `addDoctor(doctor)` | 添加医生 | | `removeDoctor(id)` | 删除医生 | | `createDoctor(...)` | 创建医生(自动生成 UUID) | #### 4.2.3 MedicineService(药品服务) | 方法 | 说明 | |------|------| | `medicineCount()` | 获取药品数量 | | `findMedicine(id)` | 查找药品 | | `for_eachMedicine(visitor)` | 遍历所有药品 | | `searchByName(keyword)` | 按名称模糊搜索 | | `addMedicine(medicine)` | 添加药品 | | `updateMedicine(...)` | 更新药品信息 | | `removeMedicine(id)` | 删除药品 | | `addOrUpdateMedicine(medicine)` | 添加或更新 | | `createMedicine(...)` | 创建药品(自动生成 UUID) | | `increaseStock(id, amount)` | 增加库存 | | `decreaseStock(id, amount)` | 减少库存(库存不足时失败) | #### 4.2.4 WardService(病房服务) | 方法 | 说明 | |------|------| | `wardCount()` | 获取病房数量 | | `findWard(id)` | 查找病房 | | `for_eachWard(visitor)` | 遍历所有病房 | | `addWard(ward)` | 添加病房 | | `createWard(...)` | 创建病房(自动生成 UUID) | | `removeWard(id)` | 删除病房 | | `addBed(wardId, bedId)` | 添加床位 | | `releaseBed(wardId, bedId)` | 释放床位 | | `releasePatient(wardId, patientId)` | 释放患者占用的床位 | | `removeBed(wardId, bedId)` | 删除床位 | | `loadFromFile(path)` | 从文件加载 | | `saveToFile(path)` | 保存到文件 | #### 4.2.5 CheckService(检查项目服务) | 方法 | 说明 | |------|------| | `checkCount()` | 获取检查项目数量 | | `findCheck(id)` | 查找检查项目 | | `for_eachCheck(visitor)` | 遍历所有检查项目 | | `searchByName(keyword)` | 按名称模糊搜索 | | `addCheck(check)` | 添加检查项目 | | `updateCheck(...)` | 更新检查项目 | | `removeCheck(id)` | 删除检查项目 | | `createCheck(...)` | 创建检查项目(自动生成 UUID) | #### 4.2.6 DepartmentService(科室服务) | 方法 | 说明 | |------|------| | `departmentCount()` | 获取科室数量 | | `findDepartment(id)` | 查找科室 | | `for_eachDepartment(visitor)` | 遍历所有科室 | | `searchDepartments(keyword)` | 模糊搜索 | | `addDepartment(department)` | 添加科室 | | `removeDepartment(id)` | 删除科室 | | `updateDepartment(id, department)` | 更新科室 | | `createDepartment(...)` | 创建科室(自动生成 UUID) | | `getDoctorsByDepartment(deptId)` | 获取科室下所有医生 | | `getMedicinesByDepartment(deptId)` | 获取科室下所有药品 | | `getDepartmentName(deptId)` | 获取科室名称 | | `canDeleteDepartment(deptId)` | 检查是否可删除(有医生或药品时不能删除) | | `getDoctorCountInDepartment(deptId)` | 获取科室下医生数量 | | `getMedicineCountInDepartment(deptId)` | 获取科室下药品数量 | | `getCheckCountInDepartment(deptId)` | 获取科室下检查项目数量 | #### 4.2.7 PatientCaseService(患者病例服务) | 方法 | 说明 | |------|------| | `getOrCreateCase(patientId)` | 获取或创建病例 | | `getCase(patientId)` | 获取病例 | | `addDiagnosisRecord(patientId, record)` | 添加诊断记录 | | `addMedicineRecord(patientId, record)` | 添加用药记录 | | `addCheckRecord(patientId, record)` | 添加检查记录 | | `addAppointmentRecord(patientId, record)` | 添加预约记录 | | `addAdmissionRecord(patientId, record)` | 添加住院记录 | | `dischargePatient(patientId, summary)` | 出院处理 | | `caseCount()` | 获取病例数量 | | `for_eachCase(visitor)` | 遍历所有病例 | | `getTotalMedicineCost(patientId)` | 计算总用药费用 | | `getDiagnosisRecordCount(patientId)` | 获取诊断记录数 | | `getMedicineRecordCount(patientId)` | 获取用药记录数 | | `getAdmissionRecordCount(patientId)` | 获取住院记录数 | | `removeCase(patientId)` | 删除病例 | #### 4.2.8 PaymentService(支付服务) | 方法 | 说明 | |------|------| | `createPayment(...)` | 创建支付记录 | | `findPayment(id)` | 查找支付记录 | | `findByPatientId(patientId, visitor)` | 按患者查询支付记录 | | `findByPaymentType(type, visitor)` | 按支付类型查询 | | `for_eachPayment(visitor)` | 遍历所有支付记录 | | `updatePaymentStatus(id, status)` | 更新支付状态 | | `completePayment(id)` | 完成支付 | | `refundPayment(id)` | 退款 | | `getTotalPaymentAmount(patientId)` | 获取患者总支付金额 | | `getPaymentsByType(patientId, type, visitor)` | 按类型获取支付记录 | | `removePayment(id)` | 删除支付记录 | #### 4.2.9 SettlementService(结算服务) | 方法 | 说明 | |------|------| | `generateSettlement(patientId, name, date)` | 生成结算单 | | `findSettlement(id)` | 查找结算单 | | `findByPatientId(patientId, visitor)` | 按患者查询结算单 | | `for_eachSettlement(visitor)` | 遍历所有结算单 | | `addItemToSettlement(id, item)` | 添加费用项 | | `calculateSettlement(id)` | 计算结算总额 | | `completeSettlement(id)` | 完成结算 | | `getPatientTotalAmount(patientId)` | 获取患者结算总额 | | `getPatientInsurancePaid(patientId)` | 获取患者医保支付总额 | | `getPatientPatientPaid(patientId)` | 获取患者自付总额 | | `removeSettlement(id)` | 删除结算单 | | `generateSettlementReport(id)` | 生成结算单报告 | #### 4.2.10 PaymentManagementService(支付管理服务) **统计结构体**: ```cpp struct PaymentStatistics { double TotalRevenue; // 总收入 double CompletedAmount; // 已完成金额 double PendingAmount; // 待支付金额 double RefundedAmount; // 已退款金额 int TotalPayments; // 总支付数 int CompletedPayments; // 已完成数 int PendingPayments; // 待支付数 int RefundedPayments; // 已退款数 }; struct PaymentMethodStatistics { std::string Method; // 支付方式 int Count; // 数量 double Amount; // 金额 }; ``` | 方法 | 说明 | |------|------| | `getAllPayments(visitor)` | 获取所有支付记录 | | `getPaymentsByStatus(status, visitor)` | 按状态过滤 | | `getPaymentsByDateRange(start, end, visitor)` | 按日期范围过滤 | | `getPaymentMethodStatistics()` | 按支付方式统计 | | `getPaymentStatistics()` | 获取支付统计 | | `getTodayPaymentStatistics()` | 获取今日统计 | | `getMonthlyPaymentStatistics()` | 获取本月统计 | | `getAllSettlements(visitor)` | 获取所有结算单 | | `getSettlementsByStatus(status, visitor)` | 按状态过滤结算单 | | `getSettlementsByPatientId(patientId, visitor)` | 按患者查询结算单 | | `searchSettlementsByPatientInfo(keyword, visitor)` | 搜索患者结算单 | | `generateDailyReport(date)` | 生成日报表 | | `generateMonthlyReport(month)` | 生成月报表 | | `generateRevenueReport()` | 生成收入报表 | | `getDailyRevenueData(days)` | 获取每日收入数据 | | `getMonthlyRevenueData(months)` | 获取每月收入数据 | | `getRevenueByType()` | 获取收入分类数据 | | `generatePatientBill(patientId)` | 生成患者账单 | | `getAnomalousPayments(visitor)` | 获取异常支付记录 | | `processRefund(paymentId, reason)` | 处理退款申请 | #### 4.2.11 ReportService(报表服务) | 方法 | 说明 | |------|------| | `wardOccupancyRate(wardId)` | 获取病房床位使用率 | --- ## 五、用户界面层 ### 5.1 CLI 命令行界面(ReplShell) 基于命令行的交互式 Shell,支持所有核心操作。 **命令分类**: #### 患者管理 ``` patient add [Outpatient|Inpatient|Discharged|Visited] patient update patient rm patient list patient search id patient search name patient search phone patient search patient load [file_path] patient save [file_path] patient admit patient release bed patient release patient ``` #### 医生管理 ``` doctor add doctor rm doctor list doctor list dept doctor search doctor search name doctor search dept doctor search title doctor search schedule doctor load [file_path] doctor save [file_path] ``` #### 药品管理 ``` medicine add medicine list medicine stock inc medicine stock dec medicine find medicine load [file_path] medicine save [file_path] ``` #### 病房管理 ``` ward add ward rm ward list ward show ward bed add ward bed rm ``` #### 检查项目管理 ``` check add check list check find check load [file_path] check save [file_path] ``` #### 科室管理 ``` department add [description] department rm department list department load [file_path] department save [file_path] ``` #### 病例管理 ``` case diagnosis add [prescription] [remarks] case medicine add case check add case admission add [reason] case discharge [summary] case appointment add [notes] case view case stats ``` #### 支付管理 ``` payment create [description] payment list payment complete payment refund payment search ``` #### 结算管理 ``` settlement generate settlement list settlement view settlement complete ``` #### 日志管理 ``` log view log export log clear ``` #### 系统命令 ``` help exit save load ``` ### 5.2 GUI 图形界面(MainWindow) 基于 Qt6 的图形界面,提供多标签页和角色视角切换。 #### 5.2.1 视角枚举(ViewRole) | 视角 | 说明 | 可见功能 | |------|------|----------| | Admin | 管理视角 | 所有功能 | | Patient | 病人视角 | 只能查看医生信息 | | Medical | 医护视角 | 患者、医生、药品、检查、病例管理 | #### 5.2.2 主要界面组件 | 标签页 | 组件 | 功能 | |--------|------|------| | 仪表盘 | summaryLabel | 显示系统统计信息 | | 病房管理 | wardTreeView, wardTable | 树形病房浏览、表格床位管理 | | 患者管理 | patientTable | 患者列表、搜索、增删改查 | | 医生管理 | doctorTable | 医生列表、搜索、增删 | | 药品管理 | medicineTable | 药品列表、搜索、库存管理 | | 检查管理 | checkTable | 检查项目列表、搜索、增删改 | | 科室管理 | departmentTable | 科室列表、搜索、增删改、详情查看 | | 日志管理 | logDisplay | 日志查看、导出、清除 | #### 5.2.3 对话框组件 | 对话框 | 说明 | |--------|------| | PatientDialog | 患者信息编辑对话框 | | DepartmentDetailDialog | 科室详情对话框(显示科室下医生、药品、检查项目) | | PaymentDialog | 支付对话框 | | PaymentManagementDialog | 支付管理对话框(统计、报表) | | SettlementDialog | 结算对话框 | #### 5.2.4 主要操作按钮 **患者操作**: - 添加、编辑、删除患者 - 查看病例 - 入院、出院 - 添加诊断记录 - 添加用药记录 - 添加检查记录 - 添加住院记录 - 挂号 **医生操作**: - 添加、删除医生 **药品操作**: - 添加、更新、删除药品 - 增加库存、减少库存 **检查操作**: - 添加、更新、删除检查项目 - 添加检查记录 **科室操作**: - 添加、编辑、删除科室 - 查看科室详情(双击行) **病房操作**: - 添加病房 - 添加床位、删除床位 - 查看入住率 **日志操作**: - 刷新日志 - 清除日志 - 导出日志 --- ## 六、工具层 ### 6.1 Logger(日志系统) | 方法 | 说明 | |------|------| | `log(type, command, details, operationID)` | 记录通用日志 | | `logShellCommand(command)` | 记录 Shell 命令 | | `logPatientOperation(operation, patientId, details)` | 记录患者操作 | | `logDiagnosisRecord(patientId, doctorId, diagnosis)` | 记录诊断记录 | | `logMedicineRecord(patientId, medicineId, medicineName, quantity)` | 记录用药记录 | | `logAdmissionRecord(patientId, wardId, bedId, reason)` | 记录住院记录 | | `logDischargeRecord(patientId, summary)` | 记录出院记录 | | `flush()` | 刷新日志到文件 | | `clear()` | 清空日志缓冲区 | | `getEntries()` | 获取所有日志条目 | | `exportToFile(filePath)` | 导出日志到文件 | | `setLogFormat(format)` | 设置日志格式 | | `setConsoleOutput(enable)` | 启用/禁用控制台输出 | ### 6.2 FileManager(文件管理) 提供所有实体类型的文件读写操作: | 方法 | 说明 | |------|------| | `readTextFile(path)` | 读取文本文件 | | `writeTextFile(path, content)` | 写入文本文件 | | `createFile(path, content)` | 创建文件 | | `deleteFile(path)` | 删除文件 | | `deleteJsonField(path, fieldName)` | 删除 JSON 字段 | | `loadWardListFromFile(path, list)` | 加载病房列表 | | `saveWardListToFile(path, list)` | 保存病房列表 | | `loadPatientListFromFile(path, list)` | 加载患者列表 | | `savePatientListToFile(path, list)` | 保存患者列表 | | `loadDoctorListFromFile(path, list)` | 加载医生列表 | | `saveDoctorListToFile(path, list)` | 保存医生列表 | | `loadMedicineListFromFile(path, list)` | 加载药品列表 | | `saveMedicineListToFile(path, list)` | 保存药品列表 | | `loadDepartmentListFromFile(path, list)` | 加载科室列表 | | `saveDepartmentListToFile(path, list)` | 保存科室列表 | | `loadPatientCaseListFromFile(path, list)` | 加载病例列表 | | `savePatientCaseListToFile(path, list)` | 保存病例列表 | | `loadCheckListFromFile(path, list)` | 加载检查项目列表 | | `saveCheckListToFile(path, list)` | 保存检查项目列表 | | `loadPaymentListFromFile(path, list)` | 加载支付记录列表 | | `savePaymentListToFile(path, list)` | 保存支付记录列表 | | `loadSettlementListFromFile(path, list)` | 加载结算单列表 | | `saveSettlementListToFile(path, list)` | 保存结算单列表 | ### 6.3 UUID(唯一标识符生成器) 生成符合 RFC 4122 标准的 UUID v4。 ### 6.4 E2hangJson(自定义 JSON 库) | 组件 | 说明 | |------|------| | JsonValue | JSON 值表示(对象、数组、字符串、数字、布尔值) | | JsonParse | JSON 解析器 | | JsonSerializer | JSON 序列化器 | | JsonError | JSON 错误处理 | **使用模式**: ```cpp // 序列化 JsonValue json = patient.toJson(); std::string jsonStr = json.toString(); // 反序列化 Patient p = Patient::fromJson(json); ``` --- ## 七、数据持久化 ### 7.1 数据文件 系统使用 JSON 格式的文本文件进行数据持久化,推荐文件路径: | 文件 | 说明 | |------|------| | `data/patients.txt` | 患者数据 | | `data/doctors.txt` | 医生数据 | | `data/medicines.txt` | 药品数据 | | `data/wards.txt` | 病房数据 | | `data/checks.txt` | 检查项目数据 | | `data/departments.txt` | 科室数据 | | `data/patient_cases.txt` | 患者病例数据 | | `data/payments.txt` | 支付记录数据 | | `data/settlements.txt` | 结算单数据 | ### 7.2 数据加载与保存 **CLI 模式**: ``` # 加载所有数据 load # 保存所有数据 save # 单独加载/保存某类数据 patient load [file_path] patient save [file_path] ``` **GUI 模式**: - 启动时自动从 `data/` 文件夹加载数据 - 点击保存按钮保存所有数据 --- ## 八、使用说明 ### 8.1 编译和运行 #### 环境要求 - C++20 兼容的编译器(GCC 10+ / Clang 12+ / MSVC 2019+) - CMake 3.16+ - Qt6 (Widgets, Charts 组件) #### 编译步骤 ```bash mkdir -p build cd build cmake .. make -j4 ``` #### 运行方式 **交互式 CLI Shell**: ```bash cd build ./his ``` **无 Shell 模式**(仅加载数据,适合程序化调用): ```bash ./his --noshell ``` **GUI 图形界面**: ```bash ./his_gui ``` **批处理模式**(管道输入): ```bash printf "patient load ../data/patients.txt\ndoctor load ../data/doctors.txt\ncase view p1001\nexit\n" | ./his ``` ### 8.2 CLI 使用示例 #### 患者管理 ```bash # 添加患者 patient add P001 张三 30 男 13800138000 Outpatient # 查看患者列表 patient list # 搜索患者 patient search name 张 patient search id P001 # 更新患者信息 patient update P001 张三 31 男 13800138000 # 删除患者 patient rm P001 ``` #### 医生管理 ```bash # 添加医生 doctor add D001 李医生 DEPT001 Chief "Mon AM, Wed PM" # 查看医生列表 doctor list # 按科室查看医生 doctor list dept DEPT001 # 搜索医生 doctor search name 李 ``` #### 药品管理 ```bash # 添加药品 medicine add M001 阿莫西林 阿莫西林胶囊 DEPT001 100 25.5 # 查看药品列表 medicine list # 增加库存 medicine stock inc M001 50 # 减少库存 medicine stock dec M001 10 ``` #### 病房管理 ```bash # 添加病房 ward add W001 DEPT001 Normal 10 # 查看病房列表 ward list # 查看病房详情 ward show W001 # 添加床位 ward bed add W001 BED001 ``` #### 病例管理 ```bash # 添加诊断记录 case diagnosis add P001 D001 "肺炎" "阿莫西林" "需要休息" # 添加用药记录 case medicine add P001 M001 阿莫西林 5 一日三次 25.5 # 添加检查记录 case check add P001 C001 X光检查 DEPT001 100.0 D001 # 入院患者 case admission add P001 W001 BED001 "肺炎治疗" # 出院患者 case discharge P001 "康复出院" # 查看病例 case view P001 # 查看统计 case stats P001 ``` #### 支付管理 ```bash # 创建支付记录 payment create P001 100.0 Cash 挂号 REG001 "门诊挂号费" # 查看支付列表 payment list # 完成支付 payment complete PAY001 # 退款 payment refund PAY001 ``` #### 结算管理 ```bash # 生成结算单 settlement generate P001 张三 2024-01-01 # 查看结算单列表 settlement list # 完成结算 settlement complete SETTLE001 ``` #### 日志管理 ```bash # 查看最近 10 条日志 log view 10 # 导出日志 log export logs/session.log # 清除日志 log clear ``` ### 8.3 GUI 使用指南 #### 启动界面 启动 GUI 后,将看到主窗口,包含多个标签页: - **仪表盘**:显示系统统计信息 - **病房管理**:树形病房浏览和床位管理 - **患者管理**:患者列表和操作 - **医生管理**:医生列表和操作 - **药品管理**:药品列表和库存管理 - **检查管理**:检查项目管理 - **科室管理**:科室列表和详情 - **日志管理**:操作日志查看 #### 视角切换 在窗口右上角可以选择视角: - **管理视角**:显示所有功能 - **病人视角**:只能查看医生信息 - **医护视角**:显示患者、医生、药品、检查、病例管理 #### 数据操作 1. **添加数据**:点击对应标签页的"添加"按钮 2. **编辑数据**:双击表格行或选中后点击"编辑" 3. **删除数据**:选中后点击"删除"按钮 4. **搜索数据**:在搜索框中输入关键词 5. **保存数据**:点击工具栏的保存按钮 #### 科室详情 双击科室行或点击"查看详情"按钮,可以看到: - 科室基本信息 - 科室下的医生列表 - 科室下的药品列表 - 科室下的检查项目列表 --- ## 九、扩展开发指南 ### 9.1 添加新的数据模型 1. 在 `include/models/` 下定义新类 2. 实现 `toJson()` 和 `fromJson()` 方法 3. 在 `HisContext` 中添加对应的 `LinkedList` 成员 4. 创建对应的 Service 类(在 `include/core/` 和 `src/core/`) 5. 在 `FileManager` 中添加文件读写方法 6. 在 `CMakeLists.txt` 中添加源文件 7. 在 `ReplShell` 中添加命令处理 8. 在 GUI 中添加对应的界面(如需要) ### 9.2 添加新的日志类型 1. 在 `LogEntryType` 枚举中添加新类型 2. 在 `Logger` 类中添加对应的日志方法 3. 在相应位置调用 `logger.log()` 方法 ### 9.3 添加新的 CLI 命令 1. 在 `ReplShell::executeLine()` 中添加命令解析 2. 实现对应的处理函数 3. 在 `printHelp()` 中添加帮助信息 ### 9.4 添加新的 GUI 界面 1. 在 `MainWindow` 中添加新的标签页 2. 创建对应的对话框类(在 `gui/dialogs/`) 3. 在 `setupUI()` 中初始化界面 4. 在对应的 refresh 方法中更新数据 5. 在槽函数中处理用户操作 6. 在 `CMakeLists.txt` 中添加新文件 --- ## 十、最佳实践 ### 10.1 内存管理 - `LinkedList` 自动管理内存,无需手动释放 - 所有模型对象通过值存储在链表中 ### 10.2 数据一致性 - 通过服务层进行所有数据操作,确保业务规则 - 病房和患者状态同步:入院/出院时同步更新患者状态和床位状态 ### 10.3 日志记录 - 所有重要操作都会自动记录到日志系统 - 支持导出日志到文件进行审计 ### 10.4 数据持久化 - 使用 `save` 命令保存数据到文件 - 使用 `load` 命令从文件加载数据 - 建议定期保存数据以防丢失 ### 10.5 错误处理 - 系统提供完善的错误处理和用户提示 - 关键操作返回布尔值表示成功/失败 - 使用 `outError` 参数返回详细错误信息 ### 10.6 ID 生成 - 所有实体使用 UUID 作为唯一标识 - 调用 `createXxx()` 方法时自动生成 UUID - 支持手动指定 ID(用于数据导入) --- ## 十一、项目结构 ``` HIS-GUI/ ├── CMakeLists.txt # CMake 构建配置 ├── README.md # 项目说明 ├── include/ # 头文件目录 │ ├── cli/ # CLI 相关头文件 │ │ ├── repl_shell.h # 交互式 Shell │ │ └── table_printer.h # 表格打印工具 │ ├── core/ # 核心业务逻辑头文件 │ │ ├── his_core.h # 组合根 │ │ ├── his_context.h # 数据上下文 │ │ ├── patient_service.h # 患者服务 │ │ ├── doctor_service.h # 医生服务 │ │ ├── medicine_service.h # 药品服务 │ │ ├── ward_service.h # 病房服务 │ │ ├── check_service.h # 检查服务 │ │ ├── department_service.h # 科室服务 │ │ ├── patient_case_service.h # 病例服务 │ │ ├── payment_service.h # 支付服务 │ │ ├── settlement_service.h # 结算服务 │ │ ├── payment_management_service.h # 支付管理服务 │ │ └── report_service.h # 报表服务 │ ├── models/ # 数据模型头文件 │ │ ├── patient.h # 患者模型 │ │ ├── doctor.h # 医生模型 │ │ ├── medicine.h # 药品模型 │ │ ├── ward.h # 病房模型 │ │ ├── check.h # 检查项目模型 │ │ ├── department.h # 科室模型 │ │ ├── patient_case.h # 病例模型 │ │ ├── payment.h # 支付模型 │ │ └── settlement.h # 结算模型 │ └── utils/ # 工具类头文件 │ ├── linkedlist.hpp # 泛型双向链表 │ ├── logger.h # 日志系统 │ ├── file_manager.h # 文件管理 │ ├── uuid.h # UUID 生成器 │ └── json/ # JSON 库 │ ├── JsonParse.h │ ├── JsonValue.h │ ├── JsonSerializer.h │ └── JsonError.h ├── src/ # 源文件目录 │ ├── main_shell.cpp # CLI 入口 │ ├── main_noshell.cpp # 无 Shell 模式入口 │ ├── cli/ # CLI 实现 │ ├── core/ # 核心业务逻辑实现 │ ├── models/ # 数据模型实现 │ └── utils/ # 工具类实现 ├── gui/ # GUI 相关代码 │ ├── main_gui.cpp # GUI 入口 │ ├── mainwindow.h/cpp # 主窗口 │ ├── payment_dialog.h/cpp # 支付对话框 │ ├── payment_management_dialog.h/cpp # 支付管理对话框 │ ├── settlement_dialog.h/cpp # 结算对话框 │ └── dialogs/ # 对话框 │ ├── patient_dialog.h/cpp │ └── department_detail_dialog.h/cpp ├── data/ # 数据文件目录 │ ├── patients.txt # 患者数据 │ ├── doctors.txt # 医生数据 │ ├── medicines.txt # 药品数据 │ ├── wards.txt # 病房数据 │ ├── checks.txt # 检查项目数据 │ ├── departments.txt # 科室数据 │ ├── patient_cases.txt # 病例数据 │ ├── payments.txt # 支付记录 │ └── settlements.txt # 结算单 ├── tests/ # 测试文件 ├── docs/ # 文档 └── build/ # 构建输出目录 ``` --- ## 十二、许可证 本项目采用 MIT 许可证。