简介:这是一份基于Visual Studio开发的医院信息系统(HIS)项目工程,适合医疗信息化开发初学者、院校软件专业学生作为课程设计与毕业设计参考。资源包共104个文件,整体约750KB,以16个C++源文件(.cpp/.h)和对应编译中间文件为代码主体,同时包含13个窗体位图、图标、SQL脚本及SQL Server数据库文件,可完整还原一个桌面端HIS系统的开发框架与运行界面。工程内容贯穿需求分析、系统设计、编码实现、测试部署全流程,涉及挂号、门诊、住院、药房、财务等核心业务,并附有第七模块相关文档。已有493人学习,适合希望快速理解传统HIS架构、学习窗体界面与数据库交互的开发者。通过对照源码、数据库脚本与可执行程序,可掌握病人信息录入、记录查询、统计打印等功能的实现思路,并在此基础上进行二次开发或功能扩展。
1. HIS.rar 到底是什么:一份能落地的医院信息系统实施包
很多第一次接触医院信息系统的朋友,下载到一份 HIS.rar,解压后面对几十个文件夹和一堆 .sql 文件直接发懵:这跟普通管理系统完全不是一个量级。HIS 系统不是单一软件,而是挂号、收费、医嘱、药库、病案、检验接口组合成的业务中台,改一个参数都可能影响全院流程。这份资源包实际是一套可部署的 HIS 实施包,包含数据库初始化脚本、客户端程序、部署文档和必要的演示数据,能解决“从零把医院信息系统跑起来”的问题。适合 HIS 实施工程师、医院信息科运维、医疗软件二次开发者,也适合想搞懂 HIS 内部业务闭环的测试人员,按章节顺序复现即可从一台空机器跑到挂号收费窗口开单。
2. 拆开 HIS.rar 先看清架构:模块边界与一条业务主线
2.1 目录结构决定架构:先看顶层再定部署方式
拿到 rar 包第一步不是双击,而是用 7-Zip 或 WinRAR 把目录树展开,只看顶层。传统 C/S 版 HIS 一般长这样:
HIS/ ├── bin/ # 编译后的 exe 和 dll ├── client/ # 客户端安装程序 ├── db/ # 数据库脚本与备份文件 ├── doc/ # 部署文档、操作手册、接口说明 └── tools/ # 辅助运维工具如果看到 web/、webapi/、war 包或 nginx 目录,说明带 B/S 模块,比如 B/S 医生站、移动查房端、报表中心。现在很多医院 HIS 是混合架构:收费窗口用 C/S 瘦客户端保证响应速度,住院医生站用浏览器访问,接口服务独立部署,所以压缩包里同时出现 bin/ 和 web/ 不奇怪。
判断依据很简单:C/S 程序的客户端需要逐台安装,运行时会写本地配置文件,升级要推包;B/S 程序只要一台应用服务器部署完,临床终端打开浏览器就能用。从 HIS.rar 的目录结构能反推出你这套系统的实施难度——看到 client/ 就要做好逐台装客户端的准备,看到 web/ 还要准备一套 Tomcat 或 Nginx。
我拿到新包会先翻 doc 目录下有没有“部署说明.doc”或“环境要求.txt”,这份文档决定后面所有步骤。没有文档的包才需要靠脚本内容反推数据库类型,这部分放到 2.3 讲。
2.2 核心模块与数据表前缀:先对齐业务线再动手
HIS 的核心不是“功能多”,而是“一条业务主线串起所有模块”。挂号收费和普通商超收银最大的区别是:挂号产生就诊身份,身份产生医嘱,医嘱产生费用,费用驱动药房发药和库存扣减,最后回到结算和病案。任何一步断了都会影响下一个财务日结。
常见模块和数据表对应关系:
| 模块 | 典型数据表 | 职责 |
|---|---|---|
| 门急诊挂号 | REG_BAS、REG_QUEUE | 号源管理、挂退号、分时段预约 |
| 门急诊收费 | OPC_FEE、OPC_INVOICE | 划价收费、退费、日结报表 |
| 医生工作站 | DOC_PRESC、DOC_ORDERS | 门诊处方、检查检验申请 |
| 护士工作站 | NUR_EXEC | 住院医嘱执行、瓶签生成 |
| 药库与药房 | PH_DRUG、PH_STOCK | 采购入库、效期管理、发放退药 |
| 住院入出转 | IP_ADT | 入院登记、转科、预交金、出院 |
| 病案管理 | MR_ARCHIVE | 病案首页、编目、借阅 |
不同 HIS 厂商前缀有差异,但 PA(病人)、OP(门诊)、IP(住院)、MR(病案)、PH(药房)这几个前缀几乎通用。我常做的第一步是用数据库工具查 REG_BAS 表,如果没有这张表,多半是产品用了 OB/GW/EMR 这种自研命名体系,这时候就要去 doc 目录翻数据字典,而不是对着表名猜。
医保接口也是 HIS 实施绕不开的一环,资源包里通常会有一份单独的接口文档和测试环境配置,这块虽然不是主程序,但联调失败是整个项目延期的常见原因,后面部署时单独说。
2.3 数据库脚本先于程序:脚本方言决定数据库类型
解压后最要紧的是看 db 目录。医院 HIS 的数据库脚本和普通 Web 项目的 sql 文件不一样,它通常包含四类内容:建表空间和用户的初始化脚本、建表脚本、字典初始化数据、演示数据。Oracle 脚本里一定有 tablespace、dmp 字样;SQL Server 脚本常带 .bak 备份或 .mdf 日志;MySQL 脚本则会有 engine=InnoDB 和 utf8mb4 设置。
常见做法是先把建表脚本按顺序执行:第一步建用户/表空间,第二步建表,第三步导字典,第四步导入演示数据。顺序错了会互相踩踏,比如表还没建好就导数据,直接报 ORA-00942。
命令层面以 Oracle 为例:
# 以 DBA 身份进 sqlplus sqlplus / as sysdba-- 建表空间和用户 CREATE TABLESPACE HIS_DATA DATAFILE '/u01/app/oracle/oradata/his/his_data.dbf' SIZE 8G AUTOEXTEND ON NEXT 512M MAXSIZE 32G; CREATE USER HIS IDENTIFIED BY "His#2024" DEFAULT TABLESPACE HIS_DATA TEMPORARY TABLESPACE TEMP; GRANT CONNECT, RESOURCE, DBA TO HIS;逻辑说明:先建独立表空间是为了避免和数据库系统表空间混在一起。医院数据量大,日志和回滚段单独规划,后面备份和扩容都好做。
参数说明:SIZE 8G 只是初始容量,医院日增数据一般几十 MB 到几百 MB,AUTOEXTEND ON 之后到 32G 时再评估是否需要增加数据文件。密码里的特殊字符用双引号包裹,避免转义问题。
提示:执行这部分脚本时务必确认当前终端是 DBA 身份,普通用户没有 CREATE TABLESPACE 权限,报错会让你误以为是包的问题。
这段 SQL 是初始化脚本的核心逻辑。很多实施工程师倒在第一步,不是 SQL 写错,而是没注意数据库字符集和 dmp 备份字符集不一致,导入后中文全变问号,这个在避坑章专门讲。
3. 把 HIS 跑起来:环境选型、初始化与三处配置
3.1 环境选型先看脚本方言
在装任何组件之前,先去 db 目录看脚本后缀。.dmp 且带 tablespace 的选 Oracle;.bak 或 .mdf 选 SQL Server;.sql 带 engine=InnoDB 的选 MySQL。医院老 HIS 八成是 Oracle,原因不外乎两个:一是医院财务数据要求严格的事务一致性,二是 Oracle 的 RAC 集群和 Data Guard 能满足双机热备需求。不建议新手在部署阶段用 MySQL 代替 Oracle 跑这套包,除非资源包明确写了支持 MySQL。
组件选型参考:
| 组件 | 推荐 | 说明 |
|---|---|---|
| 服务器操作系统 | Windows Server 2016/2019 | 医院 HIS 服务器端 Windows 生态最省事,驱动和备份软件都齐 |
| 数据库 | Oracle 11g/12c 或 SQL Server 2016 | 看脚本方言,不要混用 |
| 客户端操作系统 | Windows 10 x64 | C/S 客户端大多依赖 .NET 或 VB 运行时 |
| 中间件 | Tomcat 8.5+(B/S 模块) | 有 war 包才需要 |
| 浏览器 | Chrome 或 Edge | 别用老 IE 内核,排版会崩 |
参数说明:如果包是 B/S 架构,建议服务器内存不低于 16G。医院实时在线的并发不算高,但报表查询和医保接口并发经常把内存占满。C/S 架构对服务器压力集中在数据库,应用客户端分担了一部分计算压力,内存 8G 起步也够。
我在没有官方文档时,判断包是否支持某版本数据库,会去 db 目录翻 schema.sql 里的建表语句:Oracle 的 VARCHAR2 字段、SQL Server 的 NVARCHAR 字段一眼就能分辨,不需要猜。
3.2 初始化数据库:脚本顺序与日志定位
数据库初始化的标准顺序是先建用户,再建表,再导字典数据,最后导入 dmp 备份。dmp 如果包含全库数据,前面的建表可以省略,但要注意 dmp 里原用户的用户名和密码要和你建的一致,否则 imp 时会报 ORA-01918。
导入 dmp 的常见写法:
# 进入 sqlplus 创建用户(假设已有表空间 HIS_DATA) sqlplus / as sysdbaCREATE USER HIS IDENTIFIED BY "His#2024" DEFAULT TABLESPACE HIS_DATA; GRANT CONNECT, RESOURCE TO HIS; -- 给导入授权 GRANT IMP_FULL_DATABASE TO HIS; -- 退出 sqlplus 后命令行执行 imp -- imp HIS/His#2024@ORCL file=/data/his/db/his_full.dmp full=y log=imp.log逻辑说明:full=y 表示整库导入,会把原来用户里的所有表、索引、存储过程一起导进来;log 参数务必写,出错了看 imp.log 比看控制台输出可靠得多。
参数说明:如果你只有 schema.sql 而没有 dmp,改用 source 方式逐文件执行,命令如下:
sqlplus HIS/His#2024@ORCL @schema.sql sqlplus HIS/His#2024@ORCL @init_data.sql导入完成后立即验证对象数和关键表:
SELECT COUNT(*) FROM user_tables; SELECT COUNT(*) FROM REG_BAS WHERE ROWNUM <= 5;这段 SQL 的逻辑是:user_tables 数量验证建表是否完整,REG_BAS 能查出行说明基础表有了数据。如果第二行查询为空,说明演示数据没导进去,后面登录界面能打开但挂不了号。
3.3 连接配置三处对齐:客户端、应用服务器、数据库
初始化完成后,HIS 连接配置要改三处,任何一处不一致都会出现“登录失败”或“ORA-01017”。
第一处是 C/S 客户端配置文件,常见是 db.ini 或 conn.ini:
[DB] SERVER=192.168.1.10 PORT=1521 SERVICE_NAME=ORCL USER=HIS PASSWORD=His#2024参数说明:SERVER 写服务器 IP,不要写 localhost;SERVICE_NAME 要和数据库实际服务名一致,大小写敏感。Oracle 默认服务名是 ORCL,但有的 DBA 建库时改成了 HISDB,写错就报 ORA-12514。
第二处是 B/S 应用服务器配置,常见是 application.properties:
spring.datasource.url=jdbc:oracle:thin:@192.168.1.10:1521:ORCL spring.datasource.username=HIS spring.datasource.password=His#2024 spring.datasource.driver-class-name=oracle.jdbc.OracleDriver逻辑说明:JDBC 连接串里的 ORCL 是 SERVICE_NAME,不是 SID;如果数据库服务名是 HISDB,这里要改成 HISDB。thin 模式是纯 Java 连接,不需要在应用服务器上装 Oracle 客户端,现在主流做法都是 thin。
第三处是客户端本机环境变量,Windows 下设置 NLS_LANG:
NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK这段环境变量决定 Oracle 客户端以什么字符集与服务器通信,不一致会出现乱码,具体在避坑章展开。
三处配置改完,启动应用服务(Tomcat 执行 startup.bat,C/S 客户端直接运行 bin 目录的 exe),用管理员账号登录,登录页能弹出来,系统基本跑通。我这里说的“基本跑通”指能打开登录窗,真正的业务闭环验证在最后一章。
4. HIS 部署避坑指南:伪加密、连接失败与乱码几条排障路径
4.1 解压就翻车:RAR 伪加密与压缩包损坏
现象:用 WinRAR 打开 HIS.rar,提示需要输入密码,按资源说明里的默认密码输入后依然报“密码错误或文件损坏”,反复试了大小写和全半角都没用。换成 7-Zip 打开却能看到完整的文件目录列表,甚至能直接解压出全部文件。
原因:这类压缩包往往做了伪加密,只勾选了“加密文件名”或设置了空密码。WinRAR 的密码校验机制对这类标志位判断比较严格,7-Zip 反而宽松一些。还有一部分是上传过程中文件头损坏,表现为解压到百分之八十几突然开始报错。
解决:先用 7-Zip 打开,密码框留空直接点确定;还不行就在压缩包内找“解压密码.txt”或查看包注释。如果是分卷 rar,确保所有分卷在同一个目录且命名连续。压缩包本身损坏时用 WinRAR 的“工具-修复压缩文件”重建一次,修复后再解压成功率会高很多。
这条经验来自我第一次接 HIS 实施时,拿到的包提示加密但发布者说没设密码,折腾了一个下午才意识到是伪加密。后来我拿到任何资源包都默认用 7-Zip 当第一解压工具,遇到报错再去翻 WinRAR,省下大量无意义的密码尝试。
4.2 数据库连不上:监听、端口与服务名三处玄学
现象:客户端登录时直接报“ORA-12541: TNS:no listener”或“ORA-12514: TNS:service name not resolved”。网络能 ping 通,服务器上 Oracle 服务也显示正在运行。
原因:ORA-12541 是服务器的监听进程没起来或没监听 1521 端口;ORA-12514 是连接串里的服务名写错,把 SID 写成了服务名,或监听文件里没配置对应的 service handler。
解决:在服务器上先执行 lsnrctl status 查看监听状态,监听没起来就执行 lsnrctl start。确认端口监听后,用 tnsping 192.168.1.10:1521 验证通不通。再把连接串里的 SID 改成实际服务名,查询方式:
SELECT NAME FROM v$active_services;逻辑说明:v$active_services 返回当前数据库所有活跃服务名,把查询结果写进连接串的 SERVICE_NAME,基本能解决 ORA-12514。
参数说明:服务器启用防火墙时需要放行 1521 端口,Windows 防火墙执行:
netsh advfirewall firewall add rule name="Oracle1521" dir=in action=allow protocol=TCP localport=1521执行完 telnet 192.168.1.10 1521,能通才算防火墙这关过了。我见过最隐蔽的一次是服务器上装了安全软件,把 Oracle 的监听进程给停了,服务列表里显示正在运行,实际监听端口根本没起来。
4.3 中文乱码:三层字符集要一致
现象:登录界面是英文或乱码,导进去的基础数据里药品名称、科室名称显示成一串问号,业务单据打印出来病人姓名错位。有时候前端显示正常,导出的 Excel 却乱码。
原因:典型是三层不一致。服务器 Oracle 字符集是 ZHS16GBK,客户端 NLS_LANG 设成了 AMERICAN_AMERICA.AL32UTF8,应用服务器 JDBC 连接串没加 characterEncoding 参数。GBK 和 UTF-8 对中文的存储机制不同,数据在入库时就被转换坏了,后面怎么显示都是错的。
解决:先查服务器实际字符集:
SELECT userenv('language') FROM dual;返回 ZHS16GBK 类型,就把全链路都改为 GBK。Windows 客户端在系统环境变量加一行 NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK;JDBC 连接串加:
spring.datasource.url=jdbc:oracle:thin:@192.168.1.10:1521:ORCL?useUnicode=true&characterEncoding=GBK逻辑说明:JDBC 的 characterEncoding 要和数据库字符集一致,如果数据库是 AL32UTF8 则改为 characterEncoding=UTF-8。改完这层后,已经乱码的表数据需要重新导入一次,不是刷新就能恢复。
参数说明:环境变量修改后,已经启动的客户端要注销重登才会生效,不要改了注册表还在旧会话里测,那你看到的永远是乱码。
4.4 共享目录权限与客户端本地化
现象:C/S 客户端放在 Windows 共享文件夹里,双击 exe 可以打开登录界面,但保存处方时报“拒绝访问”或“找不到服务器路径”。也有一种情况是客户端能运行但异常卡顿,打开界面要等十几秒。
原因:共享文件夹权限不够,网络服务账号对目录只有读取没有写入。卡顿通常是因为客户端和数据库交互时要频繁读写共享目录里的临时缓存文件,在千兆局域网问题不明显,一旦经过无线网络会放大延迟。
解决:把客户端程序复制到每台终端本地磁盘,比如 C:\HISClient,配置文件里的 SERVER 仍然指向服务器 IP,这样数据走网络、程序走本地,卡顿立刻缓解。共享方式只在医院内网千兆环境下可用,且要给 Everyone 或网络账号加读写权限。我一般会同时把日志目录重定向到 D 盘,避免 C 盘空间不足把系统日志写满。
5. 进阶:用 SQL 走一遍挂号到发药闭环,验证 HIS 是否真的跑通
系统能登录只是第一步,真正的验证是走一遍完整业务闭环:挂一个测试病人,开一张处方,收费,发药,退药,再看库存在这五个动作后的变化。手上有这套资源包时,我通常直接拿 SQL 查询来验证,因为界面操作容易漏步骤,而且看不到底层数据的一致性。
下面的 SQL 适用于大多数以 REG/OP/PH 为前缀的 HIS 表,如果你的包用了别的命名,把表名替换成实际表名:
-- 1. 今天挂了多少号 SELECT COUNT(*) AS REG_COUNT FROM REG_BAS WHERE REG_DATE = TRUNC(SYSDATE); -- 2. 其中多少张处方已完成收费 SELECT COUNT(*) AS FEE_COUNT FROM OPC_FEE WHERE FEE_DATE = TRUNC(SYSDATE) AND STATUS = '1'; -- 3. 药房对应发了几张单 SELECT COUNT(*) AS SEND_COUNT FROM PH_SEND WHERE SEND_DATE = TRUNC(SYSDATE);逻辑说明:三条 SQL 分别统计挂号、收费、发药三个节点。真实场景里 REG_COUNT 应该大等于 FEE_COUNT 等于 SEND_COUNT。如果 FEE_COUNT 小于 REG_COUNT,说明有病人挂了号没交费,可能是测试数据没走完流程,也可能是收费节点存在断点。
参数说明:STATUS='1' 这个值在不同系统里定义不同,可以查数据字典表确认收费状态的枚举值。PH_SEND 如果没有这张表,试试 PH_DISPENSE 或 PH_FILL,不同厂商表名差异较大,别死磕。
再查药库库存扣减是否一致:
SELECT DRUG_CODE, DRUG_NAME, STOCK_QTY FROM PH_STOCK WHERE DRUG_CODE = '00101';这条 SQL 的逻辑是看指定药品的库存数,在界面上完成一笔发药后再执行一次,数量应该减少对应的发药量。如果数量没变,大概率是发药节点只在程序内存里执行了,没有提交到数据库,常见原因是存储过程事务没提交或者客户端断连。
我第一次部署这套 HIS 时,只看浏览器登录页弹出来就宣布上线,结果第三天药房报告退药退不进去,一查是药房库存字段没初始化,默认值是 NULL 而不是 0,前端取值时拿 NULL 做算术直接抛异常。从那以后我每次部署完都会强制走一遍“挂号—开单—收费—发药—退药”的全流程 SQL 校验,再让院方用真实病人信息做最小冒烟测试,确认数据链路通了才签字确认交付。这套包适合拿来做环境演练,按上面的顺序跑一遍,你对 HIS 实施流程的理解会比读十篇文章深刻得多。希望帮到你。
本文还有配套的精品资源,点击获取