generator-mico-cli 0.2.28 → 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.
Files changed (112) hide show
  1. package/README.md +7 -20
  2. package/bin/mico.js +27 -62
  3. package/generators/micro-react/index.js +25 -1
  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/CICD/start_dev.sh +11 -0
  7. package/generators/micro-react/templates/CICD/start_local.sh +9 -0
  8. package/generators/micro-react/templates/CICD/start_prod.sh +13 -0
  9. package/generators/micro-react/templates/CICD/start_test.sh +11 -0
  10. package/generators/micro-react/templates/CLAUDE.md +1 -0
  11. package/generators/micro-react/templates/README.md +1 -1
  12. package/generators/micro-react/templates/apps/layout/config/config.dev.ts +13 -5
  13. package/generators/micro-react/templates/apps/layout/config/config.prod.development.ts +12 -0
  14. package/generators/micro-react/templates/apps/layout/config/config.prod.testing.ts +12 -0
  15. package/generators/micro-react/templates/apps/layout/config/config.prod.ts +14 -0
  16. 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
  17. package/generators/micro-react/templates/apps/layout/docs/feature-/345/233/275/351/231/205/345/214/226.md +121 -0
  18. 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
  19. 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
  20. 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
  21. 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
  22. package/generators/micro-react/templates/apps/layout/mock/api.mock.ts +23 -31
  23. package/generators/micro-react/templates/apps/layout/mock/menus.ts +14 -0
  24. package/generators/micro-react/templates/apps/layout/mock/pages.ts +27 -8
  25. package/generators/micro-react/templates/apps/layout/package.json +2 -0
  26. package/generators/micro-react/templates/apps/layout/src/app.tsx +85 -4
  27. package/generators/micro-react/templates/apps/layout/src/common/auth/index.ts +3 -0
  28. package/generators/micro-react/templates/apps/layout/src/common/auth/tenant.ts +25 -0
  29. package/generators/micro-react/templates/apps/layout/src/common/auth/type.ts +41 -27
  30. package/generators/micro-react/templates/apps/layout/src/common/intl/formatLayoutMessage.ts +30 -0
  31. package/generators/micro-react/templates/apps/layout/src/common/intl/index.ts +6 -0
  32. package/generators/micro-react/templates/apps/layout/src/common/intl/intlRuntime.ts +14 -0
  33. package/generators/micro-react/templates/apps/layout/src/common/intl/localeMapping.ts +30 -0
  34. package/generators/micro-react/templates/apps/layout/src/common/intl/types.ts +14 -0
  35. package/generators/micro-react/templates/apps/layout/src/common/intl/useLayoutIntl.ts +40 -0
  36. package/generators/micro-react/templates/apps/layout/src/common/logger.ts +3 -4
  37. package/generators/micro-react/templates/apps/layout/src/common/menu/parser.ts +148 -85
  38. package/generators/micro-react/templates/apps/layout/src/common/menu/types.ts +29 -6
  39. package/generators/micro-react/templates/apps/layout/src/common/micro/types.ts +23 -0
  40. package/generators/micro-react/templates/apps/layout/src/common/portal-data.ts +46 -2
  41. package/generators/micro-react/templates/apps/layout/src/common/request/sso.ts +74 -15
  42. package/generators/micro-react/templates/apps/layout/src/common/request/token-refresh.ts +2 -0
  43. package/generators/micro-react/templates/apps/layout/src/components/MicroAppLoader/index.tsx +32 -6
  44. package/generators/micro-react/templates/apps/layout/src/components/PermissionFilter/index.tsx +51 -0
  45. package/generators/micro-react/templates/apps/layout/src/components/RightContent/AvatarDropdown.tsx +10 -1
  46. package/generators/micro-react/templates/apps/layout/src/components/RightContent/TenantDropdown.tsx +76 -0
  47. package/generators/micro-react/templates/apps/layout/src/components/RightContent/index.ts +1 -0
  48. package/generators/micro-react/templates/apps/layout/src/components/RightContent/tenant-dropdown.less +48 -0
  49. package/generators/micro-react/templates/apps/layout/src/constants/index.ts +1 -0
  50. package/generators/micro-react/templates/apps/layout/src/hooks/index.ts +1 -0
  51. package/generators/micro-react/templates/apps/layout/src/hooks/useMenuState.ts +18 -0
  52. package/generators/micro-react/templates/apps/layout/src/hooks/useTenant.ts +41 -0
  53. package/generators/micro-react/templates/apps/layout/src/layouts/components/header/index.tsx +4 -1
  54. package/generators/micro-react/templates/apps/layout/src/layouts/components/menu/index.tsx +21 -9
  55. package/generators/micro-react/templates/apps/layout/src/layouts/index.tsx +105 -60
  56. package/generators/micro-react/templates/apps/layout/src/locales/en-US.ts +28 -0
  57. package/generators/micro-react/templates/apps/layout/src/locales/zh-CN.ts +26 -0
  58. package/generators/micro-react/templates/apps/layout/src/pages/404/index.tsx +7 -3
  59. package/generators/micro-react/templates/apps/layout/src/pages/Home/index.less +32 -0
  60. package/generators/micro-react/templates/apps/layout/src/pages/Home/index.tsx +148 -4
  61. package/generators/micro-react/templates/apps/layout/src/requestErrorConfig.ts +2 -1
  62. package/generators/micro-react/templates/apps/layout/src/services/user.ts +79 -21
  63. package/generators/micro-react/templates/apps/layout/typings.d.ts +16 -0
  64. package/generators/micro-react/templates/docs/package-shared.md +189 -0
  65. package/generators/micro-react/templates/package.json +1 -1
  66. package/generators/micro-react/templates/packages/common-intl/README.md +78 -368
  67. package/generators/micro-react/templates/packages/common-intl/package.json +3 -13
  68. package/generators/micro-react/templates/packages/common-intl/src/index.ts +5 -6
  69. package/generators/micro-react/templates/packages/common-intl/src/intl.ts +115 -28
  70. package/generators/micro-react/templates/packages/common-intl/src/umiLocaleBridge.ts +101 -0
  71. package/generators/micro-react/templates/packages/common-intl/tsconfig.json +2 -4
  72. package/generators/micro-react/templates/packages/shared/README.md +120 -0
  73. package/generators/micro-react/templates/packages/shared/package.json +26 -0
  74. package/generators/micro-react/templates/packages/shared/services/common/index.ts +43 -0
  75. package/generators/micro-react/templates/packages/shared/services/index.ts +21 -0
  76. package/generators/micro-react/templates/packages/shared/services/request.ts +43 -0
  77. package/generators/micro-react/templates/packages/shared/timezone/index.ts +228 -0
  78. package/generators/micro-react/templates/packages/shared/tsconfig.json +20 -0
  79. package/generators/micro-react/templates/scripts/apply-sentry-plugin.ts +6 -1
  80. package/generators/micro-react/templates/turbo.json +9 -1
  81. package/generators/subapp-react/index.js +28 -22
  82. package/generators/subapp-react/templates/homepage/README.md +1 -0
  83. package/generators/subapp-react/templates/homepage/config/config.prod.development.ts +1 -0
  84. package/generators/subapp-react/templates/homepage/config/config.prod.testing.ts +1 -0
  85. package/generators/subapp-react/templates/homepage/config/config.prod.ts +1 -0
  86. package/generators/subapp-react/templates/homepage/config/config.ts +10 -0
  87. package/generators/subapp-react/templates/homepage/docs/feature-PermissionFilter/346/214/211/351/222/256/346/235/203/351/231/220.md +35 -0
  88. package/generators/subapp-react/templates/homepage/docs/feature-/345/233/275/351/231/205/345/214/226.md +124 -0
  89. package/generators/subapp-react/templates/homepage/package.json +3 -1
  90. package/generators/subapp-react/templates/homepage/src/app.tsx +104 -2
  91. package/generators/subapp-react/templates/homepage/src/common/intl/index.ts +15 -0
  92. package/generators/subapp-react/templates/homepage/src/common/intl/intlRuntime.ts +14 -0
  93. package/generators/subapp-react/templates/homepage/src/common/intl/localeMapping.ts +24 -0
  94. package/generators/subapp-react/templates/homepage/src/common/intl/subappIntlConfig.ts +28 -0
  95. package/generators/subapp-react/templates/homepage/src/common/intl/subappLocale.ts +18 -0
  96. package/generators/subapp-react/templates/homepage/src/common/intl/subappOwnIntl.ts +63 -0
  97. package/generators/subapp-react/templates/homepage/src/common/intl/types.ts +14 -0
  98. package/generators/subapp-react/templates/homepage/src/common/intl/useSubappIntl.ts +61 -0
  99. package/generators/subapp-react/templates/homepage/src/common/locale.ts +80 -0
  100. package/generators/subapp-react/templates/homepage/src/common/mainApp.ts +41 -2
  101. package/generators/subapp-react/templates/homepage/src/components/PermissionFilter/index.tsx +48 -0
  102. package/generators/subapp-react/templates/homepage/src/locales/en-US.ts +6 -0
  103. package/generators/subapp-react/templates/homepage/src/locales/zh-CN.ts +6 -0
  104. package/generators/subapp-react/templates/homepage/src/pages/index.less +10 -0
  105. package/generators/subapp-react/templates/homepage/src/pages/index.tsx +86 -1
  106. package/generators/subapp-react/templates/homepage/typings.d.ts +12 -0
  107. package/lib/utils.js +0 -1
  108. package/package.json +2 -2
  109. package/generators/micro-react/templates/apps/layout/docs/common-intl.md +0 -372
  110. package/generators/micro-react/templates/packages/common-intl/src/indexedDBUtils.ts +0 -51
  111. package/generators/micro-react/templates/packages/common-intl/src/utils.ts +0 -482
  112. package/generators/micro-react/templates/packages/common-intl/vite.config.ts +0 -25
