HarmonyOS+ArkTS实战:基于AGC的个人记账系统开发全解析
2026/9/22 16:34:17 网站建设 项目流程

简介:在移动应用开发中,声明式UI与静态类型检查正成为提升开发效率与代码稳定性的关键手段,而后端即服务(BaaS)则帮助个人开发者大幅降低服务端搭建成本。HarmonyOS生态下的ArkTS语言基于TypeScript,通过强类型约束和状态管理机制,让UI开发更直观、可靠;配合AppGallery Connect(AGC)提供的用户认证、云数据库与云函数能力,开发者无需自建服务器即可构建完整业务闭环。本文以个人记账系统为实战场景,从需求拆解、工程配置到核心模块实现,系统阐述在DevEco Studio中使用ArkTS编写界面、接入AGC后端服务的完整流程,并分享列表渲染性能、签名调试、第三方库依赖等常见问题的排查经验,为准备入门HarmonyOS应用开发的读者提供一份可落地的参考。 最近在忙一个个人记账服务系统,技术栈是 HarmonyOS + ArkTS,整个项目在 DevEco Studio 里开发,后端直接接的 AGC(AppGallery Connect),涵盖用户认证、账单记录、分类管理、统计分析、预算管理五个模块。项目不大,但前后端链路完整,做下来对 ArkTS 的应用开发、HarmonyOS 生态以及 AGC 的接入方式都有了一个比较系统的认识。如果你正准备入门 HarmonyOS 应用开发,或者想找一个可以照着做的实战项目,这篇文章应该能给你不少参考。

下面我从项目设计、开发环境、前端模块、后端接入、第三方库这几个维度展开,尽量把每个关键决策背后“为什么这么做”讲清楚,最后再补一段我在真实开发中踩过的坑。整个项目基于 DevEco Studio 编写 ArkTS 页面,使用 AGC 提供用户认证、云数据库和云函数能力,写出来的东西不是只停留在 Demo 层面,而是可以直接往生产方向迭代的骨架。

1. 项目整体设计与技术选型

1.1 需求模块拆解:五个模块怎么串成一条完整链路

个人记账系统听起来简单,但把它拆开之后会发现在移动端开发里是一个非常标准的“数据密集型应用”。我先按模块把需求理了一遍:

  • 用户认证模块:注册、登录、退出登录,支持会话保持,用户只能看到自己的数据。
  • 账单记录模块:新增一笔收入或支出,记录金额、分类、备注、时间,支持编辑和删除。
  • 分类管理模块:预设收入和支出分类,也允许用户自定义,分类需要支持图标和颜色。
  • 统计分析模块:按日、月、年维度展示收支趋势,统计各分类占比,辅助用户理解自己的消费结构。
  • 预算管理模块:设置月度预算,实时计算剩余额度,超支时给出提醒。

这五个模块不是孤立的,数据流大概是:用户登录后,从 AGC 云数据库拉取当前用户的分类、账单和预算配置;新增账单时写入云数据库;统计分析页面通过云函数或本地聚合计算账单表;预算模块则在写入账单时同步更新预算进度。整个设计其实和常规 App 的“用户体系 + 业务数据 + 数据看板”没有本质区别,但因为在 HarmonyOS 生态里用 ArkTS 实现,很多细节需要重新适配。

1.2 为什么选 ArkTS 而不是 JavaScript 或 Java

HarmonyOS 应用开发早期的选择主要集中在 Java、JavaScript 上,但 ArkTS 慢慢变成了官方主推的 UI 开发语言。我在实际写下来之后,觉得 ArkTS 有几个特性特别适合这类中大型项目。

首先是静态类型。ArkTS 基于 TypeScript 语法做了约束,强类型能在编译期拦掉很多低级错误。记账系统里账单模型、分类模型、用户模型来回传,如果没有类型检查,一个字段拼错可能到运行期才暴露,调试成本很高。ArkTS 的interfaceclass可以很好地描述这些数据结构。

其次是声明式 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。在工程里可以提前把minCompatibleVersiontargetSdkVersion配置好,避免后期做多端兼容时返工。

