医院药品管理系统这个题目,在毕业设计和中小型医院信息化项目里出现频率非常高,也是我做过较多的一类Spring Boot管理系统。它表面上是普通CRUD:管理员维护用户和角色,药房维护药品,窗口扫一下处方发药,库存不够了再补个采购单。但真正做起来你会发现问题并没有这么简单——一张处方怎么变成库存扣减,一笔采购怎么变成入库流水,效期和批号怎么体现在库存余额上,这才是这套系统最考验人的地方。本文把我做这套Spring Boot医院药品管理系统的整体思路、表结构设计、核心代码逻辑和踩坑记录完整写出来,给正在选这个方向或者准备答辩的同学参考。
如果你打算把它当成一个普通增删改查项目来做,那代码肯定也能跑,但面试官一追问就会露馅。反过来,如果你把采购、发药、库存预警这些业务链路理顺了,这个项目能讲的东西其实非常多。
1. 项目动手前,先把医院药房的业务账算明白
1.1 药房管理最容易失控的三个点
我见过不止一个版本的药品管理系统,第一版几乎都长一个样子:一张药品表,字段里有drug_name、stock_num,发药就stock_num - 1,入库就stock_num + 1。这种设计在演示时没问题,但是真实药房根本没法用,原因有三个。
第一个是药品批次和效期问题。药房里的药不是按“一个药品名”来管的,同一个盐酸左氧氟沙星注射液,可能同时存在三个批号,每个批号的生产日期、有效期、进货价都可能不同。如果系统里只有一个总数量,发药时到底先发哪个批次?有效期最近的药一直压在角落里过期,这种事用Excel管都很难避免,何况系统里连批号都没有。
第二个是发药和处方的对应关系。医院药品发出去了,必须有记录能追溯:哪张处方、谁开的、发给哪个患者、哪个药师发的、发的是哪个厂的哪一批药。药品不良反应一旦需要追溯,这些信息缺一个都麻烦。普通CRUD思维很容易把发药做成一个简单的“库存减少”,完全丢失了单据上下文。
第三个是账实不一致。药房每天有成百上千次出入库动作,任何一次漏记、错记、重复操作,都会让系统库存和实物对不上。防止这个问题不能靠自觉,而是要靠业务流程设计:所有库存变动都必须源自一张上游单据,比如采购单、处方单、报损单,系统里不允许出现没有来源的“直接改库存”操作。
1.2 核心角色和流程:从采购到发药要过几道门
这个系统我建议按一个中小型医院的门诊药房加药库来建模,不接HIS、不做全流程电子病历,先把药品进销存的主干跑通。核心角色有四类:
- 系统管理员:维护用户、角色、菜单权限,处理密码重置这类事。
- 药库管理员:维护药品字典和供应商,创建采购单、执行验收入库。
- 药房药师:接收处方、审核并发药,处理退药、报损。
- 管理/财务人员:看库存金额、科室领药、月度消耗这类统计报表。
把角色理出来后,主流程就很清晰了:
药库根据药品库存上下限和安全库存发起采购单,经过审批后到货验收入库,库存增加的同时会记一条入库流水;医生开处方或者药房窗口录入处方后,药师进行处方审核和发药,系统按“近效期先出”的原则扣减对应批号的库存;如果患者退药,要有退药单把库存加回去;每天定时的任务会扫描低库存和近效期药品,生成补货建议和效期预警;最后管理层通过日/月报表查看各科室用量、药品消耗金额和库存周转情况。
我强烈建议在动手写代码之前,先在纸上把每个流转节点画出来,标清楚每张单据的状态。例如采购单可以分为草稿 → 待审核 → 已审核 → 已入库 → 已作废;处方发药则要看库存、要校验数量、要写流水,缺一步都要设计进去。业务边界清楚了,后端服务的方法边界才会清楚。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术选型和项目搭建:Spring Boot版本怎么定,依赖怎么配
2.1 Spring Boot 用 2.7 还是 3.x
如果你现在新建项目,大概率会遇到这个选择。我的建议很直接:如果目标是毕业设计、课程项目,或者希望网上搜到的教程基本都能直接照抄,那就用JDK 8 + Spring Boot 2.7.18 + MyBatis-Plus 3.5.x + MySQL 8.0,这个组合非常成熟,资料最多,坑最少。
Spring Boot 3.0以后最大的变化是javax.*迁移到了jakarta.*,很多老代码和网上复制下来的工具类会直接编译报错。另外Spring Boot 3配合MyBatis-Plus需要额外的mybatis-plus-spring-boot3-starter,Swagger也不能再用老的SpringFox,得改用springdoc-openapi,注解也换成了io.swagger.core.v3。我见过不少同学追新用了Spring Boot 3.2,结果大部分时间都花在处理依赖兼容上,业务代码反而没时间写。
在2.7版本中,Spring Security的写法也已经切换到了SecurityFilterChain,直接用WebSecurityConfigurerAdapter会报警告甚至跑不起来。建议把下面这个配置方式作为基准模板:
java复制@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf().disable()
.sessionManage
