1. 项目概述:什么是"提醒猴"系统
"提醒猴"是一款轻量级的个人事务提醒记录系统,这个名字来源于"像猴子一样机灵地帮你记住所有事情"的设计理念。作为一个独立开发者,我在过去三年里尝试过市面上几乎所有待办事项和提醒类应用,但始终找不到一个完全符合我个人工作流需求的工具——要么功能过于复杂臃肿,要么跨平台同步体验差,要么提醒机制不够灵活。于是去年开始,我决定自己开发一套符合以下核心需求的通知系统:
- 极简交互:三步完成提醒设置
- 全平台即时同步:手机/电脑/平板数据实时一致
- 智能识别:自然语言解析提醒时间(如"明天下午三点理发")
- 分级通知:根据事项重要性采用不同提醒策略
经过8个迭代版本,现在的"提醒猴"已经稳定运行在我的日常生活和工作中,平均每天处理23条提醒事项,提醒准确率达到98.7%。下面我将完整分享这套系统的技术实现方案。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 系统架构设计
2.1 技术栈选型
经过多轮技术验证,最终确定的架构方案如下:
前端层:
- 移动端:Flutter框架(iOS/Android双端统一代码)
- Web端:Vue3 + Vant组件库
- 桌面端:Electron封装Web应用
后端服务:
- API服务:Node.js + Express
- 实时推送:Socket.IO长连接
- 数据库:MongoDB Atlas(全托管云服务)
- 文件存储:阿里云OSS
基础设施:
- 容器化:Docker + Kubernetes集群
- CI/CD:GitHub Actions自动化流水线
- 监控:Sentry错误追踪 + Prometheus指标收集
技术选型心得:Flutter在移动端的性能表现比React Native更稳定,特别是在后台任务执行方面。实测在小米Note10上,Flutter版本的后台服务存活时间比RN版本长3-4倍。
2.2 数据流设计
系统核心数据流向如下图所示(文字描述):
- 用户输入自然语言(如"每周三20:00健身")
- 客户端进行本地语义分析,提取关键要素
- 通过HTTPS将结构化数据发送至API服务
- 服务端验证后写入MongoDB并创建定时任务
- 任务触发时通过Socket.IO和厂商推送服务双通道发送提醒
- 各端收到推送后在本机创建系统级通知
3. 核心功能实现细节
3.1 自然语言时间解析
这是系统最具特色的功能模块,关键技术实现包括:
python复制# 时间关键词映射表
TIME_KEYWORDS = {
'早上': '08:00',
'上午': '10:00',
'中午': '12:00',
'下午': '15:00',
'晚上': '20:00',
'半夜': '00:00'
}
def parse_natural_time(text):
# 第一步:提取显式时间(如"15:30")
explicit_time = re.search(r'(\d{1,2}):(\d{2})', text)
if explicit_time:
return f"{explicit_time.group(1)}:{explicit_time.group(2)}"
# 第二步:匹配关键词时间
for keyword, time in TIME_KEYWORDS.items():
if keyword in text:
return time
# 第三步:默认处理(当前时间+30分钟)
return (datetime.now() + timedelta(minutes=30)).strftime('%H:%M')
实际应用中还需要处理时区转换、节假日识别等复杂场景。我们训练了一个简单的NLP模型来提升识别准确率,在1000条测试数据上达到了89%的准确度。
3.2 多端实时同步方案
同步机制的技术要点:
- 采用增量更新策略:每次只同步变更数据
- 冲突解决采用"最后修改优先"原则
- 本地SQLite缓存最近100条操作记录
- 网络恢复后自动重试失败的操作
同步性能测试数据(100KB数据量):
| 网络环境 | 平均同步耗时 | 成功率 |
|---|---|---|
| WiFi | 320ms | 99.9% |
| 4G | 780ms | 98.7% |
| 3G | 1.2s | 95.1% |
4. 典型问题排查实录
4.1 安卓后台服务被杀死
现象:在小米/华为设备上,定时提醒经常失效
排查过程:
- 检查日志发现进程被系统回收
- 测试不同保活方案(前台服务、WorkManager等)
- 最终采用Flutter后台插件+厂商白名单策略
解决方案:
xml复制<!-- AndroidManifest.xml 配置 -->
<service
android:name=".ReminderService"
android:foregroundServiceType="location|connectedDevice"
android:stopWithTask="false"/>
4.2 跨时区提醒错误
现象:出差时提醒时间自动变化
根本原因:客户端未正确处理UTC时间转换
修复方案:
dart复制DateTime parseTime(String timeStr) {
final localTime = DateTime.parse(timeStr);
return localTime.toUtc(); // 统一存储为UTC时间
}
DateTime showTime(DateTime utcTime) {
return utcTime.toLocal(); // 展示时转换本地时区
}
5. 性能优化实践
5.1 数据库查询优化
原始方案:每次同步全量查询用户所有提醒事项
优化方案:
- 添加last_modified_time索引
- 采用分页查询(每页50条)
- 客户端缓存数据版本号
优化效果对比:
| 数据量 | 原方案耗时 | 优化后耗时 |
|---|---|---|
| 100条 | 120ms | 45ms |
| 500条 | 680ms | 62ms |
| 1000条 | 1.4s | 85ms |
5.2 推送通道降级策略
为保证提醒可达性,设计了三级推送机制:
- 首选:WebSocket实时通道(毫秒级延迟)
- 备选:厂商推送服务(华为/小米等系统级通道)
- 保底:短信通知(仅用于医疗等关键提醒)
通道切换逻辑:
javascript复制function sendNotification(user, message) {
try {
// 尝试WebSocket推送
socket.sendTo(user.id, message);
// 3秒未响应则降级
setTimeout(() => {
if (!user.confirmedReceipt) {
vendorPush(user, message);
}
}, 3000);
} catch (e) {
logError(e);
smsBackup(user.phone, message);
}
}
这套系统目前已经稳定运行14个月,最让我自豪的设计是它的"渐进式提醒"功能——对于重要事项,系统会在截止时间前1天、1小时、15分钟分别提醒,这种符合人类记忆曲线的提醒方式让重要事项的完成率提升了40%。如果你也想构建自己的提醒系统,我的建议是从最简单的单机版开始,先解决核心的提醒功能,再逐步扩展同步和智能识别能力。
