先把周期性支出记录下来
订阅页面围绕服务名称、价格、扣费周期和下次扣费日期组织信息。输入模型保持结构化,后续统计、排序和提醒都建立在同一份订阅记录之上。


SubTrack 是一款面向 HarmonyOS 的原生订阅管理应用,中文界面使用“订阅Go”作为产品名称。它用来记录会员、数字服务和其他周期性支出,把服务名称、金额、扣费周期、付款方式、续费日期和提醒集中到一个本地账本中。
这类应用的表面功能是增删改查,真正的工程问题却在于周期计算、状态迁移、提醒同步、统计口径和数据恢复。SubTrack 没有把所有逻辑堆在页面里,而是将页面状态、数据仓库、备份加密、系统日历和账号服务拆成了相互协作的模块。
| 方向 | 项目实现 |
|---|---|
| 运行平台 | HarmonyOS 6.1.1,兼容 API 24,目标 API 26 |
| 当前版本 | 1.0.9,versionCode 1000900,build 9 |
| 包名 | com.pinero.subtrack |
| 开发语言 | ArkTS / ETS |
| 应用模型 | Stage 模型,入口为 EntryAbility |
| UI 框架 | ArkUI、HdsNavigation、HdsTabs、系统 Symbol 和 HDS 材质 |
| 状态管理 | V2 状态管理,@ObservedV2、@Trace 和页面本地状态 |
| 核心数据 | @kit.ArkData 的 relationalStore,SQLite 关系型数据库 |
| 配置数据 | preferences 保存主题、语言、货币、提醒和显示偏好 |
| 系统能力 | Calendar Kit、Account Kit、AppGallery Kit、文件选择器 |
| 数据保护 | CryptoArchitectureKit,PBKDF2-SHA256 与 AES-256-GCM 加密备份 |
订阅服务的问题不一定是金额很大,而是扣费周期分散、续费日期容易忘记、长期成本不容易感知。SubTrack 的信息结构围绕三个问题展开:
因此,应用不是简单的“会员名单”,而是由订阅列表、续费日历、消费洞察和个人设置组成的本地控制台。
每条 SubscriptionRecord 包含服务名称、分类、金额、币种、扣费周期、锚定日期、下一次扣费日期、自动续费状态、提醒天数、付款方式、图标、卡片背景和备注等字段。
应用支持周、月、季度、年和自定义天数周期。用户可以新增、编辑、暂停、恢复、取消和删除订阅,也可以按名称搜索,并在列表和网格布局之间切换。
列表排序优先考虑 next_charge_date,这让首页首先回答“最近要发生什么”。周期计算则由 RecurrenceCalculator 负责,数据仓库不需要把每一种周期规则散落在各个页面的点击事件里。
日历页面提供周、月、年三种视图。页面显示续费次数、预计总额和最高单笔金额,用户点击某一天后可以查看当天的订阅安排。
ReminderCalendarService 负责把应用中的有效订阅同步到系统日历。同步前会申请读写日历权限,生成或获取应用自己的日历账户,然后删除旧事件、重新计算未来事件并保存应用内的提醒绑定。这样可以避免用户修改订阅日期后,系统里残留过期提醒。
同步策略还会处理“提醒时间已经过去但续费日期还没有到”的情况:如果原定提醒点已经错过,服务会根据距离续费的剩余时间计算一个仍然有效的提醒,而不是直接写入一个已经失效的通知。
洞察页把订阅数据转换成几种更容易理解的指标:月度承诺、年度承诺、未来六个月趋势、年度扣费热力图和分类构成。
数据层区分预计金额和实付金额。订阅创建时产生的是预计支出,用户确认下一次扣费后,数据库会写入对应的 charge_occurrences 记录和实际金额。这样既能看到未来计划,也能回顾真实发生过的费用。
从工程角度看,洞察页并不需要另建一套数据源,它只需要读取订阅表和扣费发生表,按日期、分类和状态聚合即可。只要底层记录保持结构化,后续增加新的统计卡片不会破坏订阅编辑流程。
SubTrack 在 module.json5 中启用了 ohos.arkui.UIMaterial.state,并在页面中使用 HDS 导航、底部 Tab、系统材质和点光源反馈。主题设置支持跟随系统、浅色和深色模式,也支持多套强调色。
动画设置没有只提供一个“开关”,而是拆成动画强度、动画幅度、阻尼和减少动态效果等选项。用户可以在不改变业务数据的情况下调整交互节奏,这些偏好通过 preferences 持久化。
项目里还保留了沉浸光感和智感握持等 HarmonyOS 原生交互增强能力。它们属于能力受设备和系统版本影响的增强层,核心订阅流程并不依赖这些效果,因此即使设备不支持,账本、日历和备份仍然可以正常运行。
SubscriptionRepository 使用 relationalStore 创建 subtrack.db,维护订阅、扣费发生、分类、服务模板、付款方式和提醒绑定等表,并通过数据库版本号执行结构迁移。
导出备份时,应用先把多张表整理成一个 BackupSnapshot,再交给 BackupCryptoService。加密流程包括:
备份文件不是数据库文件的简单复制,而是一个带版本和认证信息的可迁移数据格式。这样可以在未来升级字段时保留兼容判断,也能在密码错误或文件被修改时拒绝恢复。
“我的”页面可以通过 Account Kit 授权读取华为账号头像和昵称。HuaweiAccountProfileService 会校验授权请求和响应中的 state,再把头像缓存到应用沙箱中,页面只保存本地可用的展示信息。
应用更新页面使用 AppGallery Kit 检查版本、展示版本详情,并在检测到新版本时引导用户前往应用市场。语言、货币和主题等设置则保存在本地 preferences,支持中文、英文、日语以及多种离线记账币种。
1Index.ets2 ├─ SubscriptionState V2 UI 状态、当前 Tab、筛选与编辑态3 ├─ SubscriptionRepository RDB 表、查询、写入、迁移与统计原始数据4 ├─ RecurrenceCalculator 周期和下一次续费日期计算5 ├─ ReminderCalendarService 系统日历事件同步与提醒绑定6 ├─ BackupFileService 文件选择、导入、导出7 ├─ BackupCryptoService PBKDF2 + AES-GCM 加密与解密8 └─ AppLocalization 中文、英文、日文文案与格式化页面状态和持久化数据之间通过明确的方法调用连接,而不是让 UI 组件直接拼接 SQL。以“编辑一条订阅”为例:
SubscriptionEditorRules 校验金额、周期、名称和日期。SubscriptionRepository.updateSubscription 更新订阅表,并重建相关的待处理扣费记录。SubscriptionState 替换内存中的订阅列表,首页、日历和洞察页面获得一致数据。ReminderCalendarService 重新同步对应事件。这种链路能够让业务更新、界面刷新和系统提醒保持同一个事实来源。
下面是 SubTrack 代码中实际对应的 HarmonyOS 能力和官方文档入口:
HdsNavigationHdsTabsIndex.ets
SubscriptionRepository.etsrelationalStore
ReminderCalendarService.ets
BackupCryptoService.ets
HuaweiAccountProfileService.ets
下面的截图来自 SubTrack 1.0.2 的上架素材,按订阅、洞察、货币、外观、个人设置、语言和版本更新八个场景排列。每张图片都控制在手机预览卡片内,阅读正文时可以横向滑动查看。
订阅页面围绕服务名称、价格、扣费周期和下次扣费日期组织信息。输入模型保持结构化,后续统计、排序和提醒都建立在同一份订阅记录之上。
洞察页将月度承诺、年度承诺和趋势信息集中呈现。它不只告诉用户“现在有几项订阅”,还帮助用户看到长期成本的变化形状。
货币设置页将可用货币和当前选择集中管理。货币只是展示层配置,不改变订阅金额的核心记录结构,便于在统计页面统一换算和格式化。
外观与交互页面提供主题模式、强调色和界面行为配置。设置状态通过持久化存储跨页面同步,避免用户修改后必须重新进入页面才能看到效果。
“我的”页面承担全局设置入口,包括提醒、账号、外观和应用信息。分组后的入口降低了功能寻找成本,也让后续增加设置项时有明确的扩展位置。
语言设置从应用偏好中独立出来,支持用户在不改变账单数据的情况下切换界面语言。显示文本和业务数据分离,便于后续维护多语言资源。
版本详情页集中展示当前版本、更新说明和版本变更信息。它为 AppGallery Kit 的版本检测结果提供了清晰的承接页面,也让用户知道更新解决了什么问题。
软件更新页面负责检查新版本并引导用户前往应用市场。更新流程与本地订阅数据解耦,升级应用时不会改变用户已经保存的记录。
SubTrack 的核心价值在于将一个看似简单的订阅列表做成了可维护的原生应用:RDB 负责结构化数据,周期计算负责日期推导,日历服务负责系统提醒,洞察页面负责长期视角,备份模块负责可迁移性,ArkUI 与 HDS 负责一致的移动端交互。
它也体现了鸿蒙原生项目里“能力分层”的重要性。系统账号、日历、文件选择器、应用市场和材质效果都可以增强体验,但核心数据链路仍然由应用自己掌握。这样即使某项系统能力受权限、设备或 API 版本限制,订阅记录本身也不会失效。
SubTrack 的下一步,仍然是把每一次记录和每一次提醒做得更可靠。
时间不会提醒每一次扣款,却会把每一次选择悄悄累积起来。愿这个小小的账本,让生活里的数字变得清楚,也让每一次续费都更接近真正想留下的东西。
如果这篇文章对你有帮助,欢迎分享给更多人!
部分内容可能已过时