package/README.md CHANGED
@@ -17,29 +17,21 @@
17
17
  ## 要求
18
18
 
19
19
  - Node >= 18
20
- - Yeoman CLI: `npm install -g yo`
21
20
 
22
21
  ## 安装和使用
23
22
 
24
23
  ```bash
25
- npm install -g yo generator-mico-cli
24
+ pnpm install -g generator-mico-cli
26
25
  ```
27
26
 
28
27
  ## 包装器 CLI
29
28
 
30
- 全局安装后,`mico` 命令可用于委托给 Yeoman 生成器。
31
- 如果 `generators/<name>` 下存在本地生成器,它将作为 `yo mico-cli:<name>` 运行。
29
+ 全局安装后,`mico` 命令可用于运行内置的 Yeoman 生成器。
32
30
 
33
31
  ```bash
34
32
  mico create subapp-react
35
33
  ```
36
34
 
37
- 等同于:
38
-
39
- ```bash
40
- yo subapp-react
41
- ```
42
-
43
35
  列出所有可用的生成器:
44
36
 
45
37
  ```bash
@@ -64,12 +56,6 @@ mico create micro-react --dry-run
64
56
  mico doctor
65
57
  ```
66
58
 
67
- 将额外参数传递给生成器:
68
-
69
- ```bash
70
- mico create micro-react -- --help
71
- ```
72
-
73
59
  ## 配置文件
