1. 项目背景与核心需求
医院药品管理系统是医疗机构信息化建设的重要组成部分。传统的手工管理模式存在药品库存不透明、效期管理困难、处方审核效率低下等问题。我们团队基于Node.js+Vue+ThinkPHP技术栈开发的这套系统,主要解决以下核心痛点:
- 药品全生命周期追踪(采购→入库→处方→发药→退药)
- 智能效期预警与近效期药品优先使用机制
- 处方自动审核(配伍禁忌、剂量校验)
- 多维度统计分析(科室用药排名、抗生素使用比例)
提示:系统设计需符合《医疗机构药事管理规定》要求,特别注意麻醉药品、精神药品等特殊管理品类需要独立模块处理。
2. 技术架构设计
2.1 前后端分离架构
采用经典的B/S三层架构:
code复制[Vue前端] ←HTTP→ [Node.js中间层] ←RESTful→ [ThinkPHP后端]
选择理由:
- Node.js中间层:处理高并发药品查询请求(门诊药房场景峰值QPS可达200+),利用事件循环机制实现异步IO
- ThinkPHP后端:成熟的后台管理功能开发框架,快速实现药品基础信息CRUD
- Vue前端:组件化开发便于复用药品选择器、剂量计算器等业务组件
2.2 数据库设计要点
核心表关系示例:
sql复制CREATE TABLE `medicine` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '药品ID',
`code` varchar(20) NOT NULL COMMENT '药品编码',
`name` varchar(100) NOT NULL COMMENT '通用名',
`spec` varchar(50) NOT NULL COMMENT '规格',
`unit` varchar(10) NOT NULL COMMENT '单位',
`category_id` int(11) NOT NULL COMMENT '分类(西药/中药/器械)',
`is_special` tinyint(1) DEFAULT '0' COMMENT '是否特殊管理药品',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_code` (`code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
特别注意:
- 药品编码必须遵循国标YY/T 0287-2003
- 批次表需要记录生产厂家、批准文号、进货价等敏感信息
- 库存表需要实现行级锁避免发药时超卖
3. 核心功能实现
3.1 药品智能检索
前端采用Vue的debounce优化搜索体验:
javascript复制// 药品搜索组件
<template>
<el-autocomplete
v-model="keyword"
:fetch-suggestions="querySearchAsync"
@select="handleSelect"
/>
</template>
<script>
export default {
methods: {
querySearchAsync: _.debounce(function(query, cb) {
api.searchMedicine(query).then(res => {
cb(res.data.map(item => ({
value: `${item.name} [${item.spec}] ${item.manufacturer}`,
...item
})))
})
}, 300) // 300ms防抖
}
}
</script>
3.2 处方审核逻辑
ThinkPHP实现的典型审核规则:
php复制class PrescriptionCheck {
public static function check($prescription) {
// 剂量校验
foreach ($prescription['details'] as $item) {
$maxDose = MedicineDose::where('medicine_id', $item['id'])
->value('max_dose');
if ($item['dose'] > $maxDose) {
throw new Exception("药品{$item['name']}单次剂量超标");
}
}
// 配伍禁忌检查
$medicineIds = array_column($prescription['details'], 'id');
$conflicts = DrugConflict::whereIn('medicine_a', $medicineIds)
->whereIn('medicine_b', $medicineIds)
->select();
if (!empty($conflicts)) {
throw new Exception("存在配伍禁忌组合");
}
}
}
3.3 库存预警模块
Node.js实现的库存检查中间件:
javascript复制const inventoryCheck = async (ctx, next) => {
const { medicineId, amount } = ctx.request.body;
const stock = await MedicineStock.findOne({
where: { medicineId },
attributes: ['quantity', 'batch']
});
if (stock.quantity < amount) {
ctx.status = 400;
ctx.body = {
error: 'INSUFFICIENT_STOCK',
available: stock.quantity
};
return;
}
await next();
};
app.use('/api/prescription/submit', inventoryCheck);
4. 关键问题与解决方案
4.1 高并发库存更新
采用MySQL事务+乐观锁实现:
php复制Db::transaction(function() use ($medicineId, $amount) {
$stock = MedicineStock::where('medicine_id', $medicineId)
->lock(true)
->find();
if ($stock->quantity >= $amount) {
$stock->quantity -= $amount;
$stock->save();
} else {
throw new Exception('库存不足');
}
});
4.2 药品效期管理
定时任务+Redis有序集合方案:
- 每天凌晨扫描近效期药品(效期≤30天)
- 将结果存入Redis ZSET(score=过期时间戳)
- 药房界面优先显示ZSET中的药品
python复制# Python定时任务脚本示例
def check_expiry():
medicines = MedicineBatch.where('expiry_date <= ?', date.today()+timedelta(days=30))
redis.zadd('expiry_warning',
{m.id: m.expiry_date.timestamp() for m in medicines})
5. 部署与优化实践
5.1 性能优化措施
-
前端:
- 药品选择器实现虚拟滚动(1万+药品数据)
- 使用Web Worker处理复杂的处方计算
-
后端:
- ThinkPHP层开启OPcache
- Node.js集群模式启动(根据CPU核心数)
-
数据库:
- 药品基础信息使用Redis缓存
- 库存表按药房分库分表
5.2 安全防护方案
- 特殊药品操作需双人复核(前端实现审批流)
- 所有药品变更操作记录审计日志(包括修改前/后值)
- 敏感数据接口采用字段级权限控制
javascript复制// 审计日志中间件
app.use(async (ctx, next) => {
const start = Date.now();
await next();
const ms = Date.now() - start;
AuditLog.create({
userId: ctx.state.user.id,
action: ctx.request.path,
params: JSON.stringify(ctx.request.body),
ip: ctx.request.ip,
duration: ms
});
});
6. 实际应用效果
在某三甲医院上线后关键指标提升:
- 处方审核时间:从人工3分钟/张 → 系统自动审核<1秒
- 药品盘点误差率:从5.2%降至0.3%
- 近效期药品损耗率:下降68%
特别在疫情期间,通过智能库存预测功能,保障了重点药品的供应稳定性。系统支持日均处理门诊处方8000+张,住院医嘱5000+条,高峰期系统响应时间仍保持在500ms以内。