generator-mico-cli 0.2.19 → 0.2.21

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 (44) hide show
  1. package/README.md +29 -0
  2. package/bin/mico.js +124 -5
  3. package/generators/micro-react/index.js +86 -17
  4. package/generators/micro-react/templates/.eslintrc.js +24 -1
  5. package/generators/micro-react/templates/CICD/start_dev.sh +1 -1
  6. package/generators/micro-react/templates/CLAUDE.md +11 -5
  7. package/generators/micro-react/templates/_gitignore +2 -0
  8. package/generators/micro-react/templates/apps/layout/config/config.ts +21 -0
  9. package/generators/micro-react/templates/apps/layout/docs/common-intl.md +23 -21
  10. package/generators/micro-react/templates/apps/layout/docs/feature-/344/270/273/351/242/230/350/211/262/345/210/207/346/215/242.md +1 -1
  11. 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 +61 -36
  12. 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 +7 -2
  13. package/generators/micro-react/templates/apps/layout/docs/utils-timezone.md +4 -2
  14. package/generators/micro-react/templates/apps/layout/mock/menus.ts +7 -2
  15. package/generators/micro-react/templates/apps/layout/package.json +3 -2
  16. package/generators/micro-react/templates/apps/layout/src/common/locale.ts +3 -3
  17. package/generators/micro-react/templates/apps/layout/src/common/menu/parser.ts +3 -15
  18. package/generators/micro-react/templates/apps/layout/src/common/menu/types.ts +4 -0
  19. package/generators/micro-react/templates/apps/layout/src/components/MicroAppLoader/index.tsx +1 -1
  20. package/generators/micro-react/templates/apps/layout/src/global.less +2 -3
  21. package/generators/micro-react/templates/apps/layout/src/services/config/type.ts +2 -4
  22. package/generators/micro-react/templates/package.json +5 -2
  23. package/generators/micro-react/templates/packages/common-intl/README.md +8 -8
  24. package/generators/micro-react/templates/packages/common-intl/src/intl.ts +13 -5678
  25. package/generators/micro-react/templates/packages/common-intl/src/utils.ts +22 -21
  26. package/generators/subapp-react/index.js +81 -13
  27. package/generators/subapp-react/templates/homepage/config/config.dev.ts +8 -1
  28. package/generators/subapp-react/templates/homepage/config/config.ts +21 -0
  29. package/generators/subapp-react/templates/homepage/config/routes.ts +1 -1
  30. package/generators/subapp-react/templates/homepage/mock/api.mock.ts +2 -2
  31. package/generators/subapp-react/templates/homepage/package.json +3 -2
  32. package/generators/subapp-react/templates/homepage/src/app.tsx +1 -1
  33. package/generators/subapp-react/templates/homepage/src/common/request.ts +2 -2
  34. package/generators/subapp-react/templates/homepage/src/global.less +2 -1
  35. package/generators/subapp-react/templates/homepage/src/pages/index.less +1 -1
  36. package/generators/subapp-react/templates/homepage/src/pages/index.tsx +27 -27
  37. package/lib/utils.js +200 -2
  38. package/package.json +1 -1
  39. package/generators/micro-react/templates/packages/common-intl/.turbo/turbo-build.log +0 -13
  40. package/generators/micro-react/templates/packages/common-intl/dist/index.d.ts +0 -3
  41. package/generators/micro-react/templates/packages/common-intl/dist/index.js +0 -4388
  42. package/generators/micro-react/templates/packages/common-intl/dist/indexedDBUtils.d.ts +0 -13
  43. package/generators/micro-react/templates/packages/common-intl/dist/intl.d.ts +0 -1022
  44. package/generators/micro-react/templates/packages/common-intl/dist/utils.d.ts +0 -122
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## 概述
4
4
 
5
- `@portal-web/common-intl` 是 Portal 项目的通用国际化(i18n)库,用于管理多语言文案,支持从多语言中台拉取翻译数据。
5
+ `<%= packageScope %>/common-intl` 是 Portal 项目的通用国际化(i18n)库,用于管理多语言文案,支持从多语言中台拉取翻译数据。
6
6
 
7
7
  ## 适用场景
8
8
 
@@ -10,6 +10,8 @@
10
10
  - 需要从多语言中台动态获取翻译文案
11
11
  - 希望统一管理国际化逻辑,减少重复代码
12
12
 
