一、功能概述
与第 17 篇的"导入导出"不同,"备份恢复"更强调自动化和安全性。用户不需要手动管理 JSON 文件,应用可以定期自动创建备份快照,并在需要时一键恢复。本篇文章围绕"备份恢复"模块展开,介绍如何在Cordova Web 层实现自动备份机制(例如每天自动备份一次),并通过OpenHarmony ArkTS 插件提供备份文件管理和恢复操作。
我们继续采用"一段代码一段说明"的写作方式,并包含 ArkTS 示例代码。
二、Web 端备份恢复界面结构
<divid="backup-page"class="page page-backup"><h1>备份与恢复</h1><divclass="backup-actions"><buttonid="btn-backup-now"class="btn-primary">立即备份</button><buttonid="btn-restore"class="btn-secondary">从备份恢复</button></div><h2>备份历史</h2><ulid="backup-list"class="backup-list"></ul></div>这段 HTML 定义了备份恢复页面的结构。顶部两个按钮分别用于触发手动备份和从备份恢复;下方的列表backup-list展示所有已保存的备份快照,用户可以查看备份时间、大小等信息,并选择某个备份进行恢复。
.page-backup{padding:16px 24px;}.backup-actions{display:flex;gap:12px;margin-bottom:16px;}.backup-list{list-style:none;padding:0;margin:0;}.backup-list li{padding:8px 0;border-bottom:1px solid #374151;cursor:pointer;}样式部分为页面添加基础布局和交互反馈。备份列表项通过cursor: pointer提示用户这是可点击的元素,便于选择某个备份进行恢复。
三、自动备份机制
asyncfunctioncreateBackup(){constrecords=awaitdb.getAllDrinkRecords();consttypes=awaitdb.getAllDrinkTypes();constcontainers=awaitdb.getAllContainers();constbackup={id:Date.now(),createdAt:newDate().toISOString(),version:1,data:{records,types,containers},};awaitdb.addBackup(backup);loadBackupList();updateBackupStatus('备份完成');}createBackup函数负责创建一个新的备份快照。它从 IndexedDB 中收集所有关键数据,并将其打包为一个backup对象,包含唯一 ID、创建时间和版本号。随后调用db.addBackup将备份存储到一个专门的backups表中,这样用户就可以在备份列表中看到历史记录。完成后刷新列表并更新状态提示。
asyncfunctionsetupAutoBackup(){// 每天凌晨 2 点自动备份constnow=newDate();consttomorrow=newDate(now);tomorrow.setDate(tomorrow.getDate()+1);tomorrow.setHours(2,0,0,0);constdelay=tomorrow.getTime()-now.getTime();setTimeout(()=>{createBackup();// 之后每 24 小时备份一次setInterval(createBackup,24*60*60*1000);},delay);}setupAutoBackup函数设置了一个自动备份计划。首先计算距离明天凌晨 2 点还有多少毫秒,然后使用setTimeout在该时刻触发第一次备份;之后使用setInterval每 24 小时自动执行一次备份。虽然这种实现在页面刷新后会丢失定时器,但在实际项目中可以结合 Service Worker 或原生后台任务来实现更可靠的定时备份。
document.addEventListener('DOMContentLoaded',()=>{document.getElementById('btn-backup-now')?.addEventListener('click',createBackup);loadBackupList();setupAutoBackup();});在DOMContentLoaded时绑定手动备份按钮、加载备份列表,并启动自动备份计划。这样用户既可以随时手动备份,也能享受自动备份的便利。
四、从备份恢复数据
asyncfunctionrestoreFromBackup(backupId){constbackup=awaitdb.getBackupById(backupId);if(!backup){alert('备份不存在或已被删除');return;}constconfirmed=confirm(`确认要恢复到${backup.createdAt}的备份吗?此操作将覆盖当前数据。`);if(!confirmed)return;try{// 清空当前数据awaitdb.clearAllRecords();// 导入备份数据const{records,types,containers}=backup.data;for(constrecordofrecords){awaitdb.addDrinkRecord(record);}for(consttypeoftypes){awaitdb.addDrinkType(type);}for(constcontainerofcontainers){awaitdb.addContainer(container);}updateBackupStatus('恢复完成:数据已还原');syncRestoreStatusToNative(true);}catch(err){console.error('[Restore] failed',err);updateBackupStatus('恢复失败:请重试');syncRestoreStatusToNative(false);}}restoreFromBackup函数负责从指定备份恢复数据。首先从数据库中查询该备份,如果不存在则提示用户。随后弹出确认对话框,让用户明确知道恢复操作会覆盖当前数据。确认后,先清空所有现有数据,再逐条导入备份中的记录。通过这种方式,可以确保恢复过程的原子性和数据一致性。
functionloadBackupList(){constlist=document.getElementById('backup-list');if(!list)return;db.getAllBackups().then((items)=>{list.innerHTML='';items.forEach((item)=>{constli=document.createElement('li');li.textContent=`备份于${newDate(item.createdAt).toLocaleString()}`;li.addEventListener('click',()=>{restoreFromBackup(item.id);});list.appendChild(li);});});}loadBackupList从数据库中读取所有备份,并将其渲染为一个可点击的列表。每个列表项显示备份创建时间,点击时触发restoreFromBackup恢复该备份。
五、通过 Cordova 通知原生层备份状态
functionsyncRestoreStatusToNative(success){if(!window.cordova){console.warn('[Backup] cordova not ready, skip native sync');return;}cordova.exec(()=>{console.info('[Backup] sync restore status success');},(err)=>{console.error('[Backup] sync restore status failed',err);},'WaterTrackerBackup','onRestoreComplete',[{success}]);}syncRestoreStatusToNative在恢复完成后通知 ArkTS 插件。原生侧可以根据success标志展示相应的提示或执行后续操作(例如重新加载原生界面中的数据)。
六、OpenHarmony ArkTS 插件与备份管理
// entry/src/main/ets/plugins/WaterTrackerBackupPlugin.etsimportcommonfrom'@ohos.app.ability.common';exportinterfaceRestoreStatus{success:boolean;}exportclassBackupStore{privatestatic_lastRestoreStatus:RestoreStatus|null=null;staticsetLastRestoreStatus(status:RestoreStatus){this._lastRestoreStatus=status;}staticgetlastRestoreStatus(){returnthis._lastRestoreStatus;}}exportdefaultclassWaterTrackerBackupPlugin{context:common.UIAbilityContext;constructor(ctx:common.UIAbilityContext){this.context=ctx;}onRestoreComplete(args:Array<Object>,callbackId:number){conststatus=args[0]asRestoreStatus;BackupStore.setLastRestoreStatus(status);console.info(`[BackupPlugin] restore${status.success?'success':'failed'}`);}}ArkTS 侧的WaterTrackerBackupPlugin插件接收恢复状态,并通过BackupStore缓存最新结果。
七、ArkUI 中展示备份恢复状态
// entry/src/main/ets/pages/BackupStatusPage.etsimport{BackupStore}from'../plugins/WaterTrackerBackupPlugin';@Component struct BackupStatusView{build(){conststatus=BackupStore.lastRestoreStatus;Column(){Text('备份恢复状态').fontSize(18).margin({bottom:8});if(status){Text(`上次恢复:${status.success?'成功':'失败'}`).fontSize(14);}else{Text('暂无恢复记录').fontSize(14);}}.padding(16)}}BackupStatusView组件在原生界面中展示最近一次恢复的状态,让用户在 ArkUI 页面也能了解备份恢复的进度。
八、小结
本篇文章从自动备份机制、手动备份、备份列表展示、数据恢复到 Cordova 桥接和 ArkTS 插件,完整演示了"备份恢复"在 Cordova&openharmony 混合应用中的实现路径。Web 层通过createBackup和setupAutoBackup实现了自动备份,通过restoreFromBackup实现了数据恢复;syncRestoreStatusToNative将恢复结果推送给原生侧,ArkTS 侧通过BackupStore和WaterTrackerBackupPlugin缓存状态,ArkUI 组件BackupStatusView则提供原生展示入口。
通过"一段代码一段说明"的方式,我们把整个备份恢复流程拆解得足够细致。你可以在此基础上进一步扩展,例如添加备份加密、压缩存储、云端同步等功能,让"备份恢复"真正成为用户数据安全的最后一道防线.