Files
HIS-GUI/docs/ReadmeA/ReadmeA.tex
2026-04-01 14:33:14 +08:00

1226 lines
45 KiB
TeX
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}
% --- 字体设置 (来自文件2) ---
% 【修复:由于非 Windows 系统(如 Overleaf)通常没有 SimSun 字体直接调用会导致报错。已将其注释。ctexart 会自动适配环境自带的中文字体】
% \setCJKmainfont{SimSun}
% \setCJKmonofont{SimSun}
% --- 全局排版优化 (来自文件1) ---
\emergencystretch=3em
\setlist{nosep, leftmargin=2em}
% --- 文件1 代码块样式设置 ---
\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
}
% --- 文件2 标题设置 ---
\title{医院信息系统HIS\\数据结构与系统架构说明文档}
\author{代码分析}
\date{\today}
\begin{document}
% ==========================================
% 全局目录
% ==========================================
\tableofcontents
\newpage
% ==========================================
% 第一部分HIS 医疗管理系统设计说明书来自文件1
% ==========================================
% --- 标题部分 ---
\begin{center}
{\LARGE \textbf{《HIS 医疗管理系统设计说明书2025级}}\\
\vspace{0.5em}
{\large (需求功能与系统约定)}
\vspace{1em}
\end{center}
% --- 正文部分 ---
\section{系统概述与设计目标}
本系统为一个面向小型医院的轻量级医疗信息管理系统Hospital Information System, HIS采用 C++ 纯链表实现。通过模块化设计,实现业务逻辑与交互界面的解耦,保障系统的高扩展性与可维护性。
\begin{itemize}
\item \textbf{业务闭环}:实现完整的挂号、诊疗、检查、住院、开药等医疗生命周期。
\item \textbf{数据规模}:支持至少 100 名门诊患者、30 名住院患者、20 名医生、5 个科室及 20 类药品。
\item \textbf{底层要求}:全程基于手写\textbf{链表}实现内存数据流转采用文本文件JSON数组持久化。
\item \textbf{鲁棒性}:具备极强的异常拦截能力,从容应对测试工程师的极端输入场景(防崩溃设计)。
\end{itemize}
\section{系统架构与项目目录结构}
系统采用分层架构设计CLI交互层 $\rightarrow$ Service逻辑层 $\rightarrow$ Model实体层 $\rightarrow$ Storage持久层
\begin{itemize}
\item \textbf{CLI层}:命令解析与结果输出
\item \textbf{Service层}:业务规则处理
\item \textbf{Model层}:数据结构定义
\item \textbf{Storage层}:数据存储与文件持久化
\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=2.8cm,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=2.8cm,align=center},
edge/.style={->,thick}
]
% 层
\node[box] (repl) {CLI 层 \\ \texttt{ReplShell}};
\node[svc, below=1.2cm of repl] (wardsvc) {服务层 \\ \texttt{WardService} \\ \texttt{DoctorService} \\ \texttt{MedicineService}};
\node[data, below=1.2cm of wardsvc] (ctx) {内存上下文 \\ \texttt{HisContext}};
\node[box, below=1.2cm of ctx] (list) {通用数据结构 \\ \texttt{LinkedList<Key, Value>}};
% 模型
\node[data, right=3.4cm of ctx] (models) {实体模型 \\ \texttt{Ward}, \texttt{Doctor}, \texttt{Medicine}};
% 关系
\draw[edge] (repl) -- (wardsvc);
\draw[edge] (wardsvc) -- (ctx);
\draw[edge] (ctx) -- (list);
\draw[edge] (wardsvc.east) .. controls +(right:7mm) and +(up:7mm) .. (models.east);
\draw[edge] (ctx.east) -- (models.east);
% 文件管理
\node[box, left=3cm of ctx] (filemgr) {持久化模块 \\ \texttt{FileManager}};
\draw[edge] (wardsvc.west) -- (filemgr.east);
% 说明
\node[below=0.4cm of list] (note) {\texttt{load} 逻辑:\texttt{WardService} 先清空 \texttt{HisContext.wards} 再读文件填充,通常不造成累积内存泄漏。};
\end{tikzpicture}
\caption{HIS 系统模块架构图}
\end{figure}
\newpage
项目工程文件结构如下:
\begin{lstlisting}[language=bash]
his-project/
├── CMakeLists.txt # 根构建配置
├── data/ # 原始数据目录(评测时展示的文件)
│ ├── patients.txt # 【存储JSON数组的文本文件】至少30条记录
│ ├── doctors.txt
│ ├── wards.txt # 病房信息
│ └── medicines.txt # 药品库
├── include/ # 头文件目录 (.h / .hpp)
│ ├── models/ # 1. 纯数据实体层 (Entity)
│ │ ├── patient.h
│ │ ├── doctor.h
│ │ └── medicine.h
│ ├── utils/ # 2. 底层工具与驱动层
│ │ ├── linked_list.hpp # 【核心】全手写的泛型链表 template<T>
│ │ ├── file_manager.h # 文件读写封装
│ │ └── e2hang_json.h # 你的 C++20 JSON 解析库头文件
│ ├── core/ # 3. 核心业务层 (his-core)
│ │ ├── his_context.h # 全局上下文(持有所有内存链表的实例)
│ │ ├── patient_service.h # 处理挂号、看诊等纯逻辑
│ │ └── report_service.h # 报表统计算法
│ └── cli/ # 4. 交互表现层 (his-cli)
│ ├── repl_shell.h # 交互式命令行主循环
│ └── format_printer.h # 负责把链表数据打印成漂亮的 ASCII 表格
├── src/ # 源文件目录 (.cpp) => 源文件目录 (实现)
│ ├── main.cpp # 程序唯一入口初始化、启动REPL和退出保存
│ ├── models/ # 实体类方法实现
│ │ ├── patient.cpp # 患者属性操作及 JSON 序列化实现
│ │ ├── doctor.cpp # 医生属性操作
│ │ ├── ward.cpp # 病房/床位逻辑实现
│ │ └── medicine.cpp # 药品多名称匹配逻辑实现
│ ├── core/ # his-core核心业务实现 (无输入输出)
│ │ ├── his_context.cpp # 全局单例:管理所有内存链表的加载与保存
│ │ ├── patient_service.cpp # 实现挂号、诊疗记录、病历生成逻辑
│ │ ├── inpatient_service.cpp # 实现住院分配、床位流转逻辑
│ │ ├── pharmacy_service.cpp # 实现处方发药、库存增减、入库逻辑
│ │ └── report_service.cpp # 实现多维度报表统计与数据分析算法
│ ├── utils/ # 基础设施实现
│ │ ├── file_manager.cpp # 处理 .txt 文件的物理读写
│ │ ├── input_sanitizer.cpp # 【鲁棒性核心】针对测试工程师的输入清洗
│ │ └── e2hang_json.cpp # 你的 C++20 JSON 解析库实现
│ └── cli/ # his-cli命令行交互实现
│ ├── repl_shell.cpp # 交互式 Shell 主循环 (REPL)
│ ├── command_parser.cpp # 指令分发器:将输入映射到 Service 函数
│ └── table_printer.cpp # 美化工具:将结果格式化为 ASCII 表格
└── tests/ # 测试用例目录
├── test_linked_list.cpp # 必须先确保链表绝对可靠
└── test_core_logic.cpp # 灌入异常数据测试业务层鲁棒性
\end{lstlisting}
\section{数据实体与约定}
\subsection{通用数据约定}
\begin{itemize}
\item \textbf{唯一性}:所有系统实体均采用\textbf{唯一ID}作为数据主标识。
\item \textbf{宽容性}\textbf{允许患者姓名重复},系统必须在底层支持重名/同名情况下的精准区分。
\item \textbf{存储规约}:所有内存态数据全程挂载并依托于\textbf{自定义泛型链表}进行流转;数据的磁盘持久化统一采用 \textbf{JSON 数组}格式存储于对应的 TXT 文件中。
\end{itemize}
\subsection{患者Patient}
\begin{itemize}
\item \textbf{实体属性}PatientID唯一主键、姓名、年龄、性别、联系方式、当前状态门诊 / 住院 / 已出院)。
\item \textbf{系统约定}:一名患者的生命周期内可对应多条医疗记录;系统查询接口必须支持按患者姓名的\textbf{模糊查询}
\end{itemize}
\subsection{医生Doctor}
\begin{itemize}
\item \textbf{实体属性}DoctorID唯一主键、姓名、所属科室ID、职称主任 / 副主任 / 主治 / 住院医师)、出诊时间安排。
\item \textbf{系统约定}:每位医生有且仅隶属于一个明确的科室;为保证医院各科室的接诊流转能力,约定\textbf{每个科室至少包含3名注册医生}
\end{itemize}
\subsection{科室Department}
\begin{itemize}
\item \textbf{实体属性}DepartmentID唯一主键、科室名称。
\end{itemize}
\subsection{医疗记录MedicalRecord【核心】}
\begin{itemize}
\item \textbf{实体属性}RecordID唯一主键、关联的 PatientID、关联的 DoctorID、业务类型挂号 / 看诊 / 检查 / 住院)、发生时间、详细结构化信息。
\item \textbf{系统约定}:一条合法的医疗记录\textbf{必须同时强关联}当前存在的患者与医生;为保障防篡改性与溯源严肃性,医疗记录\textbf{不可直接修改},必须采用“撤销废除 + 重建新单”的机制。
\end{itemize}
\subsection{病房与床位Ward \& Bed}
\begin{itemize}
\item \textbf{病房属性}WardID唯一主键、病房类型普通 / 特殊 / ICU等、关联科室ID、最大床位容量。
\item \textbf{床位属性}BedID唯一主键、所属病房ID、当前状态空闲 / 已占用、绑定的患者ID。
\item \textbf{系统约定}:同一时间段内,一个物理床位\textbf{仅能属于一名患者};系统须支持基于患者住院/出院动作的\textbf{床位动态分配与自动释放}
\end{itemize}
\subsection{药品Medicine}
\begin{itemize}
\item \textbf{实体属性}MedicineID唯一主键、通用名、商品名、别名、当前库存数量、所属科室、单价。
\item \textbf{系统约定}:检索接口必须支持\textbf{多名称混合匹配};在处方发药与出库操作中引入强校验拦截,任何情况下\textbf{药品库存均不得为负}
\end{itemize}
\newpage
\section{核心功能需求}
\subsection{数据管理功能}
\begin{itemize}
\item \textbf{1增加操作}
\begin{itemize}
\item \textbf{操作对象}:添加患者、医生、医疗记录、药品信息。
\item \textbf{约束要求}:支持单条命令行输入与 TXT 文件批量导入;自动校验合法性。
\end{itemize}
\item \textbf{2修改操作}
\begin{itemize}
\item \textbf{操作对象}:支持修改患者基本信息、修改药品属性信息。
\item \textbf{业务约定}:医疗记录属于核心溯源数据,\textbf{不可直接修改}
\end{itemize}
\item \textbf{3删除操作}
\begin{itemize}
\item \textbf{操作对象}:删除患者档案、删除医疗记录、删除下架药品。
\item \textbf{业务约束}:必须进行严谨的\textbf{依赖检查}(例如:若患者当前仍在住院,则系统必须拦截并拒绝删除操作)。
\end{itemize}
\end{itemize}
\subsection{查询功能}
系统需支持灵活的多维度数据检索:
\begin{itemize}
\item \textbf{按患者查询}:查询指定患者完整的历史就诊记录与生命周期。
\item \textbf{按医生查询}:查询特定医生的挂号列表与诊疗情况。
\item \textbf{按科室查询}:查询该科室的人员构成与整体运转信息。
\item \textbf{按药品查询}:根据名称查询药品的实时库存与单价信息。
\item \textbf{技术要求}:必须支持按姓名/药品名称的\textbf{模糊查询},且支持\textbf{排序处理}
\end{itemize}
\subsection{住院管理功能}
\begin{itemize}
\item \textbf{业务操作}:为患者分配床位、办理出院处理、实时更新床位状态。
\item \textbf{系统约定}:办理住院时若无空闲床位,系统需自动拒绝;办理出院后系统需自动释放占用的床位资源。
\end{itemize}
\subsection{药房管理功能}
\begin{itemize}
\item \textbf{业务操作}:药品入库(补给)、药品出库、凭医生处方发药。
\item \textbf{系统约定}:发药需强校验,\textbf{库存不足时明确禁止发药}并警报提示;处方开药数量须设上限。
\end{itemize}
\subsection{报表与统计功能}
系统需支持以下维度的核心统计报表:
\begin{itemize}
\item \textbf{医院营业额统计}:综合汇总各项检查费用、药品开销与住院费用。
\item \textbf{医生工作量统计}:统计各医生/各科室的接诊患者数量与频次。
\item \textbf{当前住院患者报表}:生成当前全院或指定科室仍在住院的患者清单。
\item \textbf{床位使用率统计}:计算并展示各病房/科室床位的实时占用百分比。
\item \textbf{药品库存统计}:一览当前所有药品的库存余量状况及高频消耗趋势。
\end{itemize}
\subsection{业务流程管理}
\begin{itemize}
\item \textbf{住院管理}:执行床位检索 $\rightarrow$ 分配绑定 $\rightarrow$ 状态更新 $\rightarrow$ 出院释放。无空床时业务拒绝。
\item \textbf{药房管理}:处理入库补给、处方强校验发药(库存不足禁止发药)、单次开药限量限制。
\end{itemize}
\subsection{报表与统计 (多权限视角)}
支持格式化的 ASCII 表格打印输出:医院综合营业额、医生工作量排行、住院患者一览表、全院/科室床位使用率统计、药品库存消耗趋势。
\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] {MedicalRecord\\医疗记录};
\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 (report) [right=3.5cm of dept] {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] (pharmacy) -- node[below, draw=none]{库存更新} (medicine);
% =====================
% 报表汇总
% =====================
\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] (dept.east) -- (report.west);
\draw[dashedarrow] (ward.east) -| (report.north);
\draw[dashedarrow] (medicine.east) -| (report.south);
% =====================
% 分组背景(增强可读性)
% =====================
\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=gray!40, fill=gray!10, rounded corners, fit=(report), label=above:{\textbf{统计分析}}] {};
\end{scope}
\end{tikzpicture}
\end{center}
\section{交互层(CLI)与鲁棒性设计}
\subsection{ REPL 命令行交互}
系统封装了交互式 Shell支持如 \texttt{his > add patient}\texttt{his > admit P001}\texttt{his > report doctor} 等语义化指令,参数输入灵活,错误提示友好。
\subsection{极致鲁棒性(防崩溃拦截)}
结合 \texttt{input\_sanitizer.cpp} 提供全方位输入保护:
\begin{itemize}
\item \textbf{输入异常}:拦截非法字符(防命令注入)、阻断空输入与超长字符串、自动纠正格式错误。
\item \textbf{业务异常}妥善处理无空床、库存穿透、非法ID关联引用、并发重名等业务死锁状态。
\end{itemize}
\section{数据持久化与扩展机制}
系统根目录 \texttt{data/} 下维持 \texttt{patients.txt} 等存储媒介。采用 JSON 数组格式。遵循“启动时全量挂载,执行关键操作或退出时序列化落盘”的策略。后期可进一步无缝拓展:历史数据预测分析(如病床流转预测)、医生智能推荐以及多角色权限(RBAC)认证系统。
% ==========================================
% 第二部分数据结构与系统架构说明来自新版文件2
% ==========================================
\newpage
% --- 恢复文件2 的样式设置 ---
\pagestyle{fancy}
\fancyhf{}
\fancyhead[C]{HIS 系统数据结构说明文档}
\fancyfoot[C]{\thepage}
\lstset{
basicstyle=\ttfamily\small,
keywordstyle=\color{blue},
commentstyle=\color{gray},
stringstyle=\color{red},
breaklines=true,
frame=single,
language=C++,
showstringspaces=false
}
\maketitle
\begin{abstract}
本文档基于HISHospital Information System项目源代码详细分析阐述了系统的核心数据结构、数据模型、存储机制及各个服务模块的功能设计。HIS是一个医院信息管理系统用于管理患者、医生、病房、药物及医疗记录等关键信息采用链表+哈希表混合数据结构实现高效的数据操作。
\end{abstract}
\section{系统概述}
\subsection{项目定义}
医院信息系统HIS, Hospital Information System是一个综合性医院管理平台旨在实现对医院各项资源和流程的数字化管理包括
\begin{itemize}
\item 患者信息管理
\item 医生、科室管理
\item 病房和床位管理
\item 药物库存管理
\item 患者医疗记录管理(诊断、处方、住院等)
\item 医疗数据分析与报告
\end{itemize}
\subsection{架构设计}
系统采用分层架构设计:
\begin{itemize}
\item \textbf{数据模型层Models}:定义各个实体对象
\item \textbf{数据存储层Utils}:提供通用的链表和哈希数据结构
\item \textbf{业务逻辑层Core Services}实现CRUD操作和业务规则
\item \textbf{表现层CLI}:命令行交互界面
\end{itemize}
\section{核心数据结构}
\subsection{通用存储结构LinkedList}
LinkedList是系统的基础数据结构采用双向链表 + 哈希表的混合设计:
\subsubsection{结构特点}
\begin{table}[h]
\centering
\begin{tabular}{|l|l|l|}
\hline
\textbf{特性} & \textbf{说明} & \textbf{复杂度} \\
\hline
插入操作 & 在链表头部插入新元素 & $O(1)$ \\
\hline
查找操作 & 通过哈希表快速定位 & $O(1)$ \\
\hline
删除操作 & 从链表中移除并更新哈希表 & $O(1)$ \\
\hline
遍历操作 & 按链表顺序遍历所有元素 & $O(n)$ \\
\hline
\end{tabular}
\caption{LinkedList操作复杂度}
\end{table}
\subsubsection{模板定义}
\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; // 当前元素数量
};
\end{lstlisting}
\subsection{全局上下文HisContext}
\subsubsection{职责}
HisContext是系统的数据容器持有所有实体的LinkedList作为各服务类的共享数据源。
\subsubsection{定义}
\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, PatientCase>
patientCases;
};
}
\end{lstlisting}
\section{核心数据实体}
\subsection{患者实体Patient}
\subsubsection{用途}
存储患者的基本信息,包括个人资料和当前就诊状态。
\subsubsection{属性定义}
\begin{table}[h]
\centering
\begin{tabular}{|l|l|l|l|}
\hline
\textbf{属性名} & \textbf{类型} & \textbf{含义} & \textbf{是否主键} \\
\hline
PatientID & string & 患者唯一标识 &\\
\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 // 已出院
};
\end{lstlisting}
\subsubsection{关键方法}
\begin{itemize}
\item \verb|updateBasicInfo()| - 更新患者基本信息
\item \verb|canBeRemoved()| - 检查患者是否可删除(住院中禁止删除)
\item \verb|nameMatches()| - 名字模糊匹配查询
\item \verb|toJson()/fromJson()| - JSON序列化接口
\end{itemize}
\subsection{医生实体Doctor}
\subsubsection{用途}
记录医生的专业信息,包括科室归属和职务等级。
\subsubsection{属性定义}
\begin{table}[h]
\centering
\begin{tabular}{|l|l|l|}
\hline
\textbf{属性名} & \textbf{类型} & \textbf{含义} \\
\hline
DoctorID & string & 医生唯一标识 \\
\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{病房与床位实体Ward \& Bed}
\subsubsection{用途}
管理医院的住院资源,包括病房的床位分配和患者住院状态。
\subsubsection{Bed结构}
\begin{table}[h]
\centering
\begin{tabular}{|l|l|l|}
\hline
\textbf{属性名} & \textbf{类型} & \textbf{含义} \\
\hline
BedID & string & 床位唯一标识 \\
\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 & 病房唯一标识 \\
\hline
DepartmentID & string & 所属科室ID \\
\hline
Type & enum & 病房类型 \\
\hline
MaxBeds & int & 最大床位数 \\
\hline
Beds & vector & 床位列表 \\
\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()| - 释放指定床位
\item \verb|releasePatient()| - 根据患者ID释放床位
\item \verb|addBed()/removeBed()| - 床位增减操作
\item \verb|freeBedCount()| - 获取空闲床位数
\item \verb|occupancyRate()| - 计算床位使用率
\end{itemize}
占用率计算公式:
$$\text{OccupancyRate} = \frac{\text{OccupiedBeds}}{\text{MaxBeds}}$$
\subsection{药物实体Medicine}
\subsubsection{用途}
管理医院的药物库存,支持快速查询和库存管理。
\subsubsection{属性定义}
\begin{table}[h]
\centering
\begin{tabular}{|l|l|l|}
\hline
\textbf{属性名} & \textbf{类型} & \textbf{含义} \\
\hline
MedicineID & string & 药物唯一标识 \\
\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|addAlias()| - 添加别名
\end{itemize}
\subsection{患者病例实体PatientCase}
\subsubsection{用途}
患者病例是一个聚合实体,记录患者的所有医疗记录,包括诊断、处方、住院等历史信息。
\subsubsection{包含的子记录类型}
\paragraph{1. 诊断记录 (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}
\paragraph{2. 药房记录 (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}$$
\paragraph{3. 住院记录 (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}
\paragraph{4. 预约记录 (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}
\subsubsection{PatientCase顶层属性}
\begin{table}[h]
\centering
\begin{tabular}{|l|l|l|}
\hline
\textbf{属性名} & \textbf{类型} & \textbf{含义} \\
\hline
PatientID & string & 患者ID \\
\hline
DiagnosisRecords & vector & 诊断记录列表 \\
\hline
MedicineRecords & vector & 药房记录列表 \\
\hline
AdmissionRecords & vector & 住院记录列表 \\
\hline
AppointmentRecords & vector & 预约记录列表 \\
\hline
CreatedTime & time\_t & 病例创建时间 \\
\hline
LastModifiedTime & time\_t & 最后修改时间 \\
\hline
\end{tabular}
\caption{PatientCase属性表}
\end{table}
\subsubsection{关键方法}
\begin{itemize}
\item \verb|addDiagnosisRecord()| - 添加诊断记录
\item \verb|addMedicineRecord()| - 添加药房记录
\item \verb|addAdmissionRecord()| - 添加住院记录
\item \verb|addAppointmentRecord()| - 添加预约记录
\item \verb|dischargeFromLatestAdmission()| - 出院并填写出院小结
\item \verb|getCurrentAdmission()| - 获取当前住院记录(如果有)
\item \verb|getLatestAdmission()| - 获取最后一次住院记录
\item \verb|getTotalMedicineCost()| - 累计药物费用
\item \verb|getLatestDiagnosis()| - 获取最新诊断
\end{itemize}
\section{业务逻辑层:服务类}
\subsection{患者服务PatientService}
\subsubsection{职责}
\begin{itemize}
\item 患者的CRUD操作
\item 患者状态管理(门诊/住院/出院)
\item 患者住院和出院流程
\item 多维度查询按ID、姓名、联系方式
\end{itemize}
\subsubsection{关键接口}
\begin{lstlisting}
class PatientService {
public:
// 查询操作
const Patient* findPatient(const std::string& patientId) const;
void findByName(const std::string& keyword, ...);
void findByContact(const std::string& keyword, ...);
// 修改操作
bool addPatient(const Patient& p);
bool updatePatient(const std::string& patientId, ...);
bool removePatient(const std::string& patientId, ...);
// 住院/出院
bool admitPatient(const std::string& wardId,
const std::string& patientId, ...);
bool releasePatient(const std::string& wardId,
const std::string& patientId);
};
\end{lstlisting}
\subsection{病房服务WardService}
\subsubsection{职责}
\begin{itemize}
\item 病房和床位的CRUD操作
\item 病房数据的持久化JSON文件
\item 床位分配和回收管理
\end{itemize}
\subsubsection{关键接口}
\begin{lstlisting}
class WardService {
public:
// 查询
const Ward* findWard(const std::string& wardId) const;
// 修改
bool addWard(const Ward& w);
bool removeWard(const std::string& wardId);
bool addBed(const std::string& wardId, ...);
bool removeBed(const std::string& wardId, ...);
// 持久化
bool loadFromFile(const std::string& path, ...);
bool saveToFile(const std::string& path, ...);
};
\end{lstlisting}
\subsection{患者病例服务PatientCaseService}
\subsubsection{职责}
\begin{itemize}
\item 管理患者的完整医疗记录
\item 诊断、处方、住院、预约记录的添加和查询
\item 患者出院流程处理
\item 医疗统计(费用、记录数等)
\end{itemize}
\subsubsection{关键接口}
\begin{lstlisting}
class PatientCaseService {
public:
// 病例获取
PatientCase* getOrCreateCase(const std::string& patientId);
const PatientCase* getCase(const std::string& patientId) const;
// 记录添加
bool addDiagnosisRecord(const std::string& patientId, ...);
bool addMedicineRecord(const std::string& patientId, ...);
bool addAdmissionRecord(const std::string& patientId, ...);
bool addAppointmentRecord(const std::string& patientId, ...);
// 出院处理
bool dischargePatient(const std::string& patientId,
const std::string& dischargeSummary);
// 统计查询
double getTotalMedicineCost(const std::string& patientId) const;
size_t getDiagnosisRecordCount(const std::string& patientId) const;
};
\end{lstlisting}
\subsection{医生服务DoctorService}
\subsubsection{职责}
\begin{itemize}
\item 医生信息的CRUD操作
\item 医生查询和筛选
\end{itemize}
\subsection{药物服务MedicineService}
\subsubsection{职责}
\begin{itemize}
\item 药物库存管理
\item 药物查询和匹配
\item 库存增减操作
\end{itemize}
\subsection{报告服务ReportService}
\subsubsection{职责}
\begin{itemize}
\item 生成系统统计报表
\item 数据分析展示
\end{itemize}
\section{系统架构图}
\subsection{数据流架构}
\begin{verbatim}
┌─────────────────────────────────────────────┐
│ CLI命令行交互层
│ - REPL Shell交互式命令行
│ - 表格打印(数据展示) │
└────────────────┬────────────────────────────┘
┌─────────────────────────────────────────────┐
│ HisCore组合根/依赖注入容器) │
│ - PatientService │
│ - WardService │
│ - DoctorService │
│ - MedicineService │
│ - PatientCaseService │
│ - ReportService │
└────────────────┬────────────────────────────┘
┌─────────────────────────────────────────────┐
│ HisContext全局数据容器
│ - LinkedList<PatientID, Patient> │
│ - LinkedList<WardID, Ward> │
│ - LinkedList<DoctorID, Doctor> │
│ - LinkedList<MedicineID, Medicine> │
│ - LinkedList<PatientID, PatientCase> │
└────────────────┬────────────────────────────┘
┌─────────────────────────────────────────────┐
│ LinkedList双向链表+哈希表混合结构) │
│ - O(1) 查找/插入/删除 │
│ - 支持高效遍历 │
└─────────────────────────────────────────────┘
\end{verbatim}
\subsection{CLI命令总览}
\begin{itemize}
\item help
\item exit | quit
\item root <path>
\item path <file>
\item doctor add <doctorId> <name> <departmentId> <Chief|AssociateChief|Attending|Resident> <schedule>
\item doctor rm <doctorId>
\item doctor list
\item doctor list dept <departmentId>
\item doctor search <keyword>
\item doctor search name <name\_keyword>
\item doctor search dept <departmentId>
\item doctor search title <title\_keyword>
\item doctor search schedule <schedule\_keyword>
\item medicine add <id> <genericName> <brandName> <departmentId> <stock> <unitPrice>
\item medicine list
\item medicine stock inc <id> <amount>
\item medicine stock dec <id> <amount>
\item medicine find <keyword>
\item medicine load [file\_path]
\item medicine save [file\_path]
\item ward add <wardId> <departmentId> <Normal|Special|ICU> <maxBeds>
\item ward rm <wardId>
\item ward list
\item ward show <wardId>
\item ward bed add <wardId> <bedId>
\item ward bed rm <wardId> <bedId>
\item patient add <patientId> <name> <age> <gender> <contact> [Outpatient|Inpatient|Discharged]
\item patient update <patientId> <name> <age> <gender> <contact>
\item patient rm <patientId>
\item patient list
\item patient search id <patientId\_keyword>
\item patient search name <name\_keyword>
\item patient search phone <contact\_keyword>
\item patient search <keyword>
\item patient load [file\_path]
\item patient save [file\_path]
\item patient admit <wardId> <patientId>
\item patient release bed <wardId> <bedId>
\item patient release patient <wardId> <patientId>
\item case view <patientId>
\item case diagnosis add <patientId> <doctorId> <diagnosis> [prescription] [remarks]
\item case medicine add <patientId> <medicineId> <medicineName> <quantity> <usage> <unitPrice>
\item case admission add <patientId> <wardId> <bedId> [reason]
\item case appointment add <patientId> <doctorId> <date> [notes]
\item case discharge <patientId> [summary]
\item case stats <patientId>
\item report occupancy <wardId>
\item log view [count]
\item log clear
\item log export <file\_path>
\item log format set <format\_string>
\item file create <file\_path>
\item file delete <file\_path>
\item file rm-field <file\_path> <field>
\end{itemize}
\subsection{实体关系图}
\begin{verbatim}
Patient (患者)
├── 1:1 ──> PatientCase (患者病例)
│ ├── 1:n ──> DiagnosisRecord (诊断记录)
│ ├── 1:n ──> MedicineRecord (药房记录)
│ ├── 1:n ──> AdmissionRecord (住院记录)
│ └── 1:n ──> AppointmentRecord (预约记录)
└── M:1 ──> Ward (病房)
├── 1:n ──> Bed (床位)
└── M:1 ──> Department (科室)
Doctor (医生)
└── M:1 ──> Department (科室)
Medicine (药物)
└── M:1 ──> Department (科室)
\end{verbatim}
\section{关键业务流程}
\subsection{患者住院流程}
\begin{enumerate}
\item 患者通过 PatientService.addPatient() 注册为门诊患者
\item 医生通过 PatientCaseService.addDiagnosisRecord() 添加诊断
\item 需要住院时,调用 PatientService.admitPatient()
\begin{itemize}
\item 查找 WardService 中的可用病房
\item 从病房获取空闲床位
\item 分配患者到该床位
\item 更新患者状态为 Inpatient
\end{itemize}
\item 住院期间,通过 PatientCaseService 添加诊断和处方
\item 出院时,调用 PatientCaseService.dischargePatient()
\begin{itemize}
\item 填写出院小结
\item 释放床位
\item 更新患者状态为 Discharged
\end{itemize}
\end{enumerate}
\subsection{处方和药物管理流程}
\begin{enumerate}
\item 医生通过 PatientCaseService.addMedicineRecord() 开药
\item 系统记录药物ID、数量、用法、单价
\item 根据处方自动计算费用(数量 $\times$ 单价)
\item 可通过 PatientCaseService.getTotalMedicineCost() 查询患者总费用
\end{enumerate}
\subsection{床位资源管理流程}
\begin{enumerate}
\item 通过 WardService 初始化病房及床位
\item Ward 对象维护床位列表BedStatus
\item 患者住院时调用 Ward.admitPatient()
\begin{itemize}
\item 查找第一个空闲床位
\item 将患者ID分配给床位
\item 更改床位状态为 Occupied
\end{itemize}
\item 患者出院时调用 Ward.releasePatient()
\begin{itemize}
\item 根据患者ID找到占用的床位
\item 释放床位PatientID置空
\item 更改床位状态为 Free
\end{itemize}
\end{enumerate}
\section{数据持久化}
\subsection{JSON序列化策略}
系统中所有数据模型都支持JSON序列化通过 \verb|toJson()| 和 \verb|fromJson()| 接口实现。
\subsection{文件存储}
\begin{itemize}
\item \verb|wardservice.cpp| 提供 \verb|loadFromFile()| 和 \verb|saveToFile()| 方法
\item 支持将Ward数据持久化到JSON文件
\item 系统启动时自动加载已保存的数据
\end{itemize}
\subsection{必需的数据文件}
系统需要以下基础数据文件(位于 data/ 目录):
\begin{itemize}
\item \verb|patients.txt| - 患者信息
\item \verb|doctors.txt| - 医生信息
\item \verb|wards.txt| - 病房信息
\item \verb|medicines.txt| - 药物库存
\end{itemize}
\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}: 链表的通用操作模板
\end{itemize}
\subsection{数据结构优化}
\begin{itemize}
\item 双向链表支持高效的插入/删除($O(1)$
\item 哈希表索引支持高效查询($O(1)$
\item 混合设计兼顾查询性能和遍历灵活性
\end{itemize}
\subsection{业务规则}
\begin{itemize}
\item 患者在住院状态中禁止删除Patient.canBeRemoved()
\item 床位容量受限于病房的 MaxBeds 上限
\item 出院记录必须包含出院小结
\item 每个患者只能有一个"当前住院记录"
\end{itemize}
\section{系统使用示例}
\subsection{创建患者并住院}
\begin{lstlisting}
HisCore his;
// 创建患者
Patient p("P001", "张三", 35, "男", "13800000001");
his.patientService.addPatient(p);
// 患者住院
std::string bedId;
his.patientService.admitPatient("W001", "P001", bedId);
// 添加诊断
DiagnosisRecord diag("D001", "感冒", "板蓝根冲剂");
his.patientCaseService.addDiagnosisRecord("P001", diag);
// 添加药房记录
MedicineRecord med("M001", "板蓝根", 2,
"一日两次,饭后服用", 25.0, "D001");
his.patientCaseService.addMedicineRecord("P001", med);
// 患者出院
his.patientCaseService.dischargePatient("P001", "病情好转,出院");
\end{lstlisting}
\section{总结}
HIS系统通过精心设计的数据结构和分层架构实现了医院信息管理的核心功能
\begin{enumerate}
\item \textbf{高效的数据操作}通过LinkedList混合结构提供$O(1)$的查找和修改
\item \textbf{完整的数据模型}:覆盖患者、医生、病房、药物及医疗记录
\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}