HarmonyOS应用实战-启示散页-53-导入备份别直接覆盖:先做差异预览和冲突选择
HarmonyOS 应用实战 53导入备份别直接覆盖先做差异预览和冲突选择用户把一段“题库名#答案1#答案2”的文本粘进《答案之书》时最危险的时刻并不是解析失败而是解析成功后直接把当前编辑内容替换掉。用户往往在这时才发现自己刚改的两条答案没了导入文本里还有重复项甚至根本分不清这次导入会新增、删掉还是覆盖什么。这个项目当前的导入链路其实很克制DeckImport.parseDeckImport只负责清洗文本ImportDeckDialog把成功结果回调给页面DeckCreatePage.applyImport仅把名称和答案填回编辑表单最终仍需用户点击“创建”才由DeckService.save写入仓储。它尚未实现备份合并或覆盖恢复。本文在这个真实边界上设计一层可审计的“差异预览”避免把建议能力误说成现有功能。先分清当前“导入文本”不是“恢复备份”两者都可能带来一组答案但提交语义不同场景当前项目的真实行为用户可撤回性不能省略的判断在新建页导入名称#答案…解析后回填本页表单关闭页面即可放弃文本格式、长度、去重后数量点击创建DeckService.save生成新题库并落库需删除新题库名称、最小/最大答案数从备份恢复到已有题库当前项目未实现风险高新增、修改、删除与冲突因此不能拿“解析成功”当作“可以覆盖”。当前parseDeckImport会trim每一段、跳过空项和超长项、用Set去重并在有效答案不足最小数量时返回错误它保护的是输入质量不知道“当前题库里有哪些旧数据”。差异判断必须在读到目标题库之后进行。为什么直接把解析结果塞回页面仍然不够DeckCreatePage.applyImport(name, answers)会为每条导入答案生成新的本地 key促使ForEach重新挂载TextInput这是为了解决输入框初始文本只读取一次的 UI 行为。它解决了“页面显示不刷新”却不代表可以承担恢复规则。如果以后把“导入”入口开放到编辑已有题库下面两种做法都会出事// 不要在确认导入时就把现有数据清空this.answersimportedAnswers.map((text:string)({text}));// 也不要让页面自己猜测是否可覆盖awaitDeckRepository.saveDeck(rawDeck);第一段会让用户失去比较机会第二段绕过了DeckService.save的名称、数量和刷新信号约束。页面适合收集选择Service 才应决定最终写什么。预览模型只描述差异不制造持久化副作用对于当前项目的文本格式答案没有跨导入稳定 id因此第一版只能以“清洗后的文本”识别重复。它足够解释新增与重复但不能可靠地判断“这条是改名后的旧答案”。这种限制应显式展示给用户。interfaceImportPreview{targetDeckId?:string;importedName:string;additions:string[];duplicates:string[];skipped:string[];canCommit:boolean;notices:string[];}typeImportStrategycreate|append|replace;这里没有Deck、AppStorage或 Repository 引用。预览阶段是纯计算同一份文本无论点几次都只能得到同一份结果只有用户选定策略后才进入写入路径。replace需要额外确认因为它会移除目标中未出现的答案。用现有解析器作为第一道门而不是另写一套规则建议能力应复用当前parseDeckImport否则“弹窗能导入、恢复入口却拒绝”的规则分叉迟早会发生。以下是可放进 HSP 服务层的示例其中DeckService.get是项目已有读入口。import{DeckService}from../services/DeckService;import{parseDeckImport}from../utils/DeckImport;asyncfunctionbuildImportPreview(raw:string,targetDeckId?:string):PromiseImportPreview{constparsedparseDeckImport(raw);if(!parsed.ok||!parsed.deck){return{importedName:,additions:[],duplicates:[],skipped:[],canCommit:false,notices:[parsed.error??导入文本无效]};}consttargettargetDeckId?awaitDeckService.get(targetDeckId):null;constexisting:SetstringnewSetstring(target?.answers.map((a)a.text)??[]);constadditionsparsed.deck.answers.filter((text)!existing.has(text));constduplicatesparsed.deck.answers.filter((text)existing.has(text));return{targetDeckId,importedName:parsed.deck.name,additions,duplicates,skipped:[],canCommit:additions.length0||!target,notices:target?[按文本比较改写后的答案会被视为新增]:[]};}这段代码的关键是读取目标题库后才建立existing集合。它信任解析器已完成的格式和长度校验却不信任页面传来的targetDeckId拿不到目标题库时不能悄悄降级为覆盖应停止提交并提示用户重新选择。三种策略的边界必须写在提交前差异预览不是多显示一行“发现 3 条变化”而是让用户在提交前看到操作含义。策略写入结果适合场景风险控制create调用DeckService.save新建题库从剪贴板导入一套新问题原题库完全不动append保留原答案只追加additions补充题目重复项不再次写入replace以导入后的集合为准用户明确恢复某一份快照二次确认并展示删除数量提交时不要直接调用DeckRepository。项目中的DeckService.save会清洗答案、校验最小/最大数量、生成答案 id、写入 Repository并在成功后更新AppStorageKey.LastDeckUpdateAt。这条顺序让列表页等订阅者在“最终事实已经落库”后才重新读取。asyncfunctioncommitPreview(preview:ImportPreview,strategy:ImportStrategy):Promisevoid{if(!preview.canCommit){thrownewError(preview.notices.join());}if(strategycreate){awaitDeckService.save({name:preview.importedName,answers:preview.additions});return;}consttargetpreview.targetDeckId?awaitDeckService.get(preview.targetDeckId):null;if(!target){thrownewError(目标题库不存在停止导入);}constanswersstrategyappend?[...target.answers.map((a)a.text),...preview.additions]:[...preview.duplicates,...preview.additions];awaitDeckService.save({id:target.id,name:target.name,answers,colorKey:target.colorKey});}示例故意把replace的结果写得直白它只保留本次导入解析到的答案。真实 UI 还应在按钮上标出“将删除 N 条未出现在导入文本中的答案”并让用户再次确认不要用一个模糊的“导入成功”掩盖数据删除。一个容易漏掉的约束保存会重建答案 id当前DeckService.save接收string[]然后为每条答案调用newId(a)创建新的Answer。这意味着用它更新已有题库时答案的 id 会整体变化。对于当前仅按答案文本收藏的项目这不一定立即出错但若后续收藏、分享或统计依赖answerIdappend/replace就不能直接复用这条保存接口。更稳的演进路线是先把“文本导入”限制在创建题库只有在领域模型为答案引入稳定身份、并设计清楚旧 id 的保留规则后再开放已有题库的合并恢复。不要为了一个导入按钮悄悄破坏收藏和路由参数的引用关系。页面只负责把预览和确认交给用户页面层可以保留一个State preview来显示数量与风险但它不应在onClick里自行计算并保存。一个安全的交互顺序是输入变化时重新预览点击“继续”时固定本次预览选择策略后展示确认文案确认按钮调用 Service成功后关闭弹窗并让页面按LastDeckUpdateAt重读。粘贴文本 → parseDeckImport → buildImportPreview → 用户选择 create / append / replace → 明确确认 → DeckService.save → Repository → LastDeckUpdateAt → 列表重新读取特别是不要把完整题库对象塞进AppStorage来“传递导入结果”。这里的AppStorage只承担刷新信号跨重启可信的数据仍在 Preferences/Repository 中页面需要时再从DeckService读取。验证时要故意制造反例以下检查覆盖的是当前源码事实与上文建议能力的衔接建议在实现后逐项完成输入空文本、没有#分隔、空题库名、少于最小答案数确认parseDeckImport返回可读错误且不出现写入。输入首尾空格、空项、重复答案和超长答案确认预览数量与解析后的有效答案一致。新建模式导入成功后退出并重新进入题库列表确认由DeckService.list读到新题库。目标题库在预览后被删除点击确认时应报“目标题库不存在”不能创建一个同名替代品。append与replace分别验证前者不减少旧答案后者的删除数与确认文案一致。如果以后接入收藏或分享验证保存后旧answerId的处理契约而不是只看页面能否显示。常见问题与定位顺序现象优先看哪里根因与修复提示导入成功却没新增题库DeckCreatePage是否只回填表单当前链路需用户继续点击创建文案应区分“已填入”和“已保存”同一答案出现两次比较前是否使用解析后的文本统一复用parseDeckImport的 trim/去重结果覆盖后收藏或深链失效是否通过save重建了答案 id先定义稳定身份和迁移规则别把覆盖能力提前上线列表未刷新刷新信号是否早于持久化只在DeckService.save成功后更新LastDeckUpdateAt预览与最终写入数量不同页面和 Service 各写了一份过滤逻辑把清洗与策略计算集中到同一服务排查时先打印“策略、目标题库是否存在、解析后数量、预计新增/删除数量”这些非敏感摘要不要记录用户完整问题、答案正文或整段导入文本。数量足以追踪状态链路也不会把用户内容带进日志。小结《答案之书》当前的导入能力是安全的“文本回填”它还不是备份恢复。要把它升级为恢复入口核心不是新增一个覆盖按钮而是把解析、差异、策略、提交分成四个不可混淆的阶段解析器保证输入可用预览服务解释变化用户确认策略DeckService最后保存并通知重读。这样做能让每一次删除、追加和新建都有来源也为以后处理稳定答案 id、收藏迁移和真正的备份文件版本打下边界。本文代码中的预览与策略层为设计示例是否已经在真机实现、恢复或发布仍需以实际工程验证为准。

