资讯动态

【中国方言题库|04】HarmonyOS ArkTS 粤语分库实战:处理繁简文本、读音与练习入口

发布时间:2026/10/27 18:36:53 来源:尧图企业网站定制
【中国方言题库04】HarmonyOS ArkTS 粤语分库实战处理繁简文本、读音与练习入口证据边界本文静态复核YueBankPage.ets、BankDetailPage.ets、BankCard.ets、MockBanks.ets与路由清单。没有执行构建、模拟器或真机验证显式读音模型、章节标注和状态枚举属于建议实现。入口、文本与数据责任图粤语专题入口只固定题库身份共享详情容器负责页面能力数据装配层再按b_yue选择题目。三张图分别说明主题、执行流和责任边界。一、先从真实入口确认地区身份YueBankPage.ets是一个薄入口import { BankDetailContent } from ./BankDetailPageEntry Component struct YueBankPage { build() { Column() { BankDetailContent({ fixedBankId: b_yue }) } .width(100%) .height(100%) } }它只负责把b_yue注入共享详情组件。题库简介、文化提示、进度、章节列表、随机练习和模拟考试均由BankDetailContent实现。本文的唯一标记是粤语读音必须有可核验的音频来源。代码中出现audioHint、播放按钮或 TTS API都不能自动证明输出的是标准粤语更不能证明是真人录音。二、b_yue是整条链路的统一主键粤语题库目录如下{ id: b_yue, regionId: yue, name: 粤语题库, cover: $r(app.media.img_bank_cover_yue), totalCount: 0, accuracy: 0, hot: 95, chapters: YUE_CHAPTERS }章节包括const YUE_CHAPTERS: Chapter[] makeChapters(yue, [ 基础发音, 九声六调, 日常对话, 茶餐厅词汇, 老广俗语, 香港流行语 ])这里要区分地区 IDyue题库 IDb_yue章节 ID 前缀yue_c1到yue_c6分库入口和练习页传递的是题库 ID章节模式还会传章节 ID。本地进度也按bankId chapterId查询。任何一层混用yue和b_yue都会出现详情为空或进度不更新。三、粤语文字不是简单的“繁体中文”题库包含唔该 冇见 食咗饭未 好攰 边个 做乜 返屋企 钟意这些内容既包含传统字形也包含粤语书写中的常用方言字。它们不能被普通简繁转换库无差别处理。例如“冇”“咗”“乜”不是把普通话简体文本机械转为繁体就能得到的。当前源码没有发现自动繁简转换服务。题干、选项、解析和audioHint都按本地数据原样保存、原样渲染。这一事实可以准确描述为应用保留题库中录入的粤语字形不在运行时自动改写。不能描述为应用已实现完整的简繁双向转换。如果产品需要简体解释与粤语原文并存应把两者建成不同字段而不是运行时替换字符。四、为粤语文本建立类型化模型当前RawQuestion使用interface RawQuestion { type: string stem: string options: string[] answer: number analysis: string example?: string audioHint?: string }它可以承载题目但无法明确区分“粤语原文”“普通话释义”“粤拼”和“显示字形策略”。更适合粤语内容的模型可以是interface YueExpression { id: string traditionalText: string simplifiedExplanation: string jyutping?: string meaning: string exampleTraditional?: string exampleExplanation?: string audioResource?: Resource audioSourceNote?: string }这里不把粤语原文命名为泛化的traditional后就自动推导简体。simplifiedExplanation是编辑审核后的普通话解释jyutping是独立读音标注音频资源与来源说明也是独立字段。五、字体与 Unicode 显示要在真机验证ArkUIText能显示 Unicode 字符但最终可见效果还取决于系统字体是否包含对应字形。测试应覆盖“唔、冇、咗、攰、啲、嚟”等字符是否缺字。粤拼数字或声调标记是否被截断。大字体下原文和释义能否换行。粗体是否仍有可用字形。phone、tablet、2in1 是否使用一致字体回退。不要为了一个缺字字符把整套大型字体打进包。应先确认系统字体覆盖再评估是否需要小范围字体资源及其授权。Text(expression.traditionalText) .fontSize(Sizes.TITLE_FONT) .fontWeight(FontWeight.Bold) .maxLines(2) .textOverflow({ overflow: TextOverflow.Ellipsis })若原文承担核心学习信息最好不要强制单行省略。可以允许两行并让卡片高度随内容增长。六、当前题库中的audioHint只是文本大量原始题目包含{ type: audio, stem: 听音理解“得唔得呀”是在问, audioHint: 得唔得呀, options: [行不行, 去哪里, 吃什么, 几点钟], answer: 0, analysis: “得唔得”就是可不可以、行不行。 }audioHint的类型是string内容是待朗读文本不是音频文件、URI 或媒体资源。仅凭这个字段无法证明发音者、口音、地区或录制质量。更关键的是当前目录构建会把所有audio题重分类为vocabconst reclassified: RawQuestion[] source.map((r: RawQuestion) { if (r.type audio) { return { type: vocab, stem: r.stem, options: r.options, answer: r.answer, analysis: r.analysis, example: r.example, audioHint: r.audioHint } as RawQuestion } return r })注释写明“听音题题型已下线”。因此这些题在当前缓存中是词汇题不能因为仍保留audioHint就说“粤语听音题已上线”。七、PracticePage 的 TTS 也不能证明粤语读音PracticePage创建文本转语音引擎时使用this.ttsEngine await textToSpeech.createEngine({ language: zh-CN, person: 0, online: 0 })失败后回退到this.ttsEngine await textToSpeech.createEngine({ language: zh-CN, person: 0, online: 1 })这说明语言参数是zh-CN。优先本地引擎。失败后可能使用在线引擎。模块声明ohos.permission.INTERNET与在线回退一致。但它没有指定或验证粤语音色。即便引擎能朗读“唔该”输出也可能按普通话字音处理。商店文案不应写“标准粤语发音”“真人粤语朗读”。此外PracticePage 的播放 UI只在question.type audio时出现而目录已经把audio改成vocab。因此当前普通题链路中播放分支可能根本不会触发。八、真正的粤语读音需要独立资源契约若要上线粤语读音建议使用明确资源interface PronunciationAsset { id: string expressionId: string locale: yue-Hant region?: HK | GZ speakerType: human | licensed-engine resource: Resource durationMs: number sourceNote: string reviewedAt: string }播放前按表达 ID 查找资源private canPlay(entry: YueExpression): boolean { return entry.audioResource ! undefined }没有资源时隐藏播放按钮只显示粤拼或文本读音不使用普通话 TTS 伪装成粤语。若采用系统支持的粤语 TTS也要根据官方 API 的实际 locale 与设备支持矩阵实现并在不可用时给出降级状态。九、繁简展示应是内容策略不是全局替换一个清晰的卡片可以这样组织粤语原文你食咗饭未 粤拼nei5 sik6 zo2 faan6 mei6 普通话释义你吃饭了吗 例句语境日常问候这不是“把整页切换为繁体”而是保留学习对象并提供解释。若增加繁简偏好可以只控制解释文本的资源版本不能修改题库答案所依赖的粤语原文。错误做法包括将“咗”替换成普通话“了”后仍称为粤语原文。对题干和答案分别转换导致匹配失效。用字符替换表生成粤拼。把香港与广州语音差异压成唯一“标准答案”。十、分库详情的文化 Profile 已经落地BankDetailContent为b_yue提供{ subtitle: 从茶餐厅到地铁口练最常见的粤语表达, intro: 粤语题库覆盖基础发音、日常对话和城市常见短句适合想先听懂、再敢开口的人。, cultureNote: 内容会把早茶、通勤、港式流行语和礼貌表达放进同一套练习里实用度很高。, focusTags: [听辨节奏, 礼貌表达, 生活口语], sceneTags: [早茶点单, 通勤借过, 街头问路] }这些内容真实展示在详情页但“基础发音”“听辨节奏”是学习主题不等于当前已有可验证音频。技术文章要把“题库覆盖的知识点”和“应用提供的播放能力”分开。十一、章节、随机与考试入口保持同一bankId粤语分库可进入{ bankId: b_yue, chapterId, mode: chapter } { bankId: b_yue, mode: random } { bankId: b_yue, mode: exam }PracticePage 应以b_yue查找题库题目不依赖上一页标题或当前 Tab。参数校验包括chapter 模式必须有属于粤语题库的章节 ID。random 模式只能从粤语题目抽取。exam 模式按粤语真实可用题量出卷。无效题库或空题集不直接进入结果页。如果用户从收藏或搜索进入粤语题目也应携带同一题库 ID使进度写回正确分区。十二、本地进度不能被文本变体拆成两份学习记录应使用稳定题目 ID而不是题干文本作为 key。否则编辑人员把“你食咗饭未”改成另一字形后旧进度会丢失或重复。当前题目 ID由id: ${bankId}_q${i 1}生成。它比题干稳定但依赖数组顺序在中间插入题目可能让后续 ID整体变化。长期维护可为每道题提供人工稳定 ID例如id: yue_daily_have_you_eaten_001文本、粤拼、释义和例句可以更新学习记录仍归到同一道题。十三、去重不能只依赖题干trim()当前目录按题干去重const key r.stem.trim() if (seen.has(key)) continue seen.add(key)粤语文本中直角引号、弯引号、全半角标点、空格和繁简差异都可能让语义相同题目绕过去重。可以建立内容规范化仅用于去重 key不修改展示文本function normalizeForDedup(text: string): string { return text .normalize(NFKC) .replace(/[“”]/g, ) .replace(/\s/g, ) .trim() }但不要自动做简繁转换去重因为不同字形可能对应有意的教学差异。疑似重复应交给内容审核确认。十四、Unicode 安全不等于语义安全ArkTS 字符串能够保存粤语字符但以下操作仍需谨慎不用substring()按 UTF-16 单元截断用户可见文本。搜索时明确是否区分繁简与异体字。高亮匹配要保持原始索引。导出和日志使用 UTF-8。JSON 与资源文件保持一致编码。如果实现搜索别名可以为每个表达维护searchAliasessearchAliases: [ 食咗饭未, 吃饭了吗, nei5 sik6 zo2 faan6 mei6 ]显示仍使用原文搜索可以匹配解释或粤拼。十五、音频播放的状态机必须完整真实音频能力至少包含idle - preparing - playing - completed - error还要处理连续点击同一个按钮。播放一个词时切换另一个词。页面退到后台。音频焦点被其他应用占用。资源不存在或损坏。在线引擎不可用。按钮不能只显示一个永远不变的播放图标。加载、播放和错误状态要让用户看得懂离开页面时停止并释放资源。十六、多设备布局复用共享详情能力YueBankPage根容器满宽满高BankDetailContent根据断点和实际宽度切换常规窗口单列滚动。lg且宽度不小于 700vp双栏。底部随机练习与模拟考试按钮使用系统导航避让高度。若后续新增粤语词条音频区应避免在左右两栏同时创建播放器可以把播放器服务保持为页面级单实例。2in1 还应支持鼠标悬停、键盘焦点与空格播放。音频按钮的触控/点击区域不能只有 20vp 图标本身。十七、隐私与权限说明要对应在线回退模块声明ohos.permission.INTERNET。如果语音功能使用在线 TTS 回退隐私与审核备注应准确说明核心题库与学习记录保存在本地。若本地语音引擎不可用系统语音能力可能尝试在线服务。当前是否实际启用粤语播放要以题型和 locale 支持为准。应用不需要麦克风权限因为这是语音输出而非录音。不能同时写“完全离线”和保留在线引擎回退。如果产品决定使用纯本地真实音频资源可以删除不必要的在线回退与网络权限再重新构建验证。十八、粤语分库测试矩阵入口与参数YueBankPage 固定展示b_yue。外部传入其他 bankId 不覆盖固定 ID。路由清单包含pages/YueBankPage。三种练习模式均保持b_yue。文本粤语原文不被自动改写。“唔、冇、咗、攰、啲、嚟”真机无缺字。普通话释义与粤语原文分字段。大字体和窄屏不截断核心文本。搜索别名不改变原文。音频audioHint不被当作音频资源。重分类后的 vocab 题不显示虚假听音按钮。只有真实资源或已验证粤语 locale 才允许播放。无资源时隐藏按钮。播放失败有状态反馈。数据粤语进度不串到其他题库。文本编辑后稳定题目 ID不变。重复题目经规范化检查。题量来自最终去重、重分类后的集合。十九、可以宣传与不能宣传的边界可以准确描述粤语分库拥有独立入口并固定b_yue。本地题库包含粤语字形、普通话解释和文化语境。页面展示学习进度和六个章节。支持章节、随机和考试入口。共享详情适配 phone、tablet、2in1。当前不能直接描述已实现简繁双向转换。已提供标准粤语或真人粤语读音。所有“听音题”当前都可播放。audioHint是录音文件。zh-CNTTS 输出已经过粤语发音验证。二十、总结粤语分库的工程难点不在十几行入口代码而在内容语义不能被技术名词掩盖。YueBankPage真实完成了固定地区身份和共享详情复用题库真实保存了粤语字形、释义和文化场景练习链路真实支持章节、随机和考试。但当前没有运行时简繁转换历史听音题被重分类为词汇题audioHint只是文本zh-CNTTS 也不能证明粤语读音。要把“繁简文本与读音”做成可复核能力应使用结构化粤语原文、普通话解释、粤拼与真实音频资源建立来源和播放状态再经过真机字形、发音和多设备验证。保持这条事实边界才既保护用户体验也避免上架材料夸大功能。繁简文本不是一次全局替换粤语题库里的字形、词义、书写习惯和显示语言是不同维度。把所有繁体字机械转换为简体可能改变题目要考查的原始写法完全不转换又可能让只使用简体界面的用户难以理解。更稳的方式是保留题目原文并为需要解释的内容增加独立字段例如规范释义、普通话说明或可选的简体辅助文本。转换规则不应散落在 ArkUI 页面。页面只决定显示哪一种字段文本服务负责规范化与缺失回退题库数据仍保存可追溯原文。这样调整显示策略时不会改写题目本体也不会让同一道题在列表、练习和结果页出现不同字形。测试时需要准备三类样本繁简字形相同、字形不同但语义一致、粤语惯用字不能直接按普通话替换。每类样本都要核对题干、选项、答案与解析不能只比较标题。若转换后的选项发生重复还要阻止该题进入练习因为用户将无法区分正确答案。读音提示必须与音频能力分开当前数据模型中出现的读音或audioHint可以作为文字提示但字段名称不等于已经具备可播放音频。没有真实音频文件、播放组件、资源授权与设备验证时文章和界面都不应宣传听力训练。文字读音还要明确采用的标注体系并允许某些题目没有提示。建议把展示能力写成显式模型而不是用非空字符串推断播放器存在interfacePronunciationHint {text?:stringscheme?:jyutping|customaudioResource?:Resourcereviewed:boolean}functioncanPlayAudio(hint?:PronunciationHint):boolean{returnhint?.audioResource!undefined}这是建议实现不是当前源码已经存在的接口。它把文本提示、标注体系、人工校对和音频资源拆开。页面可在只有文字时显示“读音提示”只有资源真实存在时才渲染播放按钮从数据结构上避免能力夸大。用反例检查粤语内容是否串库第一组反例是从粤语入口携带其他题库 ID。由于fixedBankId应优先生效页面仍应展示b_yue。第二组是传入不存在的 ID数据层不应静默回退到四川话或其他题库而应返回题库不存在。第三组是完成粤语章节后进入其他地区进度数字不应变化。还要交叉核对页面标题、章节 ID、题目来源和持久化键。只看“粤语题库”标题并不足以证明内容正确如果RAW_MAP键写错标题可以正确而题目已经串区。进度键至少包含 bankId章节记录还应包含 chapterId不能使用可能变更的显示名称作为主键。六章分配要能解释内容归属源码声明基础发音、九声六调、日常对话、茶餐厅词汇、老广俗语和香港流行语六个章节。若题目只是按数组序号取模分配六章都能获得数据却不保证题意与章节标题一致数组顺序变化还会让同一道题转移章节。长期方案是让原始题目显式携带稳定 chapterId并在装配阶段校验该章节属于b_yue。迁移前先生成每章题量、无效章节、重复题干和跨库引用报告再由熟悉粤语的人审核语义。关键词脚本能发现结构问题不能替代语言判断。题目内容本身也需要来源与校对记录。技术架构只能保证数据按 ID 隔离不能自动证明读音、用字和文化解释准确。涉及地域差异的说法应注明适用语境避免把某一地区或某一代际的表达概括为全部粤语使用者。页面状态与练习入口一起收敛题库不存在、题库存在但无题、某章节为空是三种状态。前者只保留返回空题库隐藏随机练习和考试空章节仅禁用对应入口。加载阶段也应阻止重复点击避免在数据尚未就绪时打开空练习页。typeYueBankStateloading|notFound|empty|readyprivatecanStart(questionCount:number):boolean{returnthis.pageStatereadyquestionCount0}状态枚举同样属于建议改造。它让渲染提示和按钮能力来自同一判定避免多个布尔值互相矛盾。共享详情容器负责通用状态粤语包装页继续只负责固定身份职责边界不会因为补空态而倒退。发布前验证清单检查项验证方法预期结果固定入口携带错误 bankId 进入 YueBankPage仍使用 b_yue繁简文本抽查题干、选项、答案和解析原文可追溯辅助文本一致读音边界检查只有 hint、没有音频的题目不出现播放能力数据隔离对比粤语与其他题库内容标题、章节、题目不串库进度隔离完成粤语章节后打开其他题库其他题库进度不变空态测试无题库、空题库和空章节提示与可用按钮匹配适配长文本、小窗、横屏和深色模式文本不遮挡入口可达本轮仅完成静态源码复核没有运行 hvigor 构建、模拟器或真机测试。表中的动态结论需要在目标环境执行后确认不能从代码存在直接表述为已经通过。真机复核还应覆盖连续进入与返回、快速重复点击、应用重启后的进度恢复以及繁体系统语言和简体系统语言下的显示差异。若页面增加复制、朗读或分享功能需要重新检查文本来源、权限、无障碍描述和隐私材料不能默认沿用当前结论。每次题库内容更新后应抽样比较缓存前后题量和稳定题目 ID确认修订没有误删答案、打乱章节或覆盖已有进度。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