74
60
 
75
61
  可以在项目目录或用户主目录创建 `.micorc` 或 `.micorc.json` 文件来预设默认值。
@@ -83,6 +69,7 @@ mico create micro-react -- --help
83
69
  ```json
84
70
  {
85
71
  "projectName": "my-app",
72
+ "appId": "portal_dev",
86
73
  "packageScope": "@my-company",
87
74
  "cdnPrefix": "portal",
88
75
  "author": "Team <team@example.com>",
@@ -96,6 +83,7 @@ mico create micro-react -- --help
96
83
  | 字段 | 类型 | 适用生成器 | 说明 | 默认值 |
97
84
  |------|------|-----------|------|--------|
98
85
  | `projectName` | string | micro-react | 项目名称 | 当前目录名 |
86
+ | `appId` | string | micro-react | 开发环境 `window.__MICO_CONFIG__.appId`(请求代理等) | `portal_dev` |
99
87
  | `packageScope` | string | 所有 | 包作用域(如 `@my-company`) | micro-react: `@<projectName>`;其他: 从根 `package.json` 检测 |
100
88
  | `cdnPrefix` | string | micro-react | CDN 路径前缀(如 `portal`、`admin/v2`) | 空字符串 |
101
89
  | `author` | string | micro-react | 作者信息 | `Your Name <email@example.com>` |
@@ -168,8 +156,7 @@ DevTools Sources 面板中可在 `webpack://<name>/src/` 下定位原始 TypeScr
168
156
  # 1. 安装依赖
169
157
  pnpm install
170
158
 
171
- # 2. 将本地包链接到全局(需要先安装 yo)
172
- npm install -g yo
159
+ # 2. 将本地包链接到全局
173
160
  npm link
174
161
 
175
162
  # 3. 验证链接成功