相关新闻

【2014-02-25】cocos2dx学习笔记:自定义工程路径及cocoswidget配置

【2014-02-25】cocos2dx学习笔记:自定义工程路径及cocoswidget配置

[历史归档] 本文原发布于 cstriker1407.info 个人博客,内容为历史存档,仅供参考。 发布时间: 2014-02-25 | 标题:cocos2dx学习笔记:自定义工程路径及cocoswidget配置 | 分类: 编…

2026/7/29 15:58:45 阅读更多 →
CrystalDiskInfo:硬盘健康监测的终极免费指南,让数据安全掌握在你手中

CrystalDiskInfo:硬盘健康监测的终极免费指南,让数据安全掌握在你手中

CrystalDiskInfo:硬盘健康监测的终极免费指南,让数据安全掌握在你手中 【免费下载链接】CrystalDiskInfo CrystalDiskInfo 项目地址: https://gitcode.com/gh_mirrors/cr/CrystalDiskInfo 在数字时代,你的硬盘存储着工作文件、珍贵照片…

2026/7/29 15:58:45 阅读更多 →
【2014-02-19】cocos2dx学习笔记:水果忍者划痕效果

【2014-02-19】cocos2dx学习笔记:水果忍者划痕效果

[历史归档] 本文原发布于 cstriker1407.info 个人博客,内容为历史存档,仅供参考。 发布时间: 2014-02-19 | 标题:cocos2dx学习笔记:水果忍者划痕效果 | 分类: 编程 / C &&am…

