做个喝水提醒小工具,其实就三块逻辑

举报
茉莉风铃 发表于 2026/10/03 15:37:56 2026/10/03
【摘要】 做一个喝水提醒小工具的三个部分——按天记录水量与目标量、页面内定时加系统通知双通道提醒、以及跨天自然清零的统计方式,附后台降频和权限被拒的兜底处理。

久坐写代码容易一上午不喝水,想起来的时候已经渴得不行。做个提醒工具听起来要定时、要通知、要记录,拆开看其实就三块:存什么、怎么提醒、什么时候清零。

1.存什么

一条记录只要两个字段:时间和水量。日期单独存,方便按天汇总:

const KEY = 'water-v1';
const GOAL = 1500;

function addDrink(records, amount) {
  const ml = Number(amount);
  if (!(ml > 0)) throw new Error('水量不合法');
  return [...records, { ml, date: today(), at: Date.now() }];
}

function todayTotal(records) {
  const d = today();
  return records
    .filter((r) => r.date === d)
    .reduce((sum, r) => sum + r.ml, 0);
}

function today() {
  return new Date().toISOString().slice(0, 10);
}

水量用毫升整数,不用小数,避免浮点那堆麻烦。目标量做成可改的配置,每个人不一样,写死 1500 只是个默认值。

2.怎么提醒

最省事的是页面内定时提示,不用申请权限:

let timer = null;
function startReminder(minutes, onTick) {
  stopReminder();
  timer = setInterval(() => onTick(), minutes * 60 * 1000);
}
function stopReminder() {
  if (timer) clearInterval(timer);
  timer = null;
}

想用系统通知的话走 Notification API,但要先申请权限,而且用户拒绝之后就完全没提示了。所以做法是两条腿:系统通知能用就用,用不了退化成页面内的横幅。

还有个细节:页面切到后台时定时器会被降频,提醒会不准。这时候 visibilitychange 回来时补一次判断,看距上次喝水过了多久,超了就提示。

3.什么时候清零

按天统计,跨天自然清零,不需要定时任务去清数据:

function recentDays(records, n) {
  const days = [...new Set(records.map((r) => r.date))].sort();
  return days.slice(-n).map((d) => ({
    day: d,
    total: records.filter((r) => r.date === d).reduce((s, r) => s + r.ml, 0),
    done: records.filter((r) => r.date === d).reduce((s, r) => s + r.ml, 0) >= GOAL,
  }));
}

简单总结一下:历史记录留着但不是每天都看,真正展示的是"最近几天达成情况"。数据量不大,全存本地就行。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。