Harmony鸿蒙6.0实战开发项目--鸿蒙记账本(登录、注册、记账、图表)【代码在文末】
摘要 HarmonyAccount是一个基于HarmonyOS开发的个人记账应用,采用ArkTS和ArkUI框架实现。项目包含用户登录注册、收支记录、账单管理、数据统计和可视化图表等功能模块,使用本地Preferences和RDB数据库存储数据。应用采用Stage模型分层架构,包括页面层、组件层、数据层和公共能力层,通过状态管理实现数据驱动UI更新。主要功能包括:用户认证(登录/注册)、收支记录(
Harmony鸿蒙6.0实战开发项目–鸿蒙记账本(登录、注册、记账、图表)
本项目是一个基于 HarmonyOS ArkTS + ArkUI 开发的鸿蒙记账本,项目名为 HarmonyAccount。功能覆盖登录、注册、收入支出记录、账单列表、年度统计和经济图表,适合用来练习 HarmonyOS 应用中的页面组织、路由跳转、本地存储、RDB 数据库和自定义图表。
功能如下:
- 用户登录或注册
- 新增收入、支出
- 首页展示本月统计
- 账单页展示明细
- 图表页展示趋势和结构
- 本地数据库保存账单
一、系统架构总览
项目采用 HarmonyOS Stage 模型开发,整体可以拆成四层:
| 层级 | 主要文件 | 职责 |
|---|---|---|
| 页面层 | AuthPage.ets、Index.ets、addBalance.ets、BillInfoPage.ets、ChartPage.ets |
页面结构、路由跳转、用户交互 |
| 组件层 | BalanceList.ets、HarmonyCharts.ets |
账单列表、统计图表等复用 UI |
| 数据层 | AuthStore.ets、balanceTypes.ets、BillingInfo.ets |
登录状态、分类配置、账单模型 |
| 公共能力层 | DBManager.ets、BillingInfoUtils.ets、StringUtils.ts |
数据库存取、账单计算、格式处理 |
核心数据流如下:
页面操作
-> 更新 ArkUI 状态
-> 调用 AuthStore / DBManager
-> 写入 Preferences 或 RDB
-> 页面重新读取数据
-> @State / @Link 驱动 UI 刷新
项目中主要用了两类本地存储:
| 存储方式 | 用途 |
|---|---|
preferences |
保存本地账户和登录状态 |
relationalStore |
保存收入、支出、分类和时间戳 |
二、运行截图
1. 登录页
登录页包含账号、密码和注册入口。

2. 注册页
注册页包含用户名、账号、密码和确认密码。提交时完成基础校验。

3. 首页总览
首页展示本月结余、收入、支出和支出率,下方展示最近账单。

4. 首页账单
首页只展示最近几条账单,完整明细放到账单页,避免首页信息过密。

5. 记账页
记账页支持收入和支出切换,用户选择分类后输入金额、备注和日期。

6. 月度账单
账单页按照日期分组,展示当前月份的收入和支出明细。

7. 经济图表
图表页展示近 6 个月结余趋势,以及本月收入、支出和消费结构。

8. 年度统计
年度统计页按月份展示收入、支出和结余。

9. 我的页面
我的页面展示账号信息、账单数、本月收入、本月支出,并提供退出登录。

三、系统详细介绍
1. 登录与注册
登录注册页面位于 AuthPage.ets,账户逻辑封装在 AuthStore.ets。
AuthStore 使用 preferences 保存本地用户信息和当前登录状态。这里没有接入服务端,适合作为本地登录注册流程的练习版本。
核心数据结构:
export interface AccountProfile {
username: string;
account: string;
password: string;
}
export interface AuthResult {
success: boolean;
message: string;
profile?: AccountProfile;
}
登录注册主要处理四件事:
- 注册时校验用户名、账号和密码
- 登录时校验账号和密码
- 登录成功后保存当前用户
- 退出登录时清理会话状态
注册成功后写入本地存储:
const user: AccountProfile = { username, account, password };
const prefs: preferences.Preferences = await AuthStore.getPrefs(context);
await prefs.put(AuthStore.USER_KEY, JSON.stringify(user));
await prefs.put(AuthStore.SESSION_KEY, user.username);
await prefs.flush();
登录成功后使用 router.replaceUrl() 进入首页,避免用户返回到登录页。
2. 首页总览
首页位于 Index.ets,是 App 的主界面。
首页主要展示:
- 本月结余
- 本月收入
- 本月支出
- 支出率
- 最近账单
- 底部导航
账单数据通过 DBManager.getInstance().getAllBillingInfo() 获取,读取后再根据当前月份过滤。
月度过滤采用 [月初, 下月初):
private getSelectedMonthBills(): BillingInfo[] {
const start: number = this.getMonthStart(0).getTime();
const end: number = this.getMonthStart(1).getTime();
return this.currentBillingInfo.filter((item: BillingInfo) =>
item.timestamp >= start && item.timestamp < end
);
}
这种写法比直接比较月份更稳定,也能避免把下个月第一天的数据算进来。
3. 记账录入
记账页位于 addBalance.ets。
用户新增账单的流程:
- 选择支出或收入
- 选择账单分类
- 输入金额
- 填写备注
- 选择日期
- 保存账单
保存时组装 BillingInfo,再写入 RDB:
DBManager.getInstance().addBillingInfo({
type: {
icon: this.activeType,
name: this.selectedTypeName
},
amount: parseFloat(this.balanceAmount),
direction: this.activeTab == 0 ? BillingDirection.OUT : BillingDirection.IN,
timestamp: this.getRecordTimestamp(),
remark: this.remark
})
这里的 timestamp 会保留当前时分秒,避免当天账单被保存成 00:00:00 后在列表中过滤异常。
4. 账单列表
账单列表封装在 BalanceList.ets。
列表会先过滤当前月份,再按时间倒序排列:
private getSelectedMonthBills(): BillingInfo[] {
const start: number = this.getMonthStart(0).getTime();
const end: number = this.getMonthStart(1).getTime();
return this.currentBillingInfo
.filter((item: BillingInfo) => item.timestamp >= start && item.timestamp < end)
.sort((a: BillingInfo, b: BillingInfo) => b.timestamp - a.timestamp);
}
为了让账单更容易浏览,组件会把账单按日期分组:
interface DayBillGroup {
label: string;
bills: BillingInfo[];
}
最终展示时只渲染有数据的日期,不显示空分组。
5. 经济图表
图表组件位于 HarmonyCharts.ets。
目前包含三块内容:
| 图表 | 说明 |
|---|---|
| 本月概览 | 展示收入、支出、结余 |
| 收支趋势 | 展示近 6 个月结余折线 |
| 消费结构 | 展示本月支出分类占比 |
近 6 个月趋势数据由账单计算得到:
private getTrendPoints(): TrendPoint[] {
const points: TrendPoint[] = [];
for (let i = 5; i >= 0; i--) {
const bills: BillingInfo[] = this.getMonthBills(i);
const income: number = this.sumByDirection(bills, BillingDirection.IN);
const expense: number = this.sumByDirection(bills, BillingDirection.OUT);
points.push({
month: this.getMonthLabel(i),
income,
expense,
balance: income - expense
});
}
return points;
}
趋势图使用 ArkUI 的 Line、Circle、Stack 等组件绘制,没有额外引入第三方图表库。为了避免点线错位,折线、圆点和月份标签使用同一套横向坐标。
消费结构会统计本月支出分类,并按金额从高到低排序。这样能直接看出钱主要花在哪些分类上。
6. 本地数据库
数据库逻辑封装在 DBManager.ets,底层使用 HarmonyOS relationalStore。
新增账单时写入表字段:
let bucket: relationalStore.ValuesBucket = {
'TYPE': JSON.stringify(data.type),
'AMOUNT': data.amount,
'DIRECTION': data.direction,
'TIMESTAMP': data.timestamp,
'IMAGE': data.image ?? '',
'REMARK': data.remark ?? ''
};
账单表结构:
| 字段 | 类型 | 说明 |
|---|---|---|
ID |
INTEGER |
自增主键 |
TYPE |
TEXT |
分类信息,JSON 字符串 |
AMOUNT |
REAL |
金额 |
DIRECTION |
INTEGER |
收入或支出 |
TIMESTAMP |
BIG INT |
账单时间 |
REMARK |
TEXT |
备注 |
IMAGE |
TEXT |
图片字段,预留 |
核心账单模型:
export enum BillingDirection {
IN,
OUT
}
export interface BillingInfo {
id?: number;
type: BillingType;
amount: number;
direction: BillingDirection;
timestamp: number;
remark?: string;
image?: string;
}
四、核心模型说明
项目内部没有网络接口,页面和组件之间主要通过本地数据模型传递信息。
| 模型 | 类型 | 说明 |
|---|---|---|
AccountProfile |
interface |
本地账户信息 |
AuthResult |
interface |
登录注册结果 |
BillingInfo |
interface |
单条账单 |
BillingDirection |
enum |
收入或支出 |
BillingType |
interface |
分类图标和名称 |
DayBillGroup |
interface |
日期分组后的账单 |
CategoryMetric |
interface |
消费结构统计项 |
TrendPoint |
interface |
趋势图点位数据 |
这些模型把页面展示和业务数据拆开,后续如果接入云端同步,也可以基于这些结构继续扩展。
五、数据流向示例
以“新增一笔支出”为例:
用户选择支出分类
-> 输入金额和备注
-> 选择账单日期
-> 点击完成
-> addBalance.ets 组装 BillingInfo
-> DBManager.addBillingInfo() 写入 RDB
-> router.back() 返回首页
-> Index.onPageShow() 重新读取账单
-> 首页统计、账单列表、图表同步刷新
这个流程覆盖了鸿蒙应用里常见的页面跳转、状态更新、本地数据库读写和 UI 刷新。
六、开发中的关键处理
1. 首页账单和账单页保持一致
首页的最近账单和底部导航中的账单页,都基于同一批本月账单数据过滤。
关键点是统一使用:
item.timestamp >= start && item.timestamp < end
这样首页和账单页不会出现“新增了账单,但某个页面看不到”的问题。
2. 日期边界使用半开区间
按月统计时不要只判断月份数字,最好使用明确的开始和结束时间。
本月账单 = timestamp >= 本月月初 && timestamp < 下月月初
这种方式能覆盖本月所有时间,也不会误算下月数据。
3. 保存日期时保留时间
如果只保存选中日期的零点时间,部分筛选逻辑会在边界处出问题。项目中保存账单时会保留当前时分秒,让当天新增记录更稳定地出现在列表中。
4. 图表点线坐标统一
趋势图中折线、圆点、月份标签必须使用同一套坐标。否则折线看起来会偏移,尤其在移动端宽度变化时更明显。
5. 页面文案保持克制
项目界面只保留标题、字段名、按钮名、状态提示和错误提示。欢迎语、宣传语、重复说明都删除掉,让页面更像真实工具,而不是展示页。
七、适合继续扩展的方向
这个项目可以继续扩展:
- 预算设置
- 账单搜索
- 分类管理
- 账单删除和编辑
- 数据导出
- 多账户数据隔离
- 云端同步
- 图表筛选和年度对比
如果想继续提高完整度,可以优先做账单编辑、删除、搜索和预算提醒,这些功能和记账 App 的使用场景最接近。
八、项目总结
鸿蒙记账本项目覆盖了 HarmonyOS 实战开发中比较常见的能力:
- ArkUI 页面搭建
- ArkTS 状态管理
- 页面路由跳转
- 本地登录注册
- Preferences 轻量存储
- RDB 数据库存储
- 月度账单筛选
- 日期分组列表
- 自定义图表绘制
它的功能不复杂,但能把页面、组件、数据、存储和状态刷新串起来。对于正在学习 HarmonyOS 的同学来说,这类项目比单独写组件更容易建立完整的开发思路。
更多推荐



所有评论(0)