尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
【寻迹校园 HarmonyOS NEXT 实战 10】表单校验应该放在哪里:ReportService 的隐私友好校验策略
【寻迹校园 HarmonyOS NEXT 实战 10】表单校验应该放在哪里ReportService 的隐私友好校验策略这是“寻迹校园 HarmonyOS NEXT 实战”系列第 10 篇。本文结合PublishValidation与ReportService.validateDraft()说明页面即时反馈、Service 最终门禁、隐私拦截、日期真实性和图片数量校验如何形成同一套可测试规则。上图为本文原创生成的校验门禁概念图不是项目截图。用户输入先经过页面提示真正写入前仍必须由 Service 统一验证。一、输入框 maxLength 为什么不是业务校验maxLength只能限制字符数量无法回答这些问题标题只有空格是否有效分类是否来自允许词表事件日期是否真的存在日期是否晚于今天公开描述是否包含手机号拾得物是否填写私密核验特征图片数量是否超过系统约束编辑时是否偷偷改变了记录类型。按钮禁用也不能成为唯一防线。调用方可能来自另一个页面、自动化测试或未来的深链入口。只要 Service 接受ReportDraft它就必须自己完成最终校验。二、页面校验与 Service 校验各负责什么页面层负责即时体验输入变化后清理错误、在字段附近显示提示、控制步骤切换和按钮状态。Service 层负责业务安全任何创建或更新动作都重新校验完整草稿失败时不进入 Repository。两层可以使用同一个PublishValidation结果但不能只保留页面层。正确顺序是用户输入 - 页面给出即时提示 - 组装 ReportDraft - Service.validateDraft() - 失败返回字段错误不写入 - 成功归一化、复制图片、Repository 持久化三、用 PublishValidation 承载字段级错误项目没有只返回一个布尔值而是定义字段级错误对象exportclassPublishValidation{titleError:string;categoryError:string;areaError:string;eventDateError:string;descriptionError:string;privateFeatureError:string;photoError:string;isValid():boolean{returnthis.titleError.length0this.categoryError.length0this.areaError.length0this.eventDateError.length0this.descriptionError.length0this.privateFeatureError.length0this.photoError.length0;}}页面能够把错误放到正确字段旁边Service 也可以在createReport()和updateReport()中复用同一规则。四、当前项目的校验规则validateDraft()覆盖以下字段字段规则用户提示标题去空格后至少 2 个字物品名称至少填写 2 个字分类去空格后至少 2 个字请填写物品分类区域去空格后至少 2 个字请填写具体校园区域日期YYYY-MM-DD、真实日期、不晚于今天请选择不晚于今天的事件日期公开描述至少 5 个字公开描述至少填写 5 个字隐私内容拦截明显手机号、微信号和证件号公开描述中不要填写敏感信息私密特征拾得记录至少 4 个字请填写私密核验特征照片最多 3 张最多选择 3 张照片真实实现保持顺序清晰validateDraft(draft:ReportDraft):PublishValidation{constvalidationnewPublishValidation();if(draft.title.trim().length2)validation.titleError物品名称至少填写 2 个字;if(draft.category.trim().length2)validation.categoryError请填写物品分类;if(draft.area.trim().length2)validation.areaError请填写具体校园区域;if(!this.isValidEventDate(draft.eventDate)){validation.eventDateError请选择不晚于今天的事件日期;}if(draft.description.trim().length5){validation.descriptionError公开描述至少填写 5 个字;}if(this.containsSensitiveContent(draft.description)){validation.descriptionError公开描述中不要填写手机号、微信号或证件号码;}if(draft.reportTypeReportType.FOUNDdraft.privateFeature.trim().length4){validation.privateFeatureError拾得物品需填写至少 4 个字的私密核验特征;}if(draft.imageUris.length3)validation.photoError最多选择 3 张照片;returnvalidation;}五、校验顺序也会影响用户体验公开描述先检查长度再检查敏感内容。后一个错误可以覆盖前一个错误使用户优先看到更重要的隐私风险而不是只提示“字数不足”。如果未来需要同时展示多个问题可以把单字符串升级为错误数组或错误码集合。但当前单字段显示一个最关键错误能够控制页面复杂度。六、日期校验不能只依赖正则2026-02-31能匹配YYYY-MM-DD正则却不是有效日期。项目的日期校验分四步正则检查格式构造Date并检查是否为NaN把解析后的年、月、日与原字符串逐项比较把今天设为 23:59:59拒绝未来日期。privateisValidEventDate(value:string):boolean{constnormalized:stringvalue.trim();if(!/^\d{4}-\d{2}-\d{2}$/.test(normalized))returnfalse;constselected:Datethis.parseDate(normalized);if(Number.isNaN(selected.getTime()))returnfalse;constyearNumber(normalized.substring(0,4));constmonthNumber(normalized.substring(5,7));constdayNumber(normalized.substring(8,10));if(selected.getFullYear()!year||selected.getMonth()!month-1||selected.getDate()!day)returnfalse;consttodaynewDate();today.setHours(23,59,59,999);returnselected.getTime()today.getTime();}日期选择器改善输入体验Service 校验保证任何调用路径都无法绕过真实性检查。上图展示两层校验的职责页面提供快速反馈Service 决定是否允许写入Repository 只接收已经通过业务门禁的数据。七、隐私拦截应该诚实描述能力边界当前项目使用轻量规则拦截明显内容关键词“微信”“手机号”“身份证”以及中国大陆手机号格式。privatecontainsSensitiveContent(value:string):boolean{consttext:stringvalue.trim();returntext.includes(微信)||text.includes(手机号)||text.includes(身份证)||/1[3-9][0-9]{9}/.test(text);}这是一道演示级防线不是完整敏感信息识别系统。它可能漏掉使用空格或符号分隔的号码拼音、谐音和图片中的联系方式QQ、邮箱、宿舍门牌和精确交接地点非中国大陆手机号经过编码或刻意规避的文本。因此文章和产品都不能宣称“已识别所有敏感信息”。更完整的生产方案需要规范化、规则库、服务端内容安全、人工审核和申诉链路。八、私密字段不是公开描述的替代垃圾桶拾得物的私密核验特征用于认领审核例如夹层内特定物品。它应该满足最小化原则只记录能验证归属的必要特征不记录无关身份信息。它还需要明确访问边界不出现在首页和详情公开区域不参与 Agent 输入不作为公开匹配理由只在认领审核场景展示删除记录时同步清理日志不得打印原文。校验“至少 4 个字”只是完整保护的一小部分数据流和访问控制同样重要。九、Service 最终门禁如何阻止无效写入创建和更新都先调用validateDraft()asynccreateReport(draft:ReportDraft):PromiseOperationResultItemReport{constvalidation:PublishValidationthis.validateDraft(draft);if(!validation.isValid()){returnnewOperationResultItemReport(false,请检查必填信息,undefined,ErrorCategory.VALIDATION);}// 通过后才复制图片并写入 Repository}这保证无论来自表单提交、编辑页还是未来其他入口非法草稿都不会进入持久化层。Repository 不需要重复理解标题长度和隐私关键词。十、按钮禁用仍然有价值但不是安全边界页面可以根据当前输入禁用“下一步”或“发布”减少无效点击并在 loading、图片选择或草稿保存期间防止冲突。但按钮禁用只负责体验状态可能过时未来调用方也可能不经过这个按钮。最终是否写入必须以 Service 校验结果为准。两者关系不是二选一而是“页面早反馈 Service 强门禁”。十一、如何测试校验规则建议使用表驱动测试覆盖标题空、空格、1 字、2 字、长文本分类与区域空值、未知旧值和权威词表值日期空、格式错、闰日、2 月 31 日、今天和明天描述4 字、5 字、手机号、关键词和普通文本类型丢失与拾得对私密特征的不同要求图片0、1、3、4 张组合错误多个字段同时无效更新动作类型变化、非用户创建记录和非开放状态。测试应该直接调用ReportService.validateDraft()和创建/更新方法而不是只模拟按钮点击。这样规则可以在没有 ArkUI 页面的环境中快速回归。十二、错误文案也是契约错误文案要告诉用户如何修复而不是泄露内部异常。存储异常应该映射成“保存失败请稍后重试”而不是把数据库路径、SQL 或堆栈直接显示在页面。同一错误在页面、测试和日志中应有稳定分类例如VALIDATION、STORAGE和CAPABILITY。用户看到可理解文案开发者通过受控日志定位原因。十三、生产级扩展方向当项目接入后端后校验需要分层扩展客户端即时反馈、基础格式、减少无效请求Service跨页面统一业务规则服务端鉴权、幂等、最终数据约束内容安全文本与图片检测人工治理复杂边界和申诉数据库非空、长度、枚举和唯一性约束。任何一层都不能单独替代其他层。特别是客户端校验永远不能当成服务端安全边界。十四、本文小结表单校验的正确位置不是“页面或 Service 二选一”。页面负责即时反馈ReportService负责最终门禁Repository 只处理已经通过业务规则的数据。PublishValidation提供字段级错误日期检查验证真实日历值隐私规则拦截明显联系方式并诚实保留能力边界。下一篇将进入本地数据层介绍ReportDraftRepository如何让三步表单在退出后恢复同时安全管理图片 URI。系列导航第 10 篇 / 共 50 篇。上一篇《三步结构化发布表单》下一篇《本地草稿恢复与图片 URI 生命周期》。
RELATED

相关推荐

工业物联网数据中台实战:基于Kafka+Flink+InfluxDB构建时序数据平台

工业物联网数据中台实战:基于Kafka+Flink+InfluxDB构建时序数据平台

最近,不少技术圈的朋友在讨论一个有趣的现象:一些看似传统的制造业公司,其年报数据背后,正悄然透露出与前沿技术深度融合的信号。今天我们不聊股票代码,而是以“汉缆股份”这份年报中的一组关键数据为引子,…

📅 2026/10/8 13:31:56
同一微信号,手机和平板同时在线?WeChatPad 是这样强制开启微信平板模式的

同一微信号,手机和平板同时在线?WeChatPad 是这样强制开启微信平板模式的

同一微信号,手机和平板同时在线?WeChatPad 是这样强制开启微信平板模式的 【免费下载链接】WeChatPad 强制使用微信平板模式 项目地址: https://gitcode.com/gh_mirrors/we/WeChatPad 如果你和我一样,曾经在手机和平板之间反复横跳、一…

📅 2026/10/7 10:52:02
llm的api是无状态的,每次调用都需要输入以前的对话历史

llm的api是无状态的,每次调用都需要输入以前的对话历史

agent的任务记忆、模型记忆、KVCache、缓存命中、模型上下文窗口,五个概念之间的联系。任务记忆得靠传对话历史来维持,模型api调用一次后,模型的KVCache就会被搬走。缓存命中是根据token前缀匹配出以前算出的KVCache,然后补算新的…

📅 2026/10/7 7:09:49
MORE NEWS

更多资讯

📰

Zint+Zlib+Libpng预编译库集成指南:依赖链与避坑要点

简介:这套面向 Windows 开发者的预编译库包,内含 Zint、Zlib 与 Libpng 三大开源库的完整编译产物,专为 Visual Studio 2015 环境设计,提供 32 位与 64 位、Debug 和 Release 版本,可直接集成到项目中实现条形码/二维码…

📰

仓颉 stdx encoding.base64 包详解:Base64 编码解码 API 与源码级实现原理

标准库网络密码学并发编程 【免费下载链接】cangjie_stdx 仓颉编程语言提供了 stdx 模块,该模块提供了网络、安全等领域的通用能力。 项目地址: https://gitcode.com/Cangjie/cangjie_stdx 点击查看 免费下载 Base64 是文本环境中传递二进制数据的事实标…

📰

gSOAP与ONVIF对接指南:从WSDL到C代码生成的完整实践

简介:面向Linux环境下基于ONVIF协议开发网络视频设备的工程师,这份编译好的C代码框架由gSOAP工具链生成,用于快速搭建与ONVIF设备交互的客户端程序,解决手动编写SOAP/XML消息的繁琐问题。压缩包共12个文件,包含5个C源文…

📰

Zint+Zlib+Libpng预编译库集成指南:Windows下CMake生成条码PNG

简介:面向Windows开发者的预编译库合集,内含Zint、Zlib与Libpng三个开源库,专为Visual Studio 2015环境下的32位和64位工程准备,涵盖debug与release模式,可直接集成用于条形码/二维码生成、数据压缩解压及PNG图像读写。…

📰

210+ AI开源技术大咖汇聚深圳!GOSIM Shenzhen 2026完整日程发布

10月16—17日,全球开源创新峰会 GOSIM Shenzhen 2026 将在深圳南山伊敦酒店举行。自 2023 年以来,GOSIM 已先后走过上海、北京、巴黎、杭州等城市,第七站来到深圳。本届大会将重磅迎来 210 余位全球技术大咖和 2000 余位开发者,围…

📰

MonkeyDev 使用指南:基于 Xcode 的 CaptainHook/Logos 插件开发与免越狱 App 注入调试

开发工具移动开发 【免费下载链接】MonkeyDev CaptainHook Tweak、Logos Tweak and Command-line Tool、Patch iOS Apps, Without Jailbreak. 项目地址: https://gitcode.com/gh_mirrors/mo/MonkeyDev 点击查看 免费下载 导读:MonkeyDev 是 iOSOpenDev …

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