06-Flutter 鸿蒙实战 06:上传后处理流程,照片识别、故事生成和状态刷新
06. Flutter 鸿蒙实战 06上传后处理流程照片识别、故事生成和状态刷新上传成功只是开始后面还有处理接口、故事生成、照片活化和列表刷新。上传后的链路照片上传完成并不代表业务结束。这个项目的核心价值在于“老照片变成可讲述的故事”所以上传后还要触发后端处理识别照片、提取年代地点人物、生成故事、尝试生成活化视频。前端需要清楚区分“上传中”和“处理中”。上传页里两个状态分开bool _uploadingfalse;bool _processingfalse;上传阶段显示具体百分比处理阶段显示不确定进度if(_processing)...[constSizedBox(height:16),constLinearProgressIndicator(),constSizedBox(height:8),constText(正在识别照片、生成故事并活化视频请不要离开,textAlign:TextAlign.center,),]为什么要分阶段文件上传是客户端可感知的字节传输进度可以计算照片处理属于服务端任务耗时取决于识别、故事生成和视频活化前端不能伪造百分比。把这两个阶段混在一起会让用户误以为卡在上传。项目变更记录里有过真实问题活化视频失败曾经导致整张照片处理失败。后来修正为故事生成成功后活化失败只更新照片活化状态不再删除照片和故事。这里可以沉淀出一个实现原则非核心附加能力失败不应该抹掉已经成功的主数据。处理接口后的状态更新上传成功后页面会从返回结果里取出photo再触发处理流程并刷新列表。核心思想是不要只依赖本地临时状态最终要以服务端照片列表为准。finalresponseawaitapiClient.uploadPhoto(bytes:bytes,filename:file.name,mimeType:mimeType,onProgress:(value){if(mounted)setState(()_progressvalue);},);finalphotoresponse[photo];处理完成后刷新上传列表也可以让首页、故事页拿到新数据。项目里StoriesRepository.clearCache()在登录切换时清缓存上传成功后也应该考虑相关页面刷新。错误展示上传页把异常转成用户可理解文案String_message(Objectexception)userFacingError(exception);前端不要把后端错误全部吞掉也不要用“操作失败”覆盖所有情况。比如文件太大、格式不支持、网络断开、处理失败这些提示应该不同。用户能根据提示采取下一步动作。和后端任务状态的关系从tasks.md和changes.md可以看到项目围绕照片处理修过多次问题活化模型参数、活化状态枚举、视频缓存、额度耗尽提示、403 链接失效等。这些问题最后都指向同一个原则移动端页面只展示真实后端状态不假装成功。例如活化视频生成失败时照片和故事仍然可以保存视频额度耗尽时详情页提示额度问题而不是让用户重新上传照片。处理流程图上传页和后端处理链路必须放在一起理解。它不是单纯 Flutter UI而是移动端与服务端长任务协作的完整场景。处理阶段拆分上传成功不等于处理成功照片上传接口只说明原图已经到达服务器。后续识别、故事生成、活化视频都可能继续运行。前端如果把“上传成功”当成“全部完成”用户会在故事页看不到新内容或者误以为处理卡住。这个项目用_processing单独表达后端处理阶段配合提示文案和刷新逻辑让用户知道照片已经上传服务端还在继续生成内容。非核心能力失败不能删除主数据项目真实修复过一个问题活化视频失败导致整张照片处理失败。后续改成故事生成成功后活化失败只更新照片活化状态不删除照片和故事。这个处理方式可以拆成三条规则主链路照片保存 - 信息识别 - 故事生成 增强链路照片活化 - 视频缓存 - 端内播放增强链路失败时不应该破坏主链路结果。移动端页面也要按这个边界展示状态。长任务状态设计长任务不能用一次请求概括照片上传完成只能说明原图已经传到服务器。后面的识别、故事生成、语音准备、视频活化都属于服务端处理链路。移动端如果把上传成功等同于全部完成用户很容易在故事页看不到内容误以为数据丢了。比较清晰的状态语义应该这样拆selected 本地已选择照片 uploading 字节正在上传 uploaded 原图到达服务端 processing 服务端正在生成业务内容 ready 故事或照片状态可展示 failed 某个阶段失败需要明确提示当前项目用_processing区分后端处理阶段。页面文案也对应这个阶段告诉用户照片已经进入服务端处理而不是简单显示“上传中”。主数据和附加能力要隔离项目曾经遇到过一个典型问题活化视频失败导致整张照片处理失败。后面改成故事生成成功后视频活化失败只更新照片活化状态不删除照片和故事。这种处理方式更符合移动端业务优先级。主数据照片、故事、年代、地点、人物 附加能力语音、视频活化、缩略图增强主数据成功后附加能力失败不能抹掉主数据。否则用户会看到“明明上传成功了最后什么都没有”的结果。正确做法是保留照片和故事再在详情页展示视频状态或错误提示。前端状态刷新要围绕真实接口移动端不要自己猜服务端处理结果。上传完成后应该通过照片列表、故事列表、照片详情接口刷新真实状态。Futurevoid_loadPhotos()async{finalrowsawaitapi.getJsonList(/api/photos);finalphotosrows.whereTypeMapString,dynamic().map(AlbumPhoto.fromJson).toList();setState((){_photosphotos;_photosLoadingfalse;});}这段逻辑看起来普通但它保证页面展示的是服务端最终状态。识别服务是否完成、故事是否生成、视频状态是否失败都应该从接口拿。错误提示要分层上传后处理链路里错误不能全部归成“操作失败”。比较合理的提示层级如下文件错误格式不支持、体积过大 网络错误断网、超时、服务器不可达 认证错误token 失效、未登录 业务错误识别失败、额度耗尽、视频生成失败 数据错误接口结构异常、缺少必要字段这些错误的处理动作不同。文件错误要重新选择网络错误要重试认证错误要回登录页业务错误要展示具体状态数据错误要查接口结构。提示越准确用户越容易继续操作开发者也更容易定位问题。验证处理链路完整验证不能只看上传接口返回 200还要继续检查后续页面1. 上传照片后照片列表出现新照片。 2. 故事列表能看到新生成的故事。 3. 故事详情里的年代、地点、人物字段有内容。 4. 视频活化失败时故事仍然保留。 5. 刷新页面后状态不回退。这组验证能覆盖“上传成功但业务内容没落地”的问题。移动端项目做长任务时最怕页面提前报成功后面状态却跟不上把状态刷新接到真实接口上问题会少很多。处理链路排查页面文案要反映真实阶段处理阶段的文案不能继续写“上传中”。上传和处理是两个动作用户看到不同文案才知道现在不是网络传输慢而是服务端正在生成内容。正在上传 35% 字节仍在传输 正在处理照片 服务端已收到照片正在生成内容 处理失败 服务端任务失败需要重试或查看错误文案准确会减少误解。用户如果以为还在上传可能会重复点击或退出页面知道已经进入处理阶段就更容易等待或去别的页面。状态刷新不要依赖固定等待移动端常见错误是上传后Future.delayed几秒再刷新。这种写法不稳定网络快时浪费时间网络慢时仍然拿不到结果。更稳的是围绕接口状态刷新。上传接口返回 - 刷新照片列表 照片详情接口 - 查看识别字段和视频状态 故事列表接口 - 查看故事是否生成 详情页轮询 - 只针对仍在处理中的视频状态当前项目里上传页刷新照片列表故事详情页针对活化状态做轮询。不同页面只刷新自己需要的数据避免全局乱刷。失败隔离的代码边界处理链路里可以把失败分为“阻断型”和“非阻断型”。阻断型照片上传失败、故事主内容生成失败 非阻断型视频活化失败、缩略图加载失败、高清语音生成失败阻断型失败要阻止进入下一阶段非阻断型失败只更新局部状态。这个边界能避免一个附加功能失败导致整条业务链路回滚。数据一致性检查处理完成后至少要检查三个接口的数据是否一致/api/photos 上传列表里有照片 /api/stories 故事列表里有对应故事 /api/photos/{id} 照片详情里有年代、地点、人物、视频状态如果照片存在但故事不存在问题在故事生成或列表刷新如果故事存在但照片详情缺字段问题在识别结果或元数据保存如果视频状态失败但故事存在属于非阻断失败不应该删除故事。处理流程问题定位表现象优先检查对应接口或文件处理方向上传成功但故事列表没有内容故事生成是否完成/api/stories刷新故事列表检查服务端处理日志照片有但元数据为空识别结果是否写入/api/photos/{id}检查年代、地点、人物字段视频失败导致故事消失主数据和附加能力是否耦合后端处理链路、详情页状态视频失败只更新视频状态不删除故事页面一直显示处理中状态刷新是否依赖真实接口upload_page.dart、story_detail_page.dart通过详情接口刷新状态不靠固定等待长任务最怕状态含糊。上传、识别、故事生成、视频活化是不同阶段页面要分别表达。只有这样用户才能知道现在是网络慢、服务端忙还是某个附加能力失败。处理状态字段设计上传后的处理链路最好不要只用一个布尔值表示。更清楚的做法是给照片维护独立的处理字段页面根据字段组合展示状态。photo.status uploaded / analyzing / ready / failed photo.storyStatus pending / generated / failed photo.animationStatus none / processing / ready / failed photo.errorMessage 最近一次失败原因页面展示时可以按优先级判断StringprocessingLabel(PhotoInfophoto){if(photo.statusfailed)return照片识别失败;if(photo.storyStatuspending)return故事生成中;if(photo.animationStatusprocessing)return视频活化中;if(photo.animationStatusfailed)return故事已生成视频暂不可用;return处理完成;}这样比“上传成功/失败”更精确。照片识别、故事生成、视频活化可以分别失败、分别恢复页面也能给出不同提示。

