1. 项目背景与核心需求
2020年初的突发公共卫生事件让全球意识到应急物资管理的重要性。当时许多医疗机构面临口罩、防护服等关键物资短缺与分配不均的问题,而传统Excel表格和纸质记录方式在应对大规模物资调配时显得力不从心。这正是我们开发这套SpringBoot疫情物资管理系统的初衷。
这个系统需要解决三个核心痛点:
- 实时追踪物资流向(从采购到发放的全生命周期)
- 智能预警库存阈值(避免关键物资断货或积压)
- 多级机构协同调配(医院、疾控中心、社区之间的物资流转)
实际开发中发现,单纯实现CRUD功能远远不够,真正的难点在于处理高并发入库操作时的数据一致性问题,以及如何生成符合疾控部门要求的物资调拨电子凭证。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构设计
2.1 为什么选择SpringBoot
相比传统SSM框架,SpringBoot的自动配置特性让我们能快速搭建起包含以下关键组件的系统:
- 物资主数据服务(Spring Data JPA + MySQL)
- 分布式事务控制(Seata 1.5.2)
- 实时库存看板(WebSocket + ECharts)
- 电子签章模块(iText PDF + 国密SM2)
java复制// 典型的多级库存扣减代码示例
@Transactional
public void allocateMaterial(Long warehouseId, List<MaterialRequest> requests) {
// 1. 检查库存可用性
inventoryService.checkAvailability(requests);
// 2. 执行分布式锁
RedissonClient redisson = getRedissonClient();
RLock lock = redisson.getLock("wh_" + warehouseId);
try {
lock.lock(10, TimeUnit.SECONDS);
// 3. 实际扣减操作
requests.forEach(req -> {
inventoryService.deductStock(req);
allocationService.createAllocationRecord(req);
});
} finally {
lock.unlock();
}
}
2.2 核心数据模型设计
物资主表的关键字段设计体现了业务特殊性:
sql复制CREATE TABLE `t_material` (
`id` bigint NOT NULL AUTO_INCREMENT,
`material_no` varchar(32) COMMENT '国标物资编码',
`name` varchar(100) NOT NULL,
`spec` varchar(100) COMMENT '规格(如N95/医用外科)',
`batch_no` varchar(50) COMMENT '生产批号',
`expire_date` date COMMENT '失效日期',
`sterilization` tinyint COMMENT '是否无菌',
`storage_condition` varchar(20) COMMENT '存储条件',
`safety_stock` int DEFAULT 0 COMMENT '安全库存',
`current_stock` int DEFAULT 0 COMMENT '当前库存',
`unit` varchar(10) COMMENT '计量单位',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_material_no` (`material_no`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
特别注意:医疗物资必须记录批号和效期,这是与普通ERP系统的本质区别。我们通过@DynamicUpdate注解实现部分字段更新,避免全字段更新带来的性能损耗。
3. 关键业务逻辑实现
3.1 智能预警模块
采用双阈值预警机制:
- 黄色预警:库存低于安全库存的150%
- 红色预警:库存低于安全库存的50%
java复制@Scheduled(cron = "0 0/30 * * * ?")
public void checkInventoryWarning() {
List<Material> materials = materialRepository.findAll();
materials.forEach(material -> {
int threshold = (int)(material.getSafetyStock() * 1.5);
if (material.getCurrentStock() < threshold) {
WarningEvent event = new WarningEvent()
.setMaterialId(material.getId())
.setCurrentStock(material.getCurrentStock())
.setThreshold(threshold);
if (material.getCurrentStock() < material.getSafetyStock() * 0.5) {
event.setLevel(WarningLevel.RED);
// 触发短信通知
smsService.sendEmergencyAlert(event);
} else {
event.setLevel(WarningLevel.YELLOW);
}
eventPublisher.publishEvent(event);
}
});
}
3.2 物资调拨流程
调拨单状态机设计:
mermaid复制stateDiagram-v2
[*] --> DRAFT
DRAFT --> APPROVED: 提交审批
APPROVED --> REJECTED: 审批驳回
APPROVED --> ALLOCATING: 开始分配
ALLOCATING --> PART_ALLOCATED: 部分分配
ALLOCATING --> FULL_ALLOCATED: 全部分配
FULL_ALLOCATED --> DELIVERING: 出库中
DELIVERING --> RECEIVING: 运输中
RECEIVING --> PART_RECEIVED: 部分签收
RECEIVING --> FULL_RECEIVED: 全部签收
FULL_RECEIVED --> CLOSED: 归档
实际开发中发现,采用Activiti工作流引擎过于笨重,最终选择自定义状态机实现,通过枚举+策略模式灵活处理各状态转换。
4. 系统特色功能
4.1 物资溯源追踪
通过区块链技术实现关键物资的不可篡改记录:
- 采购入库时生成物资数字身份证(包含生产厂家、质检报告等)
- 每次调拨都在链上记录操作人和时间戳
- 使用Hyperledger Fabric的轻节点模式,平衡性能与安全性
4.2 智能调配算法
基于疫情热力图的物资需求预测:
python复制# 简化版的物资需求预测模型
def predict_demand(city_data):
# 输入:各城市确诊数、人口密度、医疗资源指数
# 输出:未来7天物资需求预测
model = load_model('epidemic_model.h5')
scaler = StandardScaler()
scaled_data = scaler.fit_transform(city_data)
return model.predict(scaled_data)
与库存系统联动实现:
- 自动生成跨区域调拨建议
- 优先保障高风险区域
- 动态调整安全库存参数
5. 部署与性能优化
5.1 高并发场景应对
通过以下措施支撑突发流量:
- 库存操作采用Redis原子计数器+Lua脚本
- 读写分离:主库写库存,从库读报表
- 热点数据缓存:物资基础信息缓存120分钟
- 消息队列削峰:RabbitMQ处理入库流水
yaml复制# 关键性能参数配置
spring:
redis:
lettuce:
pool:
max-active: 200
max-wait: 1000ms
datasource:
hikari:
maximum-pool-size: 50
connection-timeout: 30000
jpa:
properties:
hibernate:
order_updates: true
order_inserts: true
batch_versioned_data: true
5.2 安全防护措施
针对医疗系统的特殊要求:
-
等保三级合规:
- 密码策略:SM3加密+盐值
- 操作日志:完整审计轨迹
- 会话管理:JWT+IP绑定
-
防XSS攻击:
- PDF导出时清理HTML标签
- 前端使用DOMPurify过滤
- 响应头设置Content-Security-Policy
-
数据加密:
- 敏感字段SM4加密存储
- SSL双向认证
- 数据库TDE透明加密
6. 实际应用效果
在某省级疾控中心上线后取得显著成效:
- 物资调配效率提升300%(从平均4小时缩短到1小时)
- 库存周转率提高50%
- 过期物资损耗降低80%
- 实现全省200+医疗机构物资动态可视化管理
典型用户场景示例:
- 某医院突然收治大批患者,护士长在系统提交紧急申请
- 系统自动匹配最近仓库的防护服库存
- 疾控中心审批后生成电子调拨单
- 仓库扫码出库,物流信息实时更新
- 医院签收时扫描物资二维码完成溯源登记
7. 开发经验总结
7.1 值得推广的做法
-
物资编码标准化:
- 采用GB/T 14885《固定资产分类与代码》
- 扩展自定义属性满足特殊需求
- 生成规则:类型码+规格码+批次号
-
前后端分离架构:
- 后端:SpringBoot 2.6 + Spring Security
- 前端:Vue3 + TypeScript
- 接口文档:Swagger3 + Knife4j
-
持续交付流水线:
- 代码扫描:SonarQube
- 自动化测试:TestNG+Mockito
- 容器化部署:Docker+K8s
7.2 遇到的典型问题
-
批次管理难题:
- 现象:相同物资不同批次混放导致近效期先出失效
- 解决:增加库位管理+RFID标签识别
-
分布式事务陷阱:
- 现象:库存扣减成功但调拨单状态未更新
- 解决:引入Seata的AT模式+重试机制
-
文件上传瓶颈:
- 现象:大批量物资照片上传超时
- 解决:改用MinIO分片上传+前端压缩
这个项目让我深刻体会到,好的技术架构必须建立在对业务本质的理解之上。比如医疗物资管理不仅要考虑通用ERP功能,更要关注效期管理、资质认证、应急响应等特殊需求。下次如果再开发类似系统,我会在初期投入更多时间与疾控专家深入沟通业务场景。