@@ -216,9 +203,9 @@ pnpm test:watch
216
203
  | `tests/integration/micro-react.test.js` | micro-react 生成器集成测试 |
217
204
  | `tests/integration/subapp-react.test.js` | subapp-react 生成器集成测试 |
218
205
  | `tests/integration/subapp-umd.test.js` | subapp-umd 生成器集成测试 |
219
- | `tests/integration/mico-cli.test.js` | `mico` 入口子进程测试(help / version / list / create 透传) |
206
+ | `tests/integration/mico-cli.test.js` | `mico` 入口子进程测试(help / version / list / create / doctor) |
220
207
  | `tests/helpers/setup.js` | 测试共享工具(路径常量、monorepo fixture 工厂) |
221
- | `tests/helpers/mico-subprocess.js` | 子进程运行 `bin/mico.js`、假 `yo` 工具函数 |
208
+ | `tests/helpers/mico-subprocess.js` | 子进程运行 `bin/mico.js` 工具函数 |
222
209
 
223
210
  ### Scripts 说明
224
211
 
package/bin/mico.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  'use strict';
3
3
 
4
- const { spawn, spawnSync } = require('node:child_process');
4
+ const { spawnSync } = require('node:child_process');
5
5
  const fs = require('node:fs');
6
6
  const path = require('node:path');
7
7
  const readline = require('node:readline');
@@ -56,7 +56,6 @@ Configuration:
56
56
  }
57
57
 
58
58
  Notes:
59
- Requires Yeoman CLI (yo) installed globally.
60
59
  If a local generator exists at generators/<name>, it will be used.
