山海万灵 HarmonyOS 文化知识实战(11):护照收藏与进度统计

发布时间:2026/9/22 15:00:03

山海万灵 HarmonyOS 文化知识实战(11):护照收藏与进度统计 一、把探索行为收敛成一份可恢复的进度文化知识应用中的“收藏”并不只是给卡片切换一个图标。山海万灵把一次神兽发现同时映射到图鉴收录、地域探索比例、护照印章和下次进入时的区域位置。如果这些结果由各页面各自保存重复发现、切换区域和重启恢复很容易出现不一致。工程把可变的探索数据定义为ShanhaiLocalProgress版本号、已发现神兽 ID、已选地域、已选展厅与更新时间放在同一份记录中。图鉴资料、地域资料和展厅资料仍然属于启动数据不与用户进度混存。这样重置进度只影响本机探索记录不会删除知识内容或远端资料。export interface ShanhaiLocalProgress { schemaVersion: number; discoveredIds: string[]; selectedRegionId: string; selectedHallId: string; updatedAt: number; } export function createEmptyShanhaiLocalProgress(): ShanhaiLocalProgress { return { schemaVersion: SHANHAI_LOCAL_PROGRESS_SCHEMA_VERSION, discoveredIds: [], selectedRegionId: , selectedHallId: , updatedAt: 0 }; }二、Preferences 只保存原子字段领域状态保持完整形状仓储以shanhai_local_progress作为 Preferences 文件名分别写入 schema、发现 ID 串、地域 ID、展厅 ID 和更新时间。ID 在写入前去重并以分隔符序列化读取失败、类型不符或存储不可用时返回空进度而不是把异常值直接交给页面。async save(progress: ShanhaiLocalProgress): Promisevoid { const store: preferences.Preferences | null await this.getStore(); if (store null) { return; } await store.put(KEY_SCHEMA_VERSION, SHANHAI_LOCAL_PROGRESS_SCHEMA_VERSION); await store.put(KEY_DISCOVERED_IDS, this.serializeIds(progress.discoveredIds)); await store.put(KEY_SELECTED_REGION_ID, progress.selectedRegionId); await store.put(KEY_SELECTED_HALL_ID, progress.selectedHallId); await store.put(KEY_UPDATED_AT, progress.updatedAt); await store.flush(); }这里有两个边界需要保留。第一flush()使一次用户动作对应一次明确的落盘完成点第二仓储层吞掉的是持久化异常页面仍可继续浏览当前内容并由同步状态提示后续动作。页面不需要知道键名或序列化格式。三、发现神兽时一次性更新图鉴、护照和位置ShanhaiAppViewModel.discoverBeast是状态更新入口。它先判断目标是否存在再判断是否已经发现新发现的 ID 只追加到复制后的数组。随后把神兽所属地域和展厅写为当前探索位置持久化后用启动数据与本地进度重新生成聚合结果。const alreadyDiscovered: boolean this.localProgress.discoveredIds.indexOf(beast.id) 0; const discoveredIds: string[] this.localProgress.discoveredIds.slice(); if (!alreadyDiscovered) { discoveredIds.push(beast.id); } this.localProgress this.normalizeLocalProgress(bootstrap, { schemaVersion: SHANHAI_LOCAL_PROGRESS_SCHEMA_VERSION, discoveredIds: discoveredIds, selectedRegionId: beast.regionId, selectedHallId: beast.hallId, updatedAt: Date.now() }); await this.persistLocalProgress(); const mergedBootstrap: ShanhaiBootstrap this.applyLocalProgress(bootstrap, this.localProgress);这种顺序避免了“页面先改了计数、存储失败后无法恢复”的双源状态。重复发现不会再次增加记录但仍会返回已有发现的提示无效 ID 则保持原进度不变。四、进度和护照印章都由发现记录推导地域进度不单独保存百分比。视图模型遍历地域的beastIds统计已经发现的数量再计算百分比和“已收录 x/y”状态。护照印章也遵循同一条规则一个地域的全部神兽都在discoveredIds中时该地域才进入passportRegionIds。private derivePassportRegionIds(regions: RegionItem[], discoveredIds: string[]): string[] { return regions .filter((region: RegionItem) region.beastIds.length 0 region.beastIds.every((beastId: string) discoveredIds.indexOf(beastId) 0)) .map((region: RegionItem) region.id); } private applyDiscoveryProgressToRegions(regions: RegionItem[], discoveredIds: string[]): RegionItem[] { return regions.map((region: RegionItem): RegionItem { const discoveredCount: number region.beastIds .filter((beastId: string) discoveredIds.indexOf(beastId) 0).length; const progress: number region.beastIds.length 0 ? 0 : Math.round(discoveredCount * 100 / region.beastIds.length); return { ...region, progress: progress, status: 已收录 discoveredCount / region.beastIds.length }; }); }从同一个事实源派生统计能保证档案页的“已发现”和“护照印章”与地图卡片的区域进度始终对应。地域没有目录时进度固定为 0避免除零和虚假的完成印章。五、页面只消费结果并保留可见的失败出口本次验证安装了当前构建的山海万灵包在图鉴中完成九尾狐的发现动作后回到档案页。页面回读显示“已发现 3 种神兽”和“护照印章 1 枚”说明发现记录已经驱动统计和印章结果而不是只改变详情页上的局部控件。随后结束应用进程并重新启动同一包档案页仍保留 3 条发现记录、1 枚护照印章以及最近探索地域“青丘”。这只验证本机 Preferences 的恢复链路本文不把它扩展为云端同步、跨设备迁移或网络请求成功的结论。验收时还应把“发现”和“完成地域”分开观察前者直接增加 discoveredIds后者要等一个地域目录中的全部神兽都已收录才产生护照印章。这样既能避免单次发现被误记为地域完成也让 UI 上的两个数字能追溯到不同的派生规则。若存储层暂时不可用应用仍可保留本次会话中的知识浏览和状态展示下一次启动按空进度恢复不把未落盘的数据伪装成持久结果。页面层调用syncDiscovery后回写discoveredIds、passportRegionIds、地域和展厅数据。新出现的印章会被标记为高亮目标本地 fallback 状态会转换为页面可读的同步提示。失败时不伪造成功结果而是保留当前内容并显示重试路径。档案页把发现数和护照印章数作为明确的Prop传入统计面板统计组件不读取 Preferences。这样窄屏、宽屏和主题切换只影响排版不会改变进度计算。场景进度写入页面结果首次发现神兽追加 ID、更新地域与展厅位置图鉴、地域进度和护照候选一起重算重复发现保留原 ID 集合不重复计数继续展示关联探索提示存储读取异常使用空进度知识资料仍可浏览进度从初始状态开始本地进度重置清空进度仓储图鉴资料、个人档案和远端数据保持不变六、验收要覆盖恢复、重复动作和局部重置这条链路的验收不应只看一个数字。应先在图鉴中完成一次发现确认档案统计、地域进度和护照印章基于同一条记录更新再重启应用检查发现 ID、当前地域和展厅位置是否恢复。随后重复触发同一神兽确认计数不增加最后打开本地进度重置确认框检查取消不会变更记录确认重置后只回到探索初始状态。对于网络数据源不可用的场景继续检查本地 fallback 是否保留可浏览内容并让同步横幅提供重试入口。这样持久化失败、无效目标和重复动作都有明确的状态边界而不是由页面临时补丁掩盖。七、总结山海万灵用一份版本化的本地进度记录承载发现、地域和展厅选择Preferences 负责持久化原子字段视图模型负责归一化、去重和派生统计ArkUI 页面只展示已经聚合的结果。收藏、护照印章与探索进度因此共享同一条数据链路重置也能准确限定在本机探索状态内。
延伸阅读

更多相关文章

2026/9/20 0:19:23

.NET架构进阶:微服务、DDD与云原生核心难点实战解析

1. 这篇文章真正要解决的问题 很多 .NET 开发者工作三五年后,会陷入一个尴尬的境地:日常业务开发游刃有余,CRUD、API接口、页面渲染信手拈来,但一旦被问到“如何设计一个高可用的微服务架构”、“如何保证分布式事务的一致性”、“…

2026/9/20 0:19:18

Unity游戏实时翻译实战:XUnity.AutoTranslator部署与原理详解

1. 项目概述:当Unity游戏遇到语言壁垒作为一名在游戏本地化和工具开发领域摸爬滚打了十多年的老手,我见过太多玩家因为语言问题,与优秀的独立游戏或小众作品失之交臂。对于使用Unity引擎开发的游戏而言,文本资源往往被封装在特定的…

2026/9/22 14:55:56

UX设计师转码必看的速查手册

UX设计师转码必看的速查手册 看了一堆教程还是不会写项目?别慌,这不仅是你的问题,也是90%转行者的通病。很多设计师转码,死记硬背API却连一个完整的交互逻辑都串不起来,根源在于缺乏 UX视角的源码拆解能力 。 这份 UX转码速查手册…

2026/9/22 14:55:56

句艳东源码解析:3步解决环境配置卡死痛点

句艳东源码解析:3步解决环境配置卡死痛点 刚拿到【句艳东】相关的开发任务,是不是第一反应就是打开终端敲命令?结果没等代码跑起来,环境配置这块就卡了半天。依赖装不上、版本冲突报错、本地库找不到,折腾一下午还没个准信。这种痛苦,写代码的人谁没经…

2026/9/22 14:55:56

孤岛惊魂原始杀戮破解新手避坑:5步搞懂底层逻辑

孤岛惊魂原始杀戮破解新手避坑:5步搞懂底层逻辑 官方文档像天书?别慌。 90%的新手在接触“孤岛惊魂原始杀戮破解”这类话题时,最大的痛点就是:开发者文档太长,抓不住重点,看完还是不知道底层到底在干嘛。…

2026/9/22 14:55:56

救援大师实战项目保姆级教程

救援大师实战项目保姆级教程 复制来的代码跑不通,报错信息满屏飞,你盯着屏幕发呆,心里只有一个念头:这破东西到底怎么调?别急,今天这篇救援大师实战项目的保姆级教程,就是专门给你这种“代码搬运工”准备的。我们不讲那些虚头巴脑的理论,直接上手,带…

2026/9/22 14:50:56

3个坑让excel财务软件跑不通?源码最佳实践全解析

3个坑让excel财务软件跑不通?源码最佳实践全解析 复制来的Excel财务软件源码,改个路径就报错,或者公式计算结果全是#REF!,这种“复制粘贴”的绝望感,相信做财务自动化的同学都懂。很多教程只给最终效果,却不讲底层逻辑,导致代码在不同…

2026/9/22 10:02:42

GAMP 5 基于风险的计算机化系统验证:软件分类与审计追踪实践

简介:《A Risk-Based Approach to Compliant GxP Computerized Systems》即业内熟知的GAMP 5指南,面向制药企业质量与IT合规人员、验证工程师及计算机化系统管理者,用于解决GxP法规环境下系统合规性难以科学落地的问题。文档以风险管理为主线…

2026/9/22 9:07:39

安全托管MSSP实战:从静态防御到人机协同的攻防运营与应急响应

简介:这份PPT围绕互联网业务安全托管服务展开,面向企业安全负责人、IT运维人员及关注MSSP/MSS选型的读者,重点回应传统安全过度依赖人工、碎片化静态防御难以对抗产业化攻击等痛点。资源共1个pptx文件,包体约30.63MB,以…

2026/9/22 0:04:49

输电线路在线监测高频面试题拆解 3秒抓住官方文档重点

输电线路在线监测高频面试题拆解 3秒抓住官方文档重点 官方文档几百页翻到头还是懵?面试问到 输电线路在线监测 的数据链路时,脑子一片空白?别慌,这种 高频面试题 我整理了10年,专门治各种“文档太长抓不住重点”的毛病。…

2026/9/22 0:04:49

中介房源管理系统重构避坑:3个关键步骤搞定API变更

中介房源管理系统重构避坑:3个关键步骤搞定API变更 版本升级后 API 全变了,这种痛只有真做过的人懂。 很多团队在接手老旧房产项目时,最崩溃的不是代码烂,而是底层框架升级后,原本熟悉的接口调用方式彻底失效。 这份 保姆级教程…

2026/9/22 0:04:49

3个坑点带你一文搞懂55gg小游戏源码

3个坑点带你一文搞懂55gg小游戏源码 盯着控制台满屏的红色报错,看着那一长串 StackTrace ,是不是脑子瞬间宕机?别急,这种时候最忌讳的就是盲目改代码。很多刚入行的前端同学,面对 55gg 小游戏这类轻量级 H5…

2026/9/20 4:54:47

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/21 18:32:12

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/22 13:25:41

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码