1. 项目概述
智能药箱系统医药进销存管理系统是一个面向医药零售、家庭用药管理场景的综合性解决方案。这个系统将传统药品管理与现代物联网技术相结合,实现了药品从采购入库到销售出库的全流程数字化管理。
我在实际开发中发现,这类系统最核心的价值在于解决了三个痛点:一是药品效期管理混乱导致的过期浪费问题;二是库存盘点效率低下;三是缺乏用药提醒功能。系统采用SpringBoot框架开发,前端使用Thymeleaf模板引擎,数据库选用MySQL,整体架构遵循MVC模式。
提示:医药管理系统属于特殊行业应用,开发时需特别注意药品分类规范和数据安全性要求。
2. 系统架构设计
2.1 技术选型分析
后端采用SpringBoot 2.7.x版本,主要基于以下考虑:
- 自动配置特性大幅减少XML配置
- 内嵌Tomcat简化部署流程
- 丰富的Starter依赖快速集成常用组件
- 完善的健康检查机制保障系统稳定性
数据库选择MySQL 8.0而非5.7,主要因为:
- 原生JSON支持更好,适合存储药品的扩展属性
- 窗口函数便于生成复杂的销售统计报表
- 性能提升明显,特别是在连接数较高时
2.2 核心模块划分
系统包含六大功能模块:
- 基础信息管理:药品分类、供应商管理
- 库存管理:入库、出库、调拨、盘点
- 销售管理:零售、批发、退货处理
- 智能预警:效期预警、库存预警
- 报表统计:销售分析、库存周转率
- 系统管理:用户权限、操作日志
3. 数据库设计要点
3.1 关键表结构
sql复制CREATE TABLE `medicine` (
`id` bigint NOT NULL AUTO_INCREMENT,
`code` varchar(20) NOT NULL COMMENT '药品编码',
`name` varchar(100) NOT NULL,
`spec` varchar(50) NOT NULL COMMENT '规格',
`unit` varchar(10) NOT NULL COMMENT '单位',
`category_id` int NOT NULL COMMENT '分类ID',
`price` decimal(10,2) NOT NULL,
`cost` decimal(10,2) NOT NULL COMMENT '成本价',
`manufacturer` varchar(200) DEFAULT NULL,
`approval_number` varchar(50) DEFAULT NULL COMMENT '批准文号',
`barcode` varchar(50) DEFAULT NULL,
`shelf_life` int DEFAULT NULL COMMENT '保质期(月)',
`storage_condition` varchar(20) DEFAULT NULL COMMENT '存储条件',
`status` tinyint NOT NULL DEFAULT '1',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_code` (`code`),
KEY `idx_category` (`category_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
3.2 库存设计难点
库存管理采用"批次+货位"的双维度设计:
- 每个入库批次记录生产日期和效期
- 货位管理实现物理库存的精确定位
- 采用FIFO(先进先出)策略自动推荐出库批次
库存扣减使用乐观锁机制防止超卖:
java复制@Transactional
public boolean reduceStock(Long medicineId, String batchNo, Integer quantity) {
// 查询当前库存
Stock stock = stockMapper.selectForUpdate(medicineId, batchNo);
if(stock.getQuantity() < quantity) {
throw new BusinessException("库存不足");
}
// 乐观锁更新
int rows = stockMapper.reduceStock(medicineId, batchNo, quantity, stock.getVersion());
return rows > 0;
}
4. 核心功能实现
4.1 智能预警模块
效期预警使用Spring Scheduled定时任务:
java复制@Scheduled(cron = "0 0 9 * * ?") // 每天9点执行
public void checkExpiringMedicines() {
LocalDate warnDate = LocalDate.now().plusMonths(3); // 提前3个月预警
List<MedicineBatch> expiring = batchMapper.selectExpiring(warnDate);
expiring.forEach(batch -> {
String message = String.format("药品[%s]批次%s将在%s过期",
batch.getMedicineName(),
batch.getBatchNo(),
batch.getExpireDate());
warningService.sendWarning(batch.getResponsiblePerson(), message);
});
}
4.2 销售统计分析
使用MyBatis动态SQL构建销售统计:
xml复制<select id="selectSalesReport" resultType="SalesReportDTO">
SELECT
m.name as medicineName,
m.category_id as categoryId,
SUM(sd.quantity) as totalQuantity,
SUM(sd.amount) as totalAmount
FROM sale_detail sd
JOIN medicine m ON sd.medicine_id = m.id
WHERE 1=1
<if test="startDate != null">
AND sd.create_time >= #{startDate}
</if>
<if test="endDate != null">
AND sd.create_time <= #{endDate}
</if>
<if test="categoryId != null">
AND m.category_id = #{categoryId}
</if>
GROUP BY m.id
ORDER BY totalAmount DESC
LIMIT 100
</select>
5. 系统部署方案
5.1 环境要求
推荐部署配置:
- 服务器:2核4G以上
- JDK:Amazon Corretto 11
- MySQL:8.0.x + 配置innodb_buffer_pool_size=2G
- Redis:6.x 用于缓存和会话管理
5.2 启动参数优化
application-prod.yml关键配置:
yaml复制server:
tomcat:
max-threads: 200
min-spare-threads: 20
spring:
datasource:
hikari:
maximum-pool-size: 30
connection-timeout: 30000
redis:
lettuce:
pool:
max-active: 50
max-idle: 20
6. 开发注意事项
-
药品编码规范:建议采用69码标准,前3位国别码,4-8位厂商码,9-12位商品码,最后1位校验码
-
效期计算陷阱:
- 药品效期通常标注"有效期至",如"2025-03"表示到2025年3月31日
- 计算剩余天数时需注意时区问题
-
事务处理要点:
- 销售出库需在同一个事务中完成库存扣减和销售记录
- 使用@Transactional(rollbackFor = Exception.class)确保异常回滚
-
安全规范:
- 药品数据属于敏感信息,需加密存储
- 操作日志需记录完整操作轨迹
- 实现数据权限控制,不同门店只能查看自己的数据
7. 常见问题排查
7.1 库存不一致问题
排查步骤:
- 检查是否有直接操作数据库的情况
- 确认所有库存变更都通过统一服务入口
- 检查事务隔离级别是否为READ_COMMITTED
- 定期执行库存校对脚本
7.2 效期预警未触发
检查清单:
- 确认定时任务是否启用@EnableScheduling
- 检查服务器时间是否正确
- 查看应用日志是否有任务执行记录
- 验证SQL查询条件是否正确
8. 扩展功能建议
-
移动端对接:
- 开发微信小程序实现扫码入库
- 用药提醒推送至用户手机
-
智能硬件集成:
- 对接智能药箱硬件实现自动库存同步
- 温湿度传感器监控存储环境
-
数据分析增强:
- 使用Elasticsearch实现销售趋势分析
- 基于历史数据预测库存需求
在实际部署时发现,系统性能瓶颈往往出现在库存查询接口,建议对高频访问的库存数据使用Redis缓存。一个实用的技巧是为药品分类建立多级缓存,一级缓存有效期5分钟,二级缓存1小时,可大幅降低数据库压力。