13
+ > **注意**:本文档描述的是 `@payment-portal/common-intl` 包的完整使用方式,涵盖了所有使用该包的应用(包括本仓库外的应用如 conversation-v2、session、workorder 等)。当前仓库仅包含 `layout` 和 `basis` 两个应用。
14
+
13
15
  ## 核心特性
14
16
 
15
17
  | 特性 | 说明 |
@@ -22,7 +24,7 @@
22
24
 
23
25
  ## 两种使用模式
24
26
 
25
- 根据应用架构的不同,`@portal-web/common-intl` 支持两种使用模式:
27
+ 根据应用架构的不同,`<%= packageScope %>/common-intl` 支持两种使用模式:
26
28
 
27
29
  | 模式 | 适用场景 | 示例应用 |
28
30
  | ------------ | ------------------------------------------------ | ------------------------------------------------------------ |
@@ -64,7 +66,7 @@ import {
64
66
  getCurrentLocale,
65
67
  initIntl,
66
68
  type ILang,
67
- } from "@portal-web/common-intl";
69
+ } from "<%= packageScope %>/common-intl";
68
70
  import { Message } from "@mico-platform/ui";
69
71
  import { request } from "@umijs/max";
70
72
 
@@ -100,7 +102,7 @@ export function render(oldRender: () => void): void {
100
102
 
101
103
  ```typescript
102
104
  // apps/conversation-v2、apps/session、apps/workorder 等子应用
103
- import { intl } from "@portal-web/common-intl";
105
+ import { intl } from "<%= packageScope %>/common-intl";
104
106
 
105
107
  // 直接使用,文案来自主应用
106
108
  <h1>{intl.cs_web_workbench_conversation_record()}</h1>;
@@ -113,7 +115,7 @@ import { intl } from "@portal-web/common-intl";
113
115
  **独立应用配置(apps/mico-cs-mobile/src/app.ts)**:
114
116
 
115
117
  ```typescript
116
- import { initIntl } from "@portal-web/common-intl";
118
+ import { initIntl } from "<%= packageScope %>/common-intl";
117
119
  import { Toast } from "@arco-design/mobile-react";
118
120
  import { request } from "@umijs/max";
119
121
  import { convertLocaleToLangParam } from "./locales/utils";
@@ -149,7 +151,7 @@ export function render(oldRender: () => void): void {
149
151
  **独立应用的文案文件(apps/mico-cs-mobile/src/locales/index.ts)**:
150
152
 
151
153
  ```typescript
152
- import { i18n } from "@portal-web/common-intl";
154
+ import { i18n } from "<%= packageScope %>/common-intl";
153
155
 
154
156
  const intl = {
155
157
  sdk_h5_ticket_record: () =>
@@ -173,7 +175,7 @@ import intl from "@/locales";
173
175
 
174
176
  ## 导出 API
175
177
 
176
- `@portal-web/common-intl` 提供以下导出:
178
+ `<%= packageScope %>/common-intl` 提供以下导出:
177
179
 
178
180
  | 导出 | 类型 | 说明 |
179
181
  | -------------------- | ---- | --------------------------------------------------------- |
@@ -192,18 +194,18 @@ import intl from "@/locales";
192
194
 
193
195
  ```typescript
194
196
  // 微前端子应用 - 直接使用共享的 intl 对象
195
- import { intl } from "@portal-web/common-intl";
197
+ import { intl } from "<%= packageScope %>/common-intl";
196
198
  intl.cs_web_common_request_failed();
197
199
 
198
200
  // 独立应用 - 使用 i18n 函数构建自己的文案对象
199
- import { i18n, initIntl, LANG } from "@portal-web/common-intl";
201
+ import { i18n, initIntl, LANG } from "<%= packageScope %>/common-intl";
200
202
 
201
203
  // 获取当前语言环境
202
- import { getCurrentLocale } from "@portal-web/common-intl";
204
+ import { getCurrentLocale } from "<%= packageScope %>/common-intl";
203
205
  const currentLang = getCurrentLocale(); // 'zh_CN' | 'en' | 'ar' | 'tr'
204
206
 
205
207
  // 获取支持的语言列表
206
- import { SUPPORTED_LOCALES } from "@portal-web/common-intl";
208
+ import { SUPPORTED_LOCALES } from "<%= packageScope %>/common-intl";
207
209
  console.log(SUPPORTED_LOCALES); // ['zh_CN', 'en', 'ar', 'tr']
208
210
  ```
209
211
 
@@ -212,7 +214,7 @@ console.log(SUPPORTED_LOCALES); // ['zh_CN', 'en', 'ar', 'tr']
212
214
  ### PC 端主子应用
213
215
 
214
216
  - **文案位置**:[packages/common-intl/src/intl.ts](../packages/common-intl/src/intl.ts)
215
- - **使用方式**:`import { intl } from '@portal-web/common-intl'`
217
+ - **使用方式**:`import { intl } from '<%= packageScope %>/common-intl'`
216
218
  - **适用应用**:
217
219
  - apps/layout(主应用)
218
220
  - apps/conversation-v2(工作台子应用)
@@ -242,7 +244,7 @@ console.log(SUPPORTED_LOCALES); // ['zh_CN', 'en', 'ar', 'tr']
242
244
  // apps/your-app/package.json
243
245
  {
244
246
  "dependencies": {
245
- "@portal-web/common-intl": "workspace:*"
247
+ "<%= packageScope %>/common-intl": "workspace:*"
246
248
  }
247
249
  }
248
250
  ```
@@ -252,7 +254,7 @@ console.log(SUPPORTED_LOCALES); // ['zh_CN', 'en', 'ar', 'tr']
252
254
  **如果是 layout 的子应用**:
253
255
 
254
256
  - 无需调用 `initIntl()`
255
- - 直接使用 `import { intl } from '@portal-web/common-intl'`
257
+ - 直接使用 `import { intl } from '<%= packageScope %>/common-intl'`
256
258
 
257
259
  **如果是独立应用**:
258
260
 
@@ -311,17 +313,17 @@ console.log(SUPPORTED_LOCALES); // ['zh_CN', 'en', 'ar', 'tr']
311
313
 
312
314
  目前支持以下语言:
313
315
 
314
- | 语言常量 | 值 | 说明 |
315
- | ------------ | ------- | -------- |
316
- | `LANG.ZH_CN` | `zh_CN` | 简体中文 |
317
- | `LANG.EN` | `en` | 英语 |
318
- | `LANG.AR` | `ar` | 阿拉伯语 |
319
- | `LANG.TR` | `tr` | 土耳其语 |
316
+ | 语言常量 | 值 | 说明 |
317
+ | ------------- | ------- | -------- |
318
+ | `LANG.ZH_CN` | `zh_CN` | 简体中文 |
319
+ | `LANG.EN_US` | `en` | 英语 |
320
+ | `LANG.AR_SA` | `ar` | 阿拉伯语 |
321
+ | `LANG.TR_TR` | `tr` | 土耳其语 |
320
322
 
321
323
  ### Q: 如何在代码中获取当前语言?
322
324
 
323
325
  ```typescript
324
- import { getCurrentLocale } from "@portal-web/common-intl";
326
+ import { getCurrentLocale } from "<%= packageScope %>/common-intl";
325
327
 
326
328
  const currentLang = getCurrentLocale();
327
329
  if (currentLang === "ar") {
@@ -201,7 +201,7 @@ wc -c apps/[子应用]/dist/umi.css
201
201
  1. 主应用加载 @mico-platform/ui 并暴露到 `window.micoUI`
202
202
  2. 主应用的样式包含 `arco-theme` 属性选择器(基于 Arco)
203
203
  3. 主应用切换主题时设置 `body[arco-theme="dark"]`
204
- 4. 子应用的 UI 组件(来自 window.micoUi)自动应用暗色样式
204
+ 4. 子应用的 UI 组件(来自 window.micoUI)自动应用暗色样式
205
205
 
206
206
  #### 子应用使用 @mico-platform/ui
207
207
 
@@ -28,16 +28,16 @@
28
28
 
29
29
  ### 核心文件
30
30
 
31
- | 文件路径 | 说明 |
32
- | --------------------------------------------------- | -------------------------------- |
33
- | `src/components/MicroAppLoader/index.tsx` | qiankun 微应用加载器组件 |
34
- | `src/components/MicroAppLoader/container-manager.ts`| 容器生命周期管理、会话 ID 机制 |
35
- | `src/components/MicroAppLoader/index.less` | 加载器样式 |
36
- | `src/common/menu/parser.ts` | 菜单解析,包含加载类型判断 |
37
- | `src/common/menu/types.ts` | 类型定义 |
38
- | `src/layouts/index.tsx` | 主布局,集成微应用渲染 |
39
- | `src/app.tsx` | qiankun 全局错误处理 |
40
- | `config/config.ts` | qiankun master 配置 |
31
+ | 文件路径 | 说明 |
32
+ | --- | --- |
33
+ | `src/components/MicroAppLoader/index.tsx` | qiankun 微应用加载器组件 |
34
+ | `src/components/MicroAppLoader/micro-app-manager.ts` | 微应用管理器(单例),稳定容器 + 实例缓存 + 操作序列号 |
35
+ | `src/components/MicroAppLoader/index.less` | 加载器样式 |
36
+ | `src/common/menu/parser.ts` | 菜单解析,包含加载类型判断 |
37
+ | `src/common/menu/types.ts` | 类型定义 |
38
+ | `src/layouts/index.tsx` | 主布局,集成微应用渲染 |
39
+ | `src/app.tsx` | qiankun 全局错误处理 |
40
+ | `config/config.ts` | qiankun master 配置 |
41
41
 
42
42
  ## API / 组件接口
43
43
 
@@ -70,7 +70,7 @@ interface MicroAppLoaderProps {
70
70
  ```typescript
71
71
  interface MicroAppProps {
72
72
  /** 主应用标识 */
73
- mainApp: 'portal-web';
73
+ mainApp: '<%= projectName %>';
74
74
  /** 运行环境 */
75
75
  env: 'development' | 'testing' | 'production';
76
76
  /** 认证 token */
@@ -462,52 +462,77 @@ addGlobalUncaughtErrorHandler((event: Event | string) => {
462
462
  });
463
463
  ```
464
464
 
465
- ### container-manager API
465
+ ### MicroAppManager API (micro-app-manager.ts)
466
466
 
467
- 容器管理器提供会话 ID 机制防止并发加载冲突:
467
+ `MicroAppManager` 是单例类,管理微应用的加载、缓存、切换和卸载:
468
468
 
469
469
  ```typescript
470
- /** 开始加载会话,返回唯一会话 ID */
471
- function startLoadSession(appName: string): number;
470
+ interface MicroAppConfig {
471
+ name: string;
472
+ entry: string;
473
+ target: HTMLElement; // 目标挂载位置
474
+ props: Record<string, unknown>;
475
+ }
476
+
477
+ interface MicroAppState {
478
+ loading: boolean;
479
+ error: string | null;
480
+ mounted: boolean;
481
+ }
482
+
483
+ const manager = microAppManager; // 单例,导出即用
472
484
 
473
- /** 检查会话是否仍然有效(被新加载覆盖时返回 false) */
474
- function isLoadSessionValid(appName: string, sessionId: number): boolean;
485
+ /** 切换到指定微应用(已挂载则仅更新 props) */
486
+ manager.switchTo(config: MicroAppConfig): void;
475
487
 
476
- /** 标记加载完成 */
477
- function markLoadComplete(appName: string, sessionId: number): boolean;
488
+ /** 更新当前已挂载微应用的 props */
489
+ manager.updateProps(props: Record<string, unknown>): void;
478
490
 
479
- /** 等待当前卸载操作完成(如果有) */
480
- async function waitForUnmount(appName: string): Promise<void>;
491
+ /** 取消待处理的请求 */
492
+ manager.cancel(): void;
481
493
 
482
- /** 获取当前加载状态 */
483
- function getLoadingStatus(appName: string): 'idle' | 'loading' | 'mounted' | 'unmounting';
494
+ /** 清除所有缓存实例 */
495
+ manager.clearCache(): Promise<void>;
496
+
497
+ /** 获取调试信息 */
498
+ manager.getDebugInfo(): object;
499
+
500
+ /** 设置状态变化回调 */
501
+ manager.setStateCallback(callback: StateChangeCallback | null): void;
484
502
  ```
485
503
 
504
+ ### 核心设计
505
+
506
+ 1. **稳定容器**:容器在 `document.body` 中创建,激活时移到目标元素内,停用时移回 body 隐藏,不受 React 生命周期影响
507
+ 2. **实例缓存**:每个 entry 只 `loadMicroApp` 一次,后续切换复用已有实例(mount/unmount)
508
+ 3. **操作序列号**:通过递增的 `operationSeq` 检测过期操作,替代旧的会话 ID 机制
509
+ 4. **自动路由守卫**:由独立的 `route-guard.ts` 自动检测用户意图,业务代码无需感知
510
+
486
511
  ### 快速切换时序
487
512
 
488
513
  ```
489
514
  场景:A → B → A 快速切换
490
515
 
491
- A1 开始加载 (sessionId=1)
492
-
493
- 切换到 B,A1 cleanup 在 queueMicrotask 中执行
516
+ switchTo(A):operationSeq=1,开始 loadMicroApp
494
517
 
495
- 切换回 A,A2 开始加载 (sessionId=2)
518
+ switchTo(B):operationSeq=2,A pendingRequest 被替换
496
519
 
497
- A2 调用 waitForUnmount(),等待 A1 完全卸载
520
+ A processRequest 在异步步骤中检测 shouldAbort(mySeq=1) true
498
521
 
499
- A1 卸载完成(带 10 秒超时保护)
522
+ A 等待 mountPromise 完成后执行 safeUnmount,容器移回 body
500
523
 
501
- A2 继续加载,每个异步步骤检查 isLoadSessionValid(sessionId)
524
+ B 开始 processRequest,检查缓存 → 无缓存 → loadMicroApp
502
525
 
503
- 加载完成后立即同步最新 Props(locale/timezone 等)
526
+ B 加载完成后同步最新 Props(locale/timezone/routePath 等)
504
527
  ```
505
528
 
506
529
  ### 设计决策
507
530
 
508
531
  | 决策点 | 选择 | 理由 |
509
- |--------|------|------|
510
- | 卸载时机 | `queueMicrotask` | 在当前事件循环末尾执行,比 `requestAnimationFrame` 更快更可靠 |
511
- | 并发控制 | 会话 ID 机制 | 简单高效,无需复杂的锁机制 |
512
- | 超时时间 | 10 | 平衡等待时间与异常检测速度 |
513
- | Props 同步 | 加载后立即同步 | 确保加载期间的变化不丢失 |
532
+ | --- | --- | --- |
533
+ | 容器策略 | 稳定容器(body 中创建,移动挂载) | 不受 React 生命周期影响,避免容器被意外销毁 |
534
+ | 并发控制 | 操作序列号 + pendingRequest 队列 | 简单高效,新请求自动覆盖旧请求 |
535
+ | 实例缓存 | loadPromise 完成后立即缓存 | 即使被 abort 也可复用,避免重复加载 |
536
+ | unmount 安全 | 等待 mountPromise 完成后再 unmount | 避免 single-spa error #32 |
537
+ | 超时保护 | load 30s / mount 30s / unmount 10s | 平衡等待时间与异常检测速度 |
538
+ | Props 同步 | mount 完成后立即 safeUpdate | 确保加载期间的变化不丢失 |
@@ -1,6 +1,6 @@
1
1
  # 菜单权限控制
2
2
 
3
- > 创建时间:2026-01-24 更新时间:2026-01-27
3
+ > 创建时间:2026-01-24 更新时间:2026-02-08
4
4
 
5
5
  ## 功能概述
6
6
 
@@ -92,6 +92,10 @@
92
92
  ├── 是 → 允许访问所有菜单
93
93
 
94
94
 
95
+ 菜单项 adminOnly === true?
96
+ ├── 是 → 禁止访问(仅超级管理员可见)
97
+
98
+
95
99
  检查 side_menus 白名单
96
100
  ├── 精确匹配:menuPath === side_menus[i]
97
101
  ├── 前缀匹配:side_menus[i].startsWith(menuPath + '.')
@@ -241,7 +245,7 @@ export const NO_PERMISSION_ROUTE_LIST: string[] = ['/403', '/404'];
241
245
  │ └── 配置队列 ✅ 精确匹配 "列队管理.配置队列"
242
246
  ├── 质量管理 ❌ 不在白名单
243
247
  │ └── 抽样检查 ❌ 不在白名单
244
- └── 权限管理 ❌ 硬编码禁止(非超级用户)
248
+ └── 权限管理 ❌ adminOnly=true,非超级用户不可见
245
249
  ```
246
250
 
247
251
  ### Layout 中的权限判断
@@ -288,6 +292,7 @@ if (!isAuthReady) {
288
292
  | 免权限路由的菜单 | 显示全部 | 用户访问公开页面时应能看到所有导航选项 |
289
293
  | 免权限路由的子应用 | 直接加载 | 不等待 currentUser,避免加载卡住 |
290
294
  | 静态路由不受权限控制 | 默认允许访问 | 见下方"静态路由与动态路由"说明 |
295
+ | adminOnly 判断 | 读取菜单数据字段 | 替代硬编码菜单名称匹配,由后端数据驱动,支持多语言且无需前端维护 |
291
296
 
292
297
  ## 静态路由与动态路由
293
298
 
@@ -307,12 +307,13 @@ getCurrentTimezone() / getTimezone()
307
307
  }
308
308
  ```
309
309
 
310
+
310
311
  ## 文件清单
311
312
 
312
313
  | 文件路径 | 说明 |
313
- |----------|------|
314
+ | --- | --- |
314
315
  | `apps/layout/src/common/helpers.ts` | 时区工具函数实现 |
315
- | `apps/layout/src/common/auth/type.ts` | 存储键常量定义(`STORAGE_KEYS.TIMEZONE` 等) |
316
+ | `apps/layout/src/constants/index.ts` | 存储键常量定义(`TIMEZONE`、`STORAGE_KEYS` 等) |
316
317
  | `apps/layout/src/services/config/index.ts` | 时区列表 API 服务 |
317
318
  | `apps/layout/src/services/config/type.ts` | 时区类型定义 |
318
319
  | `apps/layout/src/components/RightContent/AvatarDropdown.tsx` | 时区切换 UI 组件 |
@@ -320,3 +321,4 @@ getCurrentTimezone() / getTimezone()
320
321
  ## 相关文档
321
322
 
322
323
  - [AvatarDropdown 组件](../apps/layout/docs/feature-avatar-dropdown.md)
324
+
@@ -21,7 +21,10 @@
21
21
  import type { MenuItem, PageConfig } from '@/common/menu/types';
22
22
 
23
23
  /** Mock 页面配置 - 只需要核心字段 */
24
- type MockPageConfig = Pick<PageConfig, 'id' | 'name' | 'route' | 'enabled' | 'htmlUrl' | 'jsUrls' | 'cssUrls'>;
24
+ type MockPageConfig = Pick<PageConfig,
25
+ | 'id' | 'name' | 'route' | 'enabled' | 'htmlUrl' | 'jsUrls' | 'cssUrls'
26
+ | 'adminOnly'
27
+ >;
25
28
 
26
29
  /** Mock 菜单项 - page 字段使用简化类型,包含多语言字段 */
27
30
  type MockMenuItem = Omit<MenuItem, 'page' | 'children'> & {
@@ -155,12 +158,14 @@ const mockMenus: MockMenuItem[] = [
155
158
  "enabled": true,
156
159
  "sortOrder": 3,
157
160
  "pageId": null,
161
+ "adminOnly": true,
158
162
  "page": {
159
163
  "id": 8,
160
164
  "name": "permission",
161
165
  "route": "/permission",
162
166
  "enabled": true,
163
- "htmlUrl": "//localhost:8010",
167
+ "adminOnly": true,
168
+ "htmlUrl": "https://cdn-portal.micoplatform.com/portal-center/common-web/0.0.1/permission/index.html",
164
169
  "jsUrls": [],
165
170
  "cssUrls": []
166
171
  },
@@ -25,8 +25,6 @@
25
25
  "@mico-platform/ui": "<%= micoUiVersion %>",
26
26
  "@mico-platform/theme": "<%= themeVersion %>",
27
27
  "@umijs/max": "^4.6.15",
28
- "babel-plugin-dynamic-import-node": "^2.3.3",
29
- "cross-env": "^10.1.0",
30
28
  "dayjs": "^1.11.19",
31
29
  "qiankun": "^2.10.16",
32
30
  "react": "^18.2.0",
@@ -37,6 +35,9 @@
37
35
  "@types/react": "^18.0.33",
38
36
  "@types/react-dom": "^18.0.11",
39
37
  "@types/spark-md5": "^3.0.5",
38
+ "babel-plugin-dynamic-import-node": "^2.3.3",
39
+ "babel-plugin-import": "^1.13.8",
40
+ "cross-env": "^10.1.0",
40
41
  "lint-staged": "^13.2.0",
41
42
  "prettier": "^2.8.7",
42
43
  "prettier-plugin-organize-imports": "^3.2.2",
@@ -122,7 +122,7 @@ export function setLocaleToStorage(locale: SupportedLocale): void {
122
122
  /**
123
123
  * 根据语言获取图标库路径
124
124
  */
125
- export function getIconFontPath(locale: SupportedLocale): string {
126
- // 如果后续需要支持 RTL 语言(如阿拉伯语),可在此扩展
127
- return withPublicPath('/font/default.js');
125
+ export function getIconFontPath(/* locale: SupportedLocale */): string {
126
+ // 如果后续需要支持 RTL 语言(如阿拉伯语),可在此扩展
127
+ return withPublicPath("/font/default.js");
128
128
  }
@@ -55,14 +55,11 @@ export const getMenuIdentifier = (
55
55
  return item.nameEn || item.nameKey || '';
56
56
  };
57
57
 
58
- // 权限管理菜单的多格式标识符(用于硬编码权限判断)
59
- const PERMISSION_MENU_IDENTIFIERS = ['权限管理', 'Permission', 'permission'];
60
-
61
58
  /**
62
59
  * 检查菜单路径是否允许访问(白名单逻辑)
63
60
  * - 免权限校验路由,始终允许访问
64
61
  * - 超级用户可以访问所有菜单
65
- * - 非超级用户不能访问"权限管理"
62
+ * - 非超级用户不能访问 adminOnly 菜单
66
63
  * - 菜单路径在 sideMenus 中,或是 sideMenus 中某项的前缀(父级菜单)
67
64
  */
68
65
  const isMenuAllowed = (
@@ -82,11 +79,8 @@ const isMenuAllowed = (
82
79
  // 超级用户可以访问所有菜单
83
80
  if (isSuperuserUser(options.isSuperuser)) return true;
84
81
 
85
- // 非超级用户不能访问"权限管理"(支持多格式匹配)
86
- if (PERMISSION_MENU_IDENTIFIERS.includes(menuPath)) return false;
87
-
88
- // 非超级用户不能访问"权限管理"
89
- if (menuPath === '权限管理') return false;
82
+ // 非超级用户不能访问 adminOnly 菜单
83
+ if (item.adminOnly) return false;
90
84
 
91
85
  const sideMenus = options.sideMenus || [];
92
86
 
@@ -103,12 +97,6 @@ const isMenuAllowed = (
103
97
  });
104
98
  };
105
99
 
106
- export const isRouteAllowed = (
107
- menuPath: string,
108
- options: MenuFilterOptions = {},
109
- ): boolean => {
110
- return isMenuAllowed(menuPath, options);
111
- };
112
100
  /**
113
101
  * 根据权限过滤菜单项(白名单逻辑)
114
102
  */
@@ -28,6 +28,8 @@ export interface PageConfig {
28
28
  prefixPath: string;
29
29
  /** 路由匹配模式 */
30
30
  routeMode: PageRouteMode;
31
+ /** 是否仅超级管理员可见 */
32
+ adminOnly?: boolean;
31
33
  /** 关联的主文档 ID */
32
34
  mainDocumentId: number;
33
35
  /** 所属工作空间子域名 */
@@ -67,6 +69,8 @@ export interface MenuItem {
67
69
  pageId: number | null;
68
70
  /** 页面配置(type=page 时存在) */
69
71
  page: PageConfig | null;
72
+ /** 是否仅超级管理员可见 */
73
+ adminOnly?: boolean;
70
74
  children: MenuItem[];
71
75
  }
72
76
 
@@ -70,7 +70,7 @@ const MicroAppLoader: React.FC<MicroAppLoaderProps> = ({
70
70
  const buildProps = useCallback(() => {
71
71
  const authInfo = getAuthInfo();
72
72
  return {
73
- mainApp: 'portal-web',
73
+ mainApp: '<%= projectName %>',
74
74
  env,
75
75
  authToken: authInfo.token,
76
76
  uid: authInfo.uid,
@@ -7,8 +7,7 @@
7
7
  box-sizing: border-box;
8
8
  }
9
9
 
10
- #<%= projectName %> {
11
- height: 100vh;
12
- min-height: 800px;
10
+ #root {
11
+ min-height: 100vh;
13
12
  display: flex;
14
13
  }
@@ -13,11 +13,9 @@ export interface ITimezone {
13
13
  }
14
14
 
15
15
  /**
16
- * 获取时区配置请求
16
+ * 获取时区配置请求(空请求体)
17
17
  */
18
- export interface IGetTimezoneListRequest {
19
- // 空请求体
20
- }
18
+ export type IGetTimezoneListRequest = Record<string, never>;
21
19
 
22
20
  /**
23
21
  * 获取时区配置响应
@@ -24,13 +24,16 @@
24
24
  "lint:fix": "eslint . --ext .js,.jsx,.ts,.tsx --fix && turbo run lint:fix",
25
25
  "check-types": "turbo run check-types",
26
26
  "lint-staged": "pnpm exec lint-staged --quiet",
27
- "prepare": "husky install",
27
+ "prepare": "husky",
28
28
  "test": "dotenv -e .env -e .env.local -- turbo run test",
29
- "create:umi-app": "./scripts/create-umi-app.sh"
29
+ "create:umi-app": "./scripts/create-umi-app.sh",
30
+ "upgrade:mico": "npx @mico-platform/mico-up"
30
31
  },
31
32
  "devDependencies": {
32
33
  "@commitlint/cli": "^19.5.0",
33
34
  "@commitlint/config-conventional": "^19.5.0",
35
+ "@typescript-eslint/eslint-plugin": "^8.54.0",
36
+ "@typescript-eslint/parser": "^8.54.0",
34
37
  "dotenv-cli": "^7.4.1",
35
38
  "eslint": "^8.57.0",
36
39
  "husky": "^9.1.7",
@@ -1,4 +1,4 @@
1
- # @portal-web/common-intl
1
+ # <%= packageScope %>/common-intl
2
2
 
3
3
  通用国际化(i18n)库,用于 Portal 多应用间的多语言文案管理。
4
4
 
@@ -18,14 +18,14 @@
18
18
  ```json
19
19
  {
20
20
  "dependencies": {
21
- "@portal-web/common-intl": "workspace:*"
21
+ "<%= packageScope %>/common-intl": "workspace:*"
22
22
  }
23
23
  }
24
24
  ```
25
25
 
26
26
  ## 两种使用模式
27
27
 
28
- 根据应用架构的不同,`@portal-web/common-intl` 支持两种使用模式:
28
+ 根据应用架构的不同,`<%= packageScope %>/common-intl` 支持两种使用模式:
29
29
 
30
30
  | 模式 | 适用场景 | 示例应用 |
31
31
  | ------------ | ------------------------------------------------ | ------------------------------------------------------------ |
@@ -49,7 +49,7 @@ import {
49
49
  getCurrentLocale,
50
50
  initIntl,
51
51
  type ILang,
52
- } from "@portal-web/common-intl";
52
+ } from "<%= packageScope %>/common-intl";
53
53
  import { Message } from "@mico-platform/ui";
54
54
  import { request } from "@umijs/max";
55
55
 
@@ -85,7 +85,7 @@ export function render(oldRender: () => void): void {
85
85
 
86
86
  ```typescript
87
87
  // apps/conversation-v2、apps/session、apps/workorder 等子应用
88
- import { intl } from "@portal-web/common-intl";
88
+ import { intl } from "<%= packageScope %>/common-intl";
89
89
 
90
90
  // 直接使用,文案来自主应用
91
91
  <h1>{intl.cs_web_workbench_conversation_record()}</h1>;
@@ -98,7 +98,7 @@ import { intl } from "@portal-web/common-intl";
98
98
  **独立应用配置**(参考 `apps/mico-cs-mobile/src/app.ts`):
99
99
 
100
100
  ```typescript
101
- import { initIntl } from "@portal-web/common-intl";
101
+ import { initIntl } from "<%= packageScope %>/common-intl";
102
102
  import { request } from "@umijs/max";
103
103
  import { convertLocaleToLangParam } from "./locales/utils";
104
104
  import { getSearchParams } from "@/common/jsbridge/jsbridge";
@@ -140,7 +140,7 @@ export function render(oldRender: () => void): void {
140
140
  **独立应用的文案文件**(`apps/mico-cs-mobile/src/locales/index.ts`):集中管理所有国际化文案
141
141
 
142
142
  ```typescript
143
- import { i18n } from "@portal-web/common-intl";
143
+ import { i18n } from "<%= packageScope %>/common-intl";
144
144
 
145
145
  const intl = {
146
146
  // 无插值示例
@@ -395,7 +395,7 @@ const intl = {
395
395
  2. 在业务代码中使用:
396
396
 
397
397
  ```typescript
398
- import { intl } from "@portal-web/common-intl";
398
+ import { intl } from "<%= packageScope %>/common-intl";
399
399
 
400
400
  // 使用新 key
401
401
  intl.cs_web_your_new_key();