HarmonyOS+ArkTS实战:基于AGC的个人记账系统开发全解析

📅 2026/8/27 2:20:04
HarmonyOS+ArkTS实战:基于AGC的个人记账系统开发全解析
简介在移动应用开发中声明式UI与静态类型检查正成为提升开发效率与代码稳定性的关键手段而后端即服务BaaS则帮助个人开发者大幅降低服务端搭建成本。HarmonyOS生态下的ArkTS语言基于TypeScript通过强类型约束和状态管理机制让UI开发更直观、可靠配合AppGallery ConnectAGC提供的用户认证、云数据库与云函数能力开发者无需自建服务器即可构建完整业务闭环。本文以个人记账系统为实战场景从需求拆解、工程配置到核心模块实现系统阐述在DevEco Studio中使用ArkTS编写界面、接入AGC后端服务的完整流程并分享列表渲染性能、签名调试、第三方库依赖等常见问题的排查经验为准备入门HarmonyOS应用开发的读者提供一份可落地的参考。 最近在忙一个个人记账服务系统技术栈是 HarmonyOS ArkTS整个项目在 DevEco Studio 里开发后端直接接的 AGCAppGallery Connect涵盖用户认证、账单记录、分类管理、统计分析、预算管理五个模块。项目不大但前后端链路完整做下来对 ArkTS 的应用开发、HarmonyOS 生态以及 AGC 的接入方式都有了一个比较系统的认识。如果你正准备入门 HarmonyOS 应用开发或者想找一个可以照着做的实战项目这篇文章应该能给你不少参考。下面我从项目设计、开发环境、前端模块、后端接入、第三方库这几个维度展开尽量把每个关键决策背后“为什么这么做”讲清楚最后再补一段我在真实开发中踩过的坑。整个项目基于 DevEco Studio 编写 ArkTS 页面使用 AGC 提供用户认证、云数据库和云函数能力写出来的东西不是只停留在 Demo 层面而是可以直接往生产方向迭代的骨架。1. 项目整体设计与技术选型1.1 需求模块拆解五个模块怎么串成一条完整链路个人记账系统听起来简单但把它拆开之后会发现在移动端开发里是一个非常标准的“数据密集型应用”。我先按模块把需求理了一遍用户认证模块注册、登录、退出登录支持会话保持用户只能看到自己的数据。账单记录模块新增一笔收入或支出记录金额、分类、备注、时间支持编辑和删除。分类管理模块预设收入和支出分类也允许用户自定义分类需要支持图标和颜色。统计分析模块按日、月、年维度展示收支趋势统计各分类占比辅助用户理解自己的消费结构。预算管理模块设置月度预算实时计算剩余额度超支时给出提醒。这五个模块不是孤立的数据流大概是用户登录后从 AGC 云数据库拉取当前用户的分类、账单和预算配置新增账单时写入云数据库统计分析页面通过云函数或本地聚合计算账单表预算模块则在写入账单时同步更新预算进度。整个设计其实和常规 App 的“用户体系 业务数据 数据看板”没有本质区别但因为在 HarmonyOS 生态里用 ArkTS 实现很多细节需要重新适配。1.2 为什么选 ArkTS 而不是 JavaScript 或 JavaHarmonyOS 应用开发早期的选择主要集中在 Java、JavaScript 上但 ArkTS 慢慢变成了官方主推的 UI 开发语言。我在实际写下来之后觉得 ArkTS 有几个特性特别适合这类中大型项目。首先是静态类型。ArkTS 基于 TypeScript 语法做了约束强类型能在编译期拦掉很多低级错误。记账系统里账单模型、分类模型、用户模型来回传如果没有类型检查一个字段拼错可能到运行期才暴露调试成本很高。ArkTS 的interface和class可以很好地描述这些数据结构。其次是声明式 UI 和状态管理。ArkTS 配合 ArkUI 的State、Prop、Link装饰器页面状态更新后 UI 会自动刷新不用像传统命令式写法那样手动操作 DOM 或组件实例。对列表、表单这种交互密集型场景来说开发效率和代码可维护性都有明显提升。另外ArkTS 在性能上也有优势。它通过方舟编译器的静态优化减少了运行时开销尤其在列表滚动、页面转场这类高频场景里实际体验比纯 JS 解释执行更稳。对于记账系统这种需要频繁刷新列表和统计图表的应用这一点很重要。1.3 后端为什么用 AGC 而不是自建服务项目预算和服务器运维能力都有限自建后端意味着要处理服务器购买、域名备案、HTTPS 证书、数据库备份、身份认证安全这些事对个人开发者来说负担很重。AGC 的好处是把这些基础设施封装好了我只需要在控制台创建应用配置认证方式然后在代码里调用 SDK。AGC 提供的核心能力刚好覆盖这个项目Auth 认证服务支持手机号、邮箱、匿名登录可以快速实现用户注册和登录。Cloud DB 云数据库提供结构化数据存储和权限管理客户端可以直接读写。Cloud Functions 云函数适合做统计汇总、预算检查这类需要服务端逻辑的操作。从后端设计角度看AGC 不要求自己维护服务器同时因为客户端和云服务是同一个生态SDK 的适配成本低可以省去很多 REST API 的胶水代码。当然如果业务逻辑极复杂或者需要自定义数据库索引和高并发架构AGC 不一定够用但记账系统这个量级完全合适。2. 开发环境搭建与工程初始化2.1 DevEco Studio 版本选择与 SDK 配置开发工具我使用的是 DevEco Studio这是 HarmonyOS 官方 IDE底层是 IntelliJ 社区版如果你之前用过 Android Studio上手会非常快。版本选择上建议使用官方最新的稳定版因为 SDK 和模拟器会跟着更新旧版本容易出现 API 不兼容的问题。SDK 配置方面需要注意 Compile SDK 版本。项目最低兼容版本我设置为 API 9 以上主要适配 HarmonyOS NEXT 5.0 及以上设备。产品需求里提到兼容范围是 A 支持 iOS 11.0 及以上、Android 4.0 及以上、HarmonyOS NEXT 5.0 及以上但实际本次开发主要目标还是 HarmonyOS NEXT。在工程里可以提前把minCompatibleVersion和targetSdkVersion配置好避免后期做多端兼容时返工。DevEco Studio 第一次启动会自动下载 HarmonyOS SDK、Toolchain、模拟器镜像。网络状况不好时容易卡住建议使用稳定网络同时确认 Node.js 环境正常。这里有个细节DevEco Studio 自带的 Node 版本可能与某些 ohpm 插件不匹配如果后面安装第三方库碰到 node-gyp 相关错误要先检查 Node 版本。2.2 创建工程时的关键选项新建项目时我选择的是 Empty Ability 模板语言选择 ArkTS然后填写应用包名。包名尽量用反域名格式例如com.example.mymoney后面在 AGC 控制台创建应用时需要保持一致。有几个关键配置容易踩坑compileSdkVersion、targetSdkVersion、minCompatibleVersion需要按实际支持的设备范围设置。如果设置太高低版本设备跑不了设置太低部分新 API 用不了。签名证书。本地调试时用自动签名即可。如果需要真机调试或发布需要配置签名证书否则 AGC 服务可能无法正常拉起。包名和 AGC 配置文件。创建完工程后要在 AGC 控制台下载agconnect-services.json放到entry/src/main/resources/rawfile目录下否则运行时 SDK 初始化会失败。工程创建后我的目录结构大致如下entry/src/main/ets/ entryability/ pages/ LoginPage.ets HomePage.ets StatisticsPage.ets BudgetPage.ets ... common/ constants/ utils/ model/ Bill.ets Category.ets Budget.ets2.3 项目目录结构与 ArkTS 基础语法速览ArkTS 组件文件通常以.ets结尾。一个最简单的页面包含三部分Entry表示这是页面入口Component表示这是一个自定义组件build()方法描述 UI 结构。下面是一个典型结构Entry Component struct LoginPage { State username: string State password: string build() { Column() { TextInput({ placeholder: 请输入账号, text: this.username }) .onChange((value: string) { this.username value }) Button(登录) .onClick(() { // 调用登录逻辑 }) } .width(100%) .height(100%) } }如果你写过 Vue 或 Flutter对这种“状态 声明式 UI”的模式不会陌生。State修饰的变量在值改变后会触发当前组件的重新渲染所以不需要手动刷新页面。这里要注意ArkTS 对类型检查很严格any类型基本不能用接口定义要提前写好不然后面越写越痛苦。3. 前端核心模块实现ArkTS 实战3.1 用户认证模块登录页与状态管理用户认证我这里接的 AGC Auth 服务。登录页设计很简单上方是 App Logo中间是账号输入框、密码输入框下方是登录按钮和注册入口。背景做了一个黑色到透明的线性渐变这个细节我放到后面单独讲。登录逻辑的核心是先调用 AGC Auth 的接口成功后拿到用户唯一标识再把它保存在本地。保存方式我用的 Preferences方便下次启动时自动恢复登录状态。import { auth } from kit.AGCKit import { preferences } from kit.ArkData async function login(username: string, password: string) { const user await auth.Auth.signInWithAccount(username, password) // 保存登录态 const prefs await preferences.getPreferences(getContext(), my_account) await prefs.put(uid, user.getUid()) await prefs.flush() }这里有三点需要注意第一密码不能明文保存在本地AGC 返回的 Token 会由 SDK 管理不要在业务代码里到处传递第二页面跳转时要判断登录态不能只靠路由控制否则绕过登录页后数据接口会报错第三AGC Auth 的初始化依赖agconnect-services.json配置如果运行时报AGC init failed优先检查配置文件是否放在rawfile下。3.2 账单记录与分类管理数据模型与列表渲染账单和分类是记账系统的核心数据。我先定义了数据模型// model/Bill.ets export interface Bill { id: string uid: string type: income | expense categoryId: string amount: number note: string createTime: number } // model/Category.ets export interface Category { id: string uid: string type: income | expense name: string icon: string color: string }账单列表页面我用List组件配合ForEach渲染。每条记录展示分类图标、备注、金额和时间右侧提供编辑和删除入口。比较关键的是金额展示收入和支出要用不同颜色区分支出用黑色或红色收入用绿色这样用户扫一眼就能看懂收支结构。添加账单的页面会用到分类选择器。这里的思路是先按当前账单类型加载对应的分类列表然后通过自定义组件展示分类网格用户点击后高亮选中分类再把表单数据提交到 AGC Cloud DB。列表渲染这里有一个性能重点数据量小用ForEach没问题但账单数据会随着时间增长最好换成LazyForEach让框架按需加载可见区域的数据避免一次性创建大量组件导致卡顿。我实际测试过几千条数据时LazyForEach的滚动流畅度明显优于ForEach。3.3 统计分析图表绘制与日期筛选统计分析页面是个人记账系统里最有“成就感”的模块。我按月份展示支出趋势折线图和分类占比饼图。HarmonyOS 自带 Charts 组件能力但需要引入相关依赖如果不想引入太重的东西也可以自定义绘制。我这边使用Canvas自绘了一个简易饼图和柱状图好处是不占额外体积流程完全可控。日期筛选是统计模块的基础。我通过一个月份选择器来切换统计周期选择后会查询该月所有账单再在本地做聚合function calculateCategoryTotal(bills: Bill[], type: string) { const result: Recordstring, number {} bills .filter(item item.type type) .forEach(bill { result[bill.categoryId] (result[bill.categoryId] || 0) bill.amount }) return result }聚合后的数据传给图表组件通过占比或数值排序展示前几大分类。这里要注意时区问题createTime统一用时间戳保存查询时先换算成月初和月末的时间戳再交给数据库查询避免因时区差异导致数据漏掉。3.4 预算管理进度计算与预警预算模块我做成了一张卡片放在首页顶部本月预算金额、本月累计支出、剩余金额、进度条和预警状态。用户可以在设置页调整每月预算保存到 AGC Cloud DB。预算进度的计算逻辑是每月 1 日查询本月支出总额用预算金额减去支出金额得到剩余当支出超过预算的 80% 时进度条变黄并显示“接近超支”超过 100% 时变红并提示“已超支”。这里的实时性很重要。我做了两种方案第一种是用户每次新增账单后重新拉取预算和支出数据第二种是云函数在写入账单时更新预算数据。考虑到用户操作频率不高我选择了第一种实现简单且够用。如果后续要支持多人协作或者多端实时同步再考虑换成云函数事件触发。3.5 界面优化黑色背景线性渐变的正确写法你可能会看到很多 HarmonyOS 页面喜欢用黑色渐变背景最典型的就是登录页。需求里写的“背景色黑色 #000000 线性渐变 80%-0%”翻译成实际效果就是从 80% 不透明的黑色渐变到完全透明。ArkUI 中可以直接用linearGradient属性实现// 登录页背景 .build() { Column() { // 页面内容 } .width(100%) .height(100%) .linearGradient({ angle: 180, colors: [[#CC000000, 0.0], [#00000000, 1.0]] }) }这里#CC000000表示 80% 不透明度的黑色#00000000是完全透明的黑色。angle: 180表示从上往下渐变。如果你想要从左到右或对角渐变调整角度即可。很多人在这一步容易写错颜色格式。ArkUI 支持#AARRGGBB格式其中前两位是透明度十六进制。如果你想要 50% 透明度应该是#80000000而不是#50FFFFFF。我一开始想当然用rgba(0,0,0,0.8)写结果编译不通过后来查文档才发现 ArkTS 里不支持rgba函数统一用十六进制或Color枚举。这个坑在自定义主题时特别常见建议直接形成肌肉记忆透明黑色从上到下就是#CC000000到#00000000。4. 后端服务接入AGC 从零到可用4.1 AGC 项目创建与开通认证服务后端接入的第一步是在 AppGallery Connect 控制台创建项目。这里要注意创建应用时平台要选 HarmonyOS包名必须和 DevEco Studio 工程里的包名完全一致否则签名校验会失败。创建完成后在“认证服务”里开启需要的登录方式。我开启了“手机号”和“邮箱”两种方便测试。然后下载agconnect-services.json放到工程entry/src/main/resources/rawfile下。记得确认 DevEco Studio 里已经添加了 AGC SDK 依赖// oh-package.json5 中的依赖 dependencies: { kit.AGCKit: file:./agc-ohos-sdk }AGC 的接入步骤不算复杂但有一个关键点如果项目使用了自动签名要确保签名文件的 SHA256 指纹已经配置到 AGC 控制台否则运行时认证服务可能报错。真机调试时尤其容易出现这个问题我一开始就是在这里卡了很久。4.2 云数据库表结构设计Cloud DB 是 AGC 提供的数据存储服务。我设计了四张表表名主要字段说明useruid,name,avatar,createTime用户信息categoryid,uid,type,name,icon,color分类数据billid,uid,type,categoryId,amount,note,createTime账单记录budgetid,uid,month,amount,updateTime月度预算Cloud DB 的权限配置很重要。账单数据是用户隐私不能所有用户都能互相读取。我在 Cloud DB 控制台把每条记录的read和write权限都设为了“创建者可用”然后请求时带上下上文中的uid这样基本上能保证数据隔离。需要注意的是Cloud DB 在客户端直接访问时查询条件有长度和次数的限制对很复杂的聚合查询支持有限。所以统计模块如果要在服务端做我更推荐用云函数。4.3 云函数实现业务逻辑前后端交互示例云函数我主要用来做两类事情月度统计汇总和预算超支检查。原因是这些操作需要遍历当前用户某个月的所有账单放在客户端做也行但每次都要全量拉数据浪费流量放在云函数里做只要把一个月的数据算好返回一个汇总结果即可。一个简单的云函数示例// 云函数入口handleMonthlyReport export async function handleMonthlyReport(params) { const { uid, monthStart, monthEnd } params // 查询这个时间范围内的账单 const bills await cloud.database().collection(bill) .where({ uid }) .where(createTime, , monthStart) .where(createTime, , monthEnd) .get() const totalIncome bills.filter(b b.type income) .reduce((sum, b) sum b.amount, 0) const totalExpense bills.filter(b b.type expense) .reduce((sum, b) sum b.amount, 0) return { totalIncome, totalExpense, count: bills.length } }客户端通过 AGC CloudFunctions 模块调用这个云函数拿到结果再渲染统计页。这样做的好处是业务逻辑集中后续如果客户端要扩展不需要改数据库查询逻辑只要扩展云函数接口即可。不过云函数也有学习成本。它运行在 Node.js 环境中虽然没有前端页面但依赖 Node 和 npm 生态。我第一次部署时遇到了内存限制和日志不直观的问题后来通过加日志、分段处理解决。对于个人记账系统这种轻量业务云函数没必要写太复杂保持单一职责更容易排查问题。5. 第三方库与打包部署实战5.1 引入 pulltorefreshv2 实现下拉刷新列表页面少不了下拉刷新。HarmonyOS 官方有Refresh组件但很多人会选第三方库比如pulltorefreshv2。我用下来觉得它的动画效果更顺滑自定义头部也比较方便。安装方式是在 DevEco Studio 的 Terminal 里执行ohpm install ohos/pulltorefreshv2然后在页面里引入import { PullToRefreshV2 } from ohos/pulltorefreshv2 Entry Component struct BillListPage { State bills: Bill[] [] build() { PullToRefreshV2({ onRefresh: () { this.loadBills() } }) { List() { ForEach(this.bills, (bill: Bill) { ListItem() { BillItemView({ bill: bill }) } }, (bill: Bill) bill.id) } } } }使用第三方库时最怕版本和 API 不匹配。pulltorefreshv2在不同版本上的构造参数不完全一样我建议安装时锁定版本号不要直接装 latest。另外三方库如果依赖了原生模块编译时可能会走到 node-gyp 这条链路接下来这个问题必须处理。5.2 node-gyp 相关问题的处理跑 HarmonyOS 工程时遇到node-gyp错误通常不是你主动装的而是某个依赖包在安装过程中需要编译原生模块。常见的报错有gyp ERR! node-gyp -v后面跟 Python 相关错误找不到 Visual Studio Build Tools 或 C 编译器Node 版本和预编译二进制不匹配。我的处理顺序是这样先确认 Node.js 版本。DevEco Studio 内置的 Node 版本可能和系统安装的不同可以在终端执行node -v查看。如果版本过低或过高部分原生模块编译会失败。安装 Python 和 C 构建环境。Windows 上建议安装 Visual Studio Build Tools勾选“使用 C 的桌面开发”macOS 上安装 Xcode Command Line Tools。如果项目不强制使用原生依赖最好避免安装带原生编译的 ohpm 包。像pulltorefreshv2这种纯 JS/ETS 的库就不会触发 node-gyp而某些涉及加密、图片处理的原生库就很可能踩坑。实在要原生依赖可以尝试清理缓存后重新安装ohpm clean ohpm install有几次我是在安装某个图表库时遇到的 node-gyp 问题后来换成纯 ArkTS 自绘方案问题迎刃而解。所以建议在选第三方库时多看一眼依赖链别等编译报错再后悔。5.3 多端适配与签名打包项目产品定义里写的是 A 支持 iOS 11.0 及以上、Android 4.0 及以上、HarmonyOS NEXT 5.0 及以上。实际到 HarmonyOS 应用开发阶段主要打包产物是 HAP 和 APP。多端适配如果后续要延伸需要走跨端框架或者多工程维护这是另一个话题我只说 HarmonyOS 这边的签名打包。打包前需要准备调试证书和 Profile在 AGC 控制台申请下载后配置到 DevEco Studio 的 Signing Configs。版本号在app.json5里配置versionCode和versionName。混淆与压缩Release 构建时开启混淆和资源压缩能明显减小包体积。打包时我遇到了一个常见问题AGC 服务和云函数在 Release 包里调用失败。排查后发现是签名指纹没有同步到 AGC 控制台重新配置后解决。所以确认签名、包名、指纹三者一致是上架前必须检查的一步。6. 常见问题与排查技巧实录6.1 编译报错排查从 ArkTS 严格模式到依赖版本ArkTS 的编译器对类型要求非常严格常见报错包括函数参数类型不匹配、对象属性不存在、用了any类型或as any强转。我自己的习惯是新建数据模型时就把 interface 定义完整避免在页面里临时拼对象这样大多数类型错误都能提前规避。另一类高频问题是第三方库版本冲突。比如pulltorefreshv2要求某 API 版本以上但工程的compileSdkVersion设置太低编译时直接报Method not found。解决办法是把compileSdkVersion抬升到库要求的版本或者换一个兼容版本。在 ohpm 安装库时注意看控制台输出的版本依赖提示不要忽略 warning。6.2 真机调试问题签名、模拟器和 AGC 服务模拟器调试时AGC 的云函数和认证服务一般没问题。但真机调试时经常会出现“AGC SDK not initialized”或者“sign verify failed”的报错。这类问题九成出在签名上。真机调试的正确流程是在 DevEco Studio 中打开自动签名让它生成调试证书和 Profile把生成的证书 SHA256 指纹复制到 AGC 控制台的应用配置里确认agconnect-services.json中的包名和证书指纹没有过期。另一个常见问题是真机连接不稳定。HarmonyOS 设备通过 USB 连接电脑后如果一直无法识别先检查是否开启了“开发者模式”和“USB 调试”再换一根数据线试试。很多时候不是代码问题而是环境问题。6.3 数据同步与性能优化列表渲染和云函数调用频率数据同步层面最直接影响体验的是列表渲染。账单多起来之后ForEach会导致页面越来越卡。我后来把所有账单列表改成了LazyForEach同时给每个ListItem设置唯一的 key避免重复渲染。云函数调用频率也要控制。统计页每次切换月份都会调用一次云函数如果用户快速切换可能产生并发请求。我在前端做了简单的请求取消和请求防抖只保留最后一次请求结果。此外云函数返回的数据量尽量精简不要返回一整批不需要的明细字段。还有一点Cloud DB 单次查询记录数有限制默认可能只能返回一小部分数据。如果账单数据很多需要做分页查询或者游标查询。我的做法是每次查询 100 条滚动到底部时再拉取下一页同时定期把历史账单归档到云函数侧做统计。最后说点实际的体会。这次个人记账系统开发下来我最大的感触是 ArkTS 的入门曲线其实比想象中平缓但前提是不要绕开类型系统和状态管理。很多从前写 JavaScript 时“无所谓”的写法在 ArkTS 里都会被编译器揪出来一开始会觉得烦但代码跑起来之后稳定性确实好很多。AGC 这套后端对个人开发者足够友好尤其是认证和云函数省掉了大量基础设施搭建的工作。如果你打算做类似的工具类应用我建议先把数据模型和 AGC 表结构设计好再动手写 UI否则中途改字段真的很痛苦。另外第三方库不是越多越好pulltorefreshv2这类纯声明式组件可以放心用但遇到 node-gyp 报错时优先考虑“能不能不用这个库”而不是“怎么编译这个库”。希望这篇实战记录能让你少踩几个坑。本文还有配套的精品资源点击获取