大多数时长管理工具走的是计时器 + 事后告警的路子:等你玩到超时,弹个提醒。但等你人在游戏里的时候,关掉一个弹窗远比关掉游戏容易——提醒基本无效。
这个应用换了个方向:它不拦你,它给你发额度。
每天早上你醒来,就有一个明确的数字摆在那里:今天可以玩多久、昨天省下多少、这个月一共玩了多少。它把一件模糊的事("我是不是玩太久了")变成一件确定的事("我今天还剩 47 分钟")。
额度是有限的,但怎么花由你决定。 这才是自律真正需要的那个抓手。
工作日与周末分开设定每日基准时长,默认 工作日 150 分钟 / 周末 240 分钟。两者都可以在设置页自由调整(5 ~ 1440 分钟)。
今天玩得少,没用完的额度会自动滚入明天。周四只玩了 1 小时,省下的额度周五就能用。
滚存上限 = 当日基准 × 1,也就是说单日额度最高为基准的 2 倍。
这是刻意设计的约束:如果额度能无限累积,长期不玩之后会攒出天文数字,自律约束就彻底失效了。
| 昨天的情况 | 今天的额度 |
|---|---|
| 玩得比额度少(省下了) | 基准 + 省下的部分(最多翻倍) |
| 正好玩完 | 基准 |
| 玩超了 | 基准(不扣减、不加罚) |
| 完全没玩 | 基准 + 昨天的额度(最多翻倍) |
超时只是让明天的额度回到基准,不会倒扣。目的是让你看清自己的节奏,不是惩罚你。
完整的推演算法见
entry/src/main/ets/model/TimeQuota.ets,纯逻辑实现,无 UI / 无存储依赖,可单独测试。
| 页签 | 内容 |
|---|---|
| 💰 额度 | 今日额度 / 已用 / 剩余、实时倒计时、开台上机与下机结算、手动补记 |
| 📒 账本 | 逐日流水:每天的基准、滚入结余、额度、实玩、结转、超时状态 |
| 📈 报表 | 本周 / 本月 / 近 30 天区间统计、达标与超时天数、游戏时长排行、连续自律天数 |
| ⚙️ 设置 | 工作日与周末基准时长、数据导出与清空 |
- 手动开台 / 下机结算:点一下开始计时,结算时自动写入当日账本
- 实时额度进度:开台期间额度条随时间推进,剩余分钟数实时更新
- 纯本地持久化:所有记录保存在本机,退出应用不丢失
这一点值得单独说明,因为它不是"顺手做到的",而是刻意设计的结果:
- 不声明任何权限 ——
module.json5中不存在requestPermissions字段,打包后的module.json里连INTERNET权限都没有 - 没有任何网络调用 —— 代码中不存在
http/fetch/rcp/@kit.NetworkKit/WebSocket等任何网络 API - 零第三方依赖 ——
dependencies: {},运行时依赖为空 - 数据只在本机 —— 存储于
preferences,不上传、不统计、不埋点
所以:这个应用在飞行模式下可以完整使用。它不需要联网,也不想要你的任何数据。
- 平台:HarmonyOS,Stage 模型,ArkTS / ArkUI 声明式 UI
- SDK:
targetSdkVersion 26.0.0,compatibleSdkVersion 6.1.0(23) - 持久化:
@kit.ArkData的preferences - 包名:
com.hongm.wangbajishi
wangbajishi/
├─ AppScope/ # 应用级配置与图标资源
│ ├─ app.json5 # 包名、版本号
│ └─ resources/base/media/ # 分层图标(前景 / 背景)
├─ entry/
│ ├─ src/main/
│ │ ├─ ets/
│ │ │ ├─ model/
│ │ │ │ ├─ TimeQuota.ets # 额度银行核心算法(纯逻辑,481 行)
│ │ │ │ └─ DataStore.ets # preferences 持久化
│ │ │ ├─ pages/Index.ets # 四个页签的主界面
│ │ │ ├─ entryability/ # 应用入口
│ │ │ └─ entrybackupability/ # 备份扩展
│ │ ├─ module.json5 # 模块配置(无权限声明)
│ │ └─ resources/ # 字符串、颜色、图标
│ └─ build-profile.json5
├─ build-profile.json5 # 工程配置(签名信息已清空)
└─ 打包签名HAP.bat # 一键打包脚本
存储于应用私有 preferences(文件名 personal_cybercafe,键 app_data_v1):
直接用 DevEco Studio 打开工程根目录,等待 Sync 完成后运行到模拟器或真机即可。
首次打开需自行配置签名证书:File → Project Structure → Signing Configs。 仓库中的
build-profile.json5已清空签名信息,请填入你自己的证书材料——切勿把自己的签名私钥提交到公开仓库。
项目根目录的 打包签名HAP.bat 会调用 DevEco Studio 自带的工具链。脚本按环境变量 DEVECO_HOME 定位安装目录,未设置时会尝试探测常见安装位置:
set DEVECO_HOME=D:\path\to\DevEco Studio
打包签名HAP.bat也可以直接调用 hvigor:
export DEVECO_SDK_HOME="/path/to/DevEco Studio/sdk"
export JAVA_HOME="/path/to/DevEco Studio/jbr"
export PATH="/path/to/DevEco Studio/tools/node:/path/to/DevEco Studio/jbr/bin:$PATH"
node "/path/to/DevEco Studio/tools/hvigor/bin/hvigorw.js" \
--mode project -p product=default \
assembleApp --analyze=normal --parallel --incremental --no-daemon
--no-daemon是为了绕开 hvigor daemon 在 Windows 上的已知问题。
产物位置:
| 用途 | 路径 |
|---|---|
| 应用市场发布 | build/outputs/default/*-signed.app |
| 真机调试安装 | entry/build/default/outputs/default/*-signed.hap |
几个开发中踩过、值得记下来的点:
- 输入框要区分「打字中间态」与「越界态」。若在输入回调里就对数值做夹取校验,多位数永远输不进去(想输
150,首位1会被夹成5)。正确做法是打字阶段只过滤回显、不落库,由防抖与显式提交统一校正。 onBlur在 ArkUI 中不可靠。点击输入框以外的空白区域并不会触发失焦,不能把它当作「结束编辑」的唯一兜底,需要配合onSubmit、页签切换、页面销毁等多个触发点。ForEach的 key 必须包含会变化的字段,否则数据更新后界面不会重新渲染。- 额度推演必须逐日迭代,不能跨越空档。没有游戏记录的日子同样会产生额度结转,只按"有记录的日期"计算会算错连续天数与累计额度。
本项目源码公开,版权归作者所有。
当前仓库尚未指定开源许可证。在作者明确许可证之前,默认保留所有权利。
自律不是靠意志力硬扛,而是把模糊的约束变成清晰的数字。
{ "workdayMin": 150, // 工作日每日基准(分钟) "weekendMin": 240, // 周末每日基准(分钟) "sessions": [ // 全部已结算记录 { "date": "2026-09-03", "game": "原神", "min": 95, "time": "22:43" } ], "cur": null // 进行中的会话,未开台时为 null }