61
60
  `);
62
61
  }
@@ -164,15 +163,6 @@ async function runDoctor() {
164
163
  console.log(' Install: npm install -g pnpm');
165
164
  }
166
165
 
167
- // Yeoman
168
- const yoIcon = results.yo.available ? '\x1b[32m✓\x1b[0m' : '\x1b[31m✗\x1b[0m';
169
- if (results.yo.available) {
170
- console.log(` ${yoIcon} yo ${results.yo.version}`);
171
- } else {
172
- console.log(` ${yoIcon} yo not found`);
173
- console.log(' Install: npm install -g yo');
174
- }
175
-
176
166
  // Git
177
167
  const gitIcon = results.git.available ? '\x1b[32m✓\x1b[0m' : '\x1b[33m⚠\x1b[0m';
178
168
  if (results.git.available) {
@@ -205,7 +195,7 @@ async function runDoctor() {
205
195
  console.log('');
206
196
 
207
197
  // 总结
208
- const allGood = results.node.satisfied && results.pnpm.available && results.yo.available;
198
+ const allGood = results.node.satisfied && results.pnpm.available;
209
199
  if (allGood) {
210
200
  console.log(' \x1b[32m✅ All required dependencies are installed!\x1b[0m');
211
201
  } else {
@@ -351,14 +341,12 @@ function performUpdate(latestVersion) {
351
341
  /**
352
342
  * 运行 Yeoman 生成器
353
343
  * @param {string} generator - 生成器名称
354
- * @param {string[]} rest - 剩余参数
355
- * @param {string[]} passthroughArgs - 透传参数
356
344
  * @param {object} options - 选项
357
345
  * @param {boolean} options.verbose - 是否启用详细输出
358
346
  * @param {boolean} options.dryRun - 是否启用 dry-run 模式
359
347
  * @param {boolean} options.force - 是否强制覆盖已有文件
360
348
  */
361
- function runGenerator(generator, rest, passthroughArgs, options = {}) {
349
+ async function runGenerator(generator, options = {}) {
362
350
  const localGeneratorEntry = path.join(
363
351
  rootDir,
364
352
  'generators',
@@ -366,42 +354,37 @@ function runGenerator(generator, rest, passthroughArgs, options = {}) {
366
354
  'index.js'
367
355
  );
368
356
 
357
+ if (!fs.existsSync(localGeneratorEntry)) {
358
+ console.error(`❌ Cannot find generator "${generator}".`);
359
+ console.error(` Expected: ${localGeneratorEntry}`);
360
+ console.error('');
361
+ console.error(' Run "mico list" to see available generators.');
362
+ process.exit(1);
363
+ }
364
+
369
365
  const pkgName = typeof pkg.name === 'string' ? pkg.name : '';
370
366
  const localNamespace =
371
367
  pkgName.replace(/^generator-/, '') || pkgName || 'generator';
368
+ const namespace = `${localNamespace}:${generator}`;
372
369
 
373
- const yoGenerator = fs.existsSync(localGeneratorEntry)
374
- ? `${localNamespace}:${generator}`
375
- : generator;
376
-
377
- const yoArgs = [yoGenerator, ...rest];
378
-
379
- // 添加 dry-run 参数给 yeoman
380
- if (options.dryRun) {
381
- yoArgs.push('--dry-run');
382
- }
383
-
384
- if (options.force) {
385
- yoArgs.push('--force');
370
+ if (options.verbose) {
371
+ process.env.MICO_VERBOSE = '1';
386
372
  }
387
-
388
- if (passthroughArgs.length > 0) {
389
- yoArgs.push('--', ...passthroughArgs);
373
+ if (options.dryRun) {
374
+ process.env.MICO_DRY_RUN = '1';
390
375
  }
391
376
 
392
- // 通过环境变量传递标志给生成器
393
- const env = { ...process.env };
394
- if (options.verbose) {
395
- env.MICO_VERBOSE = '1';
396
- }
377
+ const runOptions = {};
397
378
  if (options.dryRun) {
398
- env.MICO_DRY_RUN = '1';
379
+ runOptions.dryRun = true;
380
+ }
381
+ if (options.force) {
382
+ runOptions.force = true;
399
383
  }
400
384
 
401
385
  if (options.verbose) {
402
386
  console.log('');
403
- console.log(' \x1b[2m[verbose] Running generator:', yoGenerator, '\x1b[0m');
404
- console.log(' \x1b[2m[verbose] Arguments:', yoArgs.join(' '), '\x1b[0m');
387
+ console.log(' \x1b[2m[verbose] Running generator:', namespace, '\x1b[0m');
405
388
  if (options.dryRun) {
406
389
  console.log(' \x1b[2m[verbose] Dry-run mode enabled\x1b[0m');
407
390
  }
@@ -411,28 +394,10 @@ function runGenerator(generator, rest, passthroughArgs, options = {}) {
411
394
  console.log('');
412
395
  }
413
396
 
414
- const child = spawn('yo', yoArgs, { stdio: 'inherit', env });
415
-
416
- let exited = false;
417
- const quit = (code) => {
418
- if (!exited) {
419
- exited = true;
420
- process.exit(code);
421
- }
422
- };
423
-
424
- child.on('error', (error) => {
425
- if (error && error.code === 'ENOENT') {
426
- console.error('Cannot find "yo". Install it with: npm install -g yo');
427
- } else {
428
- console.error(error);
429
- }
430
- quit(1);
431
- });
432
-
433
- child.on('exit', (code) => {
434
- quit(typeof code === 'number' ? code : 1);
435
- });
397
+ const yeomanEnv = require('yeoman-environment');
398
+ const env = yeomanEnv.createEnv();
399
+ env.register(localGeneratorEntry, namespace);
400
+ await env.run(namespace, runOptions);
436
401
  }
437
402
 
438
403
  /**
@@ -536,7 +501,7 @@ async function main() {
536
501
  }
537
502
 
538
503
  // 运行生成器
539
- runGenerator(generator, rest.slice(1), passthroughArgs, {
504
+ await runGenerator(generator, {
540
505
  verbose: isVerbose,
541
506
  dryRun: isDryRun,
542
507
  force: isForce
@@ -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/
@@ -109,13 +121,21 @@ module.exports = class extends Generator {
109
121
  message: 'Author',
110
122
  default: rc.author || 'Your Name <email@example.com>',
111
123
  },
124
+ {
125
+ type: 'input',
126
+ name: 'intlTag',
127
+ message: '多语言中台 tag(如暂无可留空,后续在 packages/common-intl/src/intl.ts 中配置)',
128
+ default: rc.intlTag || 'fake_tag_does_not_exist',
129
+ },
112
130
  ]);
113
131
 
114
132
  this.projectName = toKebab(this.answers.projectName);
115
133
  this.ProjectName = toPascal(this.projectName);
134
+ this.appId = String(this.answers.appId ?? '').trim();
116
135
  this.packageScope = this.answers.packageScope;
117
136
  this.cdnPrefix = this.answers.cdnPrefix;
118
137
  this.author = this.answers.author;
138
+ this.intlTag = this.answers.intlTag;
119
139
  this.templateDir = this.templatePath();
120
140
  this.destDir = this.projectRoot;
121
141
  } catch (error) {
@@ -166,12 +186,14 @@ module.exports = class extends Generator {
166
186
  const templateData = {
167
187
  projectName: this.projectName,
168
188
  ProjectName: this.ProjectName,
189
+ appId: this.appId,
169
190
  packageScope: this.packageScope,
170
191
  author: this.author,
171
192
  micoUiVersion: `^${micoUiVer}`,
172
193
  themeVersion: `^${themeVer}`,
173
194
  cdnPrefix: this.cdnPrefix,
174
195
  cdnPrefixPath, // 用于拼接路径,已包含尾部斜杠
196
+ intlTag: this.intlTag,
175
197
  };
176
198
 
177
199
  this.logger.verbose('Template data:', JSON.stringify(templateData, null, 2));
@@ -196,6 +218,7 @@ module.exports = class extends Generator {
196
218
  this.log('\x1b[33m📋 Dry run mode - no files will be created\x1b[0m');
197
219
  this.log('');
198
220
  this.log(` Project: ${this.projectName}`);
221
+ this.log(` App ID: ${this.appId}`);
199
222
  this.log(` Scope: ${this.packageScope}`);
200
223
  this.log(` Destination: ${this.destDir}`);
201
224
  this.log('');
@@ -231,6 +254,7 @@ module.exports = class extends Generator {
231
254
 
232
255
  this.log('');
233
256
  this.log(`📦 Creating project: ${this.projectName}`);
257
+ this.log(` App ID: ${this.appId}`);
234
258
  this.log(` Scope: ${this.packageScope}`);
235
259
  this.log('');
236
260
 
@@ -25,6 +25,7 @@ apps/layout/docs/
25
25
  ├── feature-菜单权限控制.md # sideMenus 白名单、认证与授权分离
26
26
  ├── feature-主题色切换.md # 主题系统实现
27
27
  ├── feature-404页面.md # 404 页面
28
+ ├── feature-PermissionFilter按钮权限.md # 按钮级权限 PermissionFilter
28
29
  ├── arch-请求模块.md # HTTP 请求层模块化设计
29
30
  ├── arch-日志与常量.md # Logger 工具与常量管理
30
31
  ├── common-intl.md # 国际化公共包
@@ -41,6 +42,7 @@ apps/layout/docs/
41
42
  ### Step 1: 确认需求涉及的模块
42
43
  - 微前端相关 → 阅读 `apps/layout/docs/feature-微前端模式.md`
43
44
  - 路由/菜单/权限相关 → 阅读 `apps/layout/docs/feature-路由与菜单解耦.md` 和 `apps/layout/docs/feature-菜单权限控制.md`
45
+ - 按钮级权限(PermissionFilter)→ 阅读 `apps/layout/docs/feature-PermissionFilter按钮权限.md`;子应用见 `apps/<subapp>/docs/feature-PermissionFilter按钮权限.md`
44
46
  - 主题/样式相关 → 阅读 `apps/layout/docs/feature-主题色切换.md`
45
47
  - 请求/认证相关 → 阅读 `apps/layout/docs/arch-请求模块.md` 和 `src/common/auth/` 源码
46
48
  - 菜单相关 → 阅读 `src/common/menu/` 源码
@@ -64,6 +66,7 @@ find . -name "*.md" -type f | grep -v node_modules
64
66
  | 新建子应用 | `apps/layout/docs/feature-微前端模式.md` |
65
67
  | 路由/页面配置 | `apps/layout/docs/feature-路由与菜单解耦.md` |
66
68
  | 权限控制 | `apps/layout/docs/feature-菜单权限控制.md` |
69
+ | 按钮级权限 PermissionFilter | `apps/layout/docs/feature-PermissionFilter按钮权限.md` |
67
70
  | 主题适配 | `apps/layout/docs/feature-主题色切换.md` |
68
71
  | 提交代码 | `docs/commit-message.md` |
69
72
  | API 请求 | `apps/layout/docs/arch-请求模块.md` |
@@ -126,6 +126,7 @@ Jenkins 根据环境执行 `CICD/` 下的构建脚本:
126
126
  - [微前端模式](mdc:apps/layout/docs/feature-微前端模式.md)
127
127
  - [路由与菜单解耦](mdc:apps/layout/docs/feature-路由与菜单解耦.md)
128
128
  - [菜单权限控制](mdc:apps/layout/docs/feature-菜单权限控制.md)
129
+ - [PermissionFilter 按钮权限](mdc:apps/layout/docs/feature-PermissionFilter按钮权限.md)
129
130
  - [主题色切换](mdc:apps/layout/docs/feature-主题色切换.md)
130
131
  - [提交规范](mdc:docs/commit-message.md)
131
132
  - [部署说明](mdc:deployDesc.md)
@@ -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
@@ -123,6 +123,7 @@ layout 应用作为 qiankun 主应用,子应用通过 Umi 配置中的 qiankun
123
123
  | [微前端模式](./apps/layout/docs/feature-微前端模式.md) | qiankun 架构、MicroAppLoader、子应用配置 |
124
124
  | [路由与菜单解耦](./apps/layout/docs/feature-路由与菜单解耦.md) | PAGES/MENUS 数据源分离、双层权限控制 |
125
125
  | [菜单权限控制](./apps/layout/docs/feature-菜单权限控制.md) | sideMenus 白名单、认证与授权分离 |
126
+ | [PermissionFilter 按钮权限](./apps/layout/docs/feature-PermissionFilter按钮权限.md) | `button_perms`、主/子应用用法与数据流 |
126
127
  | [主题色切换](./apps/layout/docs/feature-主题色切换.md) | useTheme Hook、CSS 变量系统 |
127
128
  | [请求模块架构](./apps/layout/docs/arch-请求模块.md) | HTTP 请求层模块化设计 |
128
129
  | [日志与常量](./apps/layout/docs/arch-日志与常量.md) | Logger 工具与常量管理 |
@@ -79,7 +79,7 @@ pnpm list:preset
79
79
 
80
80
  ```bash
