
简介一套医院信息系统HIS前端界面源代码面向医疗信息化开发者与前端工程师用于解决挂号、病历、药方管理等医疗业务界面的构建问题。压缩包共有42个文件含9个HTML页面、8个JavaScript脚本、6个CSS样式表以及JSON数据、图片素材和说明文档整体大小约736KB。页面实现了登录注册、挂号、查看病历与药方等核心功能借助jQuery简化DOM操作和事件处理通过Ajax异步获取后台JSON数据实现局部刷新提升交互体验。说明.txt介绍了Ajax与JSON的配合用法registry与Js目录存放注册逻辑和功能脚本CSS与pic目录负责样式和界面图片。目前已有2808人学习下载这套源码覆盖了前端交互、数据请求、样式设计等环节适合作为医疗信息系统前端的参考范例。1. HIS系统源代码及说明.rar解压之后的真实交付物HIS系统源代码及说明.rar这个压缩包在医疗信息化圈子里几乎是每个接手过项目交付的人都会遇到的东西。它通常包含完整的工程代码、数据库脚本和一堆说明文档看起来是一套足够跑起来的系统。但拿到手就解压、导库、启动大概率是跑不起来的——版本不匹配、缺少中间表、前端资源路径写死任何一个问题都能让登录页卡住一整天。我按实际处置这类源码包的顺序来写先识别技术栈和完整性再初始化数据库、把服务跑起来然后说明文档怎么读、二次开发从哪里切入。最后单独列一份踩坑清单把最容易翻车的五个环节和排查方法一次说清。无论你是要给客户搭演示环境还是打算基于源码做改造这条路走通之后后面的工作都会顺很多。2. 先读结构再跑服务识别源码包里的技术栈与完整性很多人拿到 RAR 的第一反应是双击解压然后找 readme。我的习惯是先不开任何文档直接用命令行把目录树拉出来看一遍。因为说明文档可能是多年前写的和实际代码已经对不上了但目录结构不会说谎。2.1 从目录命名还原技术架构B/S 还是 C/SJava 还是 .NET解压之后在源码根目录执行find . -maxdepth 2 -type d | sort | head -50这会输出前 50 个二级目录足够判断架构类型。常见的情况有三种看到src/main/java、pom.xml、src/main/resources说明是 Maven 管理的 Java Web 项目这类在 HIS 源码包里占大多数。看到WebRoot、WEB-INF、classes、lib一般是老式 Eclipse Web 工程没有统一依赖管理lib 下会有一堆 jar 包。看到packages、*.csproj、web.config则是 .NET 的 HIS多见于早期门诊系统。我用find是因为它不会走进node_modules和.git这类大目录。如果你在 Windows 上解压的直接用资源管理器看一层目录也行但注意有些源码包会把前端dist和部署包一起打进来这时要优先看是否有.sql、.properties、.yml这类文件。对于 Java HIS我还会补一条命令确认构建方式ls pom.xml build.gradle build.xml 2/dev/null ls -la lib/ 2/dev/null有pom.xml走 Maven依赖解析方便只有lib/的老工程后面编译时就要自己补 jar工作量大不少。如果发现是前后端分离的结构——比如前端有package.json后端有pom.xml——那说明系统改造过部署时不能只启动一个 Tomcat还要处理前端配置里的后端 API 地址。这个信息在最初看目录时就要记下来否则后面会遇到前端页面能打开但登录请求全部 404 的怪问题。2.2 用三个关键文件锁定版本pom.xml、SQL 脚本与配置模板目录看完之后我会打开三个文件项目里能找到的pom.xml、.sql脚本、application.properties或jdbc.properties。这三个文件基本决定了你能不能在本机复现。先看pom.xml里的依赖版本properties java.version1.8/java.version spring.version4.3.18.RELEASE/spring.version /properties这里能看到 JDK 和 Spring 版本。HIS 源码包里 Spring 4.x JDK 8 很常见Spring Boot 版本反而不多。如果看到 Spring 4就不要用 JDK 11 去跑不然启动时大概率报IllegalArgumentException或者 ClassNotFound。同理如果依赖里有ojdbc14说明它连接的是 Oracle 9i/10g你要么装老版本 Oracle要么改 JDBC 驱动和 SQL 方言这条信息决定了你后面要不要花大精力做迁移。然后是 SQL 脚本打开一个建表语句看看CREATE TABLE t_patient ( PATIENT_ID varchar(32) NOT NULL, NAME varchar(50) DEFAULT NULL, ... ) ENGINEInnoDB DEFAULT CHARSETutf8;如果脚本里全是反引号、ENGINEInnoDB说明是 MySQL。如果是VARCHAR2、NUMBER、SEQUENCE则是 Oracle。字符集utf8和utf8mb4也有区别老项目多是utf8如果你的 MySQL 默认utf8mb4导入时要注意表级字符集覆盖。第三类是配置文件模板。源码包里经常会带*.properties.example或者jdbc.properties.bak这说明原始开发者把真实配置剥离了只留模板。看到这种文件别慌复制一份去掉.example后缀再填自己的数据库地址就行。如果连模板都没有那就翻doc目录下的部署说明通常会有配置节选。jdbc.drivercom.mysql.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/hisdb?useUnicodetruecharacterEncodingutf8 jdbc.usernameroot jdbc.password123456这里还有一个容易被忽略的点连接串里没有serverTimezone。老项目生成时 MySQL 5 不强制但你用新版驱动连 8.0 就会直接报时区错误。后面第 3 章和第 5 章都会反复提到时区这是 HIS 部署中最高频的坑。2.3 判断源码包能不能用的三个信号建库、编译、初始账号识别完技术栈下一步是判断这个包值不值得继续投入时间。我看三个信号有没有完整的建库脚本。一个能跑的 HIS至少有一个hisdb.sql或多个按模块分离的脚本。如果只有建表没有初始数据那登录账号得去文档里找或者自己往t_user里插。代码能不能编译。Maven 项目直接执行mvn compile老工程看lib是否齐全。编译报错不可怕可怕的是连依赖都没有。说明文档里有没有初始账号。很多 HIS 的说明会在第一页写系统管理员 admin/admin123或演示账号 demo/123456。没有的话看数据库初始化脚本里t_user表的 INSERT 语句密码字段如果是 MD5往往能在注释里找到原始密码。这三个信号都满足这个包就可以进入部署流程。有一个不满足就要做好补课的准备。尤其是没有初始账号的情况后面登录环节会卡住我在第 5 章会提到怎么处理。3. 在本地跑通 HIS 系统数据库初始化与启动的完整步骤技术栈摸清楚之后就到了动手阶段。这一章我以最常见的 Java MySQL 组合为例给出从建库到登录页的完整命令和配置。如果你拿到的是 Oracle 或 SQL Server 版本数据库连接串和驱动类名要对应替换但思路一致。3.1 版本对齐JDK、Tomcat、MySQL 的组合选择HIS 是典型的老系统代码依赖老版本框架所以本机环境不能追求新。我一般会先看pom.xml和 SQL 脚本然后按下表选组合源码特征JDKTomcatMySQLSpring 3.x JDK 1.61.6 或 1.775.5/5.6Spring 4.x JDK 1.81.88/8.55.7Spring Boot 2.x1.8内置5.7/8.0数据库为 Oracle按 Spring 版本对应版本仅客户端驱动表面上看 MySQL 8 向下兼容但这里有个容易翻车的点老 HIS 用的com.mysql.jdbc.Driver类名在 MySQL 8 驱动里仍然存在但连接参数serverTimezone不写会直接报时区错误反过来如果用 MySQL 8 的驱动连接 5.7又可能报Public Key Retrieval is not allowed。所以我倾向于把数据库定为 5.7并且用 5.1.x 的 JDBC 驱动少折腾。Tomcat 的版本注意一点老 HIS 的 web.xml 可能是 Servlet 2.5 规范Tomcat 9 默认走 Servlet 4.0有些过滤器写法会不兼容表现症状是请求能到后端但响应头不对。Tomcat 8.5 兼容 2.5 到 3.1基本是万金油。3.2 初始化数据库导入 SQL 脚本并处理字符集建库时字符集很关键。很多 HIS 乱码问题不是页面编码错而是数据库表本身就是 latin1 或者 utf8 和 utf8mb4 混用。我的做法是显式指定字符集mysql -uroot -p -e CREATE DATABASE hisdb DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; mysql -uroot -p hisdb --default-character-setutf8mb4 hisdb.sql第一行创建数据库第二行导入数据。这里--default-character-setutf8mb4是强制客户端按 utf8mb4 发送 SQL避免脚本里的中文字符在传输时被当成 gbk 损坏。如果你拿到的是老脚本里面表定义的默认字符集是utf8那导入后表和库的字符集可能不一致最好再执行一次mysql -uroot -p -e ALTER DATABASE hisdb CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;导入完成后不要急着启动服务先查一下到底导入了多少张表mysql -uroot -p hisdb -e SHOW TABLES; SELECT COUNT(*) FROM information_schema.tables WHERE table_schemahisdb;和文档里写的表数量对比少几十张是常见的原因多半是脚本执行到一半卡在某个报错上。我遇到过 SQL 脚本里有DELIMITER $$和触发器直接这样导入会失败这个坑第 5 章详细说。3.3 修改数据源配置并启动从命令行到 Tomcat 部署数据库好了之后改配置文件。以常见的jdbc.properties为例jdbc.drivercom.mysql.jdbc.Driver jdbc.urljdbc:mysql://127.0.0.1:3306/hisdb?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai jdbc.usernameroot jdbc.passwordyour_password注意serverTimezoneAsia/Shanghai是我后加的老配置里没有但 MySQL 8 驱动必须有才能过了连接校验。端口默认 3306如果你本机装了多个 MySQL确认127.0.0.1指向的是你初始化数据的那一个。改完之后Maven 工程用下面的命令启动内嵌 Tomcatmvn clean tomcat7:run -Dmaven.tomcat.port8080有些项目依赖的不是tomcat7插件而是 Spring Boot那就用mvn clean spring-boot:run。如果源码包是老式 Web 工程先把项目打成 war 放到 Tomcat 的webapps下再启动mvn clean package -DskipTests cp target/his.war $CATALINA_HOME/webapps/ $CATALINA_HOME/bin/startup.sh启动完之后访问http://localhost:8080/his/。如果 8080 被占用改 Tomcat 的server.xml端口老 HIS 的 JSP 页面里经常写死上下文路径his所以 war 包名字不要乱改。3.4 页面打不开时按顺序看这三个日志如果浏览器显示 404 或 500不要立刻怀疑代码。按顺序看日志Tomcat 的logs/catalina.out看应用是否成功部署有没有报ClassNotFoundException应用的logs目录HIS 一般有独立的 log4j 输出里面能看到具体到哪个 Bean 初始化失败MySQL 的general_log确认请求是否真的执行了 SQL。一个技巧是启动时用--debug参数观察 Spring 容器的加载过程mvn tomcat7:run -Dmaven.tomcat.port8080 -Dorg.springframework.web.context.ContextLoaderListenerDEBUG这个方式能显示每个 Bean 的加载状态定位到是数据源初始化失败还是某个 AOP 配置出错。多数情况下问题都出在数据源连接不上而不是业务代码本身。4. 从说明文档找到二开入口核心业务流程与代码链路系统跑起来只是第一步。真正要往里面加功能、改流程必须把说明文档和代码对照着看。这一章告诉你文档怎么读、代码怎么追、第一个改哪里最安全。4.1 说明文档里最该先读的三份部署说明、库表设计、操作手册源码包里的说明文件夹往往很乱常见的有doc、文档、需求文档、使用手册。我建议只读三份其他文件先放一边。第一份是部署说明对应第 3 章的步骤重点看有没有额外的中间件要求比如 Redis、消息队列。老 HIS 大多是单机应用但如果提到需要xxx-service和xxx-web两个工程同时启动那就不是单应用而是前后端分离或多模块。第二份是数据库设计文档。这份通常是一个几十页的 Word 或 HTML里面有表关系图。读的时候只看核心表患者、挂号、医嘱、处方、收费、药品库存。把这六张表的字段关系画下来后面改业务就有地图了。别试图记住所有表HIS 随便几百张表记不住的。第三份是操作手册。这个文件最容易被忽略但其实最有用。它按流程描述操作比如门诊挂号→医生站开医嘱→护士站审核→药房发药→收费处结算。有了操作流程你才能把代码里的模块串联起来。我通常会在操作手册上标注每个步骤对应的菜单名称再去代码里搜菜单名快速定位前端 JSP 或 Controller。4.2 跟踪一次挂号请求Controller、Service 到 SQL 的完整链路以最经典的窗口挂号为例。操作手册里说选择患者、选择科室、选择医生、保存挂号记录。对应到代码我要先搜挂号这个关键词通常能找到RegisterController。然后看它的方法Controller RequestMapping(/register) public class RegisterController { Autowired private RegisterService registerService; RequestMapping(/save) ResponseBody public Result save(RequestBody RegisterRequest req) { // 1. 校验患者是否存在不存在则先建档 Patient patient registerService.findOrCreatePatient(req.getPatientName(), req.getIdCard(), req.getPhone()); // 2. 创建挂号记录 String registerNo registerService.createRegister(patient.getPatientId(), req.getDeptId(), req.getDoctorId(), req.getScheduleDate()); // 3. 返回挂号序号前端打印挂号单 return Result.ok(registerNo); } }这段代码的逻辑很直白先找患者没有就建档再写挂号主表。registerNo是挂号序号它的生成规则一般在RegisterService里public String createRegister(String patientId, String deptId, String doctorId, Date date) { String registerNo dateFormat.format(date) deptId random.nextInt(999); String sql INSERT INTO t_register (REGISTER_NO, PATIENT_ID, DEPT_ID, DOCTOR_ID, REG_DATE, STATUS) VALUES (?, ?, ?, ?, ?, 0); jdbcTemplate.update(sql, registerNo, patientId, deptId, doctorId, date); return registerNo; }到这里一次挂号从页面输入到数据库插入的链路就清楚了。很多人说源码看不懂破局方法就是先挑一个最常点的菜单从 Controller 搜到 Service 再搜到 SQL走通一条链路。走通一条之后其他菜单都是类似套路因为老 HIS 代码大量复制粘贴。4.3 低风险二次开发的三个入口参数配置、报表 SQL、接口对接跑通链路之后想动手改我建议从三个低风险方向开始别一开始就碰挂号、收费这种主流程。第一个是参数配置。很多 HIS 有t_config或t_param表用来存单据前缀、号源池大小、超时时间等。改这些只需要 UPDATE不影响已有数据UPDATE t_config SET CONFIG_VALUE MZ WHERE CONFIG_KEY register.no.prefix;第二个是报表 SQL。说明文档里通常有一节统计报表对应代码里是ReportController下面的一堆查询。出一张简单的日就诊量报表只需要在 SQL 里加一个筛选条件SELECT DEPT_NAME, COUNT(*) AS cnt FROM t_register r LEFT JOIN t_dept d ON r.DEPT_ID d.DEPT_ID WHERE r.REG_DATE BETWEEN ? AND ? AND r.DEPT_ID ? GROUP BY DEPT_NAME;这类改动作用在查询上不产生数据写操作风险最低。第三个是外部系统接口对接。HIS 最常见的对接是医保、体检、LIS。源码包里一般会留一个openapi或者webservice包里面是空的实现类。照着另一个接口的写法仿写一个把入参和出参都定义为 Map再配一个 Spring MVC 的 URL 映射就可以让外部系统调用。需要强调的是HIS 的接口设计通常没有统一规范只做最基础的参数校验即可不要试图引入一套完整的 API 框架那会让你陷入和老代码纠缠不清的困境。5. 部署 HIS 源码包最常见的 5 个坑与排查清单这一章全部是实践中真实翻车过的场景。每条按现象 → 原因 → 解决来写你可以直接当排查清单用。5.1 数据库连接失败Access denied 与公钥检索报错现象启动服务时日志里出现Access denied for user rootlocalhost或者后面跟着Public Key Retrieval is not allowed。原因第一种是配置文件里密码错误或者密码里含有特殊字符没有转义第二种是 MySQL 8 驱动默认使用caching_sha2_password认证而连接串里没有允许获取公钥。解决先检查jdbc.properties的账号密码再看 MySQL 用户插件。命令行登录执行mysql -uroot -p -e SELECT user, host, plugin FROM mysql.user WHERE userroot;如果 plugin 是caching_sha2_password要么在连接串加allowPublicKeyRetrievaltrueuseSSLfalse要么把用户改为兼容模式ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY your_password;我一般直接改连接串不动数据库用户避免影响其他应用。5.2 页面中文乱码三处字符集不一致现象登录页正常但查询出来的患者姓名全是??或者页面返回 500日志里写Incorrect string value: \xE6\x9D\x8E\xE5\x9B\x9B。原因HTTP 请求响应编码、JSP 页面编码、数据库表编码三者不一致。老项目 JSP 常用 GBK数据库是 utf8浏览器以 GBK 发送中文到库里被转成错误字节。解决把 JSP 页面头部 charset 改为 UTF-8在web.xml里加编码过滤器filter filter-nameencodingFilter/filter-name filter-classorg.springframework.web.filter.CharacterEncodingFilter/filter-class init-param param-nameencoding/param-name param-valueUTF-8/param-value /init-param /filter同时把数据库连接串保持characterEncodingutf8这样三层都统一。改完后要清浏览器缓存因为旧页面会缓存 GBK 的响应头。5.3 登录后跳转 404丢失上下文路径现象输入账号密码页面短暂加载后跳到http://localhost:8080/main.jsp结果 404。手动访问http://localhost:8080/his/main.jsp却正常。原因JSP 或 JS 里用的是绝对路径/main.jsp没有带上下文路径/his。部署到 Tomcat 的 webapps 下时war 包名字产生的上下文路径是/his但页面写死根路径导致浏览器请求发到根目录。解决在 JSP 里统一用%request.getContextPath()%拼路径或者给项目设置 Tomcat 的Context path/ 。临时验证最快速的办法是把 war 包改名为ROOT.war让系统部署在根路径下。注意这样访问端口时就不需要/his了要同步修改配置文件里的回调地址。这个坑在源码包二次部署时很常见因为在原项目里可能正好部署在根路径。5.4 日期字段相差 8 小时连接串时区缺了 serverTimezone现象挂号记录里的时间比当前时间慢 8 小时或者开药时间显示成前一天 23 点。原因JDBC 连接 MySQL 时没指定时区驱动默认用了 JVM 时区而 MySQL 用了 UTC 或系统时区。HIS 里时间字段很多是DATETIME不带时区一对比就偏差。解决在jdbc.url里明确写时区jdbc.urljdbc:mysql://127.0.0.1:3306/hisdb?serverTimezoneAsia/ShanghaiuseLegacyDatetimeCodefalseuseLegacyDatetimeCodefalse让驱动按serverTimezone解析日期。改完配置重启 Tomcat再插一条挂号记录验证。注意如果是老项目自己用new Date()写入那 SQL 层没问题问题只出现在读取时转换。5.5 SQL 脚本导入到一半失败BOM、DELIMITER 与触发器依赖现象用source hisdb.sql导入时执行几百条后报错退出错误信息是You have an error in your SQL syntax或者Trigger already exists。原因老 HIS 的 SQL 脚本有两个隐患。一是文件带 UTF-8 BOMMySQL 会把 BOM 当成第一个字段的一部分二是脚本里有自定义分隔符DELIMITER $$用于创建存储过程或触发器如果直接以默认分号导入过程体里的分号会提前结束语句。解决先用编辑工具去掉 BOM再在 mysql 命令行里手动执行mysql -uroot -p hisdb --default-character-setutf8mb4 -e source /path/hisdb.sql如果脚本里有DELIMITER通常用mysql客户端 source 是可以识别的但要注意整个文件里不能混用$$和;的存储过程定义。对于触发器依赖表的情况最好先DROP TRIGGER IF EXISTS再创建。我习惯的做法是拆成两个文件先导入纯表结构再导入存储过程和触发器排查时能缩小范围。6. 把源码包变成你的演示环境三个进阶技巧系统能跑起来、代码也读过一遍之后接下来的目标应该是把它变成可演示、可讨论的东西。我一般会在上面加三样东西。第一样是演示数据生成器。HIS 演示最怕空库打开页面什么都没有。写一个存储过程循环生成模拟患者和挂号记录DROP PROCEDURE IF EXISTS gen_demo_data; DELIMITER $$ CREATE PROCEDURE gen_demo_data(IN num INT) BEGIN DECLARE i INT DEFAULT 0; WHILE i num DO INSERT INTO t_patient(NAME, ID_CARD, PHONE) VALUES (CONCAT(演示患者, i), CONCAT(11010119900101, LPAD(i, 4, 0)), CONCAT(138, LPAD(i, 8, 0))); SET i i 1; END WHILE; END$$ DELIMITER ; CALL gen_demo_data(500);第二样是外置配置。老 HIS 的配置文件在 war 包内每次修改要重新打包。把jdbc.properties放到 Tomcat 的conf下再在 Spring 配置里用file:路径优先加载外部配置。这样演示现场调数据库地址不用动代码。第三样是回归清单。每次改动后按患者建档→挂号→开方→收费→发药各操作一遍并核对t_register、t_prescription、t_charge、t_drug_stock四张表的记录数。这张清单我到现在还在用因为它能用最短的时间验证掉最关键的资金流和数据流。我最后一次部署 HIS 演示环境时就因为没留意时区明明库里记录正常页面时间却差 8 小时被现场问得下不来台。从那以后我每次改完配置都会重新跑一遍这四个流程再对一遍时间字段。这套习惯也分享给你希望帮到你。本文还有配套的精品资源点击获取