@harmonyos-arkts/d2h 0.1.11 → 0.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/.claude-plugin/marketplace.json +15 -13
  2. package/.claude-plugin/plugin.json +13 -7
  3. package/AGENTS.md +5 -5
  4. package/README.md +212 -212
  5. package/agents/android-to-hmos-00-orchestrator.md +318 -318
  6. package/agents/d2h.md +157 -157
  7. package/dist/bin/install-opencode.js +30 -30
  8. package/docs/environment-check.md +86 -86
  9. package/install-opencode.sh +160 -160
  10. package/opencode/agents.json +16 -16
  11. package/opencode/vscode-d2h-package.json +7 -7
  12. package/opencode/vscode-d2h-plugin.mjs +29 -29
  13. package/package.json +54 -54
  14. package/schemas/android-source-manifest.schema.json +25 -25
  15. package/schemas/checkpoint-provenance.schema.json +67 -67
  16. package/schemas/final-acceptance.schema.json +29 -29
  17. package/schemas/managed-evidence-index.schema.json +15 -15
  18. package/schemas/managed-evidence.schema.json +114 -114
  19. package/schemas/migration-config.schema.json +51 -51
  20. package/schemas/migration-report-index.schema.json +39 -39
  21. package/schemas/migration-report-item.schema.json +51 -51
  22. package/schemas/migration-report-summary.schema.json +25 -25
  23. package/schemas/migration-status.schema.json +202 -202
  24. package/schemas/preflight.schema.json +60 -60
  25. package/schemas/source-order-audit.schema.json +16 -16
  26. package/schemas/source-provenance-event.schema.json +19 -19
  27. package/schemas/spec-app-shard.schema.json +45 -45
  28. package/schemas/spec-fact-corrections-shard.schema.json +13 -13
  29. package/schemas/spec-features-shard.schema.json +43 -43
  30. package/schemas/spec-index.schema.json +26 -26
  31. package/schemas/spec-interactions-shard.schema.json +40 -40
  32. package/schemas/spec-page.schema.json +98 -98
  33. package/schemas/spec-pages-index.schema.json +1 -1
  34. package/schemas/spec-unresolved-shard.schema.json +1 -1
  35. package/schemas/task-envelope.schema.json +109 -109
  36. package/schemas/task-plan.schema.json +341 -341
  37. package/scripts/check-environment.mjs +320 -320
  38. package/skills/android2hmos_resources_convert/SKILL.md +180 -180
  39. package/skills/android2hmos_resources_convert/references/image-conversion-rules.md +230 -230
  40. package/skills/android2hmos_resources_convert/references/svg-fix-patterns.md +175 -175
  41. package/skills/android2hmos_resources_convert/references/xml-drawable-to-svg-rules.md +513 -513
  42. package/skills/arkts-app-identity/SKILL.md +238 -238
  43. package/skills/arkts-i18n/SKILL.md +496 -496
  44. package/skills/arkts-i18n/evals/evals.json +84 -84
  45. package/skills/arkts-i18n/references/code-examples.md +302 -302
  46. package/skills/arkts-i18n/references/common-pitfalls.md +391 -391
  47. package/skills/arkts-i18n/references/dynamic-language-switch.md +604 -604
  48. package/skills/arkts-i18n/references/hardcoded-string-scanner.md +348 -348
  49. package/skills/arkts-i18n/references/language-codes.md +104 -104
  50. package/skills/arkts-i18n/references/resource-file-structure.md +775 -775
  51. package/skills/arkts-i18n/references/static-vs-dynamic.md +242 -242
  52. package/skills/arkts-i18n/references/v1-compat.md +244 -244
  53. package/skills/arkts-i18n/scripts/audit_i18n_completeness.sh +174 -174
  54. package/skills/arkts-icon-sizing/SKILL.md +211 -211
  55. package/skills/arkts-icon-sizing/scripts/icon_audit.py +131 -131
  56. package/skills/arkts-icon-sizing/scripts/icon_autofix.py +88 -88
  57. package/skills/arkts-icon-sizing/scripts/icon_dims.py +179 -179
  58. package/skills/arkts-icon-sizing/scripts/icon_fix.py +119 -119
  59. package/skills/arkts-mvvm-architecture/SKILL.md +613 -613
  60. package/skills/d2h-hypium-forge/SKILL.md +309 -309
  61. package/skills/d2h-hypium-forge/references/functional-spec-template.md +140 -140
  62. package/skills/d2h-hypium-forge/references/official-api.md +135 -135
  63. package/skills/d2h-hypium-forge/references/pitfalls.md +98 -98
  64. package/skills/d2h-hypium-forge/references/testability-template.md +71 -71
  65. package/skills/d2h-hypium-forge/scripts/_common_template.py +659 -659
  66. package/skills/d2h-hypium-forge/scripts/analyze_results.py +165 -165
  67. package/skills/d2h-hypium-forge/scripts/assert_audit.py +107 -107
  68. package/skills/d2h-hypium-forge/scripts/collect_runtime_pages.py +169 -169
  69. package/skills/d2h-hypium-forge/scripts/forge_report.py +325 -325
  70. package/skills/d2h-hypium-forge/scripts/inject_resource_ids.py +114 -114
  71. package/skills/d2h-hypium-forge/scripts/lint_asserts.py +80 -80
  72. package/skills/d2h-hypium-forge/scripts/lint_locate.py +60 -60
  73. package/skills/d2h-hypium-forge/scripts/merge_appgraph.py +249 -249
  74. package/skills/d2h-hypium-forge/scripts/precondition.py +140 -140
  75. package/skills/d2h-hypium-forge/scripts/preinject_ids.py +232 -232
  76. package/skills/d2h-hypium-forge/scripts/probe.py +197 -197
  77. package/skills/d2h-hypium-forge/scripts/run_direct.py +823 -823
  78. package/skills/d2h-hypium-forge/scripts/run_parallel.py +121 -121
  79. package/skills/d2h-hypium-forge/scripts/scan_features.py +255 -255
  80. package/skills/d2h-hypium-forge/scripts/upgrade_asserts.py +66 -66
  81. package/skills/d2h-hypium-forge/scripts/validate_scenarios.py +84 -84
  82. package/skills/d2h-page-develop/SKILL.md +112 -112
  83. package/skills/d2h-page-develop/agents/openai.yaml +7 -7
  84. package/skills/d2h-page-spec-generate/SKILL.md +206 -206
  85. package/skills/d2h-page-spec-generate/scripts/build_batch_report.py +227 -227
  86. package/skills/d2h-utg-ai-generate/SKILL.md +128 -128
  87. package/skills/d2h-utg-ai-generate/references/click-paths-schema.json +76 -76
  88. package/skills/d2h-utg-ai-generate/references/extraction-guide.md +34 -34
  89. package/skills/d2h-utg-ai-generate/references/facts-contract.md +96 -96
  90. package/skills/d2h-utg-ai-generate/references/page-schema.json +61 -61
  91. package/skills/d2h-utg-ai-generate/references/utg-schema.json +89 -89
  92. package/skills/d2h-utg-ai-generate/scripts/build_page_json.py +314 -314
  93. package/skills/d2h-utg-ai-generate/scripts/build_utg.py +123 -123
  94. package/skills/d2h-utg-ai-generate/scripts/capture_from_page_json.ts +280 -280
  95. package/skills/d2h-utg-ai-generate/scripts/utg_common.py +524 -524
  96. package/skills/d2h-utg-ai-generate/scripts/utg_html.py +489 -489
  97. package/skills/d2h-utg-ai-generate/scripts/validate_utg.py +69 -69
  98. package/skills/d2h-utg-ai-generate/scripts/vendor/D3-LICENSE +13 -13
  99. package/skills/d2h-utg-ai-generate/scripts/vendor/d3-7.9.0.min.js +2 -2
  100. package/skills/d2h-utg-ai-generate/tests/test_pipeline.py +369 -369
  101. package/skills/d2h-utg-static-generate/SKILL.md +73 -73
  102. package/skills/d2h-utg-static-generate/references/discoveries.md +38 -38
  103. package/skills/d2h-utg-static-generate/scripts/generate.py +499 -499
  104. package/skills/d2h-utg-static-generate/tests/test_static.py +335 -335
  105. package/skills/d2h-utg-static-generate/tests/verify-offline-html.py +60 -60
  106. package/skills/d2h-utg-static-generate/tests/verify-produced-fixture.py +131 -131
  107. package/skills/harmonyos-migration-playbook/SKILL.md +83 -83
  108. package/skills/harmonyos-migration-playbook/agents/openai.yaml +7 -7
  109. package/skills/harmonyos-migration-playbook/references/arkts-compile.md +24 -24
  110. package/skills/harmonyos-migration-playbook/references/harmony-runtime.md +53 -53
  111. package/skills/harmonyos-migration-playbook/references/lesson-lifecycle.md +45 -45
  112. package/skills/harmonyos-migration-playbook/references/protocol-e2e.md +23 -23
  113. package/skills/harmonyos-migration-playbook/references/ui-automation.md +53 -53
  114. package/skills/harmonyos-migration-playbook/references/windows-environment.md +38 -38
  115. package/skills/maintaining-migration-report/SKILL.md +144 -144
  116. package/skills/maintaining-migration-report/references/final-acceptance.md +48 -48
  117. package/skills/maintaining-migration-report/references/source-provenance.md +66 -66
  118. package/skills/managing-d2h-toolchain/SKILL.md +24 -24
  119. package/skills/managing-d2h-toolchain/environment-requirements.json +16 -16
  120. package/skills/managing-d2h-toolchain/scripts/manage-toolchain.mjs +98 -98
  121. package/skills/managing-d2h-toolchain/toolchain.json +16 -16
  122. package/skills/native-library-substitution/SKILL.md +384 -384
  123. package/skills/native-library-substitution/references/native-library-substitution.json +56905 -56905
  124. package/skills/native-library-substitution/references/native-library-substitution.md +163 -163
  125. package/skills/preparing-migration-workspace/SKILL.md +131 -131
  126. package/skills/reviewing-migration-process/SKILL.md +62 -62
