Files
HIS-GUI/docs/info/system_documentation.md
e2hang ab53161caa 1
2026-04-06 23:29:55 +08:00

1304 lines
44 KiB
Markdown
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.
# HIS 医院信息管理系统 - 完整文档
## 一、系统概述
HISHospital 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<string> | 别名列表 |
| 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> | 床位列表 |
**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<DiagnosisRecord> | 诊断记录列表 |
| MedicineRecords | vector<MedicineRecord> | 用药记录列表 |
| CheckRecords | vector<CheckRecord> | 检查记录列表 |
| AdmissionRecords | vector<AdmissionRecord> | 住院记录列表 |
| AppointmentRecords | vector<AppointmentRecord> | 预约记录列表 |
| 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<SettlementItem> | 费用明细列表 |
| TotalAmount | double | 医疗总费用 |
| InsurancePaid | double | 医保支付金额 |
| PatientPaid | double | 患者自付金额 |
| Status | string | 结算状态("Pending", "Completed", "Settled" |
| Notes | string | 备注 |
**主要方法**
- `addItem()`:添加费用项
- `calculateTotals()`:计算总金额
### 3.4 工具数据结构
#### 3.4.1 LinkedList自定义泛型双向链表
```cpp
template<class Key, class Value>
class LinkedList {
// 内部使用双向链表 + unordered_map 索引
ListNode<Key, Value>* head; // 哨兵头节点
ListNode<Key, Value>* tail; // 哨兵尾节点
std::unordered_map<Key, ListNode<Key, Value>*> 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<std::string, Ward> wards; // 病房列表
LinkedList<std::string, Patient> patients; // 患者列表
LinkedList<std::string, Doctor> doctors; // 医生列表
LinkedList<std::string, Medicine> medicines; // 药品列表
LinkedList<std::string, Check> checks; // 检查项目列表
LinkedList<std::string, PatientCase> patientCases; // 患者病例列表
LinkedList<std::string, Department> departments; // 科室列表
LinkedList<std::string, Payment> payments; // 支付记录列表
LinkedList<std::string, Settlement> 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 <patientId> <name> <age> <gender> <contact> [Outpatient|Inpatient|Discharged|Visited]
patient update <patientId> <name> <age> <gender> <contact>
patient rm <patientId>
patient list
patient search id <keyword>
patient search name <keyword>
patient search phone <keyword>
patient search <keyword>
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 <keyword>
doctor search dept <keyword>
doctor search title <keyword>
doctor search 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>
```
#### 检查项目管理
```
check add <id> <name> <departmentId> <price>
check list
check find <keyword>
check load [file_path]
check save [file_path]
```
#### 科室管理
```
department add <name> [description]
department rm <id>
department list
department load [file_path]
department save [file_path]
```
#### 病例管理
```
case diagnosis add <patientId> <doctorId> <diagnosis> [prescription] [remarks]
case medicine add <patientId> <medicineId> <medicineName> <quantity> <usage> <unitPrice>
case check add <patientId> <checkId> <checkName> <departmentId> <price> <doctorId>
case admission add <patientId> <wardId> <bedId> [reason]
case discharge <patientId> [summary]
case appointment add <patientId> <doctorId> <date> [notes]
case view <patientId>
case stats <patientId>
```
#### 支付管理
```
payment create <patientId> <amount> <method> <type> <operationId> [description]
payment list
payment complete <paymentId>
payment refund <paymentId>
payment search <patientId>
```
#### 结算管理
```
settlement generate <patientId> <patientName> <dischargeDate>
settlement list
settlement view <settlementId>
settlement complete <settlementId>
```
#### 日志管理
```
log view <num>
log export <path>
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 张三 3013800138000 Outpatient
# 查看患者列表
patient list
# 搜索患者
patient search name 张
patient search id P001
# 更新患者信息
patient update P001 张三 3113800138000
# 删除患者
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 许可证。