news 2026/10/18 10:47:09

SSM+MySQL医院分诊管理系统源码解析:从权限设计到部署避坑指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SSM+MySQL医院分诊管理系统源码解析:从权限设计到部署避坑指南

简介:这是一个基于SSM框架与MySQL的医院分诊管理系统完整源码,面向JavaWeb学习者、毕业设计或课程设计人群,用于理解医生分诊叫号、患者信息维护、科室管理等业务流程。系统包含可运行的前后端与数据库文件,能实现分诊管理、患者管理、科室管理、系统监控等功能,并支持在线叫号与就诊状态统计。压缩包共2000个文件,约43.65MB,其中包含3341个png页面素材、182个js脚本、91个jar依赖、83个class编译文件、76个java源码、34个jsp页面以及3个sql数据库脚本等,类型覆盖前端页面、后端逻辑、依赖库与数据库初始化,便于直接导入工程学习。已有286人学习下载。适合需要完整SSM项目参考、理解医院分诊场景并希望基于现有代码二次开发的读者,借助项目中完整的业务模块划分与数据库脚本,可快速梳理流程并运行验证。

1. 医院分诊管理系统能落地吗:先说清楚这个 ssm+mysql 项目解决了什么

这是一份真正能跑通的医院分诊管理系统源码,后端用 SSM(Spring + SpringMVC + MyBatis),数据库用 MySQL,前端页面和日期控件都带全了。它不是只写了个登录页的课程设计空壳,而是把分诊、叫号、患者管理、科室管理、系统监控做成了完整闭环:医生登录后点“分诊管理”,能看到待分诊的患都信息,选定科室后直接在线叫号,患者完成就诊后状态自动推进。适合正在做 SSM 课设、需要一份完整业务参考的开发者,也适合想拿现成后台快速做二开的从业者。最直接的用途,就是把这套流程拆开看明白 SSM 项目里权限、分诊、状态流转到底是怎么组织的。

2. 拆解分诊系统的骨架:登录、权限与叫号数据流

拿到源码包先别急着启动,我建议先看几个关键文件:UserController、RoleController、UserRealm、SimpleHibernateDao、JsonMapper。别看它们零散,它们分别对应着后端的三层结构边界:Controller 层接收请求,Service 层处理业务,Dao 层通过 MyBatis 和 MySQL 交互。HibernateDao 这个名字容易让人误以为项目用了 Hibernate,其实在 SSM 项目里这通常只是一个通用 DAO 基类,命名沿用 Hibernate 风格,真正的持久层框架还是 MyBatis。下面按我复现时的理解把这些模块拆开讲。

2.1 SSM+MySQL 的选型逻辑:为什么这套组合能撑住分诊场景

分诊系统的核心数据量并不大,一个普通医院信息科管理几百条患者记录、几十个科室,单次查询和写入的压力远没到需要微服务或 NoSQL 的级别。SSM 在这种业务体量下显得非常合适:Spring 负责统一管理对象和事务,SpringMVC 负责把前端请求映射到 Controller,MyBatis 负责把 SQL 和 Java 方法做映射,MySQL 负责持久化。三层职责清楚,出问题时定位也直接。

资源里已经编译好的 .class 文件正好说明了它的结构:User.class 是用户实体,UserController 和 RoleController 是控制层入口,SimpleHibernateDao 提供通用的增删改查,JsonMapper 负责把 Java 对象转成 JSON 给前端 AJAX 调用。这种组织方式现在看可能有点“老派”,但对于想学 SSM 的人来说,它反而比 Spring Boot 那种自动装配更透明:每个 Bean 怎么创建的、每个 SQL 从哪里来,翻源码就能看到。

对于生产场景,这套组合的边界也很明确:它适合内部管理系统,不适合高并发对外业务。如果是给医院做正式生产环境,我一般会建议后面再套一层缓存和读写分离,但在源码学习、毕业设计、内部管理系统复现这个层面,SSM+MySQL 完全够用。

2.2 权限控制:User、RoleController、UserRealm 各自的职责