@@ -1,242 +1,242 @@
1
- # 纯静态 vs 动态语言切换方案
2
-
3
- > 基于代码仓实际实现的方案对比分析
4
-
5
- ---
6
-
7
- ## ✅ 已验证:纯静态国际化方案
8
-
9
- > 基于代码仓实际实现(95%+ 使用静态引用,无动态语言切换)
10
-
11
- ### 方案特点
12
-
13
- **代码仓实践**:
14
- - ✅ 依赖系统语言自动匹配
15
- - ✅ 95%+ 使用 `$r('app.string.xxx')` 静态引用(270+ 处)
16
- - ✅ 少数场景使用 `resourceManager.getStringByNameSync()` 动态获取
17
- - ❌ 未实现运行时语言切换
18
- - ⚠️ module.json5 未配置 `supportedLanguages`
19
-
20
- **优点**:
21
- - ✅ 实现简单,无需复杂状态管理
22
- - ✅ 性能最优(编译时确定资源路径)
23
- - ✅ 自动跟随系统语言,用户无感知
24
- - ✅ 代码量少,维护成本低
25
-
26
- **缺点**:
27
- - ⚠️ 无法在应用内动态切换语言
28
- - ⚠️ 用户需要通过系统设置更改语言
29
- - ⚠️ 需要重启应用才能看到语言变化
30
-
31
- ### 适用场景
32
-
33
- | 场景 | 是否适用 | 说明 |
34
- |------|---------|------|
35
- | 跟随系统语言 | ✅ 推荐 | 无需额外开发,自动适配 |
36
- | 单一市场应用 | ✅ 推荐 | 简化实现,降低复杂度 |
37
- | 国际化应用(无切换需求)| ✅ 推荐 | 依赖系统设置即可 |
38
- | 需要应用内切换语言 | ❌ 不适用 | 需实现动态方案 |
39
- | 需要记住用户语言偏好 | ❌ 不适用 | 需实现状态持久化 |
40
-
41
- ---
42
-
43
- ## 实现要点
44
-
45
- ### 1. 资源文件组织
46
-
47
- **方案 1:base/ 放中文**(代码仓采用,适合单一市场)
48
-
49
- ```
50
- entry/src/main/resources/
51
- ├── base/element/string.json # 中文(主要市场)
52
- └── en_US/element/string.json # 英文
53
- ```
54
-
55
- **工作原理**:
56
- - 系统中文 → 找不到 zh 目录 → 使用 base/ → 显示中文 ✅
57
- - 系统英文 → 找到 en_US → 显示英文 ✅
58
-
59
- **方案 2:创建 zh_CN 目录**(标准做法,适合国际化应用)
60
-
61
- ```
62
- entry/src/main/resources/
63
- ├── base/element/string.json # Fallback(英文或其他)
64
- ├── zh_CN/element/string.json # 中文
65
- └── en_US/element/string.json # 英文
66
- ```
67
-
68
- **工作原理**:
69
- - 系统中文 → 找到 zh_CN → 显示中文 ✅
70
- - 系统英文 → 找到 en_US → 显示英文 ✅
71
- - 其他语言 → 无匹配 → 使用 base/ → 显示 Fallback 语言 ✅
72
-
73
- **关键规范**:
74
- - ✅ base/ 和 en_US/(或 zh_CN/)的 string.json **行数完全一致**
75
- - ✅ 所有字符串 key 在不同语言文件中**完全对应**
76
- - ✅ 使用 `en_US/` 而非 `en/`(精确区域划分)
77
-
78
- ### 2. 静态资源引用(主流方式,95%+)
79
-
80
- **使用场景**:Button 文本、Text 标签、Title 标题等固定文本
81
-
82
- ```typescript
83
- // ✅ 推荐:在 build() 中使用静态引用
84
- Text($r('app.string.app_name'))
85
- Button($r('app.string.confirm'))
86
- .title($r('app.string.settings_title'))
87
- Image($r('app.media.logo'))
88
- ```
89
-
90
- **工作原理**:
91
- 1. 编译时扫描所有 `$r()` 引用
92
- 2. 根据系统语言自动选择资源文件:
93
- - 中文环境 → `base/element/string.json`
94
- - 英文环境 → `en_US/element/string.json`
95
- 3. 运行时自动加载匹配的资源
96
-
97
- ### 3. 动态资源获取(少数场景,<5%)
98
-
99
- **使用场景**:需要动态处理字符串(如占位符替换、复数处理)
100
-
101
- ```typescript
102
- // ✅ 基于代码仓 ColumnsDialog.ets:22
103
- const context = getContext(this)
104
- const resourceManager = context.resourceManager
105
- const str = resourceManager.getStringByNameSync('dialog_column')
106
- ```
107
-
108
- **何时使用**:
109
- - 需要替换占位符(如 `"%d 列"` → `"3 列"`)
110
- - 需要处理复数(如 `"1 column"` vs `"2 columns"`)
111
- - 需要根据字符串内容判断语言环境
112
-
113
- ### 4. module.json5 配置(可选)
114
-
115
- ```json5
116
- {
117
- "module": {
118
- "name": "entry",
119
- "type": "entry",
120
- "description": "$string:module_desc", // ✅ 使用 $string 引用
121
- "abilities": [
122
- {
123
- "name": "EntryAbility",
124
- "description": "$string:EntryAbility_desc",
125
- "label": "$string:EntryAbility_label"
126
- }
127
- ]
128
- // ⚠️ 当前代码仓未配置 supportedLanguages
129
- // 如需配置,可添加:
130
- // "supportedLanguages": ["zh-Hans", "en"]
131
- }
132
- }
133
- ```
134
-
135
- **配置说明**:
136
- - ✅ `description` 和 `label` 也支持 `$string` 引用
137
- - ⚠️ `supportedLanguages` 不是必需字段(当前代码仓未配置)
138
- - 💡 配置后可明确告知系统应用支持的语言
139
-
140
- ---
141
-
142
- ## 对比动态语言切换方案
143
-
144
- | 特性 | 纯静态方案 | 动态切换方案 |
145
- |------|-----------|------------|
146
- | **实现复杂度** | ✅ 低(仅资源文件) | ⚠️ 高(需状态管理 + UI 刷新) |
147
- | **性能** | ✅ 最优(编译时确定) | ⚠️ 中等(运行时切换) |
148
- | **用户体验** | ✅ 一致(自动跟随系统) | ⚠️ 需手动切换 |
149
- | **维护成本** | ✅ 低 | ⚠️ 高 |
150
- | **适用场景** | ✅ 大多数应用 | ⚠️ 特殊需求(如学习类应用) |
151
- | **代码量** | ✅ 少(仅配置) | ⚠️ 多(需实现切换逻辑) |
152
-
153
- ---
154
-
155
- ## 当前代码仓选择分析
156
-
157
- **选择方案**:纯静态方案 + `en_US/` 目录
158
-
159
- **选择原因**:
160
-
161
- 1. **简单可靠**
162
- - ✅ 无需维护复杂的状态管理
163
- - ✅ 自动跟随系统语言,用户无感知
164
- - ✅ 代码量少,维护成本低
165
-
166
- 2. **性能最优**
167
- - ✅ 编译时确定资源路径
168
- - ✅ 无运行时语言切换开销
169
- - ✅ 资源加载效率高
170
-
171
- 3. **需求匹配**
172
- - ✅ 代码仓只需支持中英文
173
- - ✅ 无应用内切换语言需求
174
- - ✅ 跟随系统语言即可满足需求
175
-
176
- **使用 `en_US/` 而非 `en/` 的原因**:
177
-
178
- | 方案 | 优点 | 缺点 | 代码仓选择 |
179
- |------|------|------|-----------|
180
- | `en/` | 简单,适配所有英文区域 | 无法区分不同区域(US/GB/AU) | ❌ 未选择 |
181
- | `en_US/` | 精确区域划分,可扩展 | 目录稍多 | ✅ 已选择 |
182
-
183
- **结论**:
184
- - ✅ 代码仓选择 `en_US/` 是为了精确区域划分和未来扩展性
185
- - ✅ 纯静态方案满足当前需求,无需引入动态切换的复杂性
186
- - 💡 如果未来需要动态切换,可参考 `dynamic-language-switch.md` 实现
187
-
188
- ---
189
-
190
- ## ⚠️ 未验证:动态语言切换
191
-
192
- 以下代码基于 HarmonyOS 理论 API,需要查证官方文档:
193
-
194
- ```typescript
195
- import { resourceManager } from '@kit.LocalizationKit'
196
- import { common } from '@kit.AbilityKit'
197
-
198
- // ⚠️ 未验证 - 需要确认 API 是否存在
199
- async function switchLanguage(lang: string): Promise<void> {
200
- try {
201
- const context = getContext(this) as common.UIAbilityContext
202
- const resMgr = context.resourceManager
203
-
204
- // ⚠️ 以下两个 API 需要查证官方文档
205
- await resMgr.setPreferredLanguage([lang])
206
- const langs = await resMgr.getPreferredLanguage()
207
-
208
- console.log(`Switched to: ${langs[0]}`)
209
- } catch (err) {
210
- console.error(`Failed to switch language: ${err}`)
211
- }
212
- }
213
- ```
214
-
215
- **替代方案**(如 API 不存在):
216
- - 方案 1:引导用户到系统设置修改语言
217
- - 方案 2:应用内维护语言状态,手动切换资源
218
-
219
- ---
220
-
221
- ## ✅ 已验证:资源文件结构
222
-
223
- 基于 `entry/src/main/resources/` 目录结构:
224
-
225
- ```
226
- resources/
227
- ├── base/
228
- │ └── element/
229
- │ └── string.json # 中文(996 行)
230
- ├── en_US/
231
- │ └── element/
232
- │ └── string.json # 英文(996 行)
233
- ├── dark/
234
- │ └── element/
235
- │ └── color.json # 深色模式颜色
236
- └── rawfile/ # 原始文件
237
- ```
238
-
239
- **验证结果**:
240
- - ✅ base 和 en_US 的 string.json 行数一致(996 行)
241
- - ✅ 两个文件的 key 完全对应
242
- - ✅ 使用 en_US 而非 en(精确区域划分)
1
+ # 纯静态 vs 动态语言切换方案
2
+
3
+ > 基于代码仓实际实现的方案对比分析
4
+
5
+ ---
6
+
7
+ ## ✅ 已验证:纯静态国际化方案
8
+
9
+ > 基于代码仓实际实现(95%+ 使用静态引用,无动态语言切换)
10
+
11
+ ### 方案特点
12
+
13
+ **代码仓实践**:
14
+ - ✅ 依赖系统语言自动匹配
15
+ - ✅ 95%+ 使用 `$r('app.string.xxx')` 静态引用(270+ 处)
16
+ - ✅ 少数场景使用 `resourceManager.getStringByNameSync()` 动态获取
17
+ - ❌ 未实现运行时语言切换
18
+ - ⚠️ module.json5 未配置 `supportedLanguages`
19
+
20
+ **优点**:
21
+ - ✅ 实现简单,无需复杂状态管理
22
+ - ✅ 性能最优(编译时确定资源路径)
23
+ - ✅ 自动跟随系统语言,用户无感知
24
+ - ✅ 代码量少,维护成本低
25
+
26
+ **缺点**:
27
+ - ⚠️ 无法在应用内动态切换语言
28
+ - ⚠️ 用户需要通过系统设置更改语言
29
+ - ⚠️ 需要重启应用才能看到语言变化
30
+
31
+ ### 适用场景
32
+
33
+ | 场景 | 是否适用 | 说明 |
34
+ |------|---------|------|
35
+ | 跟随系统语言 | ✅ 推荐 | 无需额外开发,自动适配 |
36
+ | 单一市场应用 | ✅ 推荐 | 简化实现,降低复杂度 |
37
+ | 国际化应用(无切换需求)| ✅ 推荐 | 依赖系统设置即可 |
38
+ | 需要应用内切换语言 | ❌ 不适用 | 需实现动态方案 |
39
+ | 需要记住用户语言偏好 | ❌ 不适用 | 需实现状态持久化 |
40
+
41
+ ---
42
+
43
+ ## 实现要点
44
+
45
+ ### 1. 资源文件组织
46
+
47
+ **方案 1:base/ 放中文**(代码仓采用,适合单一市场)
48
+
49
+ ```
50
+ entry/src/main/resources/
51
+ ├── base/element/string.json # 中文(主要市场)
52
+ └── en_US/element/string.json # 英文
53
+ ```
54
+
55
+ **工作原理**:
56
+ - 系统中文 → 找不到 zh 目录 → 使用 base/ → 显示中文 ✅
57
+ - 系统英文 → 找到 en_US → 显示英文 ✅
58
+
59
+ **方案 2:创建 zh_CN 目录**(标准做法,适合国际化应用)
60
+
61
+ ```
62
+ entry/src/main/resources/
63
+ ├── base/element/string.json # Fallback(英文或其他)
64
+ ├── zh_CN/element/string.json # 中文
65
+ └── en_US/element/string.json # 英文
66
+ ```
67
+
68
+ **工作原理**:
69
+ - 系统中文 → 找到 zh_CN → 显示中文 ✅
70
+ - 系统英文 → 找到 en_US → 显示英文 ✅
71
+ - 其他语言 → 无匹配 → 使用 base/ → 显示 Fallback 语言 ✅
72
+
73
+ **关键规范**:
74
+ - ✅ base/ 和 en_US/(或 zh_CN/)的 string.json **行数完全一致**
75
+ - ✅ 所有字符串 key 在不同语言文件中**完全对应**
76
+ - ✅ 使用 `en_US/` 而非 `en/`(精确区域划分)
77
+
78
+ ### 2. 静态资源引用(主流方式,95%+)
79
+
80
+ **使用场景**:Button 文本、Text 标签、Title 标题等固定文本
81
+
82
+ ```typescript
83
+ // ✅ 推荐:在 build() 中使用静态引用
84
+ Text($r('app.string.app_name'))
85
+ Button($r('app.string.confirm'))
86
+ .title($r('app.string.settings_title'))
87
+ Image($r('app.media.logo'))
88
+ ```
89
+
90
+ **工作原理**:
91
+ 1. 编译时扫描所有 `$r()` 引用
92
+ 2. 根据系统语言自动选择资源文件:
93
+ - 中文环境 → `base/element/string.json`
94
+ - 英文环境 → `en_US/element/string.json`
95
+ 3. 运行时自动加载匹配的资源
96
+
97
+ ### 3. 动态资源获取(少数场景,<5%)
98
+
99
+ **使用场景**:需要动态处理字符串(如占位符替换、复数处理)
100
+
101
+ ```typescript
102
+ // ✅ 基于代码仓 ColumnsDialog.ets:22
103
+ const context = getContext(this)
104
+ const resourceManager = context.resourceManager
105
+ const str = resourceManager.getStringByNameSync('dialog_column')
106
+ ```
107
+
108
+ **何时使用**:
109
+ - 需要替换占位符(如 `"%d 列"` → `"3 列"`)
110
+ - 需要处理复数(如 `"1 column"` vs `"2 columns"`)
111
+ - 需要根据字符串内容判断语言环境
112
+
113
+ ### 4. module.json5 配置(可选)
114
+
115
+ ```json5
116
+ {
117
+ "module": {
118
+ "name": "entry",
119
+ "type": "entry",
120
+ "description": "$string:module_desc", // ✅ 使用 $string 引用
121
+ "abilities": [
122
+ {
123
+ "name": "EntryAbility",
124
+ "description": "$string:EntryAbility_desc",
125
+ "label": "$string:EntryAbility_label"
126
+ }
127
+ ]
128
+ // ⚠️ 当前代码仓未配置 supportedLanguages
129
+ // 如需配置,可添加:
130
+ // "supportedLanguages": ["zh-Hans", "en"]
131
+ }
132
+ }
133
+ ```
134
+
135
+ **配置说明**:
136
+ - ✅ `description` 和 `label` 也支持 `$string` 引用
137
+ - ⚠️ `supportedLanguages` 不是必需字段(当前代码仓未配置)
138
+ - 💡 配置后可明确告知系统应用支持的语言
139
+
140
+ ---
141
+
142
+ ## 对比动态语言切换方案
143
+
144
+ | 特性 | 纯静态方案 | 动态切换方案 |
145
+ |------|-----------|------------|
146
+ | **实现复杂度** | ✅ 低(仅资源文件) | ⚠️ 高(需状态管理 + UI 刷新) |
147
+ | **性能** | ✅ 最优(编译时确定) | ⚠️ 中等(运行时切换) |
148
+ | **用户体验** | ✅ 一致(自动跟随系统) | ⚠️ 需手动切换 |
149
+ | **维护成本** | ✅ 低 | ⚠️ 高 |
150
+ | **适用场景** | ✅ 大多数应用 | ⚠️ 特殊需求(如学习类应用) |
151
+ | **代码量** | ✅ 少(仅配置) | ⚠️ 多(需实现切换逻辑) |
152
+
153
+ ---
154
+
155
+ ## 当前代码仓选择分析
156
+
157
+ **选择方案**:纯静态方案 + `en_US/` 目录
158
+
159
+ **选择原因**:
160
+
161
+ 1. **简单可靠**
162
+ - ✅ 无需维护复杂的状态管理
163
+ - ✅ 自动跟随系统语言,用户无感知
164
+ - ✅ 代码量少,维护成本低
165
+
166
+ 2. **性能最优**
167
+ - ✅ 编译时确定资源路径
168
+ - ✅ 无运行时语言切换开销
169
+ - ✅ 资源加载效率高
170
+
171
+ 3. **需求匹配**
172
+ - ✅ 代码仓只需支持中英文
173
+ - ✅ 无应用内切换语言需求
174
+ - ✅ 跟随系统语言即可满足需求
175
+
176
+ **使用 `en_US/` 而非 `en/` 的原因**:
177
+
178
+ | 方案 | 优点 | 缺点 | 代码仓选择 |
179
+ |------|------|------|-----------|
180
+ | `en/` | 简单,适配所有英文区域 | 无法区分不同区域(US/GB/AU) | ❌ 未选择 |
181
+ | `en_US/` | 精确区域划分,可扩展 | 目录稍多 | ✅ 已选择 |
182
+
183
+ **结论**:
184
+ - ✅ 代码仓选择 `en_US/` 是为了精确区域划分和未来扩展性
185
+ - ✅ 纯静态方案满足当前需求,无需引入动态切换的复杂性
186
+ - 💡 如果未来需要动态切换,可参考 `dynamic-language-switch.md` 实现
187
+
188
+ ---
189
+
190
+ ## ⚠️ 未验证:动态语言切换
191
+
192
+ 以下代码基于 HarmonyOS 理论 API,需要查证官方文档:
193
+
194
+ ```typescript
195
+ import { resourceManager } from '@kit.LocalizationKit'
196
+ import { common } from '@kit.AbilityKit'
197
+
198
+ // ⚠️ 未验证 - 需要确认 API 是否存在
199
+ async function switchLanguage(lang: string): Promise<void> {
200
+ try {
201
+ const context = getContext(this) as common.UIAbilityContext
202
+ const resMgr = context.resourceManager
203
+
204
+ // ⚠️ 以下两个 API 需要查证官方文档
205
+ await resMgr.setPreferredLanguage([lang])
206
+ const langs = await resMgr.getPreferredLanguage()
207
+
208
+ console.log(`Switched to: ${langs[0]}`)
209
+ } catch (err) {
210
+ console.error(`Failed to switch language: ${err}`)
211
+ }
212
+ }
213
+ ```
214
+
215
+ **替代方案**(如 API 不存在):
216
+ - 方案 1:引导用户到系统设置修改语言
217
+ - 方案 2:应用内维护语言状态,手动切换资源
218
+
219
+ ---
220
+
221
+ ## ✅ 已验证:资源文件结构
222
+
223
+ 基于 `entry/src/main/resources/` 目录结构:
224
+
225
+ ```
226
+ resources/
227
+ ├── base/
228
+ │ └── element/
229
+ │ └── string.json # 中文(996 行)
230
+ ├── en_US/
231
+ │ └── element/
232
+ │ └── string.json # 英文(996 行)
233
+ ├── dark/
234
+ │ └── element/
235
+ │ └── color.json # 深色模式颜色
236
+ └── rawfile/ # 原始文件
237
+ ```
238
+
239
+ **验证结果**:
240
+ - ✅ base 和 en_US 的 string.json 行数一致(996 行)
241
+ - ✅ 两个文件的 key 完全对应
242
+ - ✅ 使用 en_US 而非 en(精确区域划分)