generator-mico-cli 0.2.29 → 0.2.30
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 +2 -0
- package/generators/micro-react/index.js +17 -1
- package/generators/micro-react/templates/CICD/start_dev.sh +11 -0
- package/generators/micro-react/templates/CICD/start_local.sh +9 -0
- package/generators/micro-react/templates/CICD/start_prod.sh +13 -0
- package/generators/micro-react/templates/CICD/start_test.sh +11 -0
- package/generators/micro-react/templates/apps/layout/config/config.dev.ts +9 -3
- package/generators/micro-react/templates/apps/layout/config/config.prod.development.ts +10 -0
- package/generators/micro-react/templates/apps/layout/config/config.prod.testing.ts +10 -0
- package/generators/micro-react/templates/apps/layout/config/config.prod.ts +12 -0
- package/generators/micro-react/templates/apps/layout/docs/feature-/345/233/275/351/231/205/345/214/226.md +121 -0
- package/generators/micro-react/templates/apps/layout/docs/feature-/345/276/256/345/211/215/347/253/257/346/250/241/345/274/217.md +8 -0
- package/generators/micro-react/templates/apps/layout/mock/menus.ts +14 -0
- package/generators/micro-react/templates/apps/layout/mock/pages.ts +22 -2
- package/generators/micro-react/templates/apps/layout/package.json +3 -2
- package/generators/micro-react/templates/apps/layout/src/app.tsx +58 -5
- package/generators/micro-react/templates/apps/layout/src/common/auth/index.ts +3 -0
- package/generators/micro-react/templates/apps/layout/src/common/auth/tenant.ts +25 -0
- package/generators/micro-react/templates/apps/layout/src/common/auth/type.ts +28 -2
- package/generators/micro-react/templates/apps/layout/src/common/intl/formatLayoutMessage.ts +30 -0
- package/generators/micro-react/templates/apps/layout/src/common/intl/index.ts +6 -0
- package/generators/micro-react/templates/apps/layout/src/common/intl/intlRuntime.ts +14 -0
- package/generators/micro-react/templates/apps/layout/src/common/intl/localeMapping.ts +30 -0
- package/generators/micro-react/templates/apps/layout/src/common/intl/types.ts +14 -0
- package/generators/micro-react/templates/apps/layout/src/common/intl/useLayoutIntl.ts +40 -0
- package/generators/micro-react/templates/apps/layout/src/common/logger.ts +3 -4
- package/generators/micro-react/templates/apps/layout/src/common/menu/types.ts +27 -0
- package/generators/micro-react/templates/apps/layout/src/common/micro/types.ts +23 -0
- package/generators/micro-react/templates/apps/layout/src/common/request/sso.ts +74 -15
- package/generators/micro-react/templates/apps/layout/src/common/request/token-refresh.ts +2 -0
- package/generators/micro-react/templates/apps/layout/src/components/MicroAppLoader/index.tsx +28 -6
- package/generators/micro-react/templates/apps/layout/src/components/RightContent/TenantDropdown.tsx +76 -0
- package/generators/micro-react/templates/apps/layout/src/components/RightContent/index.ts +1 -0
- package/generators/micro-react/templates/apps/layout/src/components/RightContent/tenant-dropdown.less +48 -0
- package/generators/micro-react/templates/apps/layout/src/constants/index.ts +1 -0
- package/generators/micro-react/templates/apps/layout/src/hooks/index.ts +1 -0
- package/generators/micro-react/templates/apps/layout/src/hooks/useMenuState.ts +18 -0
- package/generators/micro-react/templates/apps/layout/src/hooks/useTenant.ts +41 -0
- package/generators/micro-react/templates/apps/layout/src/layouts/components/header/index.tsx +4 -1
- package/generators/micro-react/templates/apps/layout/src/layouts/components/menu/index.tsx +18 -6
- package/generators/micro-react/templates/apps/layout/src/locales/en-US.ts +11 -0
- package/generators/micro-react/templates/apps/layout/src/locales/zh-CN.ts +10 -0
- package/generators/micro-react/templates/apps/layout/src/pages/Home/index.less +27 -0
- package/generators/micro-react/templates/apps/layout/src/pages/Home/index.tsx +108 -12
- package/generators/micro-react/templates/apps/layout/src/requestErrorConfig.ts +2 -1
- package/generators/micro-react/templates/apps/layout/src/services/user.ts +53 -2
- package/generators/micro-react/templates/apps/layout/typings.d.ts +16 -0
- package/generators/micro-react/templates/docs/package-shared.md +189 -0
- package/generators/micro-react/templates/package.json +1 -1
- package/generators/micro-react/templates/packages/common-intl/README.md +3 -1
- package/generators/micro-react/templates/packages/common-intl/package.json +1 -1
- package/generators/micro-react/templates/packages/common-intl/src/index.ts +4 -2
- package/generators/micro-react/templates/packages/common-intl/src/intl.ts +104 -8
- package/generators/micro-react/templates/packages/common-intl/src/umiLocaleBridge.ts +101 -0
- package/generators/micro-react/templates/packages/shared/README.md +120 -0
- package/generators/micro-react/templates/packages/shared/package.json +26 -0
- package/generators/micro-react/templates/packages/shared/services/common/index.ts +43 -0
- package/generators/micro-react/templates/packages/shared/services/index.ts +21 -0
- package/generators/micro-react/templates/packages/shared/services/request.ts +43 -0
- package/generators/micro-react/templates/packages/shared/timezone/index.ts +228 -0
- package/generators/micro-react/templates/packages/shared/tsconfig.json +20 -0
- package/generators/micro-react/templates/scripts/apply-sentry-plugin.ts +6 -1
- package/generators/micro-react/templates/turbo.json +9 -1
- package/generators/subapp-react/templates/homepage/config/config.ts +10 -0
- package/generators/subapp-react/templates/homepage/docs/feature-/345/233/275/351/231/205/345/214/226.md +124 -0
- package/generators/subapp-react/templates/homepage/package.json +2 -1
- package/generators/subapp-react/templates/homepage/src/app.tsx +100 -5
- package/generators/subapp-react/templates/homepage/src/common/intl/index.ts +15 -0
- package/generators/subapp-react/templates/homepage/src/common/intl/intlRuntime.ts +14 -0
- package/generators/subapp-react/templates/homepage/src/common/intl/localeMapping.ts +24 -0
- package/generators/subapp-react/templates/homepage/src/common/intl/subappIntlConfig.ts +28 -0
- package/generators/subapp-react/templates/homepage/src/common/intl/subappLocale.ts +18 -0
- package/generators/subapp-react/templates/homepage/src/common/intl/subappOwnIntl.ts +63 -0
- package/generators/subapp-react/templates/homepage/src/common/intl/types.ts +14 -0
- package/generators/subapp-react/templates/homepage/src/common/intl/useSubappIntl.ts +61 -0
- package/generators/subapp-react/templates/homepage/src/common/locale.ts +80 -0
- package/generators/subapp-react/templates/homepage/src/common/mainApp.ts +2 -0
- package/generators/subapp-react/templates/homepage/src/locales/en-US.ts +6 -0
- package/generators/subapp-react/templates/homepage/src/locales/zh-CN.ts +6 -0
- package/generators/subapp-react/templates/homepage/src/pages/index.less +10 -0
- package/generators/subapp-react/templates/homepage/src/pages/index.tsx +51 -0
- package/generators/subapp-react/templates/homepage/typings.d.ts +12 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -69,6 +69,7 @@ mico doctor
|
|
|
69
69
|
```json
|
|
70
70
|
{
|
|
71
71
|
"projectName": "my-app",
|
|
72
|
+
"appId": "portal_dev",
|
|
72
73
|
"packageScope": "@my-company",
|
|
73
74
|
"cdnPrefix": "portal",
|
|
74
75
|
"author": "Team <team@example.com>",
|
|
@@ -82,6 +83,7 @@ mico doctor
|
|
|
82
83
|
| 字段 | 类型 | 适用生成器 | 说明 | 默认值 |
|
|
83
84
|
|------|------|-----------|------|--------|
|
|
84
85
|
| `projectName` | string | micro-react | 项目名称 | 当前目录名 |
|
|
86
|
+
| `appId` | string | micro-react | 开发环境 `window.__MICO_CONFIG__.appId`(请求代理等) | `portal_dev` |
|
|
85
87
|
| `packageScope` | string | 所有 | 包作用域(如 `@my-company`) | micro-react: `@<projectName>`;其他: 从根 `package.json` 检测 |
|
|
86
88
|
| `cdnPrefix` | string | micro-react | CDN 路径前缀(如 `portal`、`admin/v2`) | 空字符串 |
|
|
87
89
|
| `author` | string | micro-react | 作者信息 | `Your Name <email@example.com>` |
|
|
@@ -76,6 +76,18 @@ module.exports = class extends Generator {
|
|
|
76
76
|
return true;
|
|
77
77
|
},
|
|
78
78
|
},
|
|
79
|
+
{
|
|
80
|
+
type: 'input',
|
|
81
|
+
name: 'appId',
|
|
82
|
+
message:
|
|
83
|
+
'App ID(开发环境 window.__MICO_CONFIG__.appId,用于请求代理 / 网关等)',
|
|
84
|
+
default: rc.appId || 'portal_dev',
|
|
85
|
+
validate: (input) => {
|
|
86
|
+
const v = String(input ?? '').trim();
|
|
87
|
+
if (!v) return 'App ID is required';
|
|
88
|
+
return true;
|
|
89
|
+
},
|
|
90
|
+
},
|
|
79
91
|
{
|
|
80
92
|
type: 'input',
|
|
81
93
|
name: 'packageScope',
|
|
@@ -91,7 +103,7 @@ module.exports = class extends Generator {
|
|
|
91
103
|
{
|
|
92
104
|
type: 'input',
|
|
93
105
|
name: 'cdnPrefix',
|
|
94
|
-
message: `CDN path prefix (用于区分不同业务线的 CDN
|
|
106
|
+
message: `CDN path prefix (用于区分不同业务线的 CDN 目录,一般是运营配置的group名,切记不可乱填)
|
|
95
107
|
示例:CDN 完整路径 = https://cdn.example.com/<prefix>/<projectName>/<version>/
|
|
96
108
|
- 留空: https://cdn.example.com/my-project/1.0.0/
|
|
97
109
|
- 输入 "portal": https://cdn.example.com/portal/my-project/1.0.0/
|
|
@@ -119,6 +131,7 @@ module.exports = class extends Generator {
|
|
|
119
131
|
|
|
120
132
|
this.projectName = toKebab(this.answers.projectName);
|
|
121
133
|
this.ProjectName = toPascal(this.projectName);
|
|
134
|
+
this.appId = String(this.answers.appId ?? '').trim();
|
|
122
135
|
this.packageScope = this.answers.packageScope;
|
|
123
136
|
this.cdnPrefix = this.answers.cdnPrefix;
|
|
124
137
|
this.author = this.answers.author;
|
|
@@ -173,6 +186,7 @@ module.exports = class extends Generator {
|
|
|
173
186
|
const templateData = {
|
|
174
187
|
projectName: this.projectName,
|
|
175
188
|
ProjectName: this.ProjectName,
|
|
189
|
+
appId: this.appId,
|
|
176
190
|
packageScope: this.packageScope,
|
|
177
191
|
author: this.author,
|
|
178
192
|
micoUiVersion: `^${micoUiVer}`,
|
|
@@ -204,6 +218,7 @@ module.exports = class extends Generator {
|
|
|
204
218
|
this.log('\x1b[33m📋 Dry run mode - no files will be created\x1b[0m');
|
|
205
219
|
this.log('');
|
|
206
220
|
this.log(` Project: ${this.projectName}`);
|
|
221
|
+
this.log(` App ID: ${this.appId}`);
|
|
207
222
|
this.log(` Scope: ${this.packageScope}`);
|
|
208
223
|
this.log(` Destination: ${this.destDir}`);
|
|
209
224
|
this.log('');
|
|
@@ -239,6 +254,7 @@ module.exports = class extends Generator {
|
|
|
239
254
|
|
|
240
255
|
this.log('');
|
|
241
256
|
this.log(`📦 Creating project: ${this.projectName}`);
|
|
257
|
+
this.log(` App ID: ${this.appId}`);
|
|
242
258
|
this.log(` Scope: ${this.packageScope}`);
|
|
243
259
|
this.log('');
|
|
244
260
|
|
|
@@ -14,6 +14,7 @@ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
|
14
14
|
|
|
15
15
|
# 用 node 命令读取 package.json 里的 version 字段
|
|
16
16
|
VERSION=$(node -p "require('$PROJECT_ROOT/package.json').version")
|
|
17
|
+
export VERSION
|
|
17
18
|
# 输出项目版本号
|
|
18
19
|
echo "项目版本: $VERSION"
|
|
19
20
|
|
|
@@ -23,6 +24,16 @@ cd "$PROJECT_ROOT"
|
|
|
23
24
|
# 导出 PROJECT_ROOT 供 before_build.sh 使用
|
|
24
25
|
export PROJECT_ROOT
|
|
25
26
|
|
|
27
|
+
# Jenkins 等 CI 注入的构建号(供 Sentry release、layout window.__MICO_BUILD__ 等)
|
|
28
|
+
export BUILD_NUMBER="${BUILD_NUMBER:-}"
|
|
29
|
+
echo "BUILD_NUMBER: ${BUILD_NUMBER:-<unset>}"
|
|
30
|
+
|
|
31
|
+
export GIT_COMMIT="${GIT_COMMIT:-$(git rev-parse HEAD 2>/dev/null || echo '')}"
|
|
32
|
+
export BRANCH_OR_TAG="${BRANCH_OR_TAG:-${GIT_BRANCH:-$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo '')}}"
|
|
33
|
+
export BUILD_TIME="${BUILD_TIME:-$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")}"
|
|
34
|
+
echo "GIT_COMMIT: ${GIT_COMMIT:-<empty>}"
|
|
35
|
+
echo "BRANCH_OR_TAG: ${BRANCH_OR_TAG:-<empty>}"
|
|
36
|
+
|
|
26
37
|
# 在执行构建前,计算 BASE_REF / TURBO_FILTER 等增量构建信息
|
|
27
38
|
if [ -f "$PROJECT_ROOT/CICD/before_build.sh" ]; then
|
|
28
39
|
# shellcheck disable=SC1090
|
|
@@ -14,12 +14,21 @@ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
|
14
14
|
|
|
15
15
|
# 用 node 命令读取 package.json 里的 version 字段
|
|
16
16
|
VERSION=$(node -p "require('$PROJECT_ROOT/package.json').version")
|
|
17
|
+
export VERSION
|
|
17
18
|
# 输出项目版本号
|
|
18
19
|
echo "项目版本: $VERSION"
|
|
19
20
|
|
|
20
21
|
# 切换到项目根目录,确保后续命令在根目录下运行
|
|
21
22
|
cd "$PROJECT_ROOT"
|
|
22
23
|
|
|
24
|
+
# Jenkins 等 CI 注入的构建号(供 Sentry release、layout window.__MICO_BUILD__ 等)
|
|
25
|
+
export BUILD_NUMBER="${BUILD_NUMBER:-}"
|
|
26
|
+
echo "BUILD_NUMBER: ${BUILD_NUMBER:-<unset>}"
|
|
27
|
+
|
|
28
|
+
export GIT_COMMIT="${GIT_COMMIT:-$(git rev-parse HEAD 2>/dev/null || echo '')}"
|
|
29
|
+
export BRANCH_OR_TAG="${BRANCH_OR_TAG:-${GIT_BRANCH:-$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo '')}}"
|
|
30
|
+
export BUILD_TIME="${BUILD_TIME:-$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")}"
|
|
31
|
+
|
|
23
32
|
# 设置子应用的 CDN 公共路径(本地环境使用相对路径)
|
|
24
33
|
export CDN_PUBLIC_PATH="./"
|
|
25
34
|
echo "CDN_PUBLIC_PATH: $CDN_PUBLIC_PATH"
|
|
@@ -14,6 +14,7 @@ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
|
14
14
|
|
|
15
15
|
# 用 node 命令读取 package.json 里的 version 字段
|
|
16
16
|
VERSION=$(node -p "require('$PROJECT_ROOT/package.json').version")
|
|
17
|
+
export VERSION
|
|
17
18
|
# 输出项目版本号
|
|
18
19
|
echo "项目版本: $VERSION"
|
|
19
20
|
|
|
@@ -23,6 +24,18 @@ cd "$PROJECT_ROOT"
|
|
|
23
24
|
# 导出 PROJECT_ROOT 供 before_build.sh 使用
|
|
24
25
|
export PROJECT_ROOT
|
|
25
26
|
|
|
27
|
+
# Jenkins 等 CI 注入的构建号(供 Sentry release、layout window.__MICO_BUILD__ 等)
|
|
28
|
+
export BUILD_NUMBER="${BUILD_NUMBER:-}"
|
|
29
|
+
echo "BUILD_NUMBER: ${BUILD_NUMBER:-<unset>}"
|
|
30
|
+
|
|
31
|
+
# 供 Umi define 注入 window.__MICO_BUILD__(与 package.json 一致;未导出时子进程 process.env.VERSION 为空)
|
|
32
|
+
# Jenkins 常注入 GIT_BRANCH / GIT_COMMIT,BRANCH_OR_TAG 为业务约定名时可由 Job 覆盖
|
|
33
|
+
export GIT_COMMIT="${GIT_COMMIT:-$(git rev-parse HEAD 2>/dev/null || echo '')}"
|
|
34
|
+
export BRANCH_OR_TAG="${BRANCH_OR_TAG:-${GIT_BRANCH:-$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo '')}}"
|
|
35
|
+
export BUILD_TIME="${BUILD_TIME:-$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")}"
|
|
36
|
+
echo "GIT_COMMIT: ${GIT_COMMIT:-<empty>}"
|
|
37
|
+
echo "BRANCH_OR_TAG: ${BRANCH_OR_TAG:-<empty>}"
|
|
38
|
+
|
|
26
39
|
# 在执行构建前,计算 BASE_REF / TURBO_FILTER 等增量构建信息(用于增量构建)
|
|
27
40
|
if [ -f "$PROJECT_ROOT/CICD/before_build.sh" ]; then
|
|
28
41
|
# shellcheck disable=SC1090
|
|
@@ -14,6 +14,7 @@ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
|
14
14
|
|
|
15
15
|
# 用 node 命令读取 package.json 里的 version 字段
|
|
16
16
|
VERSION=$(node -p "require('$PROJECT_ROOT/package.json').version")
|
|
17
|
+
export VERSION
|
|
17
18
|
# 输出项目版本号
|
|
18
19
|
echo "项目版本: $VERSION"
|
|
19
20
|
|
|
@@ -23,6 +24,16 @@ cd "$PROJECT_ROOT"
|
|
|
23
24
|
# 导出 PROJECT_ROOT 供 before_build.sh 使用
|
|
24
25
|
export PROJECT_ROOT
|
|
25
26
|
|
|
27
|
+
# Jenkins 等 CI 注入的构建号(供 Sentry release、layout window.__MICO_BUILD__ 等)
|
|
28
|
+
export BUILD_NUMBER="${BUILD_NUMBER:-}"
|
|
29
|
+
echo "BUILD_NUMBER: ${BUILD_NUMBER:-<unset>}"
|
|
30
|
+
|
|
31
|
+
export GIT_COMMIT="${GIT_COMMIT:-$(git rev-parse HEAD 2>/dev/null || echo '')}"
|
|
32
|
+
export BRANCH_OR_TAG="${BRANCH_OR_TAG:-${GIT_BRANCH:-$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo '')}}"
|
|
33
|
+
export BUILD_TIME="${BUILD_TIME:-$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")}"
|
|
34
|
+
echo "GIT_COMMIT: ${GIT_COMMIT:-<empty>}"
|
|
35
|
+
echo "BRANCH_OR_TAG: ${BRANCH_OR_TAG:-<empty>}"
|
|
36
|
+
|
|
26
37
|
# 在执行构建前,计算 BASE_REF / TURBO_FILTER 等增量构建信息
|
|
27
38
|
if [ -f "$PROJECT_ROOT/CICD/before_build.sh" ]; then
|
|
28
39
|
# shellcheck disable=SC1090
|
|
@@ -19,7 +19,7 @@ const config: ReturnType<typeof defineConfig> = {
|
|
|
19
19
|
window.__MICO_MENUS__ = ${JSON.stringify(mockMenus)};
|
|
20
20
|
window.__MICO_PAGES__ = ${JSON.stringify(mockPages)};
|
|
21
21
|
window.__MICO_CONFIG__ = {
|
|
22
|
-
appId: '<%=
|
|
22
|
+
appId: '<%= appId %>',
|
|
23
23
|
appName: '<%= projectName %>',
|
|
24
24
|
title: '测试样例',
|
|
25
25
|
logo: '',
|
|
@@ -34,8 +34,14 @@ const config: ReturnType<typeof defineConfig> = {
|
|
|
34
34
|
// 关闭权限控制(调试用)
|
|
35
35
|
disableAuth: false,
|
|
36
36
|
// SSO 外跳地址(与 resolveExternalLoginPath 读取的 externalLoginPath 一致;生产由注入的 __MICO_CONFIG__ 提供)
|
|
37
|
-
externalLoginPath:
|
|
38
|
-
|
|
37
|
+
externalLoginPath: 'https://micous-idp.cig.tencentcs.com/sso/tn-456d1d3feb5f4e09ad28ab35ee4d2e66/ai-138064426b9e43818098705df5400eef/cas',
|
|
38
|
+
// 多语言中台(可选):intl 与 common-intl 包 initIntl 合并;见 packages/common-intl/README.md
|
|
39
|
+
// 这里只是一个例子,需要根据业务在翻译中台的配置来替换
|
|
40
|
+
// intl: {
|
|
41
|
+
// tag: 'cs_fe_pc',
|
|
42
|
+
// app_name: 'middle',
|
|
43
|
+
// indexedDBParams: { dbName: 'mico_cs_pc_i18n_db' },
|
|
44
|
+
// },
|
|
39
45
|
};
|
|
40
46
|
`,
|
|
41
47
|
},
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
// https://umijs.org/config/
|
|
2
2
|
|
|
3
3
|
import { defineConfig } from '@umijs/max';
|
|
4
|
+
import { readFileSync } from 'node:fs';
|
|
5
|
+
import { join } from 'node:path';
|
|
4
6
|
// 开发环境,不上传 sourcemap。调试时如有需要再解开
|
|
5
7
|
// import { applySentryPlugin } from "../../../scripts/apply-sentry-plugin";
|
|
8
|
+
const packageVersion: string = JSON.parse(
|
|
9
|
+
readFileSync(join(__dirname, '../../../package.json'), 'utf-8'),
|
|
10
|
+
).version;
|
|
6
11
|
const { CDN_PUBLIC_PATH } = process.env;
|
|
7
12
|
|
|
8
13
|
const PUBLIC_PATH: string = CDN_PUBLIC_PATH
|
|
@@ -33,6 +38,11 @@ const config: ReturnType<typeof defineConfig> = {
|
|
|
33
38
|
'https://dashboard-api-test.micoplatform.com/api/yufu_login/',
|
|
34
39
|
'process.env.REFRESH_ENDPOINT':
|
|
35
40
|
'https://dashboard-api-test.micoplatform.com/api/yufu_login/refresh/',
|
|
41
|
+
'process.env.BUILD_NUMBER': process.env.BUILD_NUMBER ?? '',
|
|
42
|
+
'process.env.BRANCH_OR_TAG': process.env.BRANCH_OR_TAG ?? '',
|
|
43
|
+
'process.env.GIT_COMMIT': process.env.GIT_COMMIT ?? '',
|
|
44
|
+
'process.env.VERSION': process.env.VERSION ?? packageVersion,
|
|
45
|
+
'process.env.BUILD_TIME': process.env.BUILD_TIME ?? '',
|
|
36
46
|
'process.env.LOCALE_REQUEST_URL':
|
|
37
47
|
'https://api-test.micoplatform.com/lang_server/pull',
|
|
38
48
|
},
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
// https://umijs.org/config/
|
|
2
2
|
|
|
3
3
|
import { defineConfig } from '@umijs/max';
|
|
4
|
+
import { readFileSync } from 'node:fs';
|
|
5
|
+
import { join } from 'node:path';
|
|
4
6
|
// 测试环境,不上传 sourcemap。调试时如有需要再解开
|
|
5
7
|
// import { applySentryPlugin } from "../../../scripts/apply-sentry-plugin";
|
|
8
|
+
const packageVersion: string = JSON.parse(
|
|
9
|
+
readFileSync(join(__dirname, '../../../package.json'), 'utf-8'),
|
|
10
|
+
).version;
|
|
6
11
|
const { CDN_PUBLIC_PATH } = process.env;
|
|
7
12
|
|
|
8
13
|
const PUBLIC_PATH: string = CDN_PUBLIC_PATH
|
|
@@ -33,6 +38,11 @@ const config: ReturnType<typeof defineConfig> = {
|
|
|
33
38
|
'https://dashboard-api-test.micoplatform.com/api/yufu_login/',
|
|
34
39
|
'process.env.REFRESH_ENDPOINT':
|
|
35
40
|
'https://dashboard-api-test.micoplatform.com/api/yufu_login/refresh/',
|
|
41
|
+
'process.env.BUILD_NUMBER': process.env.BUILD_NUMBER ?? '',
|
|
42
|
+
'process.env.BRANCH_OR_TAG': process.env.BRANCH_OR_TAG ?? '',
|
|
43
|
+
'process.env.GIT_COMMIT': process.env.GIT_COMMIT ?? '',
|
|
44
|
+
'process.env.VERSION': process.env.VERSION ?? packageVersion,
|
|
45
|
+
'process.env.BUILD_TIME': process.env.BUILD_TIME ?? '',
|
|
36
46
|
'process.env.LOCALE_REQUEST_URL':
|
|
37
47
|
'https://api-test.micoplatform.com/lang_server/pull',
|
|
38
48
|
},
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
// https://umijs.org/config/
|
|
2
2
|
|
|
3
3
|
import { defineConfig } from '@umijs/max';
|
|
4
|
+
import { readFileSync } from 'node:fs';
|
|
5
|
+
import { join } from 'node:path';
|
|
4
6
|
import { applySentryPlugin } from '../../../scripts/apply-sentry-plugin';
|
|
7
|
+
|
|
8
|
+
const packageVersion: string = JSON.parse(
|
|
9
|
+
readFileSync(join(__dirname, '../../../package.json'), 'utf-8'),
|
|
10
|
+
).version;
|
|
11
|
+
|
|
5
12
|
const { CDN_PUBLIC_PATH } = process.env;
|
|
6
13
|
|
|
7
14
|
const PUBLIC_PATH: string = CDN_PUBLIC_PATH
|
|
@@ -21,6 +28,11 @@ const config: ReturnType<typeof defineConfig> = {
|
|
|
21
28
|
'https://dashboard-api.micoplatform.com/api/yufu_login/',
|
|
22
29
|
'process.env.REFRESH_ENDPOINT':
|
|
23
30
|
'https://dashboard-api.micoplatform.com/api/yufu_login/refresh/',
|
|
31
|
+
'process.env.BUILD_NUMBER': process.env.BUILD_NUMBER ?? '',
|
|
32
|
+
'process.env.BRANCH_OR_TAG': process.env.BRANCH_OR_TAG ?? '',
|
|
33
|
+
'process.env.GIT_COMMIT': process.env.GIT_COMMIT ?? '',
|
|
34
|
+
'process.env.VERSION': process.env.VERSION ?? packageVersion,
|
|
35
|
+
'process.env.BUILD_TIME': process.env.BUILD_TIME ?? '',
|
|
24
36
|
'process.env.LOCALE_REQUEST_URL':
|
|
25
37
|
'https://api.micoplatform.com/lang_server/pull',
|
|
26
38
|
},
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# 国际化(common-intl 与 Umi 兜底)
|
|
2
|
+
|
|
3
|
+
> 创建时间:2026-04-07
|
|
4
|
+
|
|
5
|
+
## 功能概述
|
|
6
|
+
|
|
7
|
+
layout 主应用通过 **`<%= packageScope %>/common-intl`**(`packages/common-intl` 中转包)绑定中台 **`tag`**,在 **`app.tsx`** 中 **`configureLocale`** 与 Umi **`umi_locale`** 对齐;当 **`window.__MICO_CONFIG__.intl` 或 `commonIntl`** 含有效 **`tag`、`app_name`** 时视为启用中台,首屏在 **`render`** 中 **`fetchMultilingualData`**。业务侧统一使用 **`useLayoutIntl()`**:**`i18n` 优先**,与 `defaultMessage` 比较后未命中则 **Umi `formatMessage`**(`src/locales/*`)。未启用中台时 **仅 Umi**。
|
|
8
|
+
|
|
9
|
+
## 技术方案
|
|
10
|
+
|
|
11
|
+
### 技术栈
|
|
12
|
+
|
|
13
|
+
- Umi 4 `@umijs/max`:`locale` 运行时、`export const locale`、`useIntl`
|
|
14
|
+
- `<%= packageScope %>/common-intl`:`configureLocale`、`fetchMultilingualData`、`i18n`、`intl`(包内 `initIntl`)
|
|
15
|
+
- 门控与类型:`src/common/intl/intlRuntime.ts`、`types.ts`
|
|
16
|
+
|
|
17
|
+
### 核心实现
|
|
18
|
+
|
|
19
|
+
1. **`app.tsx`**:最早 **`configureLocale({ getLocale, setLocale })`**,与 **`getCurrentLocale`** / **`setLocaleToStorage`**(`src/common/locale.ts`)及 **`localeMapping`** 一致;**`export const locale`** 供 Umi 插件;**`render`** 仅在 **`isCommonIntlEnabled()`** 为真时调用 **`fetchMultilingualData`**(`request`、`Message`、`lang`、`LOCALE_REQUEST_URL`)。
|
|
20
|
+
2. **`useLayoutIntl.ts`**:读取 **`isCommonIntlEnabled()`**;启用时 **`i18n({ key, defaultMessage })`**,否则直接 **`useIntl().formatMessage`**;兜底规则与 **`defaultMessage`**、Umi 结果比较(同子应用 **`useSubappIntl`** 策略)。
|
|
21
|
+
3. **全局暴露**:**`window.CommonIntl`** 指向包模块,供子应用 **externals** 复用。
|
|
22
|
+
4. **包内实现**:**`packages/common-intl/src/intl.ts`** 中 **`initIntl`** 合并 **`__MICO_CONFIG__`** 与默认 tag,详见包 README。
|
|
23
|
+
|
|
24
|
+
## 文件清单(相对 `apps/layout`)
|
|
25
|
+
|
|
26
|
+
| 文件路径 | 说明 |
|
|
27
|
+
| --- | --- |
|
|
28
|
+
| `src/common/intl/useLayoutIntl.ts` | 页面统一 Hook |
|
|
29
|
+
| `src/common/intl/intlRuntime.ts` | `isCommonIntlEnabled`、`getCommonIntlConfig` |
|
|
30
|
+
| `src/common/intl/localeMapping.ts` | Umi locale ↔ `ILang` |
|
|
31
|
+
| `src/common/intl/types.ts` | `IMicoConfigCommonIntl` |
|
|
32
|
+
| `src/common/intl/index.ts` | 导出 `useLayoutIntl`、`intl`、`isCommonIntlEnabled` 等 |
|
|
33
|
+
| `src/common/locale.ts` | URL / storage / 浏览器语言(与 Umi 一致) |
|
|
34
|
+
| `src/app.tsx` | `configureLocale`、`locale`、`render`、**`window.CommonIntl`** |
|
|
35
|
+
| `config/config.ts` | `locale` 插件(`default`、`antd: false`、`baseNavigator: false`) |
|
|
36
|
+
| `src/locales/zh-CN.ts`、`en-US.ts` | Umi 兜底文案 |
|
|
37
|
+
| `src/pages/Home/index.tsx` | 国际化用法示例(可选参考) |
|
|
38
|
+
|
|
39
|
+
## API / 组件接口
|
|
40
|
+
|
|
41
|
+
### `useLayoutIntl`
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
const {
|
|
45
|
+
formatMessage, // 与 useIntl 相同 descriptor / values 签名
|
|
46
|
+
commonIntlEnabled, // 是否启用中台(有效 tag + app_name)
|
|
47
|
+
locale, // 当前 Umi 风格 locale(getCurrentLocale)
|
|
48
|
+
intl, // 包内便捷对象,仅 commonIntlEnabled 为 true 时非 undefined
|
|
49
|
+
} = useLayoutIntl();
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### `window.__MICO_CONFIG__.intl` / `commonIntl`
|
|
53
|
+
|
|
54
|
+
二者取其一(见 `intlRuntime`),字段含义一致:
|
|
55
|
+
|
|
56
|
+
| 字段 | 说明 |
|
|
57
|
+
| --- | --- |
|
|
58
|
+
| `tag` | 多语言中台 tag(必填) |
|
|
59
|
+
| `app_name` | 中台应用名(必填) |
|
|
60
|
+
| `indexedDBParams` | 可选本地缓存参数 |
|
|
61
|
+
|
|
62
|
+
## 使用示例
|
|
63
|
+
|
|
64
|
+
**运行时注入(示例):**
|
|
65
|
+
|
|
66
|
+
```javascript
|
|
67
|
+
window.__MICO_CONFIG__ = {
|
|
68
|
+
commonIntl: {
|
|
69
|
+
tag: 'cs_fe_pc',
|
|
70
|
+
app_name: 'middle',
|
|
71
|
+
indexedDBParams: { dbName: 'mico_cs_web_i18n_db' },
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**页面:**
|
|
77
|
+
|
|
78
|
+
```tsx
|
|
79
|
+
import { useLayoutIntl } from '@/common/intl';
|
|
80
|
+
|
|
81
|
+
const { formatMessage, commonIntlEnabled, locale } = useLayoutIntl();
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<span>
|
|
85
|
+
{formatMessage({ id: 'page.home.title', defaultMessage: '首页' })}
|
|
86
|
+
</span>
|
|
87
|
+
);
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**包内预置文案(中台 key 亦可走 `i18n`):**
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
import { intl } from '@/common/intl';
|
|
94
|
+
|
|
95
|
+
intl.common_hello();
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## 设计决策
|
|
99
|
+
|
|
100
|
+
| 决策点 | 选择 | 理由 |
|
|
101
|
+
| --- | --- | --- |
|
|
102
|
+
| 门控 | `intl` 与 `commonIntl` 字段兼容 | 与注入脚本、历史配置一致 |
|
|
103
|
+
| 首屏拉取 | 仅 `isCommonIntlEnabled()` 时 `render` 内 fetch | 未配置中台时不阻塞首屏 |
|
|
104
|
+
| 合并策略 | `i18n` 与 Umi 二选一兜底 | 与微前端子应用 `useSubappIntl` 对齐,便于维护 |
|
|
105
|
+
|
|
106
|
+
## 已知限制与待改进
|
|
107
|
+
|
|
108
|
+
- **`LOCALE_REQUEST_URL`** 未配置时,行为依赖上游 **`fetchMultilingualData`** 实现。
|
|
109
|
+
- 中台文案与 **`src/locales`** 的 key 需自行约定,避免重复 id 语义冲突。
|
|
110
|
+
|
|
111
|
+
## 注意事项
|
|
112
|
+
|
|
113
|
+
- 修改语言时请走与 **`getCurrentLocale`** / **`setLocaleToStorage`** 一致的入口,避免与 **`configureLocale`** 脱节。
|
|
114
|
+
- 子应用不复制上述 **`render`** 逻辑时,嵌入主应用后通常仍依赖主应用已加载的 **`CommonIntl`**;独立运行子应用需自行 **`render` + fetch**(见子应用模板文档)。
|
|
115
|
+
|
|
116
|
+
## 相关文档
|
|
117
|
+
|
|
118
|
+
- [packages/common-intl README](../../../../packages/common-intl/README.md)
|
|
119
|
+
- [Layout 国际化(CLI 仓库总览)](../../../../../../docs/feat-layout-国际化翻译.md)
|
|
120
|
+
- [子应用国际化(模板内说明)](../../../../../subapp-react/templates/homepage/docs/feature-国际化.md)
|
|
121
|
+
- [微前端模式](./feature-微前端模式.md)(主应用暴露 `CommonIntl`)
|
|
@@ -136,6 +136,14 @@ interface MicroAppProps {
|
|
|
136
136
|
|
|
137
137
|
**说明**:子应用在 `mount` 生命周期中通过 `props` 接收这些数据。
|
|
138
138
|
|
|
139
|
+
### 国际化(common-intl)
|
|
140
|
+
|
|
141
|
+
- **共享文案(默认)**:主应用在 `render` 中拉取中台后,子应用 `import { intl } from '<%= packageScope %>/common-intl'` 即可(与主应用同一默认 tag),详见 `packages/common-intl/README.md`。
|
|
142
|
+
- **不同 tag**:上游支持多次 `initIntl`,子应用可对同一依赖再绑定一套 tag 并在子应用 `render` 中拉取;或直连 `@common-web/common-intl`,见 README「不同 tag」。
|
|
143
|
+
- **可选模板层**:若子应用需 `formatMessage` 式 API 与 Umi 兜底,见仓库 `docs/feat-subapp-国际化翻译.md`(生成项目根目录文档以实际为准)。
|
|
144
|
+
|
|
145
|
+
主应用 **不向** 子应用 props 传递 `commonIntl`;子应用 **locale** 以 props 与主应用对齐(见上表 `locale`)。
|
|
146
|
+
|
|
139
147
|
### 子应用 Props 更新机制
|
|
140
148
|
|
|
141
149
|
主应用通过 qiankun 的 `update()` 方法实时通知子应用状态变化,无需重新加载:
|
|
@@ -116,6 +116,20 @@ const mockMenus: MockMenuItem[] = [
|
|
|
116
116
|
adminOnly: true,
|
|
117
117
|
children: [],
|
|
118
118
|
},
|
|
119
|
+
{
|
|
120
|
+
id: 9,
|
|
121
|
+
name: '小组管理',
|
|
122
|
+
nameEn: 'Group Management',
|
|
123
|
+
nameKey: 'cs_web_menu_group_management',
|
|
124
|
+
type: 'page',
|
|
125
|
+
path: '/group-management',
|
|
126
|
+
icon: 'Group',
|
|
127
|
+
enabled: true,
|
|
128
|
+
sortOrder: 4,
|
|
129
|
+
pageId: 125,
|
|
130
|
+
adminOnly: true,
|
|
131
|
+
children: [],
|
|
132
|
+
}
|
|
119
133
|
];
|
|
120
134
|
|
|
121
135
|
export default mockMenus;
|
|
@@ -31,7 +31,7 @@ const mockPages: PublicPageItem[] = [
|
|
|
31
31
|
// htmlUrl:
|
|
32
32
|
// 'https://cdn-portal.micoplatform.com/portal-center/common-web/0.0.2/login/index.html',
|
|
33
33
|
htmlUrl:
|
|
34
|
-
'https://cdn-portal.micoplatform.com/portal-center/common-web/0.0.
|
|
34
|
+
'https://cdn-portal.micoplatform.com/portal-center/common-web/0.0.9/login/index.html',
|
|
35
35
|
jsUrls: [],
|
|
36
36
|
cssUrls: [],
|
|
37
37
|
prefixPath: '/user',
|
|
@@ -51,7 +51,27 @@ const mockPages: PublicPageItem[] = [
|
|
|
51
51
|
// htmlUrl:
|
|
52
52
|
// 'https://cdn-portal.micoplatform.com/portal-center/common-web/0.0.3/permission/index.html',
|
|
53
53
|
htmlUrl:
|
|
54
|
-
'https://cdn-portal.micoplatform.com/portal-center/common-web/0.0.
|
|
54
|
+
'https://cdn-portal.micoplatform.com/portal-center/common-web/0.0.9/permission/index.html',
|
|
55
|
+
jsUrls: [],
|
|
56
|
+
cssUrls: [],
|
|
57
|
+
prefixPath: '',
|
|
58
|
+
routeMode: 'prefix',
|
|
59
|
+
enabled: true,
|
|
60
|
+
accessControlEnabled: true,
|
|
61
|
+
adminOnly: true,
|
|
62
|
+
routeKey: null,
|
|
63
|
+
mainDocumentId: 59,
|
|
64
|
+
version: 'v2026.02.26-04.13-419',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: 125,
|
|
68
|
+
name: '小组管理',
|
|
69
|
+
route: '/group-management',
|
|
70
|
+
base: '/',
|
|
71
|
+
// htmlUrl:
|
|
72
|
+
// 'https://cdn-portal.micoplatform.com/portal-center/common-web/0.0.3/permission/index.html',
|
|
73
|
+
htmlUrl:
|
|
74
|
+
'https://cdn-portal.micoplatform.com/portal-center/common-web/0.0.9/group-management/index.html',
|
|
55
75
|
jsUrls: [],
|
|
56
76
|
cssUrls: [],
|
|
57
77
|
prefixPath: '',
|
|
@@ -22,6 +22,8 @@
|
|
|
22
22
|
"test": "cross-env UMI_ENV=test max dev"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
+
"<%= packageScope %>/common-intl": "workspace:*",
|
|
26
|
+
"<%= packageScope %>/shared": "workspace:*",
|
|
25
27
|
"@mico-platform/ui": "<%= micoUiVersion %>",
|
|
26
28
|
"@mico-platform/theme": "<%= themeVersion %>",
|
|
27
29
|
"@umijs/max": "^4.6.15",
|
|
@@ -29,8 +31,7 @@
|
|
|
29
31
|
"qiankun": "^2.10.16",
|
|
30
32
|
"react": "^18.2.0",
|
|
31
33
|
"react-dom": "^18.2.0",
|
|
32
|
-
"spark-md5": "^3.0.2"
|
|
33
|
-
"<%= packageScope %>/common-intl": "workspace:*"
|
|
34
|
+
"spark-md5": "^3.0.2"
|
|
34
35
|
},
|
|
35
36
|
"devDependencies": {
|
|
36
37
|
"@types/react": "^18.0.33",
|
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
import { history, type RequestConfig } from '@umijs/max';
|
|
2
2
|
import { addGlobalUncaughtErrorHandler } from 'qiankun';
|
|
3
|
+
import * as CommonWebSentry from '@common-web/sentry';
|
|
3
4
|
import { SentryErrorBoundary } from '@common-web/sentry';
|
|
4
5
|
import { errorConfig } from './requestErrorConfig';
|
|
5
6
|
// 将 @mico-platform/ui 暴露到 window,供子应用 externals 使用
|
|
6
7
|
import * as micoUI from '@mico-platform/ui';
|
|
8
|
+
import dayjs from 'dayjs';
|
|
7
9
|
import React from 'react';
|
|
8
10
|
import ReactDOM from 'react-dom';
|
|
9
11
|
|
|
12
|
+
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
|
13
|
+
import dayjsTimezone from 'dayjs/plugin/timezone';
|
|
14
|
+
import dayjsUtc from 'dayjs/plugin/utc';
|
|
10
15
|
import { request as commonRequest } from './common/request';
|
|
16
|
+
import { configureRequest } from '<%= packageScope %>/shared/services';
|
|
17
|
+
import { configureTimezone } from '<%= packageScope %>/shared/timezone';
|
|
18
|
+
import { getTimezone } from '@/common/helpers';
|
|
11
19
|
import {
|
|
20
|
+
configureLocale,
|
|
12
21
|
fetchMultilingualData,
|
|
13
|
-
getCurrentLocale as getIntlLocale,
|
|
14
22
|
type ILang,
|
|
15
23
|
} from '<%= packageScope %>/common-intl';
|
|
16
24
|
import * as CommonIntl from '<%= packageScope %>/common-intl';
|
|
@@ -30,10 +38,32 @@ import {
|
|
|
30
38
|
} from './common/request/sso';
|
|
31
39
|
import { initTheme } from './common/theme';
|
|
32
40
|
import MicroAppLoader from './components/MicroAppLoader';
|
|
41
|
+
import { isCommonIntlEnabled } from '@/common/intl';
|
|
33
42
|
import { isNoAuthRoute } from '@/constants';
|
|
34
|
-
import { getCurrentLocale } from '@/common/locale';
|
|
35
43
|
import '@mico-platform/theme/dist/css/theme.css';
|
|
36
44
|
import './global.less';
|
|
45
|
+
import { getCurrentLocale, setLocaleToStorage } from './common/locale';
|
|
46
|
+
import { ilangToUmiLocale, umiLocaleToILang } from '@/common/intl/localeMapping';
|
|
47
|
+
|
|
48
|
+
// 主应用:将统一 request 注入 shared 包,供共享服务层(getRequest)使用
|
|
49
|
+
// 注意:模块顶层注入,确保任何业务调用 getRequest() 之前已就绪
|
|
50
|
+
configureRequest(commonRequest as <T = unknown>(url: string, options?: Record<string, unknown>) => Promise<T>);
|
|
51
|
+
|
|
52
|
+
// 主应用:扩展 dayjs 插件并注入「当前 IANA 时区」获取器,供 shared/timezone 使用
|
|
53
|
+
// 说明:apps/layout/src/common/helpers.ts 已扩展 utc/timezone,此处再补 customParseFormat(shared/timezone 的 parseDateInTimezone 需要它)
|
|
54
|
+
// dayjs.extend 内部去重,重复调用安全
|
|
55
|
+
dayjs.extend(dayjsUtc);
|
|
56
|
+
dayjs.extend(dayjsTimezone);
|
|
57
|
+
dayjs.extend(customParseFormat);
|
|
58
|
+
configureTimezone({ getTimezone });
|
|
59
|
+
|
|
60
|
+
// 主应用:common-intl initIntl 的 getLocale/setLocale 与 Umi `umi_locale` 单一数据源对齐(见 packages/common-intl configureLocale)
|
|
61
|
+
configureLocale({
|
|
62
|
+
getLocale: () => umiLocaleToILang(getCurrentLocale()),
|
|
63
|
+
setLocale: (lang: ILang) => {
|
|
64
|
+
setLocaleToStorage(ilangToUmiLocale(lang));
|
|
65
|
+
},
|
|
66
|
+
});
|
|
37
67
|
|
|
38
68
|
// ==================== qiankun 全局错误处理 ====================
|
|
39
69
|
// 捕获子应用运行时未捕获的异常,防止页面崩溃
|
|
@@ -87,15 +117,31 @@ if (typeof window !== 'undefined') {
|
|
|
87
117
|
// 注意:这里不阻止错误冒泡,让控制台仍能显示原始错误
|
|
88
118
|
// 如果需要阻止,可以 return true
|
|
89
119
|
});
|
|
120
|
+
|
|
121
|
+
// 注入构建信息
|
|
122
|
+
if (typeof window !== 'undefined') {
|
|
123
|
+
window.__MICO_BUILD__ = {
|
|
124
|
+
branchOrTag: process.env.BRANCH_OR_TAG,
|
|
125
|
+
gitCommit: process.env.GIT_COMMIT,
|
|
126
|
+
version: process.env.VERSION,
|
|
127
|
+
buildTime: dayjs(process.env.BUILD_TIME).format('YYYY-MM-DD HH:mm:ss'),
|
|
128
|
+
buildNumber: process.env.BUILD_NUMBER,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
90
131
|
}
|
|
91
132
|
|
|
92
133
|
// ==================== 微前端共享依赖 ====================
|
|
93
134
|
// 将公共库暴露到 window,供子应用复用,避免重复打包
|
|
94
135
|
// 子应用通过 externals 配置引用这些全局变量
|
|
95
|
-
if (typeof window !== 'undefined') {
|
|
136
|
+
if (typeof window !== 'undefined' && process.env.NODE_ENV === 'development') {
|
|
96
137
|
const win = window as unknown as Record<string, unknown>;
|
|
97
138
|
win.React = React;
|
|
98
139
|
win.ReactDOM = ReactDOM;
|
|
140
|
+
win.CommonWebSentry = CommonWebSentry;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (typeof window !== 'undefined') {
|
|
144
|
+
const win = window as unknown as Record<string, unknown>;
|
|
99
145
|
win.micoUI = micoUI;
|
|
100
146
|
win.CommonIntl = CommonIntl;
|
|
101
147
|
}
|
|
@@ -117,15 +163,22 @@ export const locale = {
|
|
|
117
163
|
|
|
118
164
|
// ==================== 国际化数据预加载 ====================
|
|
119
165
|
|
|
120
|
-
/**
|
|
166
|
+
/**
|
|
167
|
+
* 配置了有效 `__MICO_CONFIG__.commonIntl` 时首屏拉取中台文案;失败仍继续渲染。
|
|
168
|
+
* @see generators/micro-react/templates/packages/common-intl/README.md
|
|
169
|
+
*/
|
|
121
170
|
export function render(oldRender: () => void): void {
|
|
171
|
+
if (!isCommonIntlEnabled()) {
|
|
172
|
+
oldRender();
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
122
175
|
fetchMultilingualData({
|
|
123
176
|
requestInstance: commonRequest,
|
|
124
177
|
messageInstance: {
|
|
125
178
|
error: micoUI.Message.error,
|
|
126
179
|
warning: micoUI.Message.warning,
|
|
127
180
|
},
|
|
128
|
-
lang:
|
|
181
|
+
lang: umiLocaleToILang(getCurrentLocale()) as ILang,
|
|
129
182
|
localeRequestUrl: process.env.LOCALE_REQUEST_URL,
|
|
130
183
|
})
|
|
131
184
|
.then(oldRender)
|
|
@@ -2,12 +2,15 @@ import { authLogger } from '@/common/logger';
|
|
|
2
2
|
import { checkStaffAuth } from '@/services/auth';
|
|
3
3
|
import { handleAuthFailureRedirect } from '../request';
|
|
4
4
|
import { clearStoredTokens, getAuthInfo } from './auth-manager';
|
|
5
|
+
import { clearStoredTenantCode } from './tenant';
|
|
5
6
|
|
|
6
7
|
// 导出 STORAGE_KEYS 常量
|
|
7
8
|
export { STORAGE_KEYS } from '../../constants';
|
|
8
9
|
|
|
9
10
|
export function logout(): void {
|
|
10
11
|
clearStoredTokens();
|
|
12
|
+
// 清理当前租户,避免切换账号后残留
|
|
13
|
+
clearStoredTenantCode();
|
|
11
14
|
}
|
|
12
15
|
|
|
13
16
|
/**
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { getFromStorage, removeStorage, setStorage } from '@/common/helpers';
|
|
2
|
+
import { STORAGE_KEYS } from '@/constants';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 当前租户 code 存储工具
|
|
6
|
+
*
|
|
7
|
+
* 多租户模式下,当前选中的租户会被持久化到 localStorage,
|
|
8
|
+
* 在调用 `fetchUserInfo` 时作为 `tenant` 参数传给后端,
|
|
9
|
+
* 以获取对应租户的 menu_perms / button_perms / region_perms。
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export const getStoredTenantCode = (): string | null => {
|
|
13
|
+
return getFromStorage(STORAGE_KEYS.CURRENT_TENANT);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const setStoredTenantCode = (code: string): void => {
|
|
17
|
+
if (!code) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
setStorage(STORAGE_KEYS.CURRENT_TENANT, code);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const clearStoredTenantCode = (): void => {
|
|
24
|
+
removeStorage(STORAGE_KEYS.CURRENT_TENANT);
|
|
25
|
+
};
|