44 KiB
44 KiB
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(自定义泛型双向链表)
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 管理各类实体:
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(组合根)
组装所有服务和上下文,是系统的入口点:
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(支付管理服务)
统计结构体:
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 错误处理 |
使用模式:
// 序列化
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 组件)
编译步骤
mkdir -p build
cd build
cmake ..
make -j4
运行方式
交互式 CLI Shell:
cd build
./his
无 Shell 模式(仅加载数据,适合程序化调用):
./his --noshell
GUI 图形界面:
./his_gui
批处理模式(管道输入):
printf "patient load ../data/patients.txt\ndoctor load ../data/doctors.txt\ncase view p1001\nexit\n" | ./his
8.2 CLI 使用示例
患者管理
# 添加患者
patient add P001 张三 30 男 13800138000 Outpatient
# 查看患者列表
patient list
# 搜索患者
patient search name 张
patient search id P001
# 更新患者信息
patient update P001 张三 31 男 13800138000
# 删除患者
patient rm P001
医生管理
# 添加医生
doctor add D001 李医生 DEPT001 Chief "Mon AM, Wed PM"
# 查看医生列表
doctor list
# 按科室查看医生
doctor list dept DEPT001
# 搜索医生
doctor search name 李
药品管理
# 添加药品
medicine add M001 阿莫西林 阿莫西林胶囊 DEPT001 100 25.5
# 查看药品列表
medicine list
# 增加库存
medicine stock inc M001 50
# 减少库存
medicine stock dec M001 10
病房管理
# 添加病房
ward add W001 DEPT001 Normal 10
# 查看病房列表
ward list
# 查看病房详情
ward show W001
# 添加床位
ward bed add W001 BED001
病例管理
# 添加诊断记录
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
支付管理
# 创建支付记录
payment create P001 100.0 Cash 挂号 REG001 "门诊挂号费"
# 查看支付列表
payment list
# 完成支付
payment complete PAY001
# 退款
payment refund PAY001
结算管理
# 生成结算单
settlement generate P001 张三 2024-01-01
# 查看结算单列表
settlement list
# 完成结算
settlement complete SETTLE001
日志管理
# 查看最近 10 条日志
log view 10
# 导出日志
log export logs/session.log
# 清除日志
log clear
8.3 GUI 使用指南
启动界面
启动 GUI 后,将看到主窗口,包含多个标签页:
- 仪表盘:显示系统统计信息
- 病房管理:树形病房浏览和床位管理
- 患者管理:患者列表和操作
- 医生管理:医生列表和操作
- 药品管理:药品列表和库存管理
- 检查管理:检查项目管理
- 科室管理:科室列表和详情
- 日志管理:操作日志查看
视角切换
在窗口右上角可以选择视角:
- 管理视角:显示所有功能
- 病人视角:只能查看医生信息
- 医护视角:显示患者、医生、药品、检查、病例管理
数据操作
- 添加数据:点击对应标签页的"添加"按钮
- 编辑数据:双击表格行或选中后点击"编辑"
- 删除数据:选中后点击"删除"按钮
- 搜索数据:在搜索框中输入关键词
- 保存数据:点击工具栏的保存按钮
科室详情
双击科室行或点击"查看详情"按钮,可以看到:
- 科室基本信息
- 科室下的医生列表
- 科室下的药品列表
- 科室下的检查项目列表
九、扩展开发指南
9.1 添加新的数据模型
- 在
include/models/下定义新类 - 实现
toJson()和fromJson()方法 - 在
HisContext中添加对应的LinkedList成员 - 创建对应的 Service 类(在
include/core/和src/core/) - 在
FileManager中添加文件读写方法 - 在
CMakeLists.txt中添加源文件 - 在
ReplShell中添加命令处理 - 在 GUI 中添加对应的界面(如需要)
9.2 添加新的日志类型
- 在
LogEntryType枚举中添加新类型 - 在
Logger类中添加对应的日志方法 - 在相应位置调用
logger.log()方法
9.3 添加新的 CLI 命令
- 在
ReplShell::executeLine()中添加命令解析 - 实现对应的处理函数
- 在
printHelp()中添加帮助信息
9.4 添加新的 GUI 界面
- 在
MainWindow中添加新的标签页 - 创建对应的对话框类(在
gui/dialogs/) - 在
setupUI()中初始化界面 - 在对应的 refresh 方法中更新数据
- 在槽函数中处理用户操作
- 在
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 许可证。