/// ============================================================ /// 闲言APP — 多语言(i18n)升级开发文档 v2.0 /// 创建时间: 2026-05-19 /// 更新时间: 2026-05-19 /// 作用: 记录i18n系统问题诊断、升级方案、实施进度和归档验收 /// 上次更新: P0-P3全部完成,归档验收勾选 /// ============================================================ /// /// # 多语言(i18n)升级开发文档 v2.0 /// /// ## 一、问题诊断与优先级 /// /// | 优先级 | 问题 | 影响 | 状态 | /// |--------|------|------|------| /// | 🔴 P0 | 阿拉伯语RTL支持缺失 | 阿拉伯语完全不可用 | ✅ 已修复 | /// | 🔴 P0 | 系统语言变化不监听 | "跟随系统"名不副实 | ✅ 已修复 | /// | 🟡 P1 | T类130+参数不可维护 | 新增字段改动量巨大 | ✅ 已修复 | /// | 🟡 P1 | 无参数化翻译/复数 | 动态内容无法翻译 | ✅ 已修复 | /// | 🟡 P1 | 无翻译fallback机制 | 缺失翻译显示空白 | ✅ 已修复 | /// | 🟢 P2 | 日期/数字格式化未联动 | 体验不完整 | ✅ 已修复 | /// | 🟢 P2 | 翻译覆盖率无检测 | 协同翻译缺数据支撑 | ✅ 已修复 | /// | 🟢 P2 | 协同翻译是空壳 | 无法协作翻译 | ✅ 已修复 | /// | 🟢 P2 | localizationDelegates不完整 | Cupertino组件不跟随语言 | ✅ 已修复 | /// | 🔵 P3 | 语言切换动画 | 体验优化 | ✅ 已修复 | /// | 🔵 P3 | 更多语言支持(印地/葡/俄/法) | 市场扩展 | ✅ 已修复 | /// /// ## 二、升级方案与实施 /// /// ### 2.1 ✅ P0: 阿拉伯语RTL支持 /// **方案**: AppLocale增加isRTL/textDirection属性,appLocaleProvider增加appTextDirectionProvider, /// app.dart用Directionality包裹ScreenUtilInit /// **文件**: app_locale.dart, app.dart /// **实现**: /// - `_rtlLanguageCodes = {'ar', 'he', 'fa', 'ur'}` 常量定义 /// - `AppLocale.isRTL` getter 判断当前语言是否RTL /// - `AppLocale.textDirection` getter 返回 TextDirection.rtl/ltr /// - `appTextDirectionProvider` Riverpod Provider,监听设置变化 /// - `app.dart` 外层 `Directionality(textDirection: textDirection, child: ScreenUtilInit(...))` /// - 语言列表中阿拉伯语显示 RTL 标签 /// /// ### 2.2 ✅ P0: 系统语言变化监听 /// **方案**: _XianyanAppState增加didChangeLocales回调, /// 通过SystemLocaleVersionNotifier触发Provider刷新 /// **文件**: app.dart, app_locale.dart /// **实现**: /// - `SystemLocaleVersionNotifier extends Notifier` (Riverpod 3.0 不支持 StateProvider) /// - `systemLocaleVersionProvider` NotifierProvider /// - `appLocaleProvider` 和 `appTextDirectionProvider` 都 `ref.watch(systemLocaleVersionProvider)` /// - `didChangeLocales` 回调调用 `ref.read(systemLocaleVersionProvider.notifier).increment()` /// /// ### 2.3 ✅ P1: T类拆分分组 /// **方案**: T类改为组合模式,内含TNav/TSettings/TCommon/TProfile子类 /// 访问方式: t.nav.home / t.settings.language / t.common.cancel /// **文件**: translations.dart /// **实现**: /// - TNav(3字段): home/discover/profile /// - TCommon(16字段): cancel/ok/save/confirm/clear/reset/delete/success/failed/enabled/disabled/loading/view/search/entriesCountUnit/copyright /// - TProfile(25字段): title/myFavorites/readingHistory/darkMode/... /// - TSettings(100字段): language/generalSettings/interaction/sound/... /// - T类保留144个@Deprecated getter向后兼容 /// - 7种语言常量全部更新为新构造函数 /// /// ### 2.4 ✅ P1: 参数化翻译 /// **方案**: 增加TFunc类,提供带参数的翻译方法 /// **文件**: translations.dart /// **实现**: /// - `TFunc` 类,构造函数接收 `_langId` /// - `entriesCount(int count)` → "3 条" / "3 entries" / "3件" /// - `greeting(String name)` → "你好,张三" / "Hello, 张三" /// - `itemsSelected(int count)` → "已选3项" / "3 selected" /// - `pluralItems(int count)` → 使用 Intl.plural 处理复数 /// - `translationsFuncProvider` Riverpod Provider /// /// ### 2.5 ✅ P1: 翻译fallback /// **方案**: T类增加T.withFallback静态方法 /// **文件**: translations.dart /// **实现**: /// - `T.withFallback(T target, T fallback)` — 将fallback中非空字段覆盖target空字段 /// - 新增语言时可先创建部分翻译,缺失字段自动回退到zh_CN /// /// ### 2.6 ✅ P2: 日期/数字格式化 /// **方案**: 增加localeFormatProvider,基于当前locale提供DateFormat/NumberFormat /// **文件**: app_locale.dart /// **实现**: /// - `localeDateFormatProvider` → `DateFormat.yMMMd(locale.toLanguageTag())` /// - `localeNumberFormatProvider` → `NumberFormat.decimalPattern(locale.toLanguageTag())` /// - 使用项目已有的 `intl: ^0.20.2` 依赖 /// /// ### 2.7 ✅ P2: 翻译覆盖率检测 /// **方案**: TranslationCoverage工具类 + 语言设置页面覆盖率面板 /// **文件**: translations.dart, language_settings_page.dart /// **实现**: /// - `TranslationCoverage.checkAll()` → `Map` 各语言已翻译字段数 /// - `TranslationCoverage.checkCoverage(T target, T reference)` → 缺失字段列表 /// - `TranslationCoverage.totalFieldCount` → 总字段数 /// - 语言设置页底部显示覆盖率进度条(绿色100%/accent色<100%) /// /// ### 2.8 ✅ P2: 协同翻译功能 /// **方案**: 导出翻译为JSON到剪贴板,CupertinoActionSheet操作面板 /// **文件**: translation_io_service.dart, language_settings_page.dart /// **实现**: /// - `TranslationIOService.exportToJson(T t)` → 当前语言JSON /// - `TranslationIOService.exportAllToJson()` → 全部7种语言JSON /// - `TranslationIOService.validateTranslationJson(String)` → 验证JSON格式 /// - 协同翻译按钮点击弹出ActionSheet: Export Current / Export All Languages /// - 导出后自动复制到剪贴板 + 成功Toast /// /// ### 2.9 ✅ P2: localizationDelegates补全 /// **方案**: 添加GlobalCupertinoLocalizations.delegate /// **文件**: app.dart /// **实现**: /// - `_localizationsDelegates` 常量包含5个delegate /// - GlobalMaterialLocalizations + GlobalWidgetsLocalizations + GlobalCupertinoLocalizations + DefaultCupertinoLocalizations + FlutterQuillLocalizations /// - 鸿蒙端和非鸿蒙端统一使用 /// /// ## 三、归档验收清单 /// /// | # | 验收项 | 优先级 | 状态 | /// |---|--------|--------|------| /// | 1 | 阿拉伯语切换后界面RTL布局正确 | P0 | ✅ | /// | 2 | 系统切换语言后APP自动跟随(无需重启) | P0 | ✅ | /// | 3 | T类分组后所有现有翻译字段仍可访问 | P1 | ✅ | /// | 4 | 参数化翻译(如"3条")正确显示各语言 | P1 | ✅ | /// | 5 | 新增语言缺少翻译时fallback到中文 | P1 | ✅ | /// | 6 | 日期格式随语言切换(中文→日语→英语) | P2 | ✅ | /// | 7 | 调试面板可查看各语言翻译覆盖率 | P2 | ✅ | /// | 8 | 协同翻译可导出JSON到剪贴板 | P2 | ✅ | /// | 9 | Cupertino组件(如DatePicker)跟随语言 | P2 | ✅ | /// | 10 | flutter analyze 零错误(仅info级lint) | P0 | ✅ | /// /// ## 四、P3 实施记录 /// /// ### 4.1 ✅ P3: 语言切换动画 /// **方案**: _LocaleTransitionWrapper组件,监听locale变化触发淡入淡出 /// **文件**: app.dart /// **实现**: /// - `_LocaleTransitionWrapper extends StatefulWidget` + `SingleTickerProviderStateMixin` /// - `AnimationController` 300ms duration /// - `didUpdateWidget` 检测 `oldWidget.locale != widget.locale` /// - `AnimatedBuilder` + `Opacity` 包裹子组件 /// - 尊重 `settings.animationEnabled` 开关 /// /// ### 4.2 ✅ P3: 更多语言支持 /// **方案**: AppLocale枚举增加4种语言 + translations.dart增加4种翻译常量 /// **文件**: app_locale.dart, translations.dart /// **实现**: /// - hi(印地语): हिन्दी, 天城文书写 /// - pt(葡萄牙语): Português, 拉丁字母 /// - ru(俄语): Русский, 西里尔字母 /// - fr(法语): Français, 拉丁字母 /// - 共11种语言 + 跟随系统 /// /// ### 4.3 ✅ P3: 翻译导入功能 /// **方案**: TranslationIOService.importFromJson() + CupertinoAlertDialog输入框 /// **文件**: translation_io_service.dart, language_settings_page.dart /// **实现**: /// - `importFromJson(String jsonStr, T fallback)` → 解析JSON+fallback缺失字段 /// - `_importNav/_importCommon/_importProfile/_importSettings` 私有方法 /// - 协同翻译ActionSheet增加"Import Translation"选项 /// - CupertinoTextField 6行输入框 + 验证 + 错误提示 /// /// ### 4.4 ✅ P3: 语言智能排序 /// **方案**: AppLocale.smartSorted(),根据系统语言计算相关性分数排序 /// **文件**: app_locale.dart, language_settings_page.dart /// **实现**: /// - `smartSorted()` 静态方法 /// - `_relevanceScore()` 计算分数: 匹配语言+国家100/匹配语言80/中文50/英文40/其他20 /// - 语言设置页使用 `AppLocale.smartSorted()` 替代 `AppLocale.selectable` /// /// ## 五、归档验收清单(完整) /// /// | # | 验收项 | 优先级 | 状态 | /// |---|--------|--------|------| /// | 1 | 阿拉伯语切换后界面RTL布局正确 | P0 | ✅ | /// | 2 | 系统切换语言后APP自动跟随(无需重启) | P0 | ✅ | /// | 3 | T类分组后所有现有翻译字段仍可访问 | P1 | ✅ | /// | 4 | 参数化翻译(如"3条")正确显示各语言 | P1 | ✅ | /// | 5 | 新增语言缺少翻译时fallback到中文 | P1 | ✅ | /// | 6 | 日期格式随语言切换(中文→日语→英语) | P2 | ✅ | /// | 7 | 调试面板可查看各语言翻译覆盖率 | P2 | ✅ | /// | 8 | 协同翻译可导出JSON到剪贴板 | P2 | ✅ | /// | 9 | Cupertino组件(如DatePicker)跟随语言 | P2 | ✅ | /// | 10 | flutter analyze 零错误(仅info级lint) | P0 | ✅ | /// | 11 | 语言切换时有淡入淡出过渡动画 | P3 | ✅ | /// | 12 | 支持11种语言+跟随系统 | P3 | ✅ | /// | 13 | 翻译导入功能可粘贴JSON导入 | P3 | ✅ | /// | 14 | 语言列表按系统语言智能排序 | P3 | ✅ | /// /// ## 六、文件变更追踪 /// /// | 文件 | 变更类型 | 说明 | /// |------|----------|------| /// | lib/l10n/app_locale.dart | 修改 | isRTL/textDirection/SystemLocaleVersionNotifier/appTextDirectionProvider/localeDateFormatProvider/localeNumberFormatProvider | /// | lib/l10n/translations.dart | 重构 | TNav/TCommon/TProfile/TSettings子类+TFunc+TranslationCoverage+144个@Deprecated getter | /// | lib/l10n/translation_io_service.dart | 新增 | 翻译导出/导入/验证服务 | /// | lib/app/app.dart | 修改 | Directionality+didChangeLocales+GlobalCupertinoLocalizations+_localizationsDelegates常量 | /// | lib/features/settings/presentation/language_settings_page.dart | 修改 | 协同翻译ActionSheet+覆盖率面板+RTL标识+t.nav/t.common/t.settings分组 | /// | docs/i18n_dev_doc.dart | 修改 | 开发文档v2.0 | /// | CHANGELOG.md | 修改 | v14.16.0版本记录 |