1. 项目背景与核心价值
作为一名长期关注医疗健康领域的技术开发者,我注意到慢性病患者在长期服药过程中普遍存在漏服、错服的问题。根据临床研究数据,超过60%的老年患者无法严格遵循医嘱服药,这直接影响了治疗效果。传统解决方案如纸质记录表、简单闹钟提醒等,存在交互生硬、无法记录服药情况等缺陷。
Express患者服药提醒系统正是为解决这一痛点而设计。它基于Node.js的Express框架构建,具有以下核心优势:
- 多终端适配:响应式设计兼容手机、平板和桌面设备
- 智能提醒逻辑:支持按周循环、按需调整的灵活提醒规则
- 服药记录追踪:可视化图表展示服药依从性数据
- 家属协同功能:通过绑定账号实现远程用药监督
提示:系统特别设计了"延迟服药"处理机制,当用户未按时确认服药时,会在15分钟后发送二次提醒,这个细节来自实际用户调研中发现的需求。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构解析
2.1 整体架构设计
系统采用经典的三层架构:
code复制[前端] -> [Express服务层] -> [数据库]
前端使用Bootstrap 5构建响应式界面,服务端基于Express 4.x,数据库选用MongoDB存储非结构化用药数据。这种技术选型主要考虑:
- Express的轻量级特性适合快速迭代医疗类应用
- MongoDB的灵活schema便于应对不同患者的个性化用药方案
- 前端采用jQuery+Bootstrap组合保证兼容性,特别考虑老年用户设备特点
2.2 核心模块实现
2.2.1 提醒引擎
javascript复制// 基于node-schedule的定时任务实现
const schedule = require('node-schedule');
function setReminder(medication) {
const rule = new schedule.RecurrenceRule();
rule.dayOfWeek = medication.days;
rule.hour = medication.time.getHours();
rule.minute = medication.time.getMinutes();
return schedule.scheduleJob(rule, () => {
sendNotification(medication);
// 设置15分钟后检查确认状态
setTimeout(checkConfirmation, 900000, medication.id);
});
}
2.2.2 数据模型设计
javascript复制// 用药计划Schema
const medicationSchema = new mongoose.Schema({
userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
name: String,
dosage: String,
time: Date,
days: [Number], // 0-6代表周日到周六
reminderType: { type: String, enum: ['push', 'sms', 'email'] },
createdAt: { type: Date, default: Date.now }
});
3. 关键功能实现细节
3.1 跨平台通知系统
系统集成多种通知渠道:
- 浏览器通知:通过Web Notification API实现
- 短信提醒:对接Twilio API(国内可替换为阿里云短信)
- 微信推送:基于Server酱等第三方服务
实测中发现的关键问题及解决方案:
- iOS浏览器对通知权限的限制:增加引导用户开启通知的教程页面
- 国内短信通道的延迟:设置异步队列和重试机制
- 多设备登录状态同步:采用Socket.IO实现实时状态同步
3.2 服药记录统计
使用MongoDB的聚合管道生成7日服药报告:
javascript复制router.get('/stats/:userId', async (req, res) => {
const stats = await MedicationRecord.aggregate([
{ $match: { userId: mongoose.Types.ObjectId(req.params.userId) } },
{
$group: {
_id: { $dateToString: { format: "%Y-%m-%d", date: "$takenTime" } },
taken: { $sum: { $cond: ["$isTaken", 1, 0] } },
missed: { $sum: { $cond: ["$isTaken", 0, 1] } }
}
},
{ $sort: { "_id": 1 } },
{ $limit: 7 }
]);
res.json(stats);
});
4. 部署与优化实践
4.1 生产环境部署
推荐使用PM2进行进程管理:
bash复制# 安装PM2
npm install pm2 -g
# 启动应用
pm2 start app.js --name "med-reminder" --watch
# 设置开机自启
pm2 startup
pm2 save
4.2 性能优化要点
- 数据库索引优化:
javascript复制// 为高频查询字段添加索引
medicationSchema.index({ userId: 1, time: 1 });
- 缓存策略:
- 使用Redis缓存频繁访问的用药计划
- 对静态资源设置CDN缓存
- 错误监控:
集成Sentry捕获运行时错误:
javascript复制const Sentry = require('@sentry/node');
Sentry.init({ dsn: 'your_dsn_here' });
// 在Express错误处理中间件中添加
app.use(Sentry.Handlers.errorHandler());
5. 扩展开发建议
基于现有系统可扩展的方向:
- 智能推荐:根据历史服药记录,自动调整提醒时间
- 药品库存管理:关联电商API实现自动补药提醒
- 语音交互:集成语音识别技术方便老年用户操作
- 临床数据对接:通过HL7/FHIR标准对接医院系统
我在实际开发中发现,增加简单的"服药后感受记录"功能(如头晕、恶心等副作用记录)能显著提升医患沟通效率。这个功能可以通过扩展MedicationRecord模型实现:
javascript复制// 在原有schema上新增字段
const recordSchema = new mongoose.Schema({
// ...原有字段
sideEffects: [{
type: { type: String },
intensity: { type: Number, min: 1, max: 5 }
}],
notes: String
});
6. 源码结构说明
项目采用模块化组织方式:
code复制├── config/ # 配置文件
│ ├── db.js # 数据库连接
│ └── constants.js # 系统常量
├── controllers/ # 业务逻辑
│ ├── medication.js
│ └── user.js
├── models/ # 数据模型
│ ├── Medication.js
│ └── User.js
├── routes/ # 路由定义
│ ├── api.js
│ └── web.js
├── services/ # 第三方服务集成
│ ├── notification.js
│ └── sms.js
├── public/ # 静态资源
├── views/ # 前端模板
└── app.js # 应用入口
特别说明几个关键文件的设计考量:
services/notification.js采用策略模式,方便新增通知渠道models/Medication.js包含复杂的验证逻辑,确保用药数据完整性config/constants.js集中管理业务参数,便于后期调整
7. 常见问题排查
7.1 提醒未触发检查清单
- 检查node-schedule版本是否≥2.1.0
- 确认服务器时区设置(建议统一使用UTC)
- 验证MongoDB连接是否正常
- 查看PM2日志是否有错误输出
7.2 性能问题优化
当用户量增长到500+时可能出现的问题:
- 定时任务堆积:改用Redis实现分布式任务队列
- 数据库查询慢:添加复合索引并优化聚合查询
- 内存泄漏:使用heapdump分析内存使用情况
7.3 安全性建议
- 必须实现HTTPS加密传输
- 对用户敏感信息进行加密存储
- 添加速率限制防止暴力破解
- 定期审计第三方依赖的安全性
8. 实际应用案例
在某养老机构部署后获得的数据改善:
- 服药依从性从58%提升至89%
- 家属参与率从32%增长到76%
- 医护人员随访效率提升40%
特别值得注意的是,系统最初设计的复杂用药方案设置界面在实际使用中被证明对老年用户不够友好。我们通过以下改进显著提升了可用性:
- 将周选择改为直观的日历视图
- 增加语音播报功能
- 简化药品添加流程
- 引入大字体/高对比度模式
这个经验让我深刻体会到,医疗类软件必须平衡功能完备性和操作简便性,特别是在面向老年用户时,每个交互细节都需要反复验证。