2026/7/29 15:58:45 阅读更多 →

最新新闻

物联网安全芯片SE050与STM32的实战集成指南

物联网安全芯片SE050与STM32的实战集成指南

1. 为什么物联网设备需要专用安全芯片? 在物联网设备爆炸式增长的今天,安全性已成为最薄弱的环节。传统MCU(如STM32系列)虽然性能强大,但其安全功能往往局限于基本的加密算法支持,缺乏真正的硬件级安全防护…

2026/7/29 16:04:47 阅读更多 →
MAA明日方舟助手:5大特性让你彻底告别手动刷图,体验真正的游戏自动化

MAA明日方舟助手:5大特性让你彻底告别手动刷图,体验真正的游戏自动化

MAA明日方舟助手:5大特性让你彻底告别手动刷图,体验真正的游戏自动化 【免费下载链接】MaaAssistantArknights 《明日方舟》小助手,全日常一键长草!| A one-click tool for the daily tasks of Arknights, supporting all clients…

2026/7/29 16:04:47 阅读更多 →
3D打印火星车:从开源硬件到机电一体化的创客实践

3D打印火星车:从开源硬件到机电一体化的创客实践

1. 项目概述:从桌面到“火星”的创客之旅 “3D打印之火星车1号”,这个名字听起来就充满了科幻与探索的浪漫色彩。它不是一个遥不可及的航天项目,而是一个我们每个创客、模型爱好者,甚至是对机械和电子感兴趣的初学者,都…

