【寻迹校园 HarmonyOS NEXT 实战 09】三步结构化发布表单ArkUI 如何降低失物描述成本这是“寻迹校园 HarmonyOS NEXT 实战”系列第 9 篇。本文结合PublishTypePage与PublishFormPage拆解丢失/拾得分流、三步字段组织、草稿恢复、Photo Picker、步骤校验和防重复提交。上图为本文原创生成的三步表单概念图不是应用截图。表单依次收集基本信息、公开/私密特征和最终确认减少用户面对长表单时的认知压力。一、自由文本发布为什么很难匹配如果发布页只有一个大文本框用户可能写出昨天好像在教学楼丢了一个包有看到的联系我。这段话对人类勉强可读对筛选、匹配和安全核验却很不友好不知道是丢失还是拾得“昨天”会随日期变化“教学楼”范围过大“包”没有稳定分类公开描述可能夹带联系方式没有私密特征用于确认归属。结构化表单的目标不是让用户多填字段而是把后续搜索、匹配、认领和审核需要的信息提前组织好。二、第一步先区分丢失与拾得发布入口先展示两种业务类型我丢了物品进入丢失信息表单我捡到物品进入拾得信息表单。PublishTypePage使用稳定路由跳转而不是把显示文案当路由 keythis.typeCard(我丢了物品,发布丢失信息,AppIconName.LOST_BAG,AppColors.ON_LOST,AppColors.LOST_CONTAINER,AppRoute.PUBLISH_LOST_FORM)类型一旦进入表单就成为ReportType。编辑已有记录时不允许修改丢失/拾得类型因为类型变化会影响匹配方向、私密字段和状态机语义。三、三步表单分别收集什么项目把长表单拆成三个步骤步骤字段用户目标1. 基本信息名称、分类、校园区域、事件日期、照片让记录可被筛选和排序2. 物品特征公开描述、拾得物私密核验特征支撑匹配与安全核验3. 确认发布汇总类型、分类、地点、日期、照片和描述在写入前发现错误步骤文案由一个简单函数统一privatestepLabel(step:number):string{if(step1)return基本信息;if(step2)return物品特征;return确认发布;}它不是为了炫技而是让页面层只维护当前步骤业务规则仍交给ReportService。四、页面只保存草稿态PublishFormPage使用Local保存短生命周期输入标题、分类、区域、日期、公开描述、私密特征、图片 URI、当前步骤和错误状态。提交前页面把这些字段组装成ReportDraftprivatecreateDraft():ReportDraft{returnnewReportDraft(this.reportType,this.title,this.category,this.area,this.description,this.privateFeature,this.eventDate,this.imageUris);}页面不直接写数据库也不决定照片如何复制到应用沙箱。草稿只是输入契约最终校验和持久化由 Service 负责。上图展示从类型选择到成功回执的完整链路。每一步只暴露当前需要处理的信息最终写入只有一个入口。五、步骤切换要使用完整校验结果点击“下一步”时页面调用同一个validateDraft()但只检查当前步骤相关字段privategoNext():void{constvalidation:PublishValidationreportService.validateDraft(this.createDraft());if(this.currentStep1){this.validationvalidation;if(validation.titleError.length0validation.categoryError.length0validation.areaError.length0validation.eventDateError.length0validation.photoError.length0){this.currentStep2;this.validationnewPublishValidation();}}}这样避免页面自己维护第二套规则。即使按钮禁用条件遗漏Service 的完整校验仍是最终门禁。六、日期必须保存绝对值“昨天”“上周一”适合自然语言不适合长期记录。项目通过系统日期选择器保存YYYY-MM-DD最早日期限制为项目允许范围最晚日期不超过今天接受后统一格式化Service 再次验证日期格式与真实性。绝对日期可以稳定计算候选相差天数也不会因为用户第二天打开页面而改变含义。七、照片是可选输入但生命周期不能随意处理页面通过PhotoPickerService.selectImages(3)拉起系统选择器最多接收 3 张图片。选择器取消不是异常应该给出可理解提示并允许继续填写。页面只持有返回 URI。真正提交或保存草稿时Service/Repository 才负责把需要长期保存的内容复制到应用管理位置失败时还要清理本轮已复制但未被记录引用的文件。这条边界避免页面同时处理权限、文件复制和数据库事务。八、为什么拾得物需要私密核验特征公开描述用于搜索不能包含所有细节。拾得者可以填写“夹层内有一张特定颜色卡片”等私密特征只在认领审核时核验。丢失者的认领证明与拾得记录的私密特征应该分开保存、分开展示。公开列表和 Agent 输入都不应拿到完整私密字段。项目页面同时提示用户不要在公开描述中填写手机号、微信号、密码或完整证件号码。私密字段不是“随便放敏感信息的地方”它同样需要最小化和访问边界。九、草稿恢复如何降低中途退出成本用户可能在选择照片、查找日期或思考特征时退出。新建表单出现时页面通过reportService.loadDraft(reportType)恢复当前设备上次保存内容。草稿恢复需要注意丢失和拾得草稿分别保存只有确实存在内容时才显示“已恢复”编辑已发布记录时不加载新建草稿发布成功后清理对应类型草稿草稿图片更新后清理不再引用的旧文件保存失败显示错误不假装已落盘。当前草稿只在单机本地保存不是账号云同步。十、防重复提交与底部操作区异步提交期间必须禁用再次点击privateasyncsubmit():Promisevoid{if(this.saving)return;constdraft:ReportDraftthis.createDraft();this.validationreportService.validateDraft(draft);if(!this.validation.isValid())return;this.savingtrue;constresultawaitreportService.createReport(draft);this.savingfalse;// success / error mapping}同时还要考虑键盘和安全区底部“上一步 / 下一步 / 发布”不能被软键盘永久遮挡小屏和最大字体下按钮文案不能溢出loading 时布局不能突然跳动。十一、错误态应该靠近字段也要有页面级反馈字段错误应显示在对应输入项附近例如日期无效、公开描述太短、私密特征缺失。存储失败、Photo Picker 异常等跨字段问题则显示页面级错误。合理的反馈层级是字段错误告诉用户具体改哪一项步骤错误阻止进入下一步并保留已填内容提交错误恢复按钮状态允许安全重试成功状态进入独立成功页提供查看详情和继续匹配入口。不要只弹一个“参数错误”也不要在失败后清空整张表单。十二、验收表单不能只走一条成功路径至少需要覆盖丢失与拾得两种类型每个必填字段为空或过短未来日期和非法日期公开描述含联系方式拾得物未填写私密特征选择 0、1、3 张照片和取消选择草稿保存、恢复和发布后清理连续点击提交只产生一条记录保存失败后按钮恢复、内容保留最大字体、小屏和底部安全区。这些场景共同证明表单可交付而不仅是页面能渲染。十三、当前方案的边界本文验证的是单机 HarmonyOS 表单和本地持久化链路。它不证明服务端幂等键、账号级草稿同步、多设备并发编辑、云端内容审核和上传断点续传。如果接入后端应增加客户端请求 ID、服务端幂等约束、文件上传状态、草稿版本和冲突合并而不是继续扩大页面状态。十四、本文小结三步结构化表单把发布任务拆成类型选择、基本信息、公开/私密特征和最终确认。页面只保存草稿态Service 负责校验与写入Repository 管理数据和图片生命周期。下一篇将进一步拆解最终门禁为什么maxLength和按钮禁用不足以保护业务与隐私以及ReportService.validateDraft()应该如何统一输出字段错误。系列导航第 9 篇 / 共 50 篇。上一篇《V1.0 核心应用 V1.1 小艺增强》下一篇《ReportService 的隐私友好校验策略》。