HarmonyOS 实战|中式美食视频拆菜编辑面板:因子状态、草稿卡片与底部操作条

发布时间:2026/7/5 14:12:11

HarmonyOS 实战|中式美食视频拆菜编辑面板:因子状态、草稿卡片与底部操作条 视频拆菜页最难的地方不是把一段文字拆成几个字段而是让用户愿意把它改完。很多类似功能做出来以后看起来像一个结果页给你一堆识别结果剩下自己看。中式美食这里更偏向“草稿编辑器”先把视频或字幕整理成一版可修改的菜谱草稿再让用户逐条确认、补充、保存。所以这篇重点不放在算法而放在编辑面板。也就是因子怎么分类状态怎么表达用户怎么保留或删除一条内容保存以后怎么变成“我的菜谱草稿”。上图对应的是中式美食里的真实视频拆菜流程编辑因子、底部保存入口、已保存卡片。它看起来是 UI 问题但背后其实是数据状态设计。如果状态没拆清楚页面会很快变成一堆按钮和输入框。章节位置内容页面入口entry/src/main/ets/view/pages/VideoInsightPage.ets编辑面板entry/src/main/ets/view/components/V3VideoEditorPanels.ets数据模型entry/src/main/ets/model/entity/VideoRecipeInsight.ets草稿仓储entry/src/main/ets/model/repository/VideoInsightRepository.ets关键状态draft、confirmed、detected、uncertain、edited本文验证环境本文对应的是已上架的 HarmonyOS 应用中式美食视频拆菜页面来自真实工程。项目版本与范围开发工具DevEco Studio 6.0.0 Release运行系统HarmonyOS NEXT / HarmonyOS 6.0SDK/APIHarmonyOS SDK API 20语言与框架ArkTS 6.0、ArkUI V2、Stage 模型核心能力ComponentV2、Param、Event、TextInput、TextArea、ForEach验证方式输入字幕文本、生成草稿、修改因子、切换状态、保存后回到草稿列表我验证这块时不只看页面能不能打开而是按完整操作走一遍先输入菜名和一段做菜文字生成草稿再修改某条食材、火候或步骤把不确定内容标出来最后保存并从历史列表重新打开。本章导读中式美食把视频拆菜后的内容叫VideoRecipeInsight。它不是最终菜谱而是一份还需要人工确认的草稿。草稿里最关键的是factors。每个VideoFactor表示一条可编辑信息比如食材、步骤、火候、成熟信号、容易出错的提醒。每条因子都有自己的状态用户可以继续改也可以删掉。exporttypeVideoInsightStatusdraft|confirmed;exporttypeVideoFactorStatusdetected|uncertain|edited;exporttypeVideoFactorKindingredient|step|heat|cue|risk;exportinterfaceVideoFactor{id:string;kind:VideoFactorKind;text:string;timeLabel:string;status:VideoFactorStatus;}这个模型的好处是直接。用户看到一条内容不需要猜它属于哪里开发者保存时也不需要从一大段富文本里重新解析。先把草稿建出来VideoInsightRepository.createDraft()负责创建一份拆菜草稿。它会把标题、来源、视频地址、原始文字和初始因子放在一起。createDraft(title:string,source:string,videoUri:string,rawText:string):VideoRecipeInsight{constnow:numberDate.now();constdisplayTitle:stringtitle.trim().length0?title.trim():未命名菜谱;constcleanedRawText:stringrawText.trim();constitem:VideoRecipeInsight{id:vnow,title:displayTitle,source:source.trim(),videoUri,rawText:cleanedRawText,dishName:displayTitle,summary:cleanedRawText.length0?已按文字整理成这道菜:待你整理的菜谱草稿,status:draft,factors:this.seedFactors(now,cleanedRawText),createdAt:now,updatedAt:now};}这里有两个细节。第一标题为空时必须兜底。用户可能只是想先试一下不一定一开始就把菜名写完整。第二rawText不为空时会走提取逻辑如果没有输入文字也会生成几条默认因子保证编辑面板不是空的。空页面会让用户不知道下一步怎么做有默认草稿就能直接改。因子不是结果是待确认项仓储里有一段很实用的规则从原始文字里按关键词拆因子。比如识别到“食材、材料、调料”就倾向归到ingredient识别到“大火、中火、小火、收汁”就归到heat识别到“不要、避免、小心、容易”就归到risk。privatepushIfRoom(out:VideoFactor[],seed:number,kind:VideoFactorKind,text:string,timeLabel:string):void{constsameKindCount:numberout.filter((it:VideoFactor):booleanit.kindkind).length;if(sameKindCount5||out.length18){return;}constexisted:VideoFactor|undefinedout.find((it:VideoFactor):boolean{returnit.kindkindit.texttextit.timeLabeltimeLabel;});if(existed!undefined){return;}out.push(this.factorWithIndex(seed,out.length,kind,text,timeLabel));}这个限制很关键。视频文字可能很长如果无脑拆出几十条用户根本没有耐心一条条看。中式美食给每类最多 5 条、总数最多 18 条目的就是把编辑量控制在可接受范围。这不是追求“识别越多越好”而是追求“用户愿意确认完”。编辑面板如何表达状态V3VideoFactorListPanel不直接修改仓储它通过事件把操作抛出去EventonTextChange:(id:string,text:string)void(){};EventonTimeChange:(id:string,timeLabel:string)void(){};EventonStatusChange:(id:string,status:VideoFactorStatus)void(){};EventonRemove:(id:string)void(){};这个写法比在组件里直接操作全局数据更干净。面板只负责展示和收集用户动作真正的数据更新交给页面或 ViewModel。以后如果保存逻辑换成接口、或者加撤销都不用重写卡片 UI。每条因子卡片里用户能改三类东西操作对应字段作用改时间timeLabel保留视频中的时间线索改文字text修正识别不准、补充做法改状态status标记保留、不确定、已修改状态显示也做了差异化不确定的内容用提醒色已保留或已修改的内容用更稳定的颜色。这样用户不用读完整段文字也能知道哪些还没处理。为什么要有“都留着”编辑面板顶部有一个onAcceptAll事件对应“都留着”这类操作。这个按钮看起来很小但体验上很重要。如果系统已经拆得比较准用户不应该还要一条条点“保留”。一键保留能把人工确认成本降下来。反过来如果某条不对用户仍然可以单独改状态或删除。if(this.pendingCount0){Button(都留着).height(32).fontSize(AppFonts.xs).onClick(():voidthis.onAcceptAll());}这里的设计原则是批量操作给轻路径单条编辑给精修路径。两条路都要有不然功能会变得很累。新增一条因子怎么做识别结果一定会漏。比如字幕里没有说“转小火”但用户知道这一步很关键就需要手动补一条火候提醒。V3VideoAddFactorPanel把新增因子拆成三部分类型、时间、文字。ParamfactorKind:VideoFactorKindingredient;ParamfactorText:string;ParamfactorTime:string;EventonKindChange:(kind:VideoFactorKind)void(){};EventonTextChange:(text:string)void(){};EventonTimeChange:(timeLabel:string)void(){};EventonAdd:()void(){};这比让用户在一段大文本里继续追加要清楚。后续展示菜谱时食材、步骤、火候、风险提醒都已经分好了不需要再二次解析。已保存卡片给用户一个结果感用户点保存之后如果页面只是弹个 toast很快就没有上下文了。中式美食用了V3VideoSavedDishCard告诉用户这份草稿已经进了我的菜谱。exportstruct V3VideoSavedDishCard{ParamdishName:string;EventonOpenCustomList:()void(){};}卡片里保留菜名并提供去查看入口。这个动作很重要因为“视频拆菜”不是一次性功能它最终要和我的菜谱、收藏、笔记这些长期使用场景连接起来。草稿列表为什么要显示数量和状态V3VideoLibraryPanel展示的是已经创建过的拆菜草稿。每条记录会显示菜名、更新时间和状态。Text(item.statusconfirmed?已保存:待整理).fontSize(10).fontColor(item.statusconfirmed?#2F5D46:#9B2F21);这类状态不是为了装饰而是帮助用户快速判断哪份已经能用了哪份还需要继续整理。菜谱工具如果没有这种连续性用户下次回来就很难接上。工程验收记录检查项结果创建草稿菜名为空时有兜底标题页面不空白原始文字拆分能按食材、步骤、火候、成熟信号、风险提醒形成因子因子数量单类和总数有限制避免页面过长单条编辑时间、文字、状态都能独立修改删除因子删除后列表刷新剩余内容不丢一键保留可快速处理全部待确认内容新增因子可选择类型、补时间、写内容保存结果显示已保存卡片并能回到草稿列表查看常见问题复盘第一个问题是把“识别结果”当成“最终菜谱”。实际使用时视频字幕经常不完整用户必须能改。只展示结果不提供编辑会让这个功能停在玩具阶段。第二个问题是状态太少。如果只有保存和未保存用户不知道哪一条是系统识别的、哪一条是自己改过的、哪一条还不确定。detected、uncertain、edited这三个状态虽然简单但足够支撑编辑流程。第三个问题是按钮太散。中式美食把批量保留、单条编辑、新增因子、保存结果分成不同面板不把所有按钮塞进一个卡片里。这样页面更长一点但每个区域的任务更清楚。本章小结中式美食的视频拆菜页不是单纯做一个“识别结果展示页”而是做成了草稿编辑流程。VideoRecipeInsight负责承载整份草稿VideoFactor负责承载每条可确认内容V3VideoEditorPanels负责把这些状态变成用户能操作的面板。这套设计的核心是把不确定性摆到明面上。系统先整理一版用户再确认、修改、删除、补充最后保存成自己的菜谱。对菜谱应用来说这比一次性给一个看起来很完整但不能改的结果更接近真实使用。

相关新闻