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.
- package/README.md +5 -20
- package/bin/mico.js +27 -62
- package/generators/micro-react/index.js +8 -0
- package/generators/micro-react/templates/.cursor/rules/always-read-docs.mdc +3 -0
- package/generators/micro-react/templates/.cursor/rules/project-overview.mdc +1 -0
- package/generators/micro-react/templates/CLAUDE.md +1 -0
- package/generators/micro-react/templates/README.md +1 -1
- package/generators/micro-react/templates/apps/layout/config/config.dev.ts +4 -2
- package/generators/micro-react/templates/apps/layout/config/config.prod.development.ts +2 -0
- package/generators/micro-react/templates/apps/layout/config/config.prod.testing.ts +2 -0
- package/generators/micro-react/templates/apps/layout/config/config.prod.ts +2 -0
- 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
- 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
- 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
- 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
- package/generators/micro-react/templates/apps/layout/mock/api.mock.ts +23 -31
- package/generators/micro-react/templates/apps/layout/mock/pages.ts +5 -6
- package/generators/micro-react/templates/apps/layout/package.json +2 -1
- package/generators/micro-react/templates/apps/layout/src/app.tsx +30 -2
- package/generators/micro-react/templates/apps/layout/src/common/auth/type.ts +15 -27
- package/generators/micro-react/templates/apps/layout/src/common/menu/parser.ts +148 -85
- package/generators/micro-react/templates/apps/layout/src/common/menu/types.ts +2 -6
- package/generators/micro-react/templates/apps/layout/src/common/portal-data.ts +46 -2
- package/generators/micro-react/templates/apps/layout/src/components/MicroAppLoader/index.tsx +5 -1
- package/generators/micro-react/templates/apps/layout/src/components/PermissionFilter/index.tsx +51 -0
- package/generators/micro-react/templates/apps/layout/src/components/RightContent/AvatarDropdown.tsx +10 -1
- package/generators/micro-react/templates/apps/layout/src/layouts/components/menu/index.tsx +3 -3
- package/generators/micro-react/templates/apps/layout/src/layouts/index.tsx +105 -60
- package/generators/micro-react/templates/apps/layout/src/locales/en-US.ts +17 -0
- package/generators/micro-react/templates/apps/layout/src/locales/zh-CN.ts +16 -0
- package/generators/micro-react/templates/apps/layout/src/pages/404/index.tsx +7 -3
- package/generators/micro-react/templates/apps/layout/src/pages/Home/index.less +5 -0
- package/generators/micro-react/templates/apps/layout/src/pages/Home/index.tsx +49 -1
- package/generators/micro-react/templates/apps/layout/src/services/user.ts +28 -21
- package/generators/micro-react/templates/packages/common-intl/README.md +77 -369
- package/generators/micro-react/templates/packages/common-intl/package.json +3 -13
- package/generators/micro-react/templates/packages/common-intl/src/index.ts +3 -6
- package/generators/micro-react/templates/packages/common-intl/src/intl.ts +20 -29
- package/generators/micro-react/templates/packages/common-intl/tsconfig.json +2 -4
- package/generators/subapp-react/index.js +28 -22
- package/generators/subapp-react/templates/homepage/README.md +1 -0
- package/generators/subapp-react/templates/homepage/config/config.prod.development.ts +1 -0
- package/generators/subapp-react/templates/homepage/config/config.prod.testing.ts +1 -0
- package/generators/subapp-react/templates/homepage/config/config.prod.ts +1 -0
- package/generators/subapp-react/templates/homepage/docs/feature-PermissionFilter/346/214/211/351/222/256/346/235/203/351/231/220.md +35 -0
- package/generators/subapp-react/templates/homepage/package.json +2 -1
- package/generators/subapp-react/templates/homepage/src/app.tsx +7 -0
- package/generators/subapp-react/templates/homepage/src/common/mainApp.ts +39 -2
- package/generators/subapp-react/templates/homepage/src/components/PermissionFilter/index.tsx +48 -0
- package/generators/subapp-react/templates/homepage/src/pages/index.tsx +35 -1
- package/lib/utils.js +0 -1
- package/package.json +2 -2
- package/generators/micro-react/templates/apps/layout/docs/common-intl.md +0 -372
- package/generators/micro-react/templates/packages/common-intl/src/indexedDBUtils.ts +0 -51
- package/generators/micro-react/templates/packages/common-intl/src/utils.ts +0 -482
- 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
|
-
|
|
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
|
-
|
|
8
|
-
- **缓存机制**:支持 IndexedDB 持久化存储 + 内存缓存双重保障
|
|
9
|
-
- **插值替换**:支持 `%AA%`、`%BB%` 等占位符的动态替换
|
|
10
|
-
- **降级处理**:当翻译 key 不存在时,自动返回兜底文案
|
|
11
|
-
- **环境感知**:自动根据 `NODE_ENV` 切换开发/生产 API 地址
|
|
12
|
-
- **微前端共享**:主应用获取的文案数据自动共享给所有子应用
|
|
13
|
-
|
|
14
|
-
## 安装
|
|
15
|
-
|
|
16
|
-
在 monorepo 项目中,通过 workspace 引用:
|
|
7
|
+
在 qiankun 微前端架构中,**主应用负责获取文案**,子应用直接使用共享的文案对象,无需重复初始化。
|
|
17
8
|
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
-
|
|
42
|
-
- 文案数据存储到 `window.__MICO_COMMON_INTL_TRANSLATIONS__`
|
|
43
|
-
- 子应用直接使用 `intl` 对象,自动从 window 读取共享数据
|
|
29
|
+
### 1. 配置 tag
|
|
44
30
|
|
|
45
|
-
|
|
31
|
+
在 `src/intl.ts` 中修改 `tag` 为你的多语言中台标签:
|
|
46
32
|
|
|
47
33
|
```typescript
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
-
|
|
97
|
-
|
|
98
|
-
**独立应用配置**(参考 `apps/mico-cs-mobile/src/app.ts`):
|
|
43
|
+
主应用(`apps/layout`)在 `app.tsx` 的 `render` 函数中调用 `fetchMultilingualData`,确保渲染前完成多语言数据加载:
|
|
99
44
|
|
|
100
45
|
```typescript
|
|
101
|
-
import {
|
|
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
|
-
|
|
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
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
} as const;
|
|
71
|
+
const intl = addIntl({
|
|
72
|
+
common_hello: () =>
|
|
73
|
+
i18n({ key: 'common_hello', defaultMessage: '你好' }),
|
|
74
|
+
// 添加新文案...
|
|
75
|
+
}, i18n);
|
|
260
76
|
```
|
|
261
77
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
`LANG` 的别名,用于兼容现有代码。
|
|
265
|
-
|
|
266
|
-
### `SUPPORTED_LOCALES`
|
|
78
|
+
## 子应用使用
|
|
267
79
|
|
|
268
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
348
|
-
|
|
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
|
-
|
|
359
|
-
|
|
360
|
-
|
|
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
|
-
|
|
108
|
+
const intl = addIntl({
|
|
109
|
+
my_key: () => i18n({ key: 'my_key', defaultMessage: '我的文案' }),
|
|
110
|
+
}, i18n);
|
|
365
111
|
|
|
366
|
-
|
|
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
|
-
|
|
115
|
+
> `initIntl` 只管身份配置(tag、app_name、存储),`fetchMultilingualData` 管运行时依赖(请求实例、消息提示、语言、API 地址)。`i18n` 函数与 `tag` 绑定,不同 tag 的翻译数据互相隔离。
|
|
396
116
|
|
|
397
|
-
|
|
398
|
-
import { intl } from "<%= packageScope %>/common-intl";
|
|
117
|
+
## 常见问题
|
|
399
118
|
|
|
400
|
-
|
|
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
|
-
|
|
121
|
+
默认不需要。主应用负责初始化和获取文案,子应用直接使用共享的 `intl` 对象。仅当子应用需要独立 tag 时才自行调用。
|
|
407
122
|
|
|
408
|
-
|
|
123
|
+
### Q: 翻译数据什么时候加载?
|
|
409
124
|
|
|
410
|
-
|
|
411
|
-
# 开发模式(监听文件变化)
|
|
412
|
-
pnpm dev
|
|
125
|
+
在 UmiJS 的 `render` 钩子中调用 `fetchMultilingualData()`,确保在应用渲染前完成加载。
|
|
413
126
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
127
|
+
### Q: 如何添加新的翻译文案?
|
|
128
|
+
|
|
129
|
+
在 `src/intl.ts` 中添加对应的函数,然后在代码中通过 `intl.xxx()` 调用。
|
|
417
130
|
|
|
418
|
-
##
|
|
131
|
+
## 完整文档
|
|
419
132
|
|
|
420
|
-
|
|
133
|
+
关于 `initIntl`、`fetchMultilingualData`、`i18n`、`addIntl` 的详细 API、类型定义、缓存策略、占位符规则等,请参阅:
|
|
421
134
|
|
|
422
|
-
|
|
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": "
|
|
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
|
-
"
|
|
20
|
-
"
|
|
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 '
|
|
1
|
+
export * from '@common-web/common-intl';
|
|
2
2
|
|
|
3
|
-
//
|
|
4
|
-
export {
|
|
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 {
|
|
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
|
-
*
|
|
12
|
-
*
|
|
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
|
|
41
|
+
export default intl;
|
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"compilerOptions": {
|
|
3
|
-
"target": "
|
|
3
|
+
"target": "ES2022",
|
|
4
4
|
"useDefineForClassFields": true,
|
|
5
5
|
"module": "ESNext",
|
|
6
|
-
"lib": ["
|
|
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,
|