权限这块是这套系统里最值得看的部分。UserRealm.class 是 Apache Shiro 的核心扩展点,项目里登录认证和角色授权都在这个类里实现。常见做法是让它继承 AuthorizingRealm,重写两个方法:

public class UserRealm extends AuthorizingRealm { @Autowired private UserService userService; // 登录时调用:根据用户名查出用户,比对密码 @Override protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken token) throws AuthenticationException { String username = (String) token.getPrincipal(); User user = userService.findByUsername(username); if (user == null) { throw new UnknownAccountException("账号不存在"); } return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), ByteSource.Util.bytes(user.getSalt()), getName()); } // 授权时调用:查询角色与权限标识 @Override protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principals) { String username = (String) principals.getPrimaryPrincipal(); Set<String> roles = userService.findRolesByUsername(username); Set<String> perms = userService.findPermsByUsername(username); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); info.setRoles(roles); info.setStringPermissions(perms); return info; } }

密码处理那行值得多说一句:SimpleAuthenticationInfo 里传入了 salt 字节源,说明用户表通常有 password 和 salt 两个字段,密码不是明文存储,而是 MD5 加盐后保存。如果你在导入数据库后登录不上,先查这两个字段的格式,不要一上来就怀疑代码有 Bug。

数据库里对应三张核心表:sys_user、sys_role、sys_user_role。UserController 负责维护用户,RoleController 负责维护角色,这两张表通过中间关联表建立多对多关系。登录后 Shiro 会通过 UserRealm 加载该用户的角色和权限,前端菜单再根据权限标识显示或隐藏,这就实现了“分诊管理只有医生能看到,系统管理只有管理员能看到”的效果。你如果想把某个权限收窄,不用改代码,只需要在角色管理里给该角色去掉对应权限标识。

2.3 分诊主流程:患者添加、科室选择、叫号、完成就诊

分诊模块是整个系统的业务核心,也是最值得照着做一遍完整流程的地方。从摘要描述里可以提炼出这样一条数据流:先到“患者管理”里添加患者,添加成功后切到“分诊管理”,能看到这个患者出现在待分诊列表里,选择纠正科室后点击叫号,患者状态变为已叫号,医生在对应科室界面执行就诊完成,状态再推进到已完成。

我复现时在 Controller 里看到的典型处理逻辑是这样的:

@Controller @RequestMapping("/patient") public class PatientController { @Resource private PatientService patientService; @RequestMapping("/add") @ResponseBody public JsonResult addPatient(Patient patient) { // 0=待分诊 1=已分诊 2=已叫号 3=已完成 patient.setStatus(0); patient.setCreateTime(new Date()); patientService.insert(patient); return JsonMapper.toJsonResult(true, "患者登记成功"); } }

这段代码的关键是 status 字段。一个患者从登记到完成就诊,就是 status 从 0 一路变到 3 的过程。前端“分诊管理”点击叫号,后端其实就是一个 update 语句把 status 从 1 改成 2;点击完成就诊,就把 status 改成 3。“是否已经完成就诊”这个展示列,本质就是 status 状态的可视化。

再看分诊列表的查询 SQL,这是业务里最能体现表关系的部分:

<select id="listTriagePatients" resultType="com.example.entity.TriagePatientVO"> SELECT p.id, p.name, p.sex, p.age, p.dept_id, d.dept_name, p.status, p.triage_time FROM triage_patient p LEFT JOIN triage_dept d ON p.dept_id = d.id <where> <if test="deptId != null and deptId != ''"> AND p.dept_id = #{deptId} </if> <if test="status != null"> AND p.status = #{status} </if> </where> ORDER BY p.triage_time DESC </select>

这里用 LEFT JOIN 而不是 JOIN,原因是刚登记但还没分配科室的患者 dept_id 可能是空的,LEFT JOIN 能保证这类患者依然显示在分诊列表里。如果你自己在改需求,要注意这个点:用 INNER JOIN 会把还没选科室的患者过滤掉,用户就“找不到刚添加的人”了,这是一个特别常见的翻车点。

科室管理的本质是维护 triage_dept 表,前端加科室就是往这张表 INSERT 一条记录。系统监控部分则对应资源里的 ScheduleJobService.class,这类类通常用 Quartz 或 Spring Task 跑定时任务,比如每天统计各科的就诊人数、清理长期未完成的挂号记录。你可以在源码里搜一下这个类的调用处,就能看到定时统计是怎么接进去的。

3. 本地部署与配置:从 JDK 到数据库脚本,六步把系统跑起来

部署 SSM 项目跟部署 Spring Boot 不一样,它不是打好一个 jar 包里就启动就完事,而是要管理 Web 容器、数据库脚本、配置文件三个部分。这套系统的部署顺序建议按下面几步走,每一步都顺手验证一下再往下推进。

3.1 环境准备与版本匹配:JDK、Maven、Tomcat、MySQL

最稳的组合是 JDK 1.8、Maven 3.6、Tomcat 8.5、MySQL 5.7。资源既然已经带 .class 文件,开发者大概率就是用 JDK 1.8 编译的,你如果用更高版本也可能能跑,但排查成本会上升,不建议在环境上给自己挖坑。

先验证当前环境:

java -version mvn -v mysql --version

逻辑说明:这三条命令分别查看 JDK、Maven、MySQL 版本。SSM 项目常见的问题是编译版本和运行版本不一致,比如用 JDK 11 编译出来的 class 放到 JDK 8 的 Tomcat 里会直接报 UnsupportedClassVersionError。如果你电脑上装的是 JDK 17,我一般建议先装一个 JDK 8 并调整 JAVA_HOME,再跑这个项目——这个系统的代码基本是按老式写法写的,Lambda 和模块化特性用得少,JDK 8 最保险。

参数说明:Tomcat 版本不要低于 8,因为项目里可能用到了 Servlet 3.0 的异步注解;MySQL 5.7 和 8.0 在连接驱动上差异比较大,下面配置里会专门说明。

3.2 创建数据库与导入初始数据

源码包里的 SQL 文件一般命名为 xxx.sql 或 db.sql,先别急着双击导入,先建库再导数据,避免表名冲突。推荐在命令行里操作,比可视化工具更直观:

CREATE DATABASE IF NOT EXISTS triage_system DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci; USE triage_system; SOURCE /your/path/triage_system.sql;

逻辑说明:第一条语句创建数据库,字符集指定为 utf8mb4,这能同时兼容中文和 emoji,避免出现网页上问号乱码。第二条 SOURCE 是 MySQL 命令行导入脚本的指令,注意脚本里如果本身有 CREATE DATABASE 语句,你前面的建库可以省略,但先建库的好处是能控制字符集和权限,避免脚本默认设置不符合预期。

导入完成后验证一下关键表:

SHOW TABLES; SELECT id, username, status FROM sys_user;

如果能查到用户数据,说明脚本导入成功。如果查 tasys_user 为空,再看一眼 SQL 脚本里有没有插入语句——有些源码故意把初始化数据放成单独文件,需要一并导入。

3.3 修改 jdbc.properties 并部署到 Tomcat

SSM 项目的数据库连接信息通常集中在 jdbc.properties,位置一般在 src/main/resources 下。打开文件,把连接地址、用户名、密码改成你自己的:

jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/triage_system?useUnicode=true&characterEncoding=utf8 jdbc.username=root jdbc.password=yourpassword

参数说明:driver 用的是 com.mysql.jdbc.Driver,对应 MySQL 5.x 的驱动包。如果你用的是 MySQL 8.0,需要换成 com.mysql.cj.jdbc.Driver,并且连接地址带上 serverTimezone=Asia/Shanghai,否则启动时易报时区错误。

改完配置后,用 Maven 打包成 war:

mvn clean package -DskipTests

打包产物在 target 目录下,一般叫 triage_system.war。把它复制到 Tomcat 的 webapps 目录,启动 Tomcat:

cp target/triage_system.war $TOMCAT_HOME/webapps/ $TOMCAT_HOME/bin/startup.sh

启动后访问系统登录页。如果页面 404,先去 Tomcat 的 logs/catalina.out 看有没有部署成功;如果看到报错信息是数据库相关,回到 jdbc.properties 检查配置。

3.4 遗留的 WdatePicker.js.bak:日期控件的备份文件怎么用

源码包里出现的 WdatePicker.js.bak,是 My97 日期选择器插件脚本的备份文件。正常的日期插件目录下应该有一个 WdatePicker.js,如果它在部署时被自动改名或损坏,页面上的日期选择框就会空白或点击无响应。

处理方式很直接:在 WebRoot 或 webapp 的 js 目录下找到 WdatePicker.js.bak,把它复制一份并重命名为 WdatePicker.js,然后强制刷新浏览器缓存。不要直接删掉 .bak,因为它可能包含你当前项目正在引用的版本内容,删了再想找回就麻烦了。

实际操作命令:

cd your_project/webapp/static/My97DatePicker/ cp WdatePicker.js.bak WdatePicker.js

这里加 cp 而不是 mv,是给自己留后悔药:万一新文件有问题,备份还在。部署到生产环境前,建议把 .bak 移除或保留在源码包之外,因为服务器上部署时多余文件不会帮你跑通功能,反而可能有安全隐患。

4. 避坑排查:从启动失败到中文乱码的几个常见现场

这一章把我的实测踩坑记录按环境、功能、数据三类整理出来。每条我都按“现象 → 原因 → 解决”来写,你可以直接对照排查。

4.1 环境类:端口占用、MySQL 连接失败、时区报错

现象一:启动 Tomcat 后访问页面,提示连接被重置或直接看不到服务,查看日志发现端口被占用。

原因:Tomcat 默认 8080 端口被其他 Java 进程或其他 Web 容器占用。

解决:先用命令确认占用情况,再决定是让项目换端口还是清理原进程:

netstat -ano | grep 8080 kill 占用该端口的进程

如果不想杀进程,直接改 Tomcat 的 server.xml 里 8080 端口为 8090,再重启。无论哪种,都要保证项目前端写的请求地址和实际端口一致。

现象二:应用启动后报 Cannot create PoolableConnectionFactory 或 Access denied for user。

原因:jdbc.properties 里的数据库用户名或密码不对,或者 MySQL 用户没有访问当前库的权限。

解决:先用命令行手动登录验证:

mysql -uroot -p USE triage_system; SELECT 1;

如果命令行能通过,说明配置问题;如果命令行也失败,就是 MySQL 用户权限问题,执行授权语句,然后把密码改成与代码一致。

现象三:MySQL 8 下项目启动报 Unknown time zone 或者 Connection reset by peer。

原因:MySQL 8 驱动要求明确时区,而旧项目的连接 URL 没有配置 serverTimezone。

解决:把驱动换成 mysql-connector-java 8.x,并在连接 URL 加 serverTimezone=Asia/Shanghai,这样时间和本地保持一致,也避免 Jackson 序列化时间时把日期偏到前一天。

4.2 功能类:分诊列表不显示新患者、叫号按钮无反应

现象四:在患者管理里添加患者成功,切到分诊管理却看不到刚加的人。

原因:最常见的是查询 SQL 默认过滤了 status > 0,或者前端默认只显示“未分诊”状态;以及刚保存的数据还没生效。

解决:先到数据库里直接确认这条记录是否存在:

SELECT id, name, status, dept_id FROM triage_patient WHERE name = '刚添加的患者名' ORDER BY id DESC LIMIT 3;

如果记录存在,就看前端列表是否按状态过滤;如果记录不存在,看后端有没有提交事务。SSM 项目里 @Service 方法忘记加 @Transactional 时,插入报错后事务没回滚,页面可能提示成功但数据库没写进去。这种情况我一般会在 Service 实现类上补上 @Transactional(rollbackFor = Exception.class),并打印 SQL 日志确认执行过程。

现象五:点击“叫号”按钮没反应,浏览器控制台报 404 或 JS 错误。

原因:前端请求路径与后端 Controller 的 RequestMapping 不一致,最常见是项目部署名导致上下文路径变化。

解决:打开浏览器开发者工具,把报错的请求 URL 复制出来,对比 Controller 里的路径。如果实际访问的路径多了一层 /triage_system,而你 Controller 里写的是 /patient/call,那前端应该写上下文路径加映射路径。用 Thymeleaf 或 JSP 的${pageContext.request.contextPath}获取上下文路径,不要硬编码请求路径,这是根本解决方式。

4.3 数据类:中文乱码、密码登录失败、日期显示偏移

现象六:添加患者后,页面和数据库里的中文全是问号或乱码。

原因:连接串缺少 characterEncoding,或者数据库表本身是 latin1 字符集。

解决:

jdbc.url=jdbc:mysql://localhost:3306/triage_system?useUnicode=true&characterEncoding=utf8&useSSL=false

同时把表和字段字段类型都调整为 utf8mb4:

ALTER TABLE triage_patient DEFAULT CHARACTER SET utf8mb4; ALTER TABLE triage_patient MODIFY COLUMN name VARCHAR(50) CHARACTER SET utf8mb4 NOT NULL;

调整之前注意备份数据,这是最保险的做法。

现象七:输入正确密码却登录失败,提示密码错误。

原因:用户表里的密码是加盐哈希后的结果,而你手动改过表里的密码为明文,或者你忘记了源码默认的初始化密码格式。

解决:进数据库查一下原用户密码字段,确认它是否是一串长度固定的哈希值。如果是,就不要手工 update 成明文,应该走“修改密码”功能,让后端用相同算法重新生成哈希。项目里如果有注册或重置密码入口,从那里面操作是最稳妥的。

现象八:患者新增记录的时间显示比实际时间晚 8 小时。

原因:Tomcat 服务器时区和 MySQL 时区不一致,数据库写入的 datetime 用的是系统时区,前端展示时又按本地时区格式化,导致偏移。

解决:统一时区。在连接 URL 后加 serverTimezone=Asia/Shanghai,并在 MySQL 里执行 SET time_zone = '+8:00',如果还是不对,再看前端时间格式化的代码,确认不是手动做了加减。这个问题经常被当成“玄学”,其实就是时区没有统一,排查时按数据库、JDBC 驱动、前端格式化三层逐一排除。

5. 复现验证与进阶:创建一个新科室,把数据流从界面一路跟踪到数据库

把系统跑通之后,建议你做一次最小改造:在科室管理里新增一个“发热门诊”,用这一次操作验证整个 MVC 链路是否正确。这个验证方式能帮你检验前面所有配置是否真的生效,也能让你快速看清一个 SSM 项目的可扩展性。

新增科室页面的表单提交后,后端 Controller 大致会做这样一件事:

@Controller @RequestMapping("/dept") public class DeptController { @Resource private DeptService deptService; @RequestMapping("/save") @ResponseBody public JsonResult saveDept(Dept dept) { dept.setCreateTime(new Date()); dept.setStatus(1); deptService.insert(dept); return JsonMapper.toJsonResult(true, "科室添加成功"); } }

代码逻辑很简单,但你可以跟着三步验证:第一,看数据库 triage_dept 表是否多出这条记录;第二,退出系统重新登录,看分诊管理里患者选科室的下拉框是否出现“发热门诊”;第三,新建一个患者并把科室切换成发热门诊,再完成一次叫号,看列表里的状态是否从待分诊推进到叫号状态。

做完这个实验,你基本就掌握了这套源码的骨架:一个实体对应一张表,一个 Controller 对应一组页面操作,状态字段贯穿业务链路。之后想加“医生排班”或“挂号统计”模块,也是按同样的节奏去扩展:建表、写实体和 Mapper、写 Service、写 Controller、挂菜单权限。

另外,我建议你花十分钟做一件事:把 triage_patient 和 sys_user 的关联逻辑梳理一遍,看看分诊记录里是否记录了操作医生 ID。如果有,说明系统已经具备“统计每个医生接诊量”的基础;如果没有,这就是一个很好的扩展练习点。我在接手这类源码时,通常会用 Navicat 或 DataGrip 把表之间的关系画出来,再对照前端菜单确认每个菜单最终操作的是哪几张表,这样做比凭空看代码高效得多。

这套系统最让我认可的一点是它没有把业务做成玩具,状态流转、权限控制、科室管理都是真实的实现方式。但我第一次跑起来时还是栽在端口占用和 MySQL 版本上,后来我拿到任何 SSM 项目,都会强制自己按“先看 SQL 脚本、再查 jdbc 配置、最后启动容器”的顺序走一遍,确认环境三件套无误后,再去动业务代码。希望这些经验帮你在跑这个分诊系统时少踩一些坑。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/18 10:44:52

高光谱图像Matlab处理:PCA、KNN与CNN降维分类实战指南

简介&#xff1a;面向遥感、农业与环保领域研究人员的高光谱图像处理Matlab工具包&#xff0c;聚焦PCA、KNN与CNN三类核心算法代码实现。针对高光谱数据波段多、维度高、传统分类方法效率低的问题&#xff0c;资源提供了从主成分降维到K近邻分类、再到卷积神经网络训练的一整套…

作者头像 李华
网站建设 2026/10/18 10:43:12

基于Python+MADDPG的多智能体博弈对抗算法代码包拆解

简介&#xff1a;基于Python与MADDPG的多智能体博弈对抗算法资源包&#xff0c;面向系统学习多智能体强化学习的学生和开发者&#xff0c;适用于毕业设计、课程设计、大作业、工程实训或初期项目立项&#xff0c;能够帮助解决单智能体算法无法处理多智能体交互与对抗场景的问题…

作者头像 李华
网站建设 2026/10/18 10:39:33

AI写论文的正确打开方式:人机协作流程与文献真实性避坑指南

又到论文季了。朋友圈、群聊、各种收藏夹里&#xff0c;又开始飘起“AI写论文”“一键生成”“真实参考文献”这些词。我见过太多人被“10分钟生成万字”这种标题吸引点进去&#xff0c;然后拿着一堆AI吐出来的空话和假文献&#xff0c;在DDL前夜手忙脚乱。今天这篇&#xff0c…

作者头像 李华
网站建设 2026/10/18 10:38:34

Sublime Text 3便携版从配置到迁移:完整避坑指南

简介&#xff1a;面向编程开发者的 Sublime Text 3 免安装便携版&#xff0c;定位是轻量高效的代码编辑工具&#xff0c;解压后即可直接运行&#xff0c;省去安装与注册步骤&#xff0c;适合日常编码、移动办公或在不同电脑间快速迁移开发环境&#xff1b;编辑器支持多种编程语…

作者头像 李华
网站建设 2026/10/18 10:37:37

SSM+Vue学生综合素质评价系统:源码部署与答辩改造指南

简介&#xff1a;压缩包内是一套基于SSM框架和MySQL的高校学生综合素质评价系统&#xff0c;面向计算机相关专业学生&#xff0c;特别适合用于毕业设计或SSM整合开发实践。系统角色分为管理员、学生和教师&#xff0c;功能包括用户登录、学生注册、教师注册、个人中心、修改密码…

作者头像 李华
网站建设 2026/10/18 10:35:28

大模型上车实战:端侧部署、推理优化与数据闭环的落地指南

去年年底&#xff0c;我所在的团队接到一个任务&#xff1a;把一套基于大语言模型的语音助手从云端搬到车机端侧。项目组里吵得不可开交&#xff0c;有人觉得十亿参数模型上车&#xff0c;算力和内存都兜不住&#xff1b;有人坚持说用户反馈的延迟问题必须靠端侧解决&#xff0…

作者头像 李华