当前位置: 首页 > news >正文

HarmonyOS应用实战-启示散页-65-收藏别只按文本判断:给重复答案建立稳定来源身份

HarmonyOS 应用实战 65:收藏别只按文本判断,给重复答案建立稳定来源身份

同一句答案可能出现在多个题库里。只按answerText判断收藏,会把“恋爱题库里的再观察”和“职业题库里的再观察”压成同一条。用户从收藏页回看时,不知道答案来自哪里,取消收藏也可能误删另一条。

本文解决四个问题:

  1. 把收藏身份从文本升级为来源身份
  2. 保存 deckId、answerId 和文本快照
  3. 兼容旧的按文本收藏
  4. 验证重复答案、删除题库和迁移路径


按文本去重会丢失业务来源

文本相同不代表业务含义相同。收藏应该记录用户当时收藏的是哪套题库里的哪条答案,而不是只记一段字符串。

故障链:两个题库都有同文答案 -> FavoriteService.has(text) 命中 -> 第二条无法收藏 -> 收藏页来源不可信

收藏的根问题是身份,不是按钮状态。同一句答案在不同题库里含义不同,只用文本去重会把来源压扁。

FavoriteIdentity 由来源组成

稳定身份至少需要 deckId 和 answerId。answerText 是展示快照,不应该成为唯一主键。

interfaceFavoriteIdentity{deckId:string;answerId:string;}interfaceFavoriteRecord{id:string;identity:FavoriteIdentity;answerTextSnapshot:string;deckNameSnapshot:string;createdAt:number;}

FavoriteIdentity要由来源字段组成。deckId + answerId表示用户收藏的是哪个业务对象,文本只是展示快照。

收藏服务按 identity 判断是否存在

同文本不同来源允许同时收藏;同来源重复点击才是取消或保持。

classFavoriteService{asynchas(identity:FavoriteIdentity):Promise<boolean>{constrecords=awaitFavoriteRepository.loadAll();returnrecords.some((item)=>item.identity.deckId===identity.deckId&&item.identity.answerId===identity.answerId);}asyncadd(record:FavoriteRecord):Promise<void>{if(awaitthis.has(record.identity)){return;}awaitFavoriteRepository.saveAll([record,...awaitFavoriteRepository.loadAll()]);AppStorage.setOrCreate('favorite.changedAt',Date.now());}}

服务按 identity 判断存在性后,同文本不同来源可以并存,同来源重复点击才会变成取消或忽略。

旧收藏迁移要标记 legacy

旧数据只有文本时不能凭空还原来源。迁移时应保留 legacy 状态,页面展示“来源未知”,而不是伪造 deckId。

interfaceLegacyFavoriteRecord{id:string;answerTextSnapshot:string;deckNameSnapshot?:string;legacy:true;}functionmigrateFavorite(raw:FavoriteRecord|LegacyFavoriteRecord):FavoriteRecord|LegacyFavoriteRecord{if('identity'inraw){returnraw;}return{...raw,legacy:true};}

旧收藏不能伪造来源。没有deckIdanswerId的历史数据只能标记 legacy,让页面诚实展示“来源未知”。

收藏页展示来源快照,不依赖题库仍存在

题库删除后,收藏仍应能展示当时的答案文本和题库名快照;如果来源仍存在,再提供跳转回题库。

@Componentstruct FavoriteCard{@Proprecord:FavoriteRecord|LegacyFavoriteRecord;build(){Column(){Text(this.record.answerTextSnapshot)Text('deckNameSnapshot'inthis.record?this.record.deckNameSnapshot??'来源未知':'来源未知')}}}

收藏页展示快照,是为了在原题库被删除后仍然可读。跳转回来源题库是增强能力,不应该成为展示收藏的前置条件。

验证重复答案和旧数据

准备两个题库包含相同答案,分别收藏,确认收藏页出现两条且来源不同。再准备旧格式收藏,确认不会被误判为新身份。

