generator-mico-cli 0.2.28 → 0.2.29

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 (56) hide show
  1. package/README.md +5 -20
  2. package/bin/mico.js +27 -62
  3. package/generators/micro-react/index.js +8 -0
  4. package/generators/micro-react/templates/.cursor/rules/always-read-docs.mdc +3 -0
  5. package/generators/micro-react/templates/.cursor/rules/project-overview.mdc +1 -0
  6. package/generators/micro-react/templates/CLAUDE.md +1 -0
  7. package/generators/micro-react/templates/README.md +1 -1
  8. package/generators/micro-react/templates/apps/layout/config/config.dev.ts +4 -2
  9. package/generators/micro-react/templates/apps/layout/config/config.prod.development.ts +2 -0
  10. package/generators/micro-react/templates/apps/layout/config/config.prod.testing.ts +2 -0
  11. package/generators/micro-react/templates/apps/layout/config/config.prod.ts +2 -0
  12. package/generators/micro-react/templates/apps/layout/docs/feature-PermissionFilter/346/214/211/351/222/256/346/235/203/351/231/220.md +116 -0
  13. package/generators/micro-react/templates/apps/layout/docs/feature-/350/217/234/345/215/225/346/235/203/351/231/220/346/216/247/345/210/266.md +83 -77
  14. package/generators/micro-react/templates/apps/layout/docs/feature-/350/267/257/347/224/261/344/270/216/350/217/234/345/215/225/350/247/243/350/200/246.md +50 -35
  15. package/generators/micro-react/templates/apps/layout/docs/feature-/350/267/257/347/224/261/346/235/203/351/231/220/346/227/245/345/277/227.md +162 -0
  16. package/generators/micro-react/templates/apps/layout/mock/api.mock.ts +23 -31
  17. package/generators/micro-react/templates/apps/layout/mock/pages.ts +5 -6
  18. package/generators/micro-react/templates/apps/layout/package.json +2 -1
  19. package/generators/micro-react/templates/apps/layout/src/app.tsx +30 -2
  20. package/generators/micro-react/templates/apps/layout/src/common/auth/type.ts +15 -27
  21. package/generators/micro-react/templates/apps/layout/src/common/menu/parser.ts +148 -85
  22. package/generators/micro-react/templates/apps/layout/src/common/menu/types.ts +2 -6
  23. package/generators/micro-react/templates/apps/layout/src/common/portal-data.ts +46 -2
  24. package/generators/micro-react/templates/apps/layout/src/components/MicroAppLoader/index.tsx +5 -1
  25. package/generators/micro-react/templates/apps/layout/src/components/PermissionFilter/index.tsx +51 -0
  26. package/generators/micro-react/templates/apps/layout/src/components/RightContent/AvatarDropdown.tsx +10 -1
  27. package/generators/micro-react/templates/apps/layout/src/layouts/components/menu/index.tsx +3 -3
  28. package/generators/micro-react/templates/apps/layout/src/layouts/index.tsx +105 -60
  29. package/generators/micro-react/templates/apps/layout/src/locales/en-US.ts +17 -0
  30. package/generators/micro-react/templates/apps/layout/src/locales/zh-CN.ts +16 -0
  31. package/generators/micro-react/templates/apps/layout/src/pages/404/index.tsx +7 -3
  32. package/generators/micro-react/templates/apps/layout/src/pages/Home/index.less +5 -0
  33. package/generators/micro-react/templates/apps/layout/src/pages/Home/index.tsx +49 -1
  34. package/generators/micro-react/templates/apps/layout/src/services/user.ts +28 -21
  35. package/generators/micro-react/templates/packages/common-intl/README.md +77 -369
  36. package/generators/micro-react/templates/packages/common-intl/package.json +3 -13
  37. package/generators/micro-react/templates/packages/common-intl/src/index.ts +3 -6
  38. package/generators/micro-react/templates/packages/common-intl/src/intl.ts +20 -29
  39. package/generators/micro-react/templates/packages/common-intl/tsconfig.json +2 -4
  40. package/generators/subapp-react/index.js +28 -22
  41. package/generators/subapp-react/templates/homepage/README.md +1 -0
  42. package/generators/subapp-react/templates/homepage/config/config.prod.development.ts +1 -0
  43. package/generators/subapp-react/templates/homepage/config/config.prod.testing.ts +1 -0
  44. package/generators/subapp-react/templates/homepage/config/config.prod.ts +1 -0
  45. package/generators/subapp-react/templates/homepage/docs/feature-PermissionFilter/346/214/211/351/222/256/346/235/203/351/231/220.md +35 -0
  46. package/generators/subapp-react/templates/homepage/package.json +2 -1
  47. package/generators/subapp-react/templates/homepage/src/app.tsx +7 -0
  48. package/generators/subapp-react/templates/homepage/src/common/mainApp.ts +39 -2
  49. package/generators/subapp-react/templates/homepage/src/components/PermissionFilter/index.tsx +48 -0
  50. package/generators/subapp-react/templates/homepage/src/pages/index.tsx +35 -1
  51. package/lib/utils.js +0 -1
  52. package/package.json +2 -2
  53. package/generators/micro-react/templates/apps/layout/docs/common-intl.md +0 -372
  54. package/generators/micro-react/templates/packages/common-intl/src/indexedDBUtils.ts +0 -51
  55. package/generators/micro-react/templates/packages/common-intl/src/utils.ts +0 -482
  56. package/generators/micro-react/templates/packages/common-intl/vite.config.ts +0 -25