2026/7/29 16:04:47 阅读更多 →
Zynq上MicroBlaze的elf固化到bit流

Zynq上MicroBlaze的elf固化到bit流

参考 Zynq上MicroBlaze测试.csdn 嵌入式终端AtShell的精简版.csdn BD atshell_microblaze_system7020.tcl 这里axi_uartlite_0波特率是9600 地址映射 No.InstanceInterfaceTypeBase AddressHigh AddressRangeDescription1microblaze_0/Dataaxi_bram_ctrl_0/S_AXIMem00xC000_…

2026/7/29 16:04:47 阅读更多 →
社区餐饮选址的动线思维:把门店开进顾客的路线里

社区餐饮选址的动线思维:把门店开进顾客的路线里

餐饮选址的传统逻辑是"找人流量",但人流量大不等于客流是你的。拆解大同一个本地面馆品牌(德钰面馆,三家直营店)的布局,它给出的是另一种思路:不找人最多的地方,找顾客必经的路线&…

2026/7/29 16:04:47 阅读更多 →
I²C双向电平转换电路设计:从原理到PCB布局的完整指南

I²C双向电平转换电路设计:从原理到PCB布局的完整指南

1. 项目概述:为什么IC电平转换是嵌入式开发的必修课 在嵌入式硬件开发中,尤其是当你手头的元器件来自不同年代、不同厂商时,一个最常见也最让人头疼的问题就是电平不匹配。你可能遇到过这样的场景:主控MCU是3.3V供电的现代低功耗芯…

2026/7/29 16:03:47 阅读更多 →

日新闻

【RT-DETR多模态创新改进】CVPR 2025 | 独家特征融合创新改进篇 | 引入RLAB残差线性注意力模块,有效融合并强调多尺度特征,多种改进点,适合红外与可见光融合目标检测任务,有效涨点

【RT-DETR多模态创新改进】CVPR 2025 | 独家特征融合创新改进篇 | 引入RLAB残差线性注意力模块,有效融合并强调多尺度特征,多种改进点,适合红外与可见光融合目标检测任务,有效涨点

一、本文介绍 🔥本文在RT-DETR多模态融合目标检测中引入RLAB残差线性注意力模块,可在不同模态特征交互阶段进行多次残差细化,使可见光、红外等特征在尺度、语义和空间位置上更好对齐;随后将细化特征与解码器输出拼接并生成Q、K、V,通过线性注意力自适应强化关键通道、目…

2026/7/29 0:00:23 阅读更多 →
AI编程系列02:合并知识功能,给 AI 问数和 RAG 场景打基础

AI编程系列02:合并知识功能,给 AI 问数和 RAG 场景打基础

AI编程系列02:合并知识功能,给 AI 问数和 RAG 场景打基础 在上一期「AI编程系列」中,我们学习了如何构建一个基础的 AI 问答系统,通过简单的输入输出让模型回应问题。但现实世界中的 AI 应用往往需要处理更复杂的场景:…

2026/7/29 0:00:23 阅读更多 →
AI智能体开发实战:从工具调用到企业级部署

AI智能体开发实战:从工具调用到企业级部署

1. 从被动问答到主动执行:AI Agent的范式转变过去两年,大语言模型最显著的应用形态是聊天机器人——用户提问,AI回答。但真正的生产力革命发生在2023年下半年:当AI学会主动调用工具完成任务时,生产力工具的历史被彻底改…

2026/7/29 0:00:23 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/28 12:04:22 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/29 14:34:28 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/29 15:00:03 阅读更多 →

月新闻