news 2026/2/3 3:47:31

账户增删改查与余额统计 Cordova 与 OpenHarmony 混合开发实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
账户增删改查与余额统计 Cordova 与 OpenHarmony 混合开发实战

欢迎大家加入开源鸿蒙跨平台开发者社区,一起共建开源鸿蒙跨平台生态。

本文对应模块:pages.js中账户相关的增删改 UI 交互逻辑,以及db.js中账户表 (accounts) 的增删改查与余额字段维护方式。


1. 模块目标:保证“每个账户的余额都说得清楚”

在账户管理页面(模块14)中,我们已经有了一个清晰的账户列表 UI,用表格列出了账户名称、类型、余额、创建时间等信息。本模块要回答的是:

  • 这些账户是如何被创建、修改和删除的;
  • 余额字段是如何在记账、转账、导入导出等操作中被正确维护的;
  • 首页仪表板和其他模块如何依赖这些余额做统计。

2. 数据结构回顾:accounts 表

db.js中,账户表的 schema 定义如下(节选):

// 账户表if(!db.objectStoreNames.contains('accounts')){constaccountStore=db.createObjectStore('accounts',{keyPath:'id'});accountStore.createIndex('type','type',{unique:false});accountStore.createIndex('createdAt','createdAt',{unique:false});}

对应的高层操作方法包括:

// 获取所有账户asyncgetAccounts(){returnthis.getAll('accounts');}// 添加账户asyncaddAccount(account){account.id=this.generateId();account.createdAt=newDate().toISOString();returnthis.add('accounts',account);}// 更新账户asyncupdateAccount(account){account.updatedAt=newDate().toISOString();returnthis.update('accounts',account);}// 删除账户asyncdeleteAccount(accountId){returnthis.delete('accounts',accountId);}

可以看到,账户的核心字段包括:

  • id:唯一主键,由数据库层统一生成;
  • name:账户名称(由 UI 表单提供);
  • type:账户类型(银行卡、现金、电子钱包等);
  • balance:当前余额(初始由表单设置,后续由记账/转账逻辑维护);
  • createdAt/updatedAt:时间戳字段,方便排序和追踪变更。

3. 新增账户:从按钮到数据库的一条链路

在账户管理页面(模块14)中,我们在卡片头部放置了一个“新增账户”按钮:

<buttonid="add-account"class="pc-button pc-button-primary">新增账户</button>

PageManager的事件绑定中,一般会这样处理:

bindPageEvents(pageName){if(pageName==='accounts'){constaddBtn=document.getElementById('add-account');if(addBtn){addBtn.onclick=()=>this._showAddAccountDialog();}this.loadAccountsPage();}}

_showAddAccountDialog()的典型流程是:

  1. 弹出一个模态框,包含账户名称、类型、初始余额等字段;
  2. 用户填写完成后点击“保存”;
  3. JS 收集表单数据,构造一个account对象;
  4. 调用window.financeDB.addAccount(account)写入数据库;
  5. 关闭对话框并刷新列表(调用loadAccountsPage())。

伪代码示例:

async_handleSaveAccount(formValues){constaccount={name:formValues.name,type:formValues.type,balance:Number(formValues.balance||0),};awaitwindow.financeDB.addAccount(account);Toast.success('账户已创建');this.loadAccountsPage();}

这里的关键是:

  • idcreatedAt不由 UI 层负责,而是交由数据库层在addAccount中统一补齐;
  • balance的初始值由用户指定,后续通过记账和转账逻辑进行调整。

4. 编辑账户:更新名称、类型或余额

编辑账户的入口一般在账户列表的“操作”列中:

<td><buttonclass="pc-link"data-action="edit">编辑</button><buttonclass="pc-link pc-danger"data-action="delete">删除</button></td>

通过事件委托,可以在 JS 中捕获这些点击:

_bindAccountActions(){consttbody=document.querySelector('#accounts-table tbody');if(!tbody)return;tbody.onclick=async(event)=>{consttarget=event.target;if(!(targetinstanceofHTMLElement))return;constrow=target.closest('tr');if(!row)return;constid=row.getAttribute('data-id');if(!id)return;constaction=target.getAttribute('data-action');if(action==='edit'){this._showEditAccountDialog(id);}if(action==='delete'){this._confirmDeleteAccount(id);}};}