相关新闻

【C++ 基础】字符与字符串

【C++ 基础】字符与字符串

ASCLL码表1. 引言:从字符到字符串在 C 编程中,字符(char)和字符串(string)是最基础、最常用的数据类型之一。无论是处理用户输入、文件读写、网络通信,还是实现各种文本处理算法,都离…

2026/9/24 10:12:59 阅读更多 →
AM62L硬件防火墙权限寄存器配置实战:从总线错误到安全内存隔离

AM62L硬件防火墙权限寄存器配置实战:从总线错误到安全内存隔离

1. 从寄存器手册到实战:理解AM62L防火墙权限配置的核心逻辑 最近在调试一块基于TI AM62L处理器的工控板卡时,遇到了一个典型的“内存访问被拒”问题。一个运行在非安全世界(Non-Secure World)的用户态(User Mode&#…

2026/9/24 22:31:42 阅读更多 →
如何用Mermaid Live Editor在5分钟内创建专业流程图:新手终极指南

如何用Mermaid Live Editor在5分钟内创建专业流程图:新手终极指南

如何用Mermaid Live Editor在5分钟内创建专业流程图:新手终极指南 【免费下载链接】mermaid-live-editor Edit, preview and share mermaid charts/diagrams. New implementation of the live editor. 项目地址: https://gitcode.com/GitHub_Trending/me/mermaid-…

2026/9/23 12:18:01 阅读更多 →

最新新闻

如何快速看懂 avoid-ai-writing 的 Tier 1/2/3 词汇体系:112 条替换词表 + 10 个套话短语判定标准

如何快速看懂 avoid-ai-writing 的 Tier 1/2/3 词汇体系:112 条替换词表 + 10 个套话短语判定标准

如何快速看懂 avoid-ai-writing 的 Tier 1/2/3 词汇体系:112 条替换词表 10 个套话短语判定标准 【免费下载链接】avoid-ai-writing Skill that audits and rewrites content to remove AI writing patterns. Use it with your favorite agents including Claude C…

2026/9/25 5:00:53 阅读更多 →
CH32V307移植FreeRTOS:RISC-V适配逻辑与快速实践指南

CH32V307移植FreeRTOS:RISC-V适配逻辑与快速实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 5:00:53 阅读更多 →
π型衰减器设计实战:从电阻计算到高频调试避坑指南

π型衰减器设计实战:从电阻计算到高频调试避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 5:00:53 阅读更多 →
KingSCADA4.0信创版实战:从部署到存量工程迁移的避坑指南

KingSCADA4.0信创版实战:从部署到存量工程迁移的避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 5:00:53 阅读更多 →
HDMI转MIPI实战:基于LT6911C的选型、硬件设计与调试全解析

HDMI转MIPI实战:基于LT6911C的选型、硬件设计与调试全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 5:00:53 阅读更多 →
低功耗电压检测电路:MOS管开关控制电阻分压,将待机电流降至nA级

低功耗电压检测电路:MOS管开关控制电阻分压,将待机电流降至nA级

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 4:59:53 阅读更多 →

日新闻

AI元人文:从工具使用到思维重构的深度探索

AI元人文:从工具使用到思维重构的深度探索

最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决…

2026/9/25 0:00:41 阅读更多 →
Python+CNN车牌识别实战:从数据预处理到模型训练与部署

Python+CNN车牌识别实战:从数据预处理到模型训练与部署

简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据…

2026/9/25 0:00:41 阅读更多 →
Vim基础操作全攻略:保存退出、模式切换与高频命令实战

Vim基础操作全攻略:保存退出、模式切换与高频命令实战

1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保…

2026/9/25 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/24 14:34:13 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/24 9:10:42 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/24 14:33:56 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/24 12:50:34 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/24 14:33:48 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/24 12:49:17 阅读更多 →