81
81
  # 全局安装(一次性)
82
- pnpm add -g yo mico-cli
82
+ pnpm add -g generator-mico-cli
83
83
 
84
84
  # 在仓库根目录执行
85
85
  mico create subapp-react
@@ -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: '<%= projectName %>',
22
+ appId: '<%= appId %>',
23
23
  appName: '<%= projectName %>',
24
24
  title: '测试样例',
25
25
  logo: '',
@@ -27,15 +27,21 @@ const config: ReturnType<typeof defineConfig> = {
27
27
  defaultPath: '',
28
28
  // 免认证路由(跳过 SSO 登录),支持 /* 前缀匹配
29
29
  // noAuthRouteList: ['/*'],
30
- // 免权限校验路由(跳过菜单权限检查)
31
- noPermissionRouteList: [],
30
+ // 免权限校验路由(跳过菜单权限检查),与 mock pages 中 accessControlEnabled 示例一致时可按需配置
31
+ noPermissionRouteList: ['/group-management/*', '/logout/*'],
32
32
  // 不显示布局的路由(全屏页面)
33
33
  // noLayoutRouteList: [],
34
34
  // 关闭权限控制(调试用)
35
35
  disableAuth: false,
36
36
  // SSO 外跳地址(与 resolveExternalLoginPath 读取的 externalLoginPath 一致;生产由注入的 __MICO_CONFIG__ 提供)
37
- externalLoginPath:
38
- 'https://micous-idp.cig.tencentcs.com/sso/xxxxxxx/cas',
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
  },
@@ -71,6 +77,8 @@ const config: ReturnType<typeof defineConfig> = {
71
77
  'https://dashboard-api-test.micoplatform.com/api/yufu_login/',
72
78
  'process.env.REFRESH_ENDPOINT':
73
79
  'https://dashboard-api-test.micoplatform.com/api/yufu_login/refresh/',
80
+ 'process.env.LOCALE_REQUEST_URL':
81
+ 'https://api-test.micoplatform.com/lang_server/pull',
74
82
  },
75
83
  };
76
84
 
@@ -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,13 @@ 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 ?? '',
46
+ 'process.env.LOCALE_REQUEST_URL':
47
+ 'https://api-test.micoplatform.com/lang_server/pull',
36
48
  },
37
49
  };
38
50
 
@@ -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,13 @@ 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 ?? '',
46
+ 'process.env.LOCALE_REQUEST_URL':
47
+ 'https://api-test.micoplatform.com/lang_server/pull',
36
48
  },
37
49
  };
38
50
 
@@ -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,13 @@ 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 ?? '',
36
+ 'process.env.LOCALE_REQUEST_URL':
37
+ 'https://api.micoplatform.com/lang_server/pull',
24
38
  },
25
39
  externals: {
26
40
  react: 'React',