_showEditAccountDialog(id)的典型逻辑是:

  1. 根据id从本地缓存或通过getAccounts()查找对应账户对象;
  2. 把账户信息填充到模态框表单中;
  3. 用户修改后点击“保存”,触发_handleUpdateAccount
  4. 调用window.financeDB.updateAccount(updatedAccount)
  5. 刷新账户列表。

示例:

async_handleUpdateAccount(id,formValues){constaccounts=awaitwindow.financeDB.getAccounts();constaccount=accounts.find(acc=>acc.id===id);if(!account){Toast.error('账户不存在');return;}account.name=formValues.name;account.type=formValues.type;account.balance=Number(formValues.balance||0);awaitwindow.financeDB.updateAccount(account);Toast.success('账户信息已更新');this.loadAccountsPage();}

5. 删除账户:安全性与数据一致性

删除账户需要格外谨慎:

  • 该账户是否还有未清理的交易记录?
  • 删除后是否会影响统计报表的一致性?

在 UI 层面,一般的策略是:

  • 弹出确认对话框,提示“删除账户不会删除历史交易记录,但这些交易将无法再归属到具体账户”等信息(具体行为根据你的业务设定);
  • 只有在用户明确确认后才调用deleteAccount

示意代码:

async_confirmDeleteAccount(id){constconfirmed=awaitconfirmDialog('确定要删除这个账户吗?删除后可能影响历史报表展示。','删除账户');if(!confirmed)return;awaitwindow.financeDB.deleteAccount(id);Toast.success('账户已删除');this.loadAccountsPage();}

在数据库层面,deleteAccount本身只是删除accounts表中的记录,并不会自动清理transactions表中的历史交易。这是一个有意识的设计选择:

  • 保留历史交易有利于长期统计和回溯;
  • 即使账户被删掉,历史报表仍然可以通过交易记录来恢复一部分信息。

6. 余额统计:与首页仪表板和报表模块的关系

在首页仪表板中,总资产通常通过以下方式计算:

constaccounts=awaitwindow.financeDB.getAccounts();consttotal=accounts.reduce((sum,acc)=>sum+acc.balance,0);

因此,账户的balance字段由谁维护、如何维护,就变得非常关键:

  • 新增账户时,balance等于用户设定的初始余额;
  • 记收入时,对对应账户的balance进行加法;
  • 记支出时,对对应账户的balance进行减法;
  • 转账时,一个账户减、另一个账户加(模块11已详细说明)。

这种做法相当于在accounts表中缓存了每个账户的当前余额,而不是每次都通过聚合历史交易来计算:

  • 优点:
    • 查询速度快,首页和账户管理页加载时只需要一次getAccounts()调用;
  • 缺点:
    • 需要小心保证每次记账/转账时都正确更新余额,否则可能出现“账不平”的情况。

在目前项目的设计中,两者可以并存:

  • 对实时界面展示使用缓存的balance
  • 在某些需要严格对账的场景(例如调试、校验)时,也可以从transactions表重算一次余额做比对。

7. ArkTS 视角:账户数据与导入/导出

在数据导入/导出模块中,账户数据是整个快照的一部分:

  • 导出时:

    • JS 调用financeDB.exportData(),其中会包含accounts表的所有记录;
    • ArkTS FileManager 插件只负责把这份 JSON 写入文件,不解读字段含义;
  • 导入时:

    • ArkTS 插件从文件中读回 JSON,交给 JS;
    • JS 调用financeDB.importData(),其中会使用update('accounts', record)把账户数据写回。

这意味着:

  • 只要前端在日常使用中正确维护了balance,导出/导入时就能完整保留所有账户信息;
  • ArkTS 不需要理解“余额”的具体含义,只负责搬运数据,降低了跨层耦合度。

8. 小结:账户增删改查与余额统计的实践经验

综合来看,本模块的设计有几个值得在实际项目中借鉴的点:

  1. 把 ID 和时间戳生成逻辑集中到数据库层

    • 减少 UI 和业务层的重复代码;
    • 保证所有表的主键和时间字段风格统一;
  2. 账户增删改通过统一的 UI 入口和事件委托实现

    • 列表操作列 + 模态框的组合足够灵活,也易于维护;
  3. 在账户对象中缓存余额字段

    • 结合记账、转账逻辑及时更新,使首页和账户页加载更快;
  4. 删除账户时保留历史交易

    • 通过清晰的用户提示和谨慎的删除逻辑,兼顾数据完整性与用户控制感;
  5. 与 ArkTS 的边界清晰

    • ArkTS 只负责导入/导出层面的数据搬运,不参与账户增删改 UI 和逻辑;

