Files
HIS-GUI/docs/ReadmeA/ReadmeB.bak0
e2hang ab53161caa 1
2026-04-06 23:29:55 +08:00

1341 lines
45 KiB
Plaintext
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.
% !TeX program = xelatex
\documentclass[a4paper, 10pt]{ctexart}
% --- 综合宏包引入 ---
\usepackage{tikz}
\usetikzlibrary{arrows.meta, positioning, fit, backgrounds}
\usepackage[left=2cm, right=2cm, top=2.5cm, bottom=2.5cm]{geometry}
\usepackage{enumitem}
\usepackage{listings}
\usepackage{xcolor}
\usepackage{titlesec}
\usepackage{booktabs}
\usepackage{graphicx}
\usepackage{array}
\usepackage{fancyhdr}
\usepackage{hyperref}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{longtable}
% --- 字体设置 ---
% ctexart 会自动适配环境自带的中文字体
% --- 全局排版优化 ---
\emergencystretch=3em
\setlist{nosep, leftmargin=2em}
% --- 代码块样式设置 ---
\lstset{
basicstyle=\ttfamily\small,
commentstyle=\color{gray}\upshape,
breaklines=true,
frame=single,
rulecolor=\color{black!30},
backgroundcolor=\color{black!5},
xleftmargin=0pt,
xrightmargin=0pt,
aboveskip=1ex,
belowskip=1ex,
extendedchars=false,
columns=flexible,
keepspaces=true
}
% --- 标题设置 ---
\title{HIS 医院信息管理系统\\数据结构与系统架构说明文档}
\author{系统分析}
\date{\today}
\begin{document}
% ==========================================
% 全局目录
% ==========================================
\tableofcontents
\newpage
% ==========================================
% 第一部分:系统概述与设计目标
% ==========================================
\begin{center}
{\LARGE \textbf{《HIS 医院信息管理系统》}}\\
\vspace{0.5em}
{\large (数据结构、功能架构与使用说明)}
\vspace{1em}
\end{center}
\section{系统概述与设计目标}
本系统为一个面向中小型医院的完整医疗信息管理系统Hospital Information System, HIS采用 C++20 开发,结合 Qt6 框架构建图形界面。系统通过模块化分层设计,实现业务逻辑与交互界面的解耦,保障高扩展性与可维护性。
\begin{itemize}
\item \textbf{业务闭环}:实现完整的挂号、诊疗、检查、处方、住院、出院、支付、结算等医疗生命周期管理。
\item \textbf{双界面支持}:同时提供 CLI 命令行交互界面和 Qt6 GUI 图形界面,适配不同使用场景。
\item \textbf{数据规模}:支持大量患者、医生、药品、病房、检查项目、科室及支付结算记录的管理。
\item \textbf{底层核心}:全程基于手写\textbf{泛型双向链表 + 哈希索引}LinkedList实现内存数据流转采用 JSON 文本文件持久化。
\item \textbf{多角色视角}GUI 支持管理视角、病人视角和医护视角三种权限视图。
\item \textbf{支付结算}:支持现金、信用卡、移动支付、医保等多种支付方式,自动生成结算单与财务报表。
\item \textbf{鲁棒性}:完善的错误处理、输入校验和业务规则拦截(如住院中禁止删除患者、库存不足禁止发药等)。
\end{itemize}
\section{系统架构与项目目录结构}
系统采用四层分层架构设计UI表现层 $\rightarrow$ Core业务层 $\rightarrow$ Model实体层 $\rightarrow$ Utils工具层 $\rightarrow$ 持久化层)。
\begin{itemize}
\item \textbf{UI表现层}CLIReplShell命令行交互 / GUIQt6 MainWindow图形界面
\item \textbf{Core业务层}HisCore 组合根 + 11 个 Service 服务类
\item \textbf{Model实体层}9 个核心数据模型 + 5 种记录结构体
\item \textbf{Utils工具层}LinkedList、Logger、FileManager、UUID、E2hangJson
\item \textbf{持久化层}JSON 格式文本文件data/ 目录)
\end{itemize}
% 嵌入TikZ架构图
\begin{figure}[htbp]
\centering
\begin{tikzpicture}[
>={Stealth[length=3mm]},
box/.style={draw,rounded corners,fill=blue!10,inner sep=8pt,text width=3.2cm,align=center},
svc/.style={draw,rounded corners,fill=green!10,inner sep=8pt,text width=3.6cm,align=center},
data/.style={draw,rounded corners,fill=orange!10,inner sep=8pt,text width=3.2cm,align=center},
edge/.style={->,thick}
]
% UI层
\node[box] (cli) {CLI 层 \\ \texttt{ReplShell}};
\node[box, right=2.5cm of cli] (gui) {GUI 层 \\ \texttt{MainWindow} \\ \texttt{(Qt6)}};
% 核心层
\node[svc, below=1.5cm of cli] (core) {HisCore 组合根 \\ + 11 个 Service};
\node[data, below=1.5cm of core] (ctx) {HisContext \\ 全局数据容器};
\node[data, below=1.2cm of ctx] (list) {LinkedList$<$Key, Value$>$ \\ 双向链表+哈希索引};
% 模型
\node[data, right=3.5cm of ctx] (models) {9 大实体模型 \\ Patient, Doctor, Medicine \\ Ward, Check, Department \\ PatientCase, Payment \\ Settlement};
% 工具
\node[box, left=3.5cm of ctx] (utils) {工具层 \\ Logger, FileManager \\ UUID, E2hangJson};
% 持久化
\node[box, below=1.2cm of list] (files) {JSON 数据文件 \\ data/*.txt};
% 关系
\draw[edge] (cli) -- (core);
\draw[edge] (gui) -- (core);
\draw[edge] (core) -- (ctx);
\draw[edge] (ctx) -- (list);
\draw[edge] (list) -- (files);
\draw[edge] (ctx.east) -- (models.west);
\draw[edge] (core.west) -- (utils.east);
\draw[edge] (utils.south) |- (files.west);
\end{tikzpicture}
\caption{HIS 系统四层架构图}
\end{figure}
\newpage
项目工程文件结构如下:
\begin{lstlisting}[language=bash]
HIS-GUI/
├── CMakeLists.txt # CMake 构建配置 (Qt6 + C++20)
├── README.md # 项目简要说明
├── include/ # 头文件目录
│ ├── cli/ # CLI 交互层
│ │ ├── repl_shell.h # 交互式命令行主循环
│ │ └── table_printer.h # ASCII 表格打印工具
│ ├── core/ # 核心业务服务层 (11个Service)
│ │ ├── his_core.h # 组合根 (Composition Root)
│ │ ├── his_context.h # 全局数据上下文 (HisContext)
│ │ ├── 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/ # 数据模型层 (9个实体 + 5种记录)
│ │ ├── 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 v4 生成器
│ └── json/ # 自定义 JSON 库
│ ├── JsonValue.h
│ ├── JsonParse.h
│ ├── JsonSerializer.h
│ └── JsonError.h
├── src/ # 源文件实现
│ ├── main_shell.cpp # CLI 入口
│ ├── main_noshell.cpp # 无 Shell 模式入口
│ ├── cli/ # CLI 实现
│ ├── core/ # 11 个 Service 实现
│ ├── models/ # 9 个 Model 实现
│ └── utils/ # 工具类实现
├── gui/ # Qt6 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/ # 数据文件目录 (JSON 格式)
│ ├── patients.txt # 患者数据
│ ├── doctors.txt # 医生数据
│ ├── medicines.txt # 药品数据
│ ├── wards.txt # 病房数据
│ ├── checks.txt # 检查项目数据
│ ├── departments.txt # 科室数据
│ ├── patient_cases.txt # 患者病例数据
│ ├── payments.txt # 支付记录数据
│ └── settlements.txt # 结算单数据
├── tests/ # 测试用例
├── docs/ # 文档
└── build/ # 构建输出
\end{lstlisting}
\section{通用数据约定}
\begin{itemize}
\item \textbf{唯一性}:所有系统实体均采用 \textbf{UUID} 作为唯一主键标识,通过 \texttt{UUID::generate()} 生成符合 RFC 4122 标准的 v4 UUID。
\item \textbf{宽容性}:允许患者姓名重复,系统通过唯一 ID 精准区分同名患者。
\item \textbf{存储规约}:内存态数据全程挂载于自定义泛型链表 \textbf{LinkedList} 进行流转;磁盘持久化统一采用 \textbf{JSON 数组}格式存储于 data/ 目录下的 TXT 文件中。
\item \textbf{序列化}:所有模型均实现 \texttt{toJson()} 和 \texttt{fromJson()} 方法,与自定义 E2hangJson 库配合完成数据序列化/反序列化。
\end{itemize}
\section{核心数据结构LinkedList}
\subsection{结构特点}
LinkedList 是系统的基础泛型数据结构,采用\textbf{双向链表 + 哈希表}的混合设计:
\begin{table}[h]
\centering
\begin{tabular}{|l|l|l|}
\hline
\textbf{特性} & \textbf{说明} & \textbf{复杂度} \\
\hline
插入操作 & 在链表头部插入新元素 & $O(1)$ \\
\hline
查找操作 & 通过 unordered\_map 哈希索引定位 & $O(1)$ \\
\hline
删除操作 & 从链表中移除并更新哈希表 & $O(1)$ \\
\hline
遍历操作 & 按链表顺序从头到尾遍历 & $O(n)$ \\
\hline
移到头部 & LRU 风格,将节点移到链表头部 & $O(1)$ \\
\hline
\end{tabular}
\caption{LinkedList 操作复杂度}
\end{table}
\subsection{模板定义}
\begin{lstlisting}
template<class Key, class Value>
class LinkedList {
private:
ListNode<Key, Value>* head; // 哨兵头节点
ListNode<Key, Value>* tail; // 哨兵尾节点
std::unordered_map<Key, ListNode<Key, Value>*> mp; // 哈希索引
size_t sz; // 元素数量
public:
void insert_front(Key, Value);
void remove(Key);
ListNode* find(Key);
void move_to_front(Key);
void remove_tail();
size_t size();
void for_each(visitor);
};
\end{lstlisting}
\newpage
\section{核心数据实体}
\subsection{患者实体Patient}
\subsubsection{属性定义}
\begin{table}[h]
\centering
\begin{tabular}{|l|l|l|l|}
\hline
\textbf{属性名} & \textbf{类型} & \textbf{含义} & \textbf{是否主键} \\
\hline
PatientID & string & 患者唯一标识 (UUID) & 是 \\
\hline
Name & string & 患者姓名 & 否 \\
\hline
Age & int & 患者年龄 & 否 \\
\hline
Gender & string & 性别 & 否 \\
\hline
Contact & string & 联系电话 & 否 \\
\hline
Status & enum & 就诊状态 & 否 \\
\hline
\end{tabular}
\caption{Patient 属性表}
\end{table}
\subsubsection{就诊状态枚举}
\begin{lstlisting}
enum class PatientStatus {
Outpatient, // 门诊患者
Inpatient, // 住院患者
Discharged, // 已出院
Visited // 已就诊(门诊已完成诊断和用药)
};
\end{lstlisting}
\subsubsection{关键方法}
\begin{itemize}
\item \verb|updateBasicInfo()| - 更新患者基本信息
\item \verb|canBeRemoved()| - 检查是否可删除(住院中禁止删除)
\item \verb|nameMatches()| - 姓名模糊匹配查询
\item \verb|generateUniqueId()| - 生成 UUID
\item \verb|toJson()/fromJson()| - JSON 序列化接口
\end{itemize}
\subsection{医生实体Doctor}
\subsubsection{属性定义}
\begin{table}[h]
\centering
\begin{tabular}{|l|l|l|}
\hline
\textbf{属性名} & \textbf{类型} & \textbf{含义} \\
\hline
DoctorID & string & 医生唯一标识 (UUID) \\
\hline
Name & string & 医生姓名 \\
\hline
DepartmentID & string & 所属科室 ID \\
\hline
Title & enum & 医学职称 \\
\hline
Schedule & string & 出诊时间安排 \\
\hline
\end{tabular}
\caption{Doctor 属性表}
\end{table}
\subsubsection{医学职称枚举}
\begin{lstlisting}
enum class DoctorTitle {
Chief, // 主任医师
AssociateChief, // 副主任医师
Attending, // 主治医师
Resident // 住院医师
};
\end{lstlisting}
\subsection{科室实体Department}
\subsubsection{属性定义}
\begin{table}[h]
\centering
\begin{tabular}{|l|l|l|}
\hline
\textbf{属性名} & \textbf{类型} & \textbf{含义} \\
\hline
DepartmentID & string & 科室唯一标识 (UUID) \\
\hline
Name & string & 科室名称 \\
\hline
Description & string & 科室描述 \\
\hline
\end{tabular}
\caption{Department 属性表}
\end{table}
\subsubsection{关键方法}
\begin{itemize}
\item \verb|getDoctorsByDepartment()| - 获取科室下所有医生
\item \verb|getMedicinesByDepartment()| - 获取科室下所有药品
\item \verb|canDeleteDepartment()| - 检查是否可删除(有医生或药品时不能删)
\item \verb|getDoctorCountInDepartment()| - 获取科室下医生数量
\item \verb|getMedicineCountInDepartment()| - 获取科室下药品数量
\item \verb|getCheckCountInDepartment()| - 获取科室下检查项目数量
\end{itemize}
\subsection{药品实体Medicine}
\subsubsection{属性定义}
\begin{table}[h]
\centering
\begin{tabular}{|l|l|l|}
\hline
\textbf{属性名} & \textbf{类型} & \textbf{含义} \\
\hline
MedicineID & string & 药品唯一标识 (UUID) \\
\hline
GenericName & string & 通用名 \\
\hline
BrandName & string & 商品名 \\
\hline
Aliases & vector$<$string$>$ & 别名列表 \\
\hline
StockQuantity & int & 当前库存数量 \\
\hline
DepartmentID & string & 所属科室 ID \\
\hline
UnitPrice & double & 单价 \\
\hline
\end{tabular}
\caption{Medicine 属性表}
\end{table}
\subsubsection{关键方法}
\begin{itemize}
\item \verb|updateBasicInfo()| - 更新药品信息
\item \verb|nameMatches()| - 支持通用名、商品名及别名模糊匹配
\item \verb|decreaseStock()| - 减少库存(库存不足时失败)
\item \verb|increaseStock()| - 增加库存
\item \verb|addAlias()| - 添加别名
\end{itemize}
\subsection{检查项目实体Check}
\subsubsection{属性定义}
\begin{table}[h]
\centering
\begin{tabular}{|l|l|l|}
\hline
\textbf{属性名} & \textbf{类型} & \textbf{含义} \\
\hline
CheckID & string & 检查项目唯一标识 (UUID) \\
\hline
Name & string & 检查名称 \\
\hline
DepartmentID & string & 所属科室 ID \\
\hline
Price & double & 检查价格 \\
\hline
\end{tabular}
\caption{Check 属性表}
\end{table}
\subsection{病房与床位实体Ward \& Bed}
\subsubsection{Bed 结构}
\begin{table}[h]
\centering
\begin{tabular}{|l|l|l|}
\hline
\textbf{属性名} & \textbf{类型} & \textbf{含义} \\
\hline
BedID & string & 床位唯一标识 (UUID) \\
\hline
WardID & string & 所属病房 ID \\
\hline
Status & enum & 床位状态 \\
\hline
PatientID & string & 当前患者 ID空表示空闲 \\
\hline
\end{tabular}
\caption{Bed 属性表}
\end{table}
\subsubsection{Ward 结构}
\begin{table}[h]
\centering
\begin{tabular}{|l|l|l|}
\hline
\textbf{属性名} & \textbf{类型} & \textbf{含义} \\
\hline
WardID & string & 病房唯一标识 (UUID) \\
\hline
DepartmentID & string & 所属科室 ID \\
\hline
Type & enum & 病房类型 \\
\hline
MaxBeds & int & 最大床位数 \\
\hline
Beds & vector$<$Bed$>$ & 床位列表 \\
\hline
\end{tabular}
\caption{Ward 属性表}
\end{table}
\subsubsection{枚举定义}
\begin{lstlisting}
enum class WardType {
Normal, // 普通病房
Special, // 特殊病房
ICU // 重症监护室
};
enum class BedStatus {
Free, // 空闲
Occupied // 被占用
};
\end{lstlisting}
\subsubsection{Ward 关键方法}
\begin{itemize}
\item \verb|getFreeBedID()| - 获取第一个空闲床位
\item \verb|admitPatient()| - 为患者分配床位
\item \verb|releaseBed()| / \verb|releasePatient()| - 释放床位
\item \verb|addBed()| / \verb|removeBed()| - 增减床位
\item \verb|freeBedCount()| / \verb|occupiedBedCount()| - 床位统计
\item \verb|occupancyRate()| - 计算床位使用率
\end{itemize}
占用率计算公式:
$$\text{OccupancyRate} = \frac{\text{OccupiedBeds}}{\text{MaxBeds}}$$
\newpage
\section{病例与记录模型}
\subsection{患者病例PatientCase}
PatientCase 是聚合实体,记录患者的完整医疗历史。
\subsubsection{顶层属性}
\begin{table}[h]
\centering
\begin{tabular}{|l|l|l|}
\hline
\textbf{属性名} & \textbf{类型} & \textbf{含义} \\
\hline
PatientID & string & 患者 ID \\
\hline
DiagnosisRecords & vector & 诊断记录列表 \\
\hline
MedicineRecords & vector & 用药记录列表 \\
\hline
CheckRecords & vector & 检查记录列表 \\
\hline
AdmissionRecords & vector & 住院记录列表 \\
\hline
AppointmentRecords & vector & 预约记录列表 \\
\hline
CreatedTime & time\_t & 创建时间 \\
\hline
LastModifiedTime & time\_t & 最后修改时间 \\
\hline
\end{tabular}
\caption{PatientCase 属性表}
\end{table}
\subsection{诊断记录DiagnosisRecord}
\begin{table}[h]
\centering
\begin{tabular}{|l|l|l|}
\hline
\textbf{属性} & \textbf{类型} & \textbf{含义} \\
\hline
DoctorID & string & 诊断医生 ID \\
\hline
Diagnosis & string & 诊断内容 \\
\hline
Prescription & string & 处方(可选) \\
\hline
Remarks & string & 备注 \\
\hline
Timestamp & time\_t & 诊断时间戳 \\
\hline
\end{tabular}
\caption{DiagnosisRecord 属性}
\end{table}
\subsection{用药记录MedicineRecord}
\begin{table}[h]
\centering
\begin{tabular}{|l|l|l|}
\hline
\textbf{属性} & \textbf{类型} & \textbf{含义} \\
\hline
MedicineID & string & 药品 ID \\
\hline
MedicineName & string & 药品名称 \\
\hline
Quantity & int & 用药数量 \\
\hline
Usage & string & 用法说明 \\
\hline
UnitPrice & double & 单价 \\
\hline
DoctorID & string & 开药医生 ID \\
\hline
Timestamp & time\_t & 开药时间戳 \\
\hline
\end{tabular}
\caption{MedicineRecord 属性}
\end{table}
费用计算:$\text{TotalPrice} = \text{Quantity} \times \text{UnitPrice}$
\subsection{检查记录CheckRecord}
\begin{table}[h]
\centering
\begin{tabular}{|l|l|l|}
\hline
\textbf{属性} & \textbf{类型} & \textbf{含义} \\
\hline
CheckID & string & 检查 ID \\
\hline
CheckName & string & 检查名称 \\
\hline
DepartmentID & string & 归属科室 ID \\
\hline
Price & double & 检查价格 \\
\hline
DoctorID & string & 开单医生 ID \\
\hline
Timestamp & time\_t & 开单时间戳 \\
\hline
\end{tabular}
\caption{CheckRecord 属性}
\end{table}
\subsection{住院记录AdmissionRecord}
\begin{table}[h]
\centering
\begin{tabular}{|l|l|l|}
\hline
\textbf{属性} & \textbf{类型} & \textbf{含义} \\
\hline
WardID & string & 病房 ID \\
\hline
BedID & string & 床位 ID \\
\hline
AdmissionTime & time\_t & 入院时间 \\
\hline
DischargeTime & time\_t & 出院时间0 = 未出院) \\
\hline
Reason & string & 住院原因 \\
\hline
DischargeSummary & string & 出院小结 \\
\hline
\end{tabular}
\caption{AdmissionRecord 属性}
\end{table}
判断当前是否住院:\verb|isCurrentlyAdmitted()| 返回 \verb|DischargeTime == 0|。
\subsection{预约记录AppointmentRecord}
\begin{table}[h]
\centering
\begin{tabular}{|l|l|l|}
\hline
\textbf{属性} & \textbf{类型} & \textbf{含义} \\
\hline
DoctorID & string & 医生 ID \\
\hline
PatientID & string & 患者 ID \\
\hline
AppointmentDate & string & 预约日期YYYY-MM-DD \\
\hline
Notes & string & 备注 \\
\hline
Timestamp & time\_t & 创建时间 \\
\hline
\end{tabular}
\caption{AppointmentRecord 属性}
\end{table}
\newpage
\section{支付与结算模型}
\subsection{支付记录Payment}
\subsubsection{属性定义}
\begin{table}[h]
\centering
\begin{tabular}{|l|l|l|}
\hline
\textbf{属性名} & \textbf{类型} & \textbf{含义} \\
\hline
PaymentID & string & 支付唯一标识 (UUID) \\
\hline
PatientID & string & 患者 ID \\
\hline
Amount & double & 支付金额 \\
\hline
Method & enum & 支付方式 \\
\hline
PaymentType & string & 支付类型(挂号/检查/用药等) \\
\hline
OperationID & string & 关联的操作 ID \\
\hline
PaymentTime & time\_t & 支付时间 \\
\hline
Status & string & 状态Pending/Completed/Failed/Refunded \\
\hline
Description & string & 支付描述 \\
\hline
\end{tabular}
\caption{Payment 属性表}
\end{table}
\subsubsection{支付方式枚举}
\begin{lstlisting}
enum class PaymentMethod {
Cash, // 现金
CreditCard, // 信用卡
MobilePayment, // 移动支付(微信/支付宝)
HealthInsurance // 医保
};
\end{lstlisting}
\subsection{结算单Settlement}
\subsubsection{结算明细项SettlementItem}
\begin{table}[h]
\centering
\begin{tabular}{|l|l|l|}
\hline
\textbf{属性名} & \textbf{类型} & \textbf{含义} \\
\hline
ItemName & string & 项目名称 \\
\hline
ItemType & string & 项目类型 \\
\hline
OperationID & string & 关联操作 ID \\
\hline
Quantity & double & 数量 \\
\hline
UnitPrice & double & 单价 \\
\hline
Amount & double & 金额 \\
\hline
PaymentMethod & string & 支付方式 \\
\hline
\end{tabular}
\caption{SettlementItem 属性表}
\end{table}
\subsubsection{Settlement 属性}
\begin{table}[h]
\centering
\begin{tabular}{|l|l|l|}
\hline
\textbf{属性名} & \textbf{类型} & \textbf{含义} \\
\hline
SettlementID & string & 结算单唯一标识 (UUID) \\
\hline
PatientID & string & 患者 ID \\
\hline
PatientName & string & 患者姓名 \\
\hline
DischargeDate & string & 出院日期 \\
\hline
SettlementTime & time\_t & 结算时间 \\
\hline
Items & vector$<$SettlementItem$>$ & 费用明细列表 \\
\hline
TotalAmount & double & 医疗总费用 \\
\hline
InsurancePaid & double & 医保支付金额 \\
\hline
PatientPaid & double & 患者自付金额 \\
\hline
Status & string & 状态Pending/Completed/Settled \\
\hline
Notes & string & 备注 \\
\hline
\end{tabular}
\caption{Settlement 属性表}
\end{table}
\newpage
\section{全局上下文与组合根}
\subsection{HisContext全局数据容器}
HisContext 是系统的数据容器,持有所有实体的 LinkedList作为各服务类的共享数据源。
\begin{lstlisting}
namespace core {
class HisContext {
public:
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;
};
}
\end{lstlisting}
\subsection{HisCore组合根}
HisCore 集中组装所有服务和上下文,是系统的入口点。
\begin{lstlisting}
namespace core {
class HisCore {
public:
HisCore();
bool loadDataFromFolder(const std::string& dataFolder, std::string& outError);
void fixDepartmentReferences();
HisContext ctx_;
WardService wardService;
PatientService patientService;
PatientCaseService patientCaseService;
ReportService reportService;
DoctorService doctorService;
MedicineService medicineService;
CheckService checkService;
DepartmentService departmentService;
PaymentService paymentService;
SettlementService settlementService;
PaymentManagementService paymentManagementService;
};
}
\end{lstlisting}
\newpage
\section{业务逻辑层:服务类}
\subsection{患者服务PatientService}
\begin{itemize}
\item 患者的 CRUD 操作(增删改查)
\item 患者状态管理(门诊/住院/已出院/已就诊)
\item 住院分配与出院释放床位流程
\item 多维度查询:按 ID、姓名、联系方式模糊搜索
\end{itemize}
\subsection{医生服务DoctorService}
\begin{itemize}
\item 医生信息的 CRUD 操作
\item 按科室遍历医生
\item 模糊搜索(姓名/科室/职称/排班)
\end{itemize}
\subsection{药品服务MedicineService}
\begin{itemize}
\item 药品库存管理CRUD
\item 名称模糊匹配(通用名/商品名/别名)
\item 入库增加库存 / 出库减少库存(库存不足时失败)
\end{itemize}
\subsection{病房服务WardService}
\begin{itemize}
\item 病房和床位的 CRUD 操作
\item 病房数据的持久化JSON 文件 load/save
\item 床位分配和回收管理
\end{itemize}
\subsection{检查项目服务CheckService}
\begin{itemize}
\item 检查项目的 CRUD 操作
\item 按名称模糊搜索
\item 创建时自动生成 UUID
\end{itemize}
\subsection{科室服务DepartmentService}
\begin{itemize}
\item 科室的 CRUD 操作
\item 获取科室下的医生、药品、检查项目列表
\item 删除前检查依赖(有医生或药品时不能删除)
\item 统计科室下各类资源数量
\end{itemize}
\subsection{患者病例服务PatientCaseService}
\begin{itemize}
\item 管理患者的完整医疗记录(诊断/用药/检查/住院/预约)
\item 患者出院流程处理
\item 医疗统计(费用计算、记录数统计)
\end{itemize}
\subsection{支付服务PaymentService}
\begin{itemize}
\item 创建支付记录(支持多种支付方式)
\item 查询支付记录(按患者、按类型)
\item 更新支付状态(完成/退款)
\item 获取患者总支付金额
\end{itemize}
\subsection{结算服务SettlementService}
\begin{itemize}
\item 为患者生成结算单(出院时自动生成)
\item 添加费用项到结算单
\item 计算结算总额(总费用/医保/自付)
\item 完成结算、生成结算单报告
\end{itemize}
\subsection{支付管理服务PaymentManagementService}
\begin{itemize}
\item 支付记录管理(按状态/日期范围过滤)
\item 支付统计(总收入/已完成/待支付/已退款)
\item 支付方式统计(按 Cash/CreditCard/MobilePayment/HealthInsurance 分类)
\item 今日/本月支付统计
\item 结算单管理(按状态/患者过滤、搜索)
\item 报表生成(日报/月报/收入报表/患者账单)
\item 收入趋势数据(每日/每月/按类型)
\item 异常支付检测与退款处理
\end{itemize}
\subsection{报表服务ReportService}
\begin{itemize}
\item 病房床位使用率计算
\end{itemize}
\newpage
\section{工具层}
\subsection{Logger日志系统}
\begin{itemize}
\item 支持 12 种日志类型Shell命令/患者操作/医生操作/药品操作/病房操作/诊断/用药/住院/出院/检查/系统事件等)
\item 可配置日志格式(占位符:\{time\}, \{type\}, \{command\}, \{details\}, \{objectId\}
\item 支持控制台输出和文件输出
\item 提供专用日志方法:\verb|logShellCommand()|, \verb|logPatientOperation()|, \verb|logDiagnosisRecord()| 等
\item 支持导出日志到文件、清空日志缓冲区
\end{itemize}
\subsection{FileManager文件管理}
为所有实体类型提供统一的文件读写操作:
\begin{itemize}
\item 基础文件操作:\verb|readTextFile()|, \verb|writeTextFile()|, \verb|createFile()|, \verb|deleteFile()|
\item JSON 字段删除:\verb|deleteJsonField()|
\item 所有 9 种实体的 \verb|loadXxxListFromFile()| 和 \verb|saveXxxListToFile()| 方法
\end{itemize}
\subsection{UUID唯一标识符生成器}
生成符合 RFC 4122 标准的 UUID v4
\begin{itemize}
\item \verb|generate()| - 标准格式xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
\item \verb|generateShort()| - 无连字符格式
\item \verb|isValid()| - 格式校验
\item \verb|toShort()| / \verb|fromShort()| - 格式转换
\end{itemize}
\subsection{E2hangJson自定义 JSON 库)}
\begin{itemize}
\item JsonValueJSON 值表示(对象、数组、字符串、数字、布尔值)
\item JsonParseJSON 解析器
\item JsonSerializerJSON 序列化器
\item JsonErrorJSON 错误处理
\end{itemize}
\newpage
\section{用户界面层}
\subsection{CLI 命令行界面ReplShell}
基于命令行的交互式 Shell支持所有核心操作。主要命令分类如下
\subsubsection{患者管理}
\begin{itemize}
\item \verb|patient add| / \verb|update| / \verb|rm| / \verb|list| / \verb|search|
\item \verb|patient load| / \verb|save|
\item \verb|patient admit| / \verb|release bed| / \verb|release patient|
\end{itemize}
\subsubsection{医生管理}
\begin{itemize}
\item \verb|doctor add| / \verb|rm| / \verb|list| / \verb|search|
\item \verb|doctor list dept| / \verb|search name| / \verb|search dept| / \verb|search title|
\item \verb|doctor load| / \verb|save|
\end{itemize}
\subsubsection{药品管理}
\begin{itemize}
\item \verb|medicine add| / \verb|list| / \verb|find|
\item \verb|medicine stock inc| / \verb|dec|
\item \verb|medicine load| / \verb|save|
\end{itemize}
\subsubsection{病房管理}
\begin{itemize}
\item \verb|ward add| / \verb|rm| / \verb|list| / \verb|show|
\item \verb|ward bed add| / \verb|rm|
\end{itemize}
\subsubsection{检查项目管理}
\begin{itemize}
\item \verb|check add| / \verb|list| / \verb|find|
\item \verb|check load| / \verb|save|
\end{itemize}
\subsubsection{科室管理}
\begin{itemize}
\item \verb|department add| / \verb|rm| / \verb|list|
\item \verb|department load| / \verb|save|
\end{itemize}
\subsubsection{病例管理}
\begin{itemize}
\item \verb|case diagnosis add| / \verb|case medicine add| / \verb|case check add|
\item \verb|case admission add| / \verb|case discharge| / \verb|case appointment add|
\item \verb|case view| / \verb|case stats|
\end{itemize}
\subsubsection{支付与结算}
\begin{itemize}
\item \verb|payment create| / \verb|list| / \verb|complete| / \verb|refund| / \verb|search|
\item \verb|settlement generate| / \verb|list| / \verb|view| / \verb|complete|
\end{itemize}
\subsubsection{日志与系统}
\begin{itemize}
\item \verb|log view| / \verb|export| / \verb|clear|
\item \verb|help| / \verb|exit| / \verb|save| / \verb|load|
\end{itemize}
\subsection{GUI 图形界面MainWindow}
基于 Qt6 的图形界面,提供多标签页和角色视角切换。
\subsubsection{视角枚举ViewRole}
\begin{table}[h]
\centering
\begin{tabular}{|l|l|l|}
\hline
\textbf{视角} & \textbf{说明} & \textbf{可见功能} \\
\hline
Admin & 管理视角 & 所有功能 \\
\hline
Patient & 病人视角 & 只能查看医生信息 \\
\hline
Medical & 医护视角 & 患者、医生、药品、检查、病例管理 \\
\hline
\end{tabular}
\caption{GUI 视角枚举}
\end{table}
\subsubsection{主要标签页}
\begin{table}[h]
\centering
\begin{tabular}{|l|l|l|}
\hline
\textbf{标签页} & \textbf{主要组件} & \textbf{功能} \\
\hline
仪表盘 & summaryLabel & 系统统计信息 \\
\hline
病房管理 & wardTreeView, wardTable & 树形浏览、床位管理 \\
\hline
患者管理 & patientTable & 列表、搜索、增删改查 \\
\hline
医生管理 & doctorTable & 列表、搜索、增删 \\
\hline
药品管理 & medicineTable & 列表、搜索、库存管理 \\
\hline
检查管理 & checkTable & 列表、搜索、增删改 \\
\hline
科室管理 & departmentTable & 列表、搜索、详情查看 \\
\hline
日志管理 & logDisplay & 日志查看、导出、清除 \\
\hline
\end{tabular}
\caption{GUI 标签页组件}
\end{table}
\subsubsection{对话框组件}
\begin{itemize}
\item \textbf{PatientDialog} - 患者信息编辑对话框
\item \textbf{DepartmentDetailDialog} - 科室详情(显示科室下医生、药品、检查项目)
\item \textbf{PaymentDialog} - 支付对话框
\item \textbf{PaymentManagementDialog} - 支付管理(统计、报表、图表)
\item \textbf{SettlementDialog} - 结算对话框
\end{itemize}
\newpage
\section{系统核心交互流程图}
\begin{center}
\begin{tikzpicture}[
node distance=1.2cm,
every node/.style={
draw,
rectangle,
rounded corners,
minimum width=2cm,
minimum height=1.0cm,
align=center,
font=\small
},
arrow/.style={->, thick},
dashedarrow/.style={->, dashed}
]
% 主流程
\node (patient) {Patient\\患者};
\node (record) [right=of patient] {PatientCase\\患者病例};
\node (doctor) [right=of record] {Doctor\\医生};
\node (dept) [right=of doctor] {Department\\科室};
% 住院分支(上)
\node (ward) [above=of doctor, yshift=1cm] {Ward\\病房};
\node (bed) [right=of ward] {Bed\\床位};
% 药房分支(下左)
\node (medicine) [below=of doctor, yshift=-1cm] {Medicine\\药品};
\node (pharmacy) [right=of medicine] {Pharmacy\\药房};
% 检查分支(下右)
\node (check) [below=of dept, yshift=-1cm] {Check\\检查项目};
% 支付结算层(最右)
\node (payment) [right=3.5cm of dept, yshift=0.5cm] {Payment\\支付};
\node (settle) [right=3.5cm of dept, yshift=-0.5cm] {Settlement\\结算};
% 报表
\node (report) [below=2cm of payment] {Report\\统计报表};
% 主链路
\draw[arrow] (patient) -- node[above, draw=none]{就诊/挂号} (record);
\draw[arrow] (record) -- node[above, draw=none]{分配医生} (doctor);
\draw[arrow] (doctor) -- node[above, draw=none]{隶属} (dept);
% 住院流程
\draw[arrow] (record) -- node[right, draw=none]{住院触发} (ward);
\draw[arrow] (ward) -- node[above, draw=none]{床位分配} (bed);
\draw[arrow] (bed) |- node[pos=0.25,right, draw=none]{绑定患者} (patient);
% 药房流程
\draw[arrow] (record) -- node[right, draw=none]{开处方} (medicine);
\draw[arrow] (medicine) -- node[above, draw=none]{发药} (pharmacy);
% 检查流程
\draw[arrow] (record) -- node[right, draw=none]{开检查单} (check);
% 支付结算
\draw[arrow] (pharmacy.east) -| (payment.west);
\draw[arrow] (check.east) -| (payment.west);
\draw[arrow] (dept.east) -- (payment.west);
\draw[arrow] (payment) -- node[right, draw=none]{出院结算} (settle);
% 报表汇总
\draw[dashedarrow] (patient.south) to[out=290, in=250, looseness=0.6] (report.south);
\draw[dashedarrow] (doctor.north) to[out=70, in=135] (report.north west);
\draw[dashedarrow] (payment.south) -- (report.north);
\draw[dashedarrow] (settle.south) -- (report.north);
% 分组背景
\begin{scope}[on background layer]
\node[draw=blue!30, fill=blue!5, rounded corners, fit=(patient)(record)(doctor)(dept), label=above:{\textbf{门诊诊疗主流程}}] {};
\node[draw=green!30, fill=green!5, rounded corners, fit=(ward)(bed), label=above:{\textbf{住院管理子系统}}] {};
\node[draw=red!30, fill=red!5, rounded corners, fit=(medicine)(pharmacy), label=below:{\textbf{药房管理子系统}}] {};
\node[draw=purple!30, fill=purple!5, rounded corners, fit=(check), label=below:{\textbf{检查管理}}] {};
\node[draw=orange!30, fill=orange!5, rounded corners, fit=(payment)(settle), label=above:{\textbf{支付结算子系统}}] {};
\node[draw=gray!40, fill=gray!10, rounded corners, fit=(report), label=below:{\textbf{统计分析}}] {};
\end{scope}
\end{tikzpicture}
\end{center}
\newpage
\section{关键业务流程}
\subsection{患者完整就诊流程}
\begin{enumerate}
\item 患者注册:\verb|PatientService.addPatient()| 或 GUI 添加,状态为 Outpatient
\item 挂号预约:\verb|PatientCaseService.addAppointmentRecord()| 创建预约记录
\item 医生诊断:\verb|PatientCaseService.addDiagnosisRecord()| 添加诊断记录
\item 开药:\verb|PatientCaseService.addMedicineRecord()| 添加用药记录,同时 \verb|MedicineService.decreaseStock()| 扣减库存
\item 开检查:\verb|PatientCaseService.addCheckRecord()| 添加检查记录
\item 支付:\verb|PaymentService.createPayment()| 创建支付记录
\item 如需住院:\verb|PatientService.admitPatient()| 分配床位,状态改为 Inpatient
\item 出院:\verb|PatientCaseService.dischargePatient()| 填写出院小结,\verb|SettlementService.generateSettlement()| 生成结算单
\item 结算完成:\verb|SettlementService.completeSettlement()| 完成结算,患者状态改为 Discharged
\end{enumerate}
\subsection{住院管理流程}
\begin{enumerate}
\item 查找可用病房和空闲床位:\verb|Ward.getFreeBedID()|
\item 分配床位:\verb|Ward.admitPatient()| 绑定患者到床位
\item 更新患者状态为 Inpatient
\item 住院期间可继续添加诊断、用药、检查记录
\item 出院时:释放床位 \verb|Ward.releasePatient()|,更新患者状态为 Discharged
\end{enumerate}
\subsection{处方与药物管理流程}
\begin{enumerate}
\item 医生开具处方:\verb|PatientCaseService.addMedicineRecord()|
\item 系统记录药品 ID、数量、用法、单价
\item 自动扣减库存:\verb|MedicineService.decreaseStock()|(库存不足时拒绝)
\item 计算费用:\verb|Quantity $\times$ UnitPrice|
\item 查询患者总药费:\verb|PatientCase.getTotalMedicineCost()|
\end{enumerate}
\subsection{支付与结算流程}
\begin{enumerate}
\item 创建支付:\verb|PaymentService.createPayment()| 记录支付方式、金额、类型
\item 完成支付:\verb|PaymentService.completePayment()| 更新状态为 Completed
\item 出院时自动生成结算单:\verb|SettlementService.generateSettlement()|
\item 结算单汇总所有费用(用药/检查/住院等),区分医保支付和患者自付
\item 完成结算:\verb|SettlementService.completeSettlement()|
\item 管理端可查看统计报表:\verb|PaymentManagementService.getPaymentStatistics()|
\end{enumerate}
\newpage
\section{数据持久化}
\subsection{JSON 序列化策略}
所有数据模型均支持 JSON 序列化,通过 \verb|toJson()| 和 \verb|fromJson()| 接口实现。数据以 JSON 数组格式存储于 TXT 文件中。
\subsection{数据文件清单}
\begin{table}[h]
\centering
\begin{tabular}{|l|l|}
\hline
\textbf{文件路径} & \textbf{存储内容} \\
\hline
\verb|data/patients.txt| & 患者数据 \\
\hline
\verb|data/doctors.txt| & 医生数据 \\
\hline
\verb|data/medicines.txt| & 药品数据 \\
\hline
\verb|data/wards.txt| & 病房数据 \\
\hline
\verb|data/checks.txt| & 检查项目数据 \\
\hline
\verb|data/departments.txt| & 科室数据 \\
\hline
\verb|data/patient_cases.txt| & 患者病例数据 \\
\hline
\verb|data/payments.txt| & 支付记录数据 \\
\hline
\verb|data/settlements.txt| & 结算单数据 \\
\hline
\end{tabular}
\caption{数据文件清单}
\end{table}
\subsection{加载与保存策略}
遵循"启动时全量挂载,执行关键操作或退出时序列化落盘"的策略。
\begin{itemize}
\item CLI 模式:\verb|load| / \verb|save| 命令加载/保存所有数据;也可单独加载/保存某类数据
\item GUI 模式:启动时自动从 data/ 文件夹加载;点击保存按钮保存所有数据
\end{itemize}
\section{编译与运行}
\subsection{环境要求}
\begin{itemize}
\item C++20 兼容编译器GCC 10+ / Clang 12+ / MSVC 2019+
\item CMake 3.16+
\item Qt6Widgets, Charts 组件)
\end{itemize}
\subsection{编译步骤}
\begin{lstlisting}[language=bash]
mkdir -p build
cd build
cmake ..
make -j4
\end{lstlisting}
\subsection{运行方式}
\begin{lstlisting}[language=bash]
# 交互式 CLI Shell
./his
# 无 Shell 模式(仅加载数据)
./his --noshell
# GUI 图形界面
./his_gui
# 批处理模式(管道输入)
printf "patient load ../data/patients.txt\ncase view p1001\nexit\n" | ./his
\end{lstlisting}
\newpage
\section{实体关系图}
\begin{verbatim}
Patient (患者)
├── 1:1 ──> PatientCase (患者病例)
│ ├── 1:n ──> DiagnosisRecord (诊断记录)
│ ├── 1:n ──> MedicineRecord (用药记录)
│ ├── 1:n ──> CheckRecord (检查记录)
│ ├── 1:n ──> AdmissionRecord (住院记录)
│ └── 1:n ──> AppointmentRecord (预约记录)
├── M:1 ──> Ward (病房) ──> 1:n ──> Bed (床位)
├── 1:n ──> Payment (支付记录)
└── 1:n ──> Settlement (结算单) ──> 1:n ──> SettlementItem (结算明细)
Doctor (医生)
└── M:1 ──> Department (科室)
Medicine (药品)
└── M:1 ──> Department (科室)
Check (检查项目)
└── M:1 ──> Department (科室)
Ward (病房)
└── M:1 ──> Department (科室)
\end{verbatim}
\section{设计模式与最佳实践}
\subsection{采用的设计模式}
\begin{itemize}
\item \textbf{Repository Pattern}LinkedList + HisContext 作为数据仓储
\item \textbf{Service Pattern}:各 Service 类实现业务逻辑分离
\item \textbf{Composition Root}HisCore 集中管理依赖注入
\item \textbf{DTO Pattern}:通过 toJson()/fromJson() 实现数据传输对象
\item \textbf{Template Method}:链表的泛型操作模板
\item \textbf{Observer Pattern}Logger 记录所有关键操作
\end{itemize}
\subsection{业务规则}
\begin{itemize}
\item 患者在住院状态中禁止删除(\verb|Patient.canBeRemoved()|
\item 药品库存不得为负(\verb|MedicineService.decreaseStock()| 库存不足时返回 false
\item 同一物理床位同一时间仅能属于一名患者
\item 办理住院时无空闲床位则业务拒绝
\item 科室下有医生或药品时不能删除该科室
\item 出院记录必须包含出院小结
\item 所有实体使用 UUID 作为唯一标识
\end{itemize}
\section{总结}
HIS 医院信息管理系统通过精心设计的数据结构和分层架构,实现了医院信息管理的核心功能:
\begin{enumerate}
\item \textbf{高效的数据操作}:通过 LinkedList 混合结构提供 $O(1)$ 的查找、插入和删除
\item \textbf{完整的数据模型}:覆盖患者、医生、药品、病房、检查项目、科室、病例、支付、结算 9 大实体
\item \textbf{清晰的业务流程}:从患者挂号、诊疗、检查、开药到住院、出院、支付、结算的完整流程
\item \textbf{双界面支持}CLI 命令行 + Qt6 GUI 图形界面,适配不同使用场景
\item \textbf{多角色视角}GUI 支持管理/病人/医护三种权限视图
\item \textbf{完善的支付结算}:支持多种支付方式、医保结算、财务报表和统计图表
\item \textbf{灵活的扩展性}Service 层设计使系统易于扩展新功能
\item \textbf{数据持久化}JSON 序列化支持数据的保存和恢复
\end{enumerate}
系统的核心优势在于数据结构设计的平衡性——通过链表+哈希表的混合使用,既保证了查询效率,又支持了灵活的数据遍历和修改操作。
\appendix
\section{数据结构时间复杂度对比}
\begin{table}[h]
\centering
\begin{tabular}{|l|c|c|c|}
\hline
\textbf{操作} & \textbf{LinkedList} & \textbf{普通 Vector} & \textbf{HashMap} \\
\hline
查找 & $O(1)$ & $O(n)$ & $O(1)$ \\
\hline
插入 & $O(1)$ & $O(n)$ & $O(1)$ \\
\hline
删除 & $O(1)$ & $O(n)$ & $O(1)$ \\
\hline
遍历 & $O(n)$ & $O(n)$ & $O(n)$ \\
\hline
\end{tabular}
\caption{数据结构性能对比}
\end{table}
\end{document}