DevEco Studio 第一次启动会自动下载 HarmonyOS SDK、Toolchain、模拟器镜像。网络状况不好时容易卡住,建议使用稳定网络,同时确认 Node.js 环境正常。这里有个细节:DevEco Studio 自带的 Node 版本可能与某些 ohpm 插件不匹配,如果后面安装第三方库碰到 node-gyp 相关错误,要先检查 Node 版本。

2.2 创建工程时的关键选项

新建项目时,我选择的是 Empty Ability 模板,语言选择 ArkTS,然后填写应用包名。包名尽量用反域名格式,例如com.example.mymoney,后面在 AGC 控制台创建应用时需要保持一致。

有几个关键配置容易踩坑:

  • compileSdkVersiontargetSdkVersionminCompatibleVersion需要按实际支持的设备范围设置。如果设置太高,低版本设备跑不了;设置太低,部分新 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.ets

2.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: Record<string, 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 控制台把每条记录的readwrite权限都设为了“创建者可用”,然后请求时带上下上文中的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 版本和预编译二进制不匹配。

我的处理顺序是这样:

  1. 先确认 Node.js 版本。DevEco Studio 内置的 Node 版本可能和系统安装的不同,可以在终端执行node -v查看。如果版本过低或过高,部分原生模块编译会失败。
  2. 安装 Python 和 C++ 构建环境。Windows 上建议安装 Visual Studio Build Tools,勾选“使用 C++ 的桌面开发”;macOS 上安装 Xcode Command Line Tools。
  3. 如果项目不强制使用原生依赖,最好避免安装带原生编译的 ohpm 包。像pulltorefreshv2这种纯 JS/ETS 的库就不会触发 node-gyp,而某些涉及加密、图片处理的原生库就很可能踩坑。
  4. 实在要原生依赖,可以尝试清理缓存后重新安装:
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里配置versionCodeversionName
  • 混淆与压缩: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”的报错。这类问题九成出在签名上。

真机调试的正确流程是:

  1. 在 DevEco Studio 中打开自动签名,让它生成调试证书和 Profile;
  2. 把生成的证书 SHA256 指纹复制到 AGC 控制台的应用配置里;
  3. 确认agconnect-services.json中的包名和证书指纹没有过期。

另一个常见问题是真机连接不稳定。HarmonyOS 设备通过 USB 连接电脑后,如果一直无法识别,先检查是否开启了“开发者模式”和“USB 调试”,再换一根数据线试试。很多时候不是代码问题,而是环境问题。

6.3 数据同步与性能优化:列表渲染和云函数调用频率

数据同步层面,最直接影响体验的是列表渲染。账单多起来之后,ForEach会导致页面越来越卡。我后来把所有账单列表改成了LazyForEach,同时给每个ListItem设置唯一的 key,避免重复渲染。

云函数调用频率也要控制。统计页每次切换月份都会调用一次云函数,如果用户快速切换,可能产生并发请求。我在前端做了简单的请求取消和请求防抖,只保留最后一次请求结果。此外,云函数返回的数据量尽量精简,不要返回一整批不需要的明细字段。

还有一点,Cloud DB 单次查询记录数有限制,默认可能只能返回一小部分数据。如果账单数据很多,需要做分页查询或者游标查询。我的做法是每次查询 100 条,滚动到底部时再拉取下一页,同时定期把历史账单归档到云函数侧做统计。

最后说点实际的体会。

这次个人记账系统开发下来,我最大的感触是 ArkTS 的入门曲线其实比想象中平缓,但前提是不要绕开类型系统和状态管理。很多从前写 JavaScript 时“无所谓”的写法,在 ArkTS 里都会被编译器揪出来,一开始会觉得烦,但代码跑起来之后稳定性确实好很多。AGC 这套后端对个人开发者足够友好,尤其是认证和云函数,省掉了大量基础设施搭建的工作。如果你打算做类似的工具类应用,我建议先把数据模型和 AGC 表结构设计好,再动手写 UI,否则中途改字段真的很痛苦。另外,第三方库不是越多越好,pulltorefreshv2这类纯声明式组件可以放心用,但遇到 node-gyp 报错时,优先考虑“能不能不用这个库”而不是“怎么编译这个库”。希望这篇实战记录能让你少踩几个坑。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询