掌握了本模块后,你基本可以独立扩展账户系统:

  • 增加新的账户属性(例如币种、信用额度);
  • 增加更复杂的余额规则(例如信用卡账单日、还款日逻辑);
  • 都可以在现有的增删改查和余额维护框架上自然演进。

ArkTS 侧与账户数据备份

账户增删改查与余额统计主要发生在 Web + IndexedDB 层,但在做整库备份时,ArkTS FileManager 插件会把accounts表与其他表一起写入备份文件。导出入口示例:

exportclassFileManagerPluginextendsCordovaPlugin{asyncexportData(callbackContext:CallbackContext,args:string[]):Promise<void>{try{// json 字符串中包含 accounts、transactions、categories、budgets、goals、tags 等所有表的数据constjson=args[0];// 省略 fileIo 写文件的细节,见前文各模块示例}catch(error){// 错误处理略}}}

这样:

  • Web 层维护好的账户余额和其他属性,会作为数据库的一部分被序列化;
  • ArkTS 负责把这份序列化结果安全写入文件;
  • 在新设备或重装应用后,通过导入备份文件即可恢复所有账户及其余额状态,账户管理页面和首页仪表板不需要额外适配。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/2 18:38:14

智能决策系统日志系统设计:AI架构师的调试与分析技巧

智能决策系统日志系统设计:AI架构师的调试与分析技巧 摘要 本文深入探讨智能决策系统中日志系统的设计原理与实践技巧。作为AI架构师,我们面临的核心挑战是如何在复杂的决策流水线中建立有效的可观测性机制。文章从第一性原理出发,系统分析智能决策系统的独特日志需求,提…

作者头像 李华
网站建设 2026/1/29 20:18:25

力扣 11.盛最多水的容器 简单的双指针算法 题解

题目描述给定一个长度为 n 的整数数组 a 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, a[i]) 。找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容纳最多的水。​ 输出容器可以储存的最大水量。**说明&#xff1a;**你不能倾斜容器。输入格式…

作者头像 李华
网站建设 2026/2/2 0:17:30

深度学习驱动的论文降重工具有效规避查重风险,智能改写段落

AI工具能否有效解决数学建模论文复现与排版难题&#xff1f;本文深度评测10款热门AI论文写作工具&#xff0c;助你快速找到高效助手&#xff0c;轻松应对时间紧、任务重的学术挑战。aibiye&#xff1a;专注于语法润色与结构优化&#xff0c;提升可读性aicheck&#xff1a;一键生…

作者头像 李华
网站建设 2026/1/29 1:03:00

温度传感器PT1000与NTC10K介绍

在模拟电路的温度测量领域&#xff0c;PT1000和NTC 10K是两种最常用的温度敏感元件。它们基于不同的物理原理&#xff0c;各有独特的特性、应用场景和设计考量。一、PT1000&#xff08;铂电阻温度传感器&#xff09;1、基本介绍PT1000是一种正温度系数&#xff08;PTC&#xff…

作者头像 李华
网站建设 2026/2/2 1:46:29

震惊!这家酶制剂供应商竟让行业炸锅

震惊&#xff01;这家酶制剂供应商竟让行业炸锅&#xff1a;深度解析上海华上翔洋的创新之道在生物技术与工业制造深度融合的今天&#xff0c;酶制剂作为关键的生物催化剂&#xff0c;其性能与供应稳定性直接关系到下游食品、饲料、纺织、能源等诸多行业的革新进程。近期&#…

作者头像 李华
网站建设 2026/2/2 3:05:16

数学建模与排版无忧?这10个AI论文工具精准解决复现难题

还在为论文写作头痛&#xff1f;特别是数学建模的优秀论文复现与排版&#xff0c;时间紧、任务重&#xff0c;AI工具能帮上大忙吗&#xff1f;今天&#xff0c;我们评测10款热门AI论文写作工具&#xff0c;帮你精准筛选最适合的助手。aibiye&#xff1a;专注于语法润色与结构优…

作者头像 李华