Repository navigation
feat(i18n): 本地化硬编码中文并全量补齐繁体中文 - #550
Merged
Merged
Conversation
.claude/skills/* 自 #539 起作为指向 .agents/skills/* 的符号链接入库, runner 的 inside() 会拒绝一切符号链接,导致当前 main 上任何隔离 run 的源码快照都在构建前崩溃。快照目的只是应用源码,技能符号链接属于 贡献者工具,跳过并在 manifest 记录 skipped_symlinks 留痕,不削弱 inside() 的路径逃逸防护。
每日记账提醒的 5 处调度点(main.dart 恢复路径、reminder_providers 三处 开关/时间/完整设置、reminder_monitor_service 补偿路径)与语音记账的 麦克风受限提示原先硬编码中文,英文用户会收到中文通知/提示。 - 新增 lib/utils/app_localizations_resolver.dart:无 BuildContext 场景的 两级 locale 匹配(en 兜底),模式与 widget 层 resolver 一致 - reminder_providers 注入 Ref,开关路径按应用内语言设置取文案; main.dart/monitor_service 无 context,跟随系统语言(已知局限同 widget 层 resolver,注释说明) - ARB 新增 reminderDailyBody、voiceMicPermissionRestricted(en+zh); zh 文案与原硬编码逐字一致,中文用户零漂移,标题复用现有 reminderTitle(zh 即「记账提醒」) - ko/zh_TW 按 AGENTS.md 约定不补译,回退机制不变
批次 2:AI 对话回复、信用卡还款提醒、Android 通知渠道名、深链提示 共 ~40 处用户可见硬编码中文接入 l10n。 - ai_chat_service:processMessage 错误兜底与 AIResponse.billCards 成功 文案按调用方 l10n 取(无 l10n 时走 resolver,不再中文兜底) - agent 空回复「已完成。」改由组合根注入:NativeToolAgentModel 与 AgentAppFacade 增加 emptyFinalText 参数,ai_chat_providers 按 应用内语言传值(构造期取值,语言切换后需重启,局限已注释) - credit_card_reminder_providers:还款提醒标题/正文走 resolver (系统语言),新增带占位符键 creditCardReminderDueSoonTitle/Body - notification_android / auto_billing_service:Android 渠道名、描述、 ticker 全部本地化(主渠道复用 reminderTitle/reminderDailyTitle, 备用与截图渠道新增专用键);既有用户保留旧渠道名,新装生效 - app_link_service:深链全部结果消息(~21 处)按应用内语言取 (复用 container 读 languageProvider),新增 appLink* 键 23 个 - ARB 新增 33 键(en+zh),zh 与原硬编码逐字一致,中文用户零漂移
- 覆盖 accountBalanceAdjustment / agentActivity / agentAssistant / agentAuthorization / agentMemory / agentPermissions / agentSuggestion / agentFollowUp / agentTool / aiChat / appLink / billCard / categoryIconGroup / creditCard / reminder / transactionCopy / voiceMicPermissionRestricted 等家族 - 简转繁 + 台湾用语(設定/帳戶/佔比/彙總/回應/逾時/呼叫/資訊/自訂/ 頻道/裝置/儲存/檔案),术语与既有 2381 键对齐(記帳/帳本/「」引号) - 既有 zh_TW 翻译零改动;gen-l10n 后 zh_TW 未翻译数 = 0 - ko 按用户指示忽略
icon_picker_page.dart(341 行,含 96 个硬编码中文图标标签)在 lib/ 与测试中均无任何引用,页面从未接入路由,为长期死代码。真实图标 选择由 category_edit_page 内嵌网格承担(仅显示图标,无文字标签)。 i18n 审计中该文件 96 处命中据此由 UI 误判修正为死代码内部字符串。
批次 3:服务/数据层剩余 ~45 处用户可见硬编码中文接入 l10n。 - orphan_scanner:13 个 scanXxx 的 title/subtitle(25 处)全部本地化, 构造器注入 l10n 闭包(maintenance_providers 按应用内语言取) - custom_icon_service:5 个 CustomIconException 消息走 resolver - app_lock_service:biometric reason 改 nullable + resolver 兜底 (两个调用方本就传入 appLockBiometricReason,中文默认值不再触达) - share_poster_service / share_poster_data_service:分享文本与 默认账本兜底走 resolver - local_statistics / local_account:未分类显示兜底复用 commonUncategorized(展示期兜底,不落库) - local_category:转账兜底创建名走 resolver(查找按 kind,安全) - ARB 新增 29 键(en+zh/zh_TW) - 跳过并记录:平账分类名与交易备注(按名字查找+创建,跨语言 本地化会破坏数据完整性,需稳定键迁移,超出本批);db.dart AI对话 DB 默认值(GRAY) - 更新弹窗镜像名已确认 locale-aware(isZh 分支既有),仅将 _currentMirrorName 初始值与赋值改为双语字段取值
- agent_app_facade:6 处 l10n 空兜底改用既有 ARB 键 + resolver 兜底; 2 处 agentNativeToolsUnsupported 复用既有键 - ai_provider_factory:未配置文本/视觉/语音服务商、API 空响应等 9 处异常与探测明细走 resolver - xlsx_reader / exchange_rate_service / donation_service / update_downloader / attachment_export_import_service / category_package_service / config_export_service / local_ledger / local_repository:导入/汇率/购买/下载/归档/分类包/账本异常与 提示 ~25 处走 resolver - logger_service:日志导出头 3 行走 resolver - widget_manager:标签默认值保持现状,新增 debug 断言守卫 (非中文 locale 命中中文默认值时告警),完整参数化留待调用链专项 - ARB 新增 38 键(en+zh/zh_TW) 有意跳过(记录于审计报告):donation kMock 商品(仅开发)、 orphan_seeder 报告文案(无消费方)、同步 diff 22 处(消费端未确认)、 智谱GLM/自定义服务商(持久化配置名,应展示期本地化)、 db.dart AI对话默认值、language_provider 原生语言名(惯例)。 已知既有失败:ai_provider_factory_test 的 SSE DONE 用例在 HEAD 上 同样超时(stash 对照验证,与本次改动无关)。
GRAY 兜底改为 resolver 化后,文案随平台 locale 解析;CI runner 的 系统 locale 为英文,导致断言中文兜底文案的用例失败(Expected 查询 参数未能纠正 / Actual 英文解析结果)。 为 agent_query_regression / agent_app_facade 两个测试文件固定 TestPlatformDispatcher.localeTestValue = zh,使断言环境确定性(与 用例断言中文文案的意图一致)。resolver 同步改为读 WidgetsBinding 的 platformDispatcher(生产等价,测试可通过 localeTestValue 覆写)。 附:SSE DONE 用例超时经基线 9a269fd 复测仍失败(与本 PR 改动无关, worktree 环境因素或用例时序问题,已单独记录待查)。
纯单测(agent_message_visibility_test)直接构造 AIResponse.billCards 时,批次 2 的 resolver 兜底读取 WidgetsBinding.instance 会在未初始 化 binding 的环境下抛错——CI(offline) 307 过 1 挂即此。 - resolver 改经 _platformLocale() 取 locale:binding 已初始化时读 TestPlatformDispatcher(可用 localeTestValue 固定,测试可覆写); 纯单测退回 dart:ui 静态 - 生产行为不变(binding 恒已初始化)
死代码审计(.docs/dead-code/dead-code-audit-2026-10-10.md)确认 以下文件自 main.dart 不可达且顶层符号全仓零引用(含命名路由 字符串与同名类排除): - pages/ai/ai_model_selection_page(305) - services/data/migration_service(430) - widgets/biz/account_picker(287) - widgets/category/subcategory_container(226) - widgets/charts/balance_trend_chart(93) - cloud/sync/sync_conflict_resolver(32) - providers/credit_card_providers(32,与在用的 credit_card_reminder_providers 是两个文件) - widgets/measure_size(28) - data/repositories/repositories.dart(23,未被引用的 export barrel, 所导出仓库均经各自路径直接引用) 删除后 analyze 453 error = 既有基线,零新增。
native_tool_agent_model 的 emptyFinalText 缺省值原为硬编码『已完成。』 (批次 3 参数化时的残留)。改为:参数可空,缺省经 resolver 按语言解析 (agentEmptyFinalReply);facade 侧缺省同样走 resolver。全链不再有 硬编码中文缺省值(agentcore 包内的『完成。』缺省恒被 wrapper 覆盖, 包级清理另行处理)。
修复不一致窗口:应用内改语言(系统中文 + App 内英文)的用户,此前 会看到部分无 context 路径(冷启动提醒恢复/monitor/app_lock/xlsx/ 汇率/购买/下载/归档/分类包/config 导出/海报/日志导出头)仍出系统 语言文案,与界面语言不一致——正是用户反馈的同类问题镜像。 - resolver 增加应用内语言覆盖静态位(setAppLocaleOverride), 取值链:显式参数 > 应用内覆盖 > 系统 - languageProvider 在加载与切换语言时同步覆盖位;偏好键公开为 languagePrefKey/languagePrefCountryKey(单一事实来源) - main.dart 冷启动恢复路径直读同一组偏好键(避免与 provider 异步 加载的时序竞态),应用内覆盖在冷启动即生效 - monitor_service 等运行时路径经覆盖位自动一致,无需改动
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
摘要
全量处理英文/繁体用户反馈的未翻译问题:硬编码中文本地化(7 个提交)+ 繁体中文(zh_TW)缺失键全量补齐(235 → 0)。韩语(ko)按约定忽略。
42de183fix(qa)d225913fix(i18n)cbda608fix(i18n)2c7caf2feat(i18n)58f6ab9chore(category)20a7dfffix(i18n)718f21cfix(i18n)关键设计:无 BuildContext 场景统一走
lib/utils/app_localizations_resolver.dart(两级 locale 匹配,en 兜底);providers/facade 注入 Ref 或参数按应用内语言取文案,顶层/后台路径跟随系统语言(局限已注释);zh 文案与原硬编码逐字一致,中文用户零漂移。验收
beecount-qa-2tutsvi1,QA 包com.tntlikely.beecount.qa,Cloud 私有实例):build / preflight / transaction-copy 场景(生产 UI + App→Cloud→App 对照)/ 正常入口重启持久化 全部 PASSflutter gen-l10n通过;zh_TW 未翻译数 = 0;analyze 453 error = 既有基线(本次触及文件零 error/warning)覆盖边界
.docs/internationalization/关联 Issue
独立验收包
index.html离线查看718f21c(基线9a269fd);ZIP SHA256:93c32de058b606e505222036a232a2d6bb89272b4814f320c70c5a80fcb8e476早期附件(已被 v2 取代)
a7f72a00…)c9c627df…)