1. 项目背景与核心价值
宠物医疗行业近年来呈现爆发式增长态势,根据行业调研数据显示,2023年国内宠物医疗市场规模已突破600亿元,年复合增长率保持在18%以上。在这种背景下,传统的手工记录药品进销存方式已经无法满足现代宠物医院的运营需求。这个基于SpringBoot的药品管理系统正是为解决以下行业痛点而生:
- 药品效期管理难题:宠物药品具有严格的保质期要求,手工台账极易出现临期药品漏检
- 批次追溯需求:医疗纠纷时需要快速定位问题药品的进货批次和流向
- 智能预警缺失:库存不足、效期临近等关键节点缺乏自动提醒机制
- 多门店协同困难:连锁型宠物医院各分院间药品调拨效率低下
系统采用B/S架构设计,前端使用Vue.js+ElementUI实现响应式布局,后端基于SpringBoot+MyBatisPlus构建,数据库选用MySQL 8.0。特别针对宠物医疗场景优化了以下功能模块:
- 特殊药品分类(驱虫药/疫苗/处方粮等)
- 宠物体重关联用药剂量计算
- 与宠物电子病历系统的API对接
2. 系统架构设计解析
2.1 技术栈选型依据
后端框架选择:
- SpringBoot 2.7.x:提供自动配置、嵌入式Tomcat等开箱即用特性,相比传统SSM框架可减少30%以上的配置代码量
- MyBatis-Plus 3.5.x:内置通用CRUD操作,配合代码生成器可快速实现基础数据操作
- Hutool 5.8.x:国产工具包,提供Excel导出、加密解密等常用工具类
前端技术方案:
- Vue 3.x组合式API:更灵活的逻辑复用方式,适合复杂业务表单开发
- Element Plus:专为管理系统优化的UI组件库,内置表单验证、表格分页等常用功能
- ECharts 5.x:用于构建药品销售趋势、库存预警等数据看板
关键提示:宠物医院系统需要特别注意GPL协议风险,商业项目应避免使用AGPL协议的依赖库
2.2 核心数据模型设计
药品主表(medicine)关键字段:
@TableName("medicine") public class Medicine { @TableId(type = IdType.AUTO) private Long id; private String medicineNo; // 药品编码(条码) private String genericName; // 通用名 private String brandName; // 商品名 private Integer petType; // 适用宠物类型(1犬/2猫/3通用) private String specification; // 规格(50mg/片) private Integer packSize; // 包装数量 private String manufacturer; // 生产厂家 private Integer approvalNumber; // 兽药批准文号 private Integer categoryId; // 分类ID(1疫苗/2驱虫...) private BigDecimal costPrice; // 成本价 private BigDecimal sellingPrice; // 零售价 private String storageCondition; // 存储条件(常温/冷藏) @TableField(fill = FieldFill.INSERT) private LocalDateTime createTime; }库存批次表(stock_batch)设计要点:
- 采用批次管理策略,同一药品不同进货批次独立记录
- 包含生产日期、有效期至等关键字段
- 实现FIFO(先进先出)算法防止药品过期
3. 核心业务模块实现
3.1 智能预警系统实现
库存预警逻辑:
@Scheduled(cron = "0 0 9 * * ?") // 每天上午9点执行 public void checkStockWarning() { // 查询库存量低于安全库存的药品 List<MedicineStockVO> lowStockList = baseMapper.selectLowStock( PharmacyConstants.STOCK_WARNING_THRESHOLD); lowStockList.forEach(item -> { String content = String.format("药品【%s】库存仅剩%d%s,请及时补货", item.getMedicineName(), item.getStock(), item.getUnit()); // 插入消息通知表 MessageWarning message = new MessageWarning(); message.setTitle("库存预警通知"); message.setContent(content); message.setMsgType(1); message.setCreateTime(LocalDateTime.now()); messageMapper.insert(message); // 调用短信通知API(需配置短信网关) if(item.getNeedSmsNotify()) { smsService.sendStockWarning(item.getKeeperPhone(), content); } }); }效期预警特殊处理:
- 对疫苗类药品提前90天预警
- 普通药品提前30天预警
- 已过期药品自动锁定禁止出库
3.2 药品批次追溯实现
采用区块链思想设计审计日志表:
CREATE TABLE `medicine_operation_log` ( `id` bigint NOT NULL AUTO_INCREMENT, `batch_no` varchar(32) NOT NULL COMMENT '药品批次号', `operation_type` tinyint NOT NULL COMMENT '1入库 2出库 3退货', `operator_id` int NOT NULL COMMENT '操作人ID', `operator_name` varchar(50) DEFAULT NULL, `operation_time` datetime NOT NULL, `related_order` varchar(50) DEFAULT NULL COMMENT '关联单据号', `before_quantity` int DEFAULT NULL COMMENT '操作前数量', `after_quantity` int DEFAULT NULL COMMENT '操作后数量', `client_ip` varchar(50) DEFAULT NULL, `device_info` varchar(200) DEFAULT NULL, PRIMARY KEY (`id`), INDEX `idx_batch_no` (`batch_no`), INDEX `idx_operation_time` (`operation_time`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;4. 特殊业务场景处理
4.1 宠物体重关联用药计算
在处方开具模块实现动态剂量计算:
<template> <el-form-item label="宠物体重(kg)" prop="petWeight"> <el-input-number v-model="form.petWeight" :precision="1" :step="0.1" :min="0.5" @change="calculateDosage"/> </el-form-item> <el-form-item label="建议用量" v-if="showDosage"> {{ dosageResult }} {{ medicine.unit }} </el-form-item> </template> <script setup> const calculateDosage = () => { if(form.petWeight && medicine.dosagePerKg) { const raw = form.petWeight * medicine.dosagePerKg // 根据规格进行取整处理(如片剂需要整片使用) if(medicine.unit === '片') { dosageResult.value = Math.ceil(raw) } else { dosageResult.value = raw.toFixed(1) } } } </script>4.2 冷链药品管理方案
针对疫苗等需要冷藏的药品:
- 在药品主表标记storage_condition=2(冷藏)
- 入库时强制填写冷藏柜编号和温度记录
- 出库时生成带有温度要求的特殊标签
- 运输过程使用蓝牙温度记录仪,数据同步到系统
5. 系统安全与合规设计
5.1 兽药GSP合规要点
权限分离:
- 采购人员不能兼任验收人员
- 处方审核与调配人员角色分离
- 系统通过RBAC模型实现职责隔离
审计追踪:
- 所有药品操作记录不可删除
- 关键数据变更记录修改前后值
- 采用数据库触发器记录敏感操作
数据备份:
- 每日凌晨执行全量备份
- 采用binlog实现增量备份
- 备份文件加密后上传至OSS
5.2 处方药管理实现
@PostMapping("/prescription/audit") public Result auditPrescription(@RequestBody AuditDTO dto) { // 检查审核人资质 if(!staffService.checkPharmacist(dto.getAuditorId())) { return Result.fail("只有持证药师可审核处方"); } // 验证处方签名 if(!digitalSignService.verify(dto.getSignData())) { return Result.fail("电子签名验证失败"); } // 更新处方状态 prescriptionService.updateStatus( dto.getPrescriptionId(), PrescriptionStatus.AUDITED); // 记录审核日志 auditLogService.savePrescriptionAudit( dto.getPrescriptionId(), dto.getAuditorId(), dto.getAuditOpinion()); return Result.ok(); }6. 部署与性能优化
6.1 高并发场景应对
缓存策略:
- 使用Redis缓存药品基础信息
- 库存数据采用Redisson分布式锁
- 热点数据本地缓存(Caffeine)
数据库优化:
- 药品查询使用ES实现全文检索
- 账单表按月份分表
- 建立组合索引:
INDEX idx_category_stock (category_id, stock)
异步处理:
- 使用RabbitMQ处理库存扣减
- 报表生成走消息队列
- 短信通知采用异步发送
6.2 容器化部署方案
Docker Compose配置示例:
version: '3.8' services: app: image: pet-medicine:1.0 ports: - "8080:8080" environment: - SPRING_PROFILES_ACTIVE=prod - REDIS_HOST=redis depends_on: - redis - mysql mysql: image: mysql:8.0 environment: - MYSQL_ROOT_PASSWORD=pet@1234 - MYSQL_DATABASE=pet_medicine volumes: - mysql_data:/var/lib/mysql redis: image: redis:6.2 ports: - "6379:6379" volumes: - redis_data:/data volumes: mysql_data: redis_data:7. 项目扩展方向
移动端适配:
- 开发微信小程序供医生随时查询药品
- 集成扫码枪快速入库功能
- 移动端签名确认处方
智能采购预测:
- 基于历史销售数据的季节波动分析
- 机器学习预测未来三个月需求
- 自动生成采购建议单
供应商协同:
- 开放供应商门户
- 电子订单自动对接
- 物流轨迹实时追踪
实际开发中发现,宠物药品管理相比人用药品更需要考虑剂型转换问题。比如同一成分的驱虫药,针对小型犬可能是片剂,而大型犬可能需要口服液。我们在系统中增加了剂型转换系数字段,可以根据实际需要进行用药量自动换算,这个细节在初期设计时容易被忽略。