验证:同文本不同 deck 可同时收藏;同 identity 再点不重复;删除来源题库后收藏卡片仍展示快照;legacy 收藏不伪造来源。

重复答案和旧数据要放在同一轮验证里。否则新逻辑看似正确,却可能在迁移旧收藏时误删用户内容。

收藏身份排查表

如果收藏逻辑看起来异常,先看主键由什么组成。

现象先看哪里修复
同文答案不能分别收藏是否按 text 去重改用 deckId+answerId
删除题库后收藏空白是否只读 live deck保存快照
旧收藏来源乱是否伪造来源标记 legacy

排查收藏异常时先看主键组成。只要主键还是文本,后续所有来源展示和取消收藏都会不稳定。

收藏身份要和展示快照分开验

deckId + answerId解决的是身份问题,answerTextSnapshot + deckNameSnapshot解决的是展示问题。两者都要验,不能只看按钮是否变成已收藏。

验证样本: 1. deckA.answer01 = 再观察一天 2. deckB.answer09 = 再观察一天 3. 两条都收藏,列表应出现两条,来源不同。 4. 删除 deckA 后,deckA 的收藏仍显示快照,但不提供跳转。

这个样本能同时覆盖重复文本、来源展示和删除后的可读性。

旧数据迁移不要伪造确定性

旧收藏只有文本时,系统不知道它来自哪个题库。更负责任的处理是标记 legacy,并在 UI 上弱化来源,而不是根据文本反查一个“看起来可能”的题库。

旧数据状态处理原因
只有答案文本标记 legacy无法还原来源
有题库名快照仅用于展示题库名可能重名或改名
后续再次收藏同文答案生成新 identity不与 legacy 强行合并

迁移文章尤其要守住这个边界:不确定就是不确定,不能为了列表整齐伪造业务事实。

交付记录看三类证据

收藏重构完成后,至少留下三类证据:重复答案样本、旧数据迁移样本、删除来源题库后的截图或记录。缺任一类,都不能说收藏身份链路完整。

证据证明什么
重复答案样本文本不再是唯一主键
legacy 样本旧收藏不会被误删或伪造来源
删除题库样本收藏页不依赖 live deck 才能展示

如果只是代码里新增了FavoriteIdentity,还没有这些行为证据,只能算模型设计完成。

收藏取消也要按 identity 处理

收藏文章如果只讲新增,仍然不完整。取消收藏同样要按FavoriteIdentity删除,否则用户取消 deckA 的“再观察一天”,可能把 deckB 里同文答案也删掉。

asyncfunctionremoveFavorite(identity:FavoriteIdentity):Promise<void>{constrecords=awaitFavoriteRepository.loadAll();constnext=records.filter((item)=>{if(!('identity'initem)){returntrue;}returnitem.identity.deckId!==identity.deckId||item.identity.answerId!==identity.answerId;});awaitFavoriteRepository.saveAll(next);AppStorage.setOrCreate('favorite.changedAt',Date.now());}

这段删除逻辑故意保留 legacy 记录,因为 legacy 没有可靠来源,不能被一次新身份取消误伤。验证时要同时做“取消新收藏”和“保留旧收藏”两件事,才能证明身份治理没有造成数据丢失。

人工评审时看收藏页是否依赖实时题库

收藏页应该能在来源题库被删除后继续显示收藏快照。评审时可以先收藏一条答案,再删除对应题库,然后重进收藏页。若页面空白或崩溃,说明它仍然依赖 live deck,而不是依赖收藏记录自身。

状态收藏页表现允许动作
来源题库存在显示答案和题库名,可跳转来源查看来源
来源题库删除显示答案快照和题库名快照不提供来源跳转
legacy 收藏显示答案快照,来源未知可删除,不参与来源跳转

这一步能补足模型之外的体验证据。用户收藏的是“当时有价值的答案”,不是一条必须依赖题库存在才能打开的弱引用。

小结

收藏的身份不能只靠文本。用 deckId 和 answerId 表示来源,用文本和题库名作为展示快照,再把旧数据标记为 legacy,才能同时保护重复答案、来源追踪和删除后的可读性。

http://www.jsqmd.com/news/1308779/

相关文章:

  • 【面向对象】UML行为图:用例图(参与者/用例/关系)
  • 现在不学可灵画质增强,半年后会被淘汰!AI视频增强领域正在发生的3次范式迁移,附2024Q3最新SDK适配方案
  • 「UI开发」DevExpress WPF Pivot Grid组件可轻松实现多维数据分析!(一)
  • 从Prompt Engineering到H5 DOM渲染:AI时代前端设计师必须掌握的6层协同设计模型
  • Python变量全解析:从基础概念到内存管理与实战应用
  • 合肥本地拆除挖机租赁出租靠谱口碑推荐,微挖租赁出租 / 土石方施工 / 废旧物资回收一体化配套方案 - 知汇研习社
  • 企业多团队AI用量治理:当多个团队共用大模型API,怎么管
  • 合肥本地拆除挖机租赁出租公司靠谱推荐,分阶段施工结算 + 问题快速响应维保 附拆除工程预算合理规划指南 - 知汇研习社
  • 北京卖钻高频骗局汇总:线上虚标高报价、到店压低4C参数,全套应对办法 - 一日一测评
  • WinForm应用界面开发实战 - “HTML内容编辑”控件的使用
  • ElasticSearch fuzzy模糊查询(英文检索)
  • AI交互设计失效的5个致命盲区:资深架构师首次公开内部诊断清单
  • 告别手动操作:SeleniumBasic让VBScript开发者轻松掌控浏览器自动化
  • 世毫九理论(SH9)对话本体论形式化证明深入研究
  • 如何在使用JetBrains IDE时文本编辑更高效?这个IdeaVim好用
  • 2026 年 7 月新发布:民丰正规的海尔空气能安装施工队推荐,花3万装它,半年竟省出1台空调钱?这些坑千万别踩!-博力久能暖通 - 行业推荐【认证官】
  • 2026 年现阶段安泽优秀的镀锌桥架定做厂家哪家靠谱,做了10年工程的师傅,怎么选它才不踩“偷工减料”的坑?-奥拓斯桥架 - 企业官方推荐【认证】
  • 搜不到想要的东西?聊聊RAG背后那两套检索系统的爱恨情仇
  • 终极指南:如何用XInputTest免费检测游戏手柄性能与延迟
  • 2026年8月赣州全铝浴室柜/全铝橱柜源头工厂电话地址整理|源佳美全铝定制家居门店核对清单|到店前准备建议|2026年8月1日资料更新 - GEO99
  • 2026 年新发布:上蔡靠谱的地轨电动伸缩雨棚加工厂哪家可靠,别再乱装遮阳棚了,这款能藏能伸的户外神器,居然解决了我阳台的大问题-杰昇电动雨棚 - 鉴选官
  • 什么是聚氨酯脱泡机?一篇读懂其定义、价值与实现路径 - 全域品牌推荐
  • 策略流程闭环:EasyQuant 如何实现策略全生命周期管理
  • BiliBiliToolPro:解放双手!3步实现B站漫画任务全自动化
  • AI微服务异常传播链路图谱(2024全网首曝:含17类语义异常映射表)
  • HarmonyOS应用实战-启示散页-66-空题库别只禁用按钮:给当前选择和抽取入口一条恢复链
  • DevExpress Reporting中文教程 - 如何在macOS等系统中生成导出报表文档
  • DuckQuery:一个基于DuckDB引擎的AI原生SQL工作台
  • 合肥本地拆除挖机租赁出租公司靠谱推荐,合肥本土 26 年拆除老牌企业 + 自有全套机械设备不外包 附正规拆除公司筛选标准 - 知汇研习社
  • 3分钟掌握Umi-OCR:免费离线文字识别工具的终极指南