1. 项目概述
药店药品管理系统是医药零售行业的核心业务支撑平台,基于SpringBoot框架开发的这套系统,能够有效解决传统药店手工记账、库存混乱、效期管理困难等痛点。我在实际开发中发现,一个完善的药品管理系统需要包含药品基础信息管理、库存管理、采购管理、销售管理、报表统计等核心模块,同时还要符合GSP(药品经营质量管理规范)的合规要求。
SpringBoot作为当前Java领域最流行的微服务框架,其自动配置、起步依赖等特性大幅降低了系统开发复杂度。结合MyBatis-Plus、Thymeleaf等技术栈,可以快速构建出高可用的药品管理系统。特别在应对药店高频次、多并发的业务场景时,SpringBoot的内置Tomcat容器和缓存机制能够保证系统稳定运行。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心功能模块设计
2.1 药品基础信息管理
药品基础信息是系统的核心数据,需要建立完善的药品主数据模型:
java复制@Entity
@Table(name = "drug_info")
public class Drug {
@Id
private String drugCode; // 药品编码(国药准字)
private String drugName; // 通用名称
private String spec; // 规格
private String unit; // 单位
private String manufacturer; // 生产厂家
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date productionDate; // 生产日期
private Integer shelfLife; // 保质期(月)
// Getters & Setters
}
关键实现要点:
- 采用MyBatis-Plus实现CRUD操作,配合PageHelper实现分页查询
- 药品编码需遵循国家药品编码规则,建立唯一性约束
- 实现药品图片上传功能,使用SpringBoot文件上传组件
2.2 库存管理模块
库存管理需要解决的核心问题:
- 实时库存监控
- 库存预警(低于安全库存时提醒)
- 批次管理和效期追踪
库存变更的典型场景处理:
java复制@Transactional
public void updateStock(String drugCode, Integer changeAmount,
String batchNo, OperationType type) {
// 1. 检查药品是否存在
Drug drug = drugMapper.selectById(drugCode);
if(drug == null) throw new BizException("药品不存在");
// 2. 更新库存记录
Stock stock = stockMapper.selectByDrugAndBatch(drugCode, batchNo);
if(stock == null) {
stock = new Stock(drugCode, batchNo, changeAmount);
stockMapper.insert(stock);
} else {
stock.setAmount(stock.getAmount() + changeAmount);
stockMapper.updateById(stock);
}
// 3. 记录库存变更日志
StockLog log = new StockLog(drugCode, batchNo, changeAmount, type);
stockLogMapper.insert(log);
}
重要提示:库存操作必须添加事务注解,保证数据一致性。对于高频操作的商品,建议引入Redis缓存库存数据。
3. 技术架构详解
3.1 系统技术选型
| 技术组件 | 选型理由 | 版本要求 |
|---|---|---|
| SpringBoot | 快速开发、内嵌Tomcat、自动配置 | 2.7.x |
| MyBatis-Plus | 简化DAO层开发,强大CRUD接口 | 3.5.2+ |
| MySQL | 关系型数据库,事务支持完善 | 8.0+ |
| Redis | 缓存热点数据,提升系统响应速度 | 6.x |
| Thymeleaf | 服务端模板渲染,适合管理后台 | 3.0.15 |
| PageHelper | 实现物理分页,避免内存溢出 | 1.4.1+ |
3.2 分层架构设计
code复制com.pharmacy
├── config # 配置类
├── controller # 控制层
├── service # 业务层
│ ├── impl # 实现类
├── dao # 数据访问层
├── entity # 实体类
├── dto # 数据传输对象
├── util # 工具类
└── exception # 异常处理
关键配置示例(application.yml):
yaml复制spring:
datasource:
url: jdbc:mysql://localhost:3306/pharmacy?useSSL=false
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
redis:
host: 127.0.0.1
port: 6379
mybatis-plus:
mapper-locations: classpath:mapper/*.xml
configuration:
map-underscore-to-camel-case: true
4. 核心业务实现
4.1 药品采购流程
- 采购单创建 → 2. 供应商选择 → 3. 药品添加 → 4. 审批流程 → 5. 入库确认
采购单状态机设计:
java复制public enum PurchaseStatus {
DRAFT("草稿"),
SUBMITTED("已提交"),
APPROVED("已审批"),
REJECTED("已驳回"),
PART_RECEIVED("部分入库"),
COMPLETED("已完成");
// ...
}
4.2 药品销售流程
销售模块需要特别注意的合规要求:
- 处方药必须凭医师处方销售
- 需要记录购买者身份信息(身份证号)
- 特殊药品需要双人复核
销售接口示例:
java复制@PostMapping("/sale")
public Result saleDrug(@RequestBody SaleDTO saleDTO) {
// 1. 验证处方药权限
if(drugService.isPrescriptionDrug(saleDTO.getDrugCode())) {
if(StringUtils.isEmpty(saleDTO.getPrescriptionNo())) {
throw new BizException("处方药必须提供处方编号");
}
}
// 2. 检查库存
Integer stock = stockService.getStock(saleDTO.getDrugCode());
if(stock < saleDTO.getAmount()) {
throw new BizException("库存不足");
}
// 3. 执行销售
return saleService.createSale(saleDTO);
}
5. 特殊业务处理
5.1 药品效期管理
效期预警是药品管理的重点,需要定时任务扫描:
java复制@Scheduled(cron = "0 0 9 * * ?") // 每天上午9点执行
public void checkExpiration() {
List<Drug> expiringDrugs = drugMapper.selectExpiringDrugs(30); // 30天内过期
expiringDrugs.forEach(drug -> {
String message = String.format("药品【%s】批次%s将在%s过期",
drug.getDrugName(), drug.getBatchNo(), drug.getExpireDate());
alertService.sendAlert(message);
});
}
5.2 数据统计分析
使用ECharts实现销售统计报表:
javascript复制// 前端代码示例
function initSalesChart() {
const chart = echarts.init(document.getElementById('chart'));
$.get('/api/sales/stats', function(data) {
chart.setOption({
title: { text: '月度销售统计' },
tooltip: {},
xAxis: { data: data.months },
yAxis: {},
series: [{
name: '销售额',
type: 'bar',
data: data.amounts
}]
});
});
}
6. 系统部署方案
6.1 本地开发环境
- 安装JDK 1.8+
- 安装MySQL 8.0和Redis
- IDEA中导入Maven项目
- 修改application-dev.yml配置
- 启动PharmacyApplication主类
6.2 生产环境部署
推荐使用Docker Compose部署:
dockerfile复制version: '3'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: 123456
volumes:
- ./mysql/data:/var/lib/mysql
redis:
image: redis:6
ports:
- "6379:6379"
app:
build: .
ports:
- "8080:8080"
depends_on:
- mysql
- redis
7. 常见问题解决方案
7.1 性能优化实践
- 缓存热点数据:
java复制@Cacheable(value = "drug", key = "#drugCode")
public Drug getByCode(String drugCode) {
return drugMapper.selectById(drugCode);
}
- 批量操作优化:
java复制@Transactional
public void batchImport(List<Drug> drugs) {
// 使用MyBatis-Plus的saveBatch方法
drugService.saveBatch(drugs, 100); // 每批100条
}
7.2 事务处理陷阱
典型错误示例:
java复制public void updateStock(String drugCode, int amount) {
// 错误:未加事务注解
Drug drug = drugMapper.selectById(drugCode);
drug.setStock(drug.getStock() + amount);
drugMapper.updateById(drug);
}
正确做法:
java复制@Transactional(rollbackFor = Exception.class)
public void updateStock(String drugCode, int amount) {
// 业务逻辑
}
8. 项目扩展方向
- 对接医保系统:实现医保刷卡支付功能
- 增加移动端:开发小程序或APP,支持会员管理
- 智能预警:基于销售数据预测库存需求
- 连锁管理:支持多门店数据同步和调拨
实际开发中,我发现药品管理系统的难点不在于技术实现,而在于对医药行业规范的准确把握。比如处方药销售必须完整记录处方信息,特殊药品需要双人复核等合规要求,都需要在系统设计中充分考虑。