@@ -1,427 +1,135 @@
1
1
  # <%= packageScope %>/common-intl
2
2
 
3
- 通用国际化(i18n)库,用于 Portal 多应用间的多语言文案管理。
3
+ 本包是 [`@common-web/common-intl`](https://gitlab-vywrajy.micoworld.net/micocenter/mico-portal/portal-center/common-web/-/blob/release/0.0.9/packages/common-intl/README.md) 的项目级封装,提供预配置的 `tag` 绑定和业务文案集中管理。
4
4
 
5
- ## 功能特性
5
+ ## 微前端模式
6
6
 
7
- - **跨端兼容**:不内置 UI 提示能力,通过外部注入 `messageInstance` 实现跨平台兼容
8
- - **缓存机制**:支持 IndexedDB 持久化存储 + 内存缓存双重保障
9
- - **插值替换**:支持 `%AA%`、`%BB%` 等占位符的动态替换
10
- - **降级处理**:当翻译 key 不存在时,自动返回兜底文案
11
- - **环境感知**:自动根据 `NODE_ENV` 切换开发/生产 API 地址
12
- - **微前端共享**:主应用获取的文案数据自动共享给所有子应用
13
-
14
- ## 安装
15
-
16
- 在 monorepo 项目中,通过 workspace 引用:
7
+ qiankun 微前端架构中,**主应用负责获取文案**,子应用直接使用共享的文案对象,无需重复初始化。
17
8
 
18
- ```json
19
- {
20
- "dependencies": {
21
- "<%= packageScope %>/common-intl": "workspace:*"
22
- }
23
- }
9
+ ```
10
+ ┌─────────────────────────────────────────────────────────┐
11
+ │ apps/layout(主应用) │
12
+ │ initIntl() 绑定 tag → render() 中 fetchMultilingualData │
13
+ → 文案存储到 window.__MICO_COMMON_INTL_TRANSLATIONS__ │
14
+ └─────────────────────────────────────────────────────────┘
15
+
16
+ ┌─────────────────────┼─────────────────────┐
17
+ ↓ ↓ ↓
18
+ ┌───────────┐ ┌───────────┐ ┌───────────┐
19
+ │ 子应用 A │ │ 子应用 B │ │ 子应用 C │
20
+ │ import { │ │ import { │ │ import { │
21
+ │ intl │ │ intl │ │ intl │
22
+ │ } │ │ } │ │ } │
23
+ │ 直接使用 │ │ 直接使用 │ │ 直接使用 │
24
+ └───────────┘ └───────────┘ └───────────┘
24
25
  ```
25
26
 
26
- ## 两种使用模式
27
-
28
- 根据应用架构的不同,`<%= packageScope %>/common-intl` 支持两种使用模式:
29
-
30
- | 模式 | 适用场景 | 示例应用 |
31
- | ------------ | ------------------------------------------------ | ------------------------------------------------------------ |
32
- | 微前端模式 | qiankun 主子应用架构,主应用获取文案后子应用共享 | layout、conversation-v2、session、workorder、faq、permission |
33
- | 独立应用模式 | 独立运行的应用,自己获取和管理文案 | mico-cs-mobile |
34
-
35
- ### 微前端模式
36
-
37
- 在 qiankun 微前端架构中,**主应用负责获取文案**,子应用直接使用共享的文案对象,无需重复初始化。
38
-
39
- **工作原理**:
27
+ ## 快速开始
40
28
 
41
- - 主应用调用 `initIntl()` 获取远程文案
42
- - 文案数据存储到 `window.__MICO_COMMON_INTL_TRANSLATIONS__`
43
- - 子应用直接使用 `intl` 对象,自动从 window 读取共享数据
29
+ ### 1. 配置 tag
44
30
 
45
- **主应用配置**(参考 `apps/layout/src/app.tsx`):
31
+ `src/intl.ts` 中修改 `tag` 为你的多语言中台标签:
46
32
 
47
33
  ```typescript
48
- import {
49
- getCurrentLocale,
50
- initIntl,
51
- type ILang,
52
- } from "<%= packageScope %>/common-intl";
53
- import { Message } from "@mico-platform/ui";
54
- import { request } from "@umijs/max";
55
-
56
- // 初始化国际化模块
57
- const fetchMultilingualData = initIntl({
58
- requestInstance: request,
59
- messageInstance: {
60
- error: (msg: string) => Message.error(msg),
61
- warning: (msg: string) => Message.warning(msg),
62
- },
63
- fetchMultilingualDataParams: {
64
- tag: "cs_fe_pc",
65
- lang: getCurrentLocale() as ILang,
66
- app_name: "middle",
67
- },
68
- indexedDBParams: {
69
- dbName: "mico_cs_web_i18n_db",
70
- },
34
+ const { fetchMultilingualData, i18n } = initIntl({
35
+ tag: 'your_tag', // 替换为多语言中台的标签
36
+ app_name: 'middle',
37
+ indexedDBParams: { dbName: 'mico_i18n_db' },
71
38
  });
72
-
73
- // 在应用渲染前加载多语言数据
74
- export function render(oldRender: () => void): void {
75
- fetchMultilingualData()
76
- .then(oldRender)
77
- .catch((error: Error) => {
78
- console.error("获取多语言文案失败", error);
79
- oldRender(); // 失败时继续渲染,使用兜底文案
80
- });
81
- }
82
- ```
83
-
84
- **子应用使用**(无需初始化):
85
-
86
- ```typescript
87
- // apps/conversation-v2、apps/session、apps/workorder 等子应用
88
- import { intl } from "<%= packageScope %>/common-intl";
89
-
90
- // 直接使用,文案来自主应用
91
- <h1>{intl.cs_web_workbench_conversation_record()}</h1>;
92
39
  ```
93
40
 
94
- ### 独立应用模式
41
+ ### 2. 主应用接入
95
42
 
96
- 对于非 qiankun 架构的独立应用(如 H5 应用),需要自己调用 `initIntl()` 获取文案,并维护独立的文案文件。
97
-
98
- **独立应用配置**(参考 `apps/mico-cs-mobile/src/app.ts`):
43
+ 主应用(`apps/layout`)在 `app.tsx` `render` 函数中调用 `fetchMultilingualData`,确保渲染前完成多语言数据加载:
99
44
 
100
45
  ```typescript
101
- import { initIntl } from "<%= packageScope %>/common-intl";
102
- import { request } from "@umijs/max";
103
- import { convertLocaleToLangParam } from "./locales/utils";
104
- import { getSearchParams } from "@/common/jsbridge/jsbridge";
105
-
106
- // 初始化国际化模块
107
- const fetchMultilingualData = initIntl({
108
- // 请求实例(必填)
109
- requestInstance: request,
110
- // 消息提示实例(必填)
111
- messageInstance: {
112
- error: (msg: string) => console.error(msg),
113
- warning: (msg: string) => console.warn(msg),
114
- },
115
- // 多语言中台接口参数(必填)
116
- fetchMultilingualDataParams: {
117
- tag: 'cs_fe_mobile', // 多语言标签,参考翻译中台-文案管理列表页-Tags 表格列 https://lang-test.micoplatform.com/lang/#/langs
118
- lang: convertLocaleToLangParam(getSearchParams().language as string),
119
- app_name: 'middle', // 应用名称,参考翻译中台左上角 https://lang-test.micoplatform.com/lang/#/langs
120
- },
121
- // IndexedDB 参数(可选)
122
- indexedDBParams: {
123
- dbName: 'mico_cs_mobile_i18n_db',
124
- },
125
- });
46
+ import { fetchMultilingualData, getCurrentLocale, type ILang } from '<%= packageScope %>/common-intl';
126
47
 
127
- // 在应用渲染前加载多语言数据
128
- // 如果是基于 umi 的项目,可以在 app.tsx 的 render 函数中调用加载函数 https://umijs.org/docs/api/runtime-config#render
129
48
  export function render(oldRender: () => void): void {
130
- fetchMultilingualData()
49
+ fetchMultilingualData({
50
+ requestInstance: commonRequest,
51
+ messageInstance: {
52
+ error: micoUI.Message.error,
53
+ warning: micoUI.Message.warning,
54
+ },
55
+ lang: getCurrentLocale() as ILang,
56
+ localeRequestUrl: process.env.LOCALE_REQUEST_URL,
57
+ })
131
58
  .then(oldRender)
132
59
  .catch((error: Error) => {
133
60
  console.error('获取多语言文案失败', error);
134
- // 即使失败也继续渲染,使用兜底文案
135
61
  oldRender();
136
62
  });
137
63
  }
138
64
  ```
139
65
 
140
- **独立应用的文案文件**(`apps/mico-cs-mobile/src/locales/index.ts`):集中管理所有国际化文案
141
-
142
- ```typescript
143
- import { i18n } from "<%= packageScope %>/common-intl";
144
-
145
- const intl = {
146
- // 无插值示例
147
- sdk_h5_ticket_record: () =>
148
- i18n({
149
- key: 'sdk_h5_ticket_record',
150
- defaultMessage: '工单记录',
151
- }),
152
-
153
- // 单个插值示例
154
- sdk_h5_common_request_failed_aa: (code: string | number) =>
155
- i18n({
156
- key: 'sdk_h5_common_request_failed_aa',
157
- interpolations: [code],
158
- defaultMessage: `请求失败 (${code})`,
159
- }),
160
-
161
- // 多个插值示例
162
- sdk_h5_common_upload_failed_status_aa_bb: (
163
- statusCode: string | number,
164
- responseText: string,
165
- ) =>
166
- i18n({
167
- key: 'sdk_h5_common_upload_failed_status_aa_bb',
168
- interpolations: [statusCode, responseText],
169
- defaultMessage: `上传失败,状态码 ${statusCode}${responseText}`,
170
- }),
171
- };
172
-
173
- export default intl;
174
- ```
175
-
176
- **在组件中使用**:
177
-
178
- ```tsx
179
- import intl from '@/locales';
180
-
181
- function MyComponent() {
182
- return (
183
- <div>
184
- <h1>{intl.sdk_h5_ticket_record()}</h1>
185
- <p>{intl.sdk_h5_common_request_failed_aa(404)}</p>
186
- </div>
187
- );
188
- }
189
- ```
190
-
191
- ## API 参考
192
-
193
- ### `initIntl(params: IInitIntlParams)`
194
-
195
- 初始化国际化模块,返回 `fetchMultilingualData` 函数。
196
-
197
- #### 参数
66
+ ### 3. 添加文案
198
67
 
199
- | 参数 | 类型 | 必填 | 说明 |
200
- | -------------------------------------- | ------------------ | ---- | -------------------------------------------- |
201
- | `requestInstance` | `Function` | ✅ | HTTP 请求函数,用于请求多语言中台接口 |
202
- | `messageInstance` | `IMessageInstance` | ✅ | 消息提示实例,包含 `error` 和 `warning` 方法 |
203
- | `fetchMultilingualDataParams` | `Object` | ✅ | 多语言接口参数 |
204
- | `fetchMultilingualDataParams.tag` | `string` | ✅ | 多语言标签 |
205
- | `fetchMultilingualDataParams.lang` | `ILang` | ✅ | 语言类型 |
206
- | `fetchMultilingualDataParams.app_name` | `string` | ✅ | 应用名称 |
207
- | `indexedDBParams` | `Object` | ❌ | IndexedDB 配置参数 |
208
-
209
- #### 返回值
210
-
211
- 返回 `fetchMultilingualData(): Promise<Record<string, string>>` 函数,调用后会:
212
-
213
- 1. 从多语言中台拉取翻译数据
214
- 2. 将数据存储到 IndexedDB 和全局变量缓存(`window.__MICO_COMMON_INTL_TRANSLATIONS__`)
215
- 3. 返回翻译数据对象
216
-
217
- ### `i18n(params: II18nParams)`
218
-
219
- 国际化翻译函数,同步返回翻译后的文案。
220
-
221
- #### 参数
222
-
223
- | 参数 | 类型 | 必填 | 说明 |
224
- | ---------------- | ------------------------- | ---- | -------------------------------------------- |
225
- | `key` | `string` | ✅ | 翻译文案的 key |
226
- | `interpolations` | `Array<string \| number>` | ❌ | 插值数组,按顺序替换 `%AA%`、`%BB%` 等占位符 |
227
- | `defaultMessage` | `string` | ✅ | 兜底文案,当找不到翻译时返回 |
228
-
229
- #### 返回值
230
-
231
- 返回翻译后的字符串。
232
-
233
- ### `getCurrentLocale()`
234
-
235
- 获取当前语言环境,按优先级从高到低:
236
-
237
- 1. URL 参数 `lang`
238
- 2. localStorage 中的 `umi_locale`
239
- 3. 浏览器默认语言
240
-
241
- #### 返回值
242
-
243
- 返回当前语言类型 `ILang`。
244
-
245
- ### `setLocaleToStorage(locale: ILang)`
246
-
247
- 将语言设置保存到 localStorage。
248
-
249
- ### `LANG`
250
-
251
- 支持的语言常量对象:
68
+ `src/intl.ts` 中添加新的翻译 key:
252
69
 
253
70
  ```typescript
254
- const LANG = {
255
- ZH_CN: "zh_CN", // 简体中文
256
- EN: "en", // 英语
257
- AR: "ar", // 阿拉伯语
258
- TR: "tr", // 土耳其语
259
- } as const;
71
+ const intl = addIntl({
72
+ common_hello: () =>
73
+ i18n({ key: 'common_hello', defaultMessage: '你好' }),
74
+ // 添加新文案...
75
+ }, i18n);
260
76
  ```
261
77
 
262
- ### `LOCALE`
263
-
264
- `LANG` 的别名,用于兼容现有代码。
265
-
266
- ### `SUPPORTED_LOCALES`
78
+ ## 子应用使用
267
79
 
268
- 支持的语言列表数组:`['zh_CN', 'en', 'ar', 'tr']`
80
+ ### 默认模式:共享主应用文案
269
81
 
270
- ### 类型定义
82
+ 子应用默认与主应用共享同一个 `tag`,直接导入即可使用,**无需调用 `initIntl`**:
271
83
 
272
84
  ```typescript
273
- // 语言类型
274
- type ILang = "zh_CN" | "en" | "ar" | "tr";
85
+ import { intl } from '<%= packageScope %>/common-intl';
275
86
 
276
- // TLocale 是 ILang 的别名,用于兼容
277
- type TLocale = ILang;
278
-
279
- // 消息提示实例接口
280
- interface IMessageInstance {
281
- error: (message: string) => unknown;
282
- warning: (message: string) => unknown;
283
- }
284
-
285
- // 初始化参数接口
286
- interface IInitIntlParams {
287
- requestInstance: (
288
- url: string,
289
- options: { method: string; params: Record<string, string> }
290
- ) => Promise<{
291
- code: number;
292
- data?: Record<string, string>;
293
- errorMessage?: string;
294
- }>;
295
- messageInstance: IMessageInstance;
296
- fetchMultilingualDataParams: {
297
- tag: string;
298
- lang: ILang;
299
- app_name: string;
300
- };
301
- indexedDBParams?: {
302
- dbName?: string;
303
- dbVersion?: number;
304
- storeName?: string;
305
- keyPathKey?: string;
306
- };
307
- }
308
-
309
- // i18n 函数参数接口
310
- interface II18nParams {
311
- key: string;
312
- interpolations?: Array<string | number | undefined>;
313
- defaultMessage: string;
314
- }
87
+ intl.common_hello();
315
88
  ```
316
89
 
317
- ## 导出清单
318
-
319
- | 导出 | 类型 | 说明 |
320
- | -------------------- | ---- | --------------------------------------------------------- |
321
- | `initIntl` | 函数 | 初始化国际化模块,返回 `fetchMultilingualData` 函数 |
322
- | `i18n` | 函数 | 翻译函数,用于获取单条翻译文案 |
323
- | `intl` | 对象 | PC 端主子应用共享的文案对象(仅供 layout 及其子应用使用) |
324
- | `LANG` | 常量 | 支持的语言常量:`ZH_CN`、`EN`、`AR`、`TR` |
325
- | `LOCALE` | 常量 | `LANG` 的别名,用于兼容 |
326
- | `SUPPORTED_LOCALES` | 常量 | 支持的语言列表数组 |
327
- | `getCurrentLocale` | 函数 | 获取当前语言环境(按优先级:URL > localStorage > 浏览器) |
328
- | `setLocaleToStorage` | 函数 | 设置语言到 localStorage |
329
- | `ILang` | 类型 | 语言类型定义 |
330
- | `TLocale` | 类型 | `ILang` 的别名,用于兼容 |
331
-
332
- ## 占位符规则
90
+ 主应用通过 `window` 暴露 `<%= packageScope %>/common-intl`,子应用通过 `externals` 复用,不会重复打包。
333
91
 
334
- 翻译文案中的占位符使用大写字母对表示:
92
+ ### 独立 tag 模式
335
93
 
336
- | 占位符 | 对应 interpolations 索引 |
337
- | ------ | ------------------------ |
338
- | `%AA%` | `interpolations[0]` |
339
- | `%BB%` | `interpolations[1]` |
340
- | `%CC%` | `interpolations[2]` |
341
- | ... | ... |
342
- | `%ZZ%` | `interpolations[25]` |
343
-
344
- ### 示例
94
+ 如果子应用需要使用**独立的多语言标签**(例如子应用有自己的多语言文案),直接依赖 `@common-web/common-intl`,在子应用内自行调用 `initIntl`,不需要经过本中转包:
345
95
 
346
96
  ```typescript
347
- // 翻译文案: "共 %AA% 条记录,第 %BB% 页"
348
- i18n({
349
- key: "pagination_info",
350
- interpolations: [100, 1],
351
- defaultMessage: `共 100 条记录,第 1 页`,
352
- });
353
- // 输出: "共 100 条记录,第 1 页"
354
- ```
355
-
356
- ## 缓存策略
97
+ // apps/my-subapp/src/locales/index.ts
98
+ import { initIntl, addIntl } from '@common-web/common-intl';
357
99
 
358
- 1. **内存缓存**:翻译数据首先存储在 `window.__MICO_COMMON_INTL_TRANSLATIONS__` 全局变量中,保证 `i18n()` 函数的同步调用,同时支持微前端主子应用间的数据共享
359
- 2. **IndexedDB 缓存**:同时持久化到 IndexedDB,支持离线访问和页面刷新后的快速加载
360
- 3. **降级处理**:当 IndexedDB 不可用时(如某些 WebView 环境),仅使用内存缓存
100
+ const { fetchMultilingualData, i18n } = initIntl({
101
+ tag: 'my_subapp_tag',
102
+ app_name: 'middle',
103
+ indexedDBParams: { dbName: 'my_subapp_i18n_db' },
104
+ });
361
105
 
362
- ## 添加新翻译
106
+ export { fetchMultilingualData };
363
107
 
364
- 1. 在 `src/intl.ts` 中添加新的 key:
108
+ const intl = addIntl({
109
+ my_key: () => i18n({ key: 'my_key', defaultMessage: '我的文案' }),
110
+ }, i18n);
365
111
 
366
- ```typescript
367
- const intl = {
368
- // ... 其他 keys ...
369
-
370
- // 新增的 key(无参数)
371
- cs_web_your_new_key: () =>
372
- i18n({
373
- key: "cs_web_your_new_key",
374
- defaultMessage: "你的新文案",
375
- }),
376
-
377
- // 带参数的 key(单个参数)
378
- cs_web_your_new_key_aa: (param: string | number) =>
379
- i18n({
380
- key: "cs_web_your_new_key_aa",
381
- interpolations: [param],
382
- defaultMessage: `你的新文案 ${param}`,
383
- }),
384
-
385
- // 带参数的 key(多个参数)
386
- cs_web_your_new_key_multi: (a: string | number, b: string | number) =>
387
- i18n({
388
- key: "cs_web_your_new_key_multi",
389
- interpolations: [a, b],
390
- defaultMessage: `参数A: ${a},参数B: ${b}`,
391
- }),
392
- };
112
+ export default intl;
393
113
  ```
394
114
 
395
- 2. 在业务代码中使用:
115
+ > `initIntl` 只管身份配置(tag、app_name、存储),`fetchMultilingualData` 管运行时依赖(请求实例、消息提示、语言、API 地址)。`i18n` 函数与 `tag` 绑定,不同 tag 的翻译数据互相隔离。
396
116
 
397
- ```typescript
398
- import { intl } from "<%= packageScope %>/common-intl";
117
+ ## 常见问题
399
118
 
400
- // 使用新 key
401
- intl.cs_web_your_new_key();
402
- intl.cs_web_your_new_key_aa("参数值");
403
- intl.cs_web_your_new_key_multi("值A", "值B");
404
- ```
119
+ ### Q: 子应用需要调用 initIntl 吗?
405
120
 
406
- 3. key 和兜底文案 defaultMessage 添加到 https://micoworld.feishu.cn/wiki/Ak4pwBl86ixhXyk39bKcgQbknTf?sheet=MzAybi ,并上传到翻译中台
121
+ 默认不需要。主应用负责初始化和获取文案,子应用直接使用共享的 `intl` 对象。仅当子应用需要独立 tag 时才自行调用。
407
122
 
408
- ## 开发命令
123
+ ### Q: 翻译数据什么时候加载?
409
124
 
410
- ```bash
411
- # 开发模式(监听文件变化)
412
- pnpm dev
125
+ 在 UmiJS 的 `render` 钩子中调用 `fetchMultilingualData()`,确保在应用渲染前完成加载。
413
126
 
414
- # 构建
415
- pnpm build
416
- ```
127
+ ### Q: 如何添加新的翻译文案?
128
+
129
+ 在 `src/intl.ts` 中添加对应的函数,然后在代码中通过 `intl.xxx()` 调用。
417
130
 
418
- ## 注意事项
131
+ ## 完整文档
419
132
 
420
- 本项目暂时没有独立发包。各个业务应用 (/apps/\*) 通过 pnpm workspace 引入本项目,可参考 [/apps/mico-cs-mobile](../../apps/mico-cs-mobile/package.json)。原因:本项目代码量较少,暂时由各个业务应用各自把本项目打包到产物中,后续有必要时再优化。
133
+ 关于 `initIntl`、`fetchMultilingualData`、`i18n`、`addIntl` 的详细 API、类型定义、缓存策略、占位符规则等,请参阅:
421
134
 
422
- 1. **不要直接调用 `i18n` 函数**:应通过 `intl.xxx()` 方式调用
423
- 2. **参数类型**:插值参数支持 `string | number | undefined`。无插值时,`interpolations` 参数可以不传
424
- 3. **默认文案**:每个 key 都需要提供 `defaultMessage` 作为后备
425
- 4. **TypeScript 支持**:`intl` 对象有完整的类型提示
426
- 5. **同步调用**:`i18n` 函数是同步的,从全局变量缓存读取数据,因此必须确保在 `fetchMultilingualData()` 完成后才能使用
427
- 6. **离线支持**:即使网络请求失败,也会尝试从 IndexedDB 读取历史缓存,保证基本可用性
135
+ **[@common-web/common-intl README](https://gitlab-vywrajy.micoworld.net/micocenter/mico-portal/portal-center/common-web/-/blob/release/0.0.9/packages/common-intl/README.md)**
@@ -1,11 +1,8 @@
1
1
  {
2
2
  "name": "<%= packageScope %>/common-intl",
3
3
  "version": "0.0.1",
4
- "description": "Portal common internationalization library",
4
+ "description": "通用国际化库 - re-exports @common-web/common-intl 并提供项目级文案",
5
5
  "type": "module",
6
- "main": "./dist/index.js",
7
- "module": "./dist/index.js",
8
- "types": "./dist/index.d.ts",
9
6
  "exports": {
10
7
  ".": {
11
8
  "import": "./src/index.ts",
@@ -13,17 +10,10 @@
13
10
  }
14
11
  },
15
12
  "files": [
16
- "dist",
17
13
  "src"
18
14
  ],
19
- "scripts": {
20
- "dev": "vite build --watch",
21
- "build": "vite build && tsc --emitDeclarationOnly"
22
- },
23
- "devDependencies": {
24
- "typescript": "^5.8.3",
25
- "vite": "^7.2.4",
26
- "vite-plugin-dts": "^4.5.4"
15
+ "dependencies": {
16
+ "@common-web/common-intl": "0.2.2"
27
17
  },
28
18
  "keywords": [
29
19
  "i18n",
@@ -1,7 +1,4 @@
1
- export * from './utils';
1
+ export * from '@common-web/common-intl';
2
2
 
3
- // LOCALE/TLocale 别名(为兼容现有代码)
4
- export { LANG as LOCALE, type ILang as TLocale } from './utils';
5
-
6
- // 导出 intl 对象
7
- export { default as intl } from './intl';
3
+ // 导出 intl 对象、fetchMultilingualData、i18n(均绑定 intl.ts 中配置的 tag)
4
+ export { default as intl, fetchMultilingualData, i18n } from './intl';
@@ -1,17 +1,29 @@
1
- import { i18n } from './utils';
1
+ import { initIntl, addIntl } from '@common-web/common-intl';
2
+
3
+ // 在模块加载时即完成 tag 绑定
4
+ // tag 请根据项目实际值替换
5
+ const { fetchMultilingualData, i18n } = initIntl({
6
+ tag: '<%= intlTag %>',
7
+ app_name: 'middle', // 多语言中台的应用名。这个一般不需要改,应该就是 middle
8
+ indexedDBParams: { dbName: 'mico_i18n_db' },
9
+ });
10
+
11
+ export { fetchMultilingualData, i18n };
2
12
 
3
13
  /**
4
14
  * 国际化文案汇总
5
15
  *
6
16
  * 使用方式:
7
- * import { intl } from 'common-intl';
17
+ * import { intl } from '<%= packageScope %>/common-intl';
8
18
  * intl.common_hello()
9
19
  *
10
- * 添加新文案示例:
11
- * common_hello: () => i18n({ key: 'common_hello', defaultMessage: '你好' }),
12
- * common_welcome_aa: (name: string) => i18n({ key: 'common_welcome_aa', interpolations: [name], defaultMessage: `欢迎, ${name}` }),
20
+ * 子应用默认使用本文件的 intl 对象(与主应用共享同一个 tag)。
21
+ * 如果子应用需要使用独立的 tag,应直接依赖 @common-web/common-intl,
22
+ * 在子应用内自行调用 initIntl,不需要经过本中转包。
23
+ * 详见 @common-web/common-intl README:
24
+ * https://gitlab-vywrajy.micoworld.net/micocenter/mico-portal/portal-center/common-web/-/blob/release/0.0.9/packages/common-intl/README.md
13
25
  */
14
- const intl = {
26
+ const intl = addIntl({
15
27
  // ============ 示例文案(可删除) ============
16
28
  common_hello: () =>
17
29
  i18n({
@@ -24,27 +36,6 @@ const intl = {
24
36
  interpolations: [name],
25
37
  defaultMessage: `欢迎, ${name}`,
26
38
  }),
27
- };
28
-
29
- /**
30
- * 使用 Proxy 包装 intl 对象
31
- * 当访问不存在的 key 时,返回一个兜底函数,避免 "is not a function" 错误
32
- */
33
- const intlProxy = new Proxy(intl, {
34
- get(target, prop: string) {
35
- if (prop in target) {
36
- return target[prop as keyof typeof target];
37
- }
38
- // 不存在的 key,返回一个兜底函数
39
- console.warn(`[common-intl] Missing intl key: ${prop}`);
40
- // 未预定义的 key:仍从缓存(接口拉取的多语言数据)中查找,支持动态 key
41
- return (...interpolations: Array<string | number | undefined>) =>
42
- i18n({
43
- key: prop,
44
- interpolations,
45
- defaultMessage: prop, // 缓存无值时用 key 兜底
46
- });
47
- },
48
- });
39
+ }, i18n);
49
40
 
50
- export default intlProxy;
41
+ export default intl;
@@ -1,17 +1,15 @@
1
1
  {
2
2
  "compilerOptions": {
3
- "target": "ES2020",
3
+ "target": "ES2022",
4
4
  "useDefineForClassFields": true,
5
5
  "module": "ESNext",
6
- "lib": ["ES2020", "DOM", "DOM.Iterable"],
6
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
7
7
  "skipLibCheck": true,
8
8
  "moduleResolution": "bundler",
9
9
  "allowImportingTsExtensions": true,
10
10
  "resolveJsonModule": true,
11
11
  "isolatedModules": true,
12
12
  "noEmit": true,
13
- "declaration": true,
14
- "declarationDir": "./dist",
15
13
  "strict": true,
16
14
  "noUnusedLocals": true,
17
15
  "noUnusedParameters": true,