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.
- package/README.md +7 -20
- package/bin/mico.js +27 -62
- package/generators/micro-react/index.js +25 -1
- package/generators/micro-react/templates/.cursor/rules/always-read-docs.mdc +3 -0
- package/generators/micro-react/templates/.cursor/rules/project-overview.mdc +1 -0
- package/generators/micro-react/templates/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/CLAUDE.md +1 -0
- package/generators/micro-react/templates/README.md +1 -1
- package/generators/micro-react/templates/apps/layout/config/config.dev.ts +13 -5
- package/generators/micro-react/templates/apps/layout/config/config.prod.development.ts +12 -0
- package/generators/micro-react/templates/apps/layout/config/config.prod.testing.ts +12 -0
- package/generators/micro-react/templates/apps/layout/config/config.prod.ts +14 -0
- package/generators/micro-react/templates/apps/layout/docs/feature-PermissionFilter/346/214/211/351/222/256/346/235/203/351/231/220.md +116 -0
- package/generators/micro-react/templates/apps/layout/docs/feature-/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/docs/feature-/350/217/234/345/215/225/346/235/203/351/231/220/346/216/247/345/210/266.md +83 -77
- package/generators/micro-react/templates/apps/layout/docs/feature-/350/267/257/347/224/261/344/270/216/350/217/234/345/215/225/350/247/243/350/200/246.md +50 -35
- package/generators/micro-react/templates/apps/layout/docs/feature-/350/267/257/347/224/261/346/235/203/351/231/220/346/227/245/345/277/227.md +162 -0
- package/generators/micro-react/templates/apps/layout/mock/api.mock.ts +23 -31
- package/generators/micro-react/templates/apps/layout/mock/menus.ts +14 -0
- package/generators/micro-react/templates/apps/layout/mock/pages.ts +27 -8
- package/generators/micro-react/templates/apps/layout/package.json +2 -0
- package/generators/micro-react/templates/apps/layout/src/app.tsx +85 -4
- 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 +41 -27
- 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/parser.ts +148 -85
- package/generators/micro-react/templates/apps/layout/src/common/menu/types.ts +29 -6
- package/generators/micro-react/templates/apps/layout/src/common/micro/types.ts +23 -0
- package/generators/micro-react/templates/apps/layout/src/common/portal-data.ts +46 -2
- 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 +32 -6
- package/generators/micro-react/templates/apps/layout/src/components/PermissionFilter/index.tsx +51 -0
- package/generators/micro-react/templates/apps/layout/src/components/RightContent/AvatarDropdown.tsx +10 -1
- package/generators/micro-react/templates/apps/layout/src/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 +21 -9
- package/generators/micro-react/templates/apps/layout/src/layouts/index.tsx +105 -60
- package/generators/micro-react/templates/apps/layout/src/locales/en-US.ts +28 -0
- package/generators/micro-react/templates/apps/layout/src/locales/zh-CN.ts +26 -0
- package/generators/micro-react/templates/apps/layout/src/pages/404/index.tsx +7 -3
- package/generators/micro-react/templates/apps/layout/src/pages/Home/index.less +32 -0
- package/generators/micro-react/templates/apps/layout/src/pages/Home/index.tsx +148 -4
- package/generators/micro-react/templates/apps/layout/src/requestErrorConfig.ts +2 -1
- package/generators/micro-react/templates/apps/layout/src/services/user.ts +79 -21
- 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 +78 -368
- package/generators/micro-react/templates/packages/common-intl/package.json +3 -13
- package/generators/micro-react/templates/packages/common-intl/src/index.ts +5 -6
- package/generators/micro-react/templates/packages/common-intl/src/intl.ts +115 -28
- package/generators/micro-react/templates/packages/common-intl/src/umiLocaleBridge.ts +101 -0
- package/generators/micro-react/templates/packages/common-intl/tsconfig.json +2 -4
- 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/index.js +28 -22
- package/generators/subapp-react/templates/homepage/README.md +1 -0
- package/generators/subapp-react/templates/homepage/config/config.prod.development.ts +1 -0
- package/generators/subapp-react/templates/homepage/config/config.prod.testing.ts +1 -0
- package/generators/subapp-react/templates/homepage/config/config.prod.ts +1 -0
- package/generators/subapp-react/templates/homepage/config/config.ts +10 -0
- package/generators/subapp-react/templates/homepage/docs/feature-PermissionFilter/346/214/211/351/222/256/346/235/203/351/231/220.md +35 -0
- package/generators/subapp-react/templates/homepage/docs/feature-/345/233/275/351/231/205/345/214/226.md +124 -0
- package/generators/subapp-react/templates/homepage/package.json +3 -1
- package/generators/subapp-react/templates/homepage/src/app.tsx +104 -2
- 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 +41 -2
- package/generators/subapp-react/templates/homepage/src/components/PermissionFilter/index.tsx +48 -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 +86 -1
- package/generators/subapp-react/templates/homepage/typings.d.ts +12 -0
- package/lib/utils.js +0 -1
- package/package.json +2 -2
- package/generators/micro-react/templates/apps/layout/docs/common-intl.md +0 -372
- package/generators/micro-react/templates/packages/common-intl/src/indexedDBUtils.ts +0 -51
- package/generators/micro-react/templates/packages/common-intl/src/utils.ts +0 -482
- package/generators/micro-react/templates/packages/common-intl/vite.config.ts +0 -25
|
@@ -1,52 +1,110 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { IUserInfo } from '@/common/auth/type';
|
|
1
|
+
import { getStoredTenantCode, setStoredTenantCode } from '@/common/auth/tenant';
|
|
2
|
+
import type { IUserInfo, IUserInfoApiData } from '@/common/auth/type';
|
|
3
|
+
import { ETenantModel } from '@/common/auth/type';
|
|
3
4
|
import { getCurrentLocale, type SupportedLocale } from '@/common/locale';
|
|
5
|
+
import { request } from '@/common/request';
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
/** 新用户信息接口(与 OpenAPI `GET /api/user/info/` 一致,非旧 `/api/user/info`) */
|
|
8
|
+
const USER_INFO_API = '/api/user/info/';
|
|
6
9
|
|
|
7
10
|
/**
|
|
8
11
|
* 语言代码到接口 lang 参数的映射
|
|
9
12
|
* - zh_CN: 1 (中文)
|
|
10
13
|
* - en: 2 (英文)
|
|
11
14
|
*/
|
|
12
|
-
const LOCALE_TO_LANG: Partial<Record<SupportedLocale, number>> = {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
};
|
|
15
|
+
// const LOCALE_TO_LANG: Partial<Record<SupportedLocale, number>> = {
|
|
16
|
+
// 'zh-CN': 1,
|
|
17
|
+
// 'en-US': 2,
|
|
18
|
+
// };
|
|
16
19
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
// function getApiLangParam(): number {
|
|
21
|
+
// const locale = getCurrentLocale();
|
|
22
|
+
// return LOCALE_TO_LANG[locale] ?? 1;
|
|
23
|
+
// }
|
|
24
|
+
|
|
25
|
+
function normalizeUserInfo(data: IUserInfoApiData): IUserInfo {
|
|
26
|
+
const name = data.name || '';
|
|
27
|
+
const tenant_model = data.tenant_model ?? ETenantModel.Single;
|
|
28
|
+
return {
|
|
29
|
+
...data,
|
|
30
|
+
app_perms: Array.isArray(data.app_perms) ? data.app_perms : [],
|
|
31
|
+
region_perms: Array.isArray(data.region_perms) ? data.region_perms : [],
|
|
32
|
+
menu_perms: Array.isArray(data.menu_perms) ? data.menu_perms : [],
|
|
33
|
+
button_perms: Array.isArray(data.button_perms) ? data.button_perms : [],
|
|
34
|
+
is_superuser: Boolean(data.is_superuser),
|
|
35
|
+
tenant_model,
|
|
36
|
+
tenant: Array.isArray(data.tenant) ? data.tenant : [],
|
|
37
|
+
isMultiTenant: tenant_model === ETenantModel.Multi,
|
|
38
|
+
user_name: name,
|
|
39
|
+
username: name || data.email || '',
|
|
40
|
+
};
|
|
23
41
|
}
|
|
24
42
|
|
|
25
43
|
export interface IUserInfoResponse {
|
|
26
44
|
code: number;
|
|
27
|
-
data:
|
|
45
|
+
data: IUserInfoApiData;
|
|
28
46
|
msg: string;
|
|
29
47
|
}
|
|
30
48
|
|
|
49
|
+
export interface ISimpleUser {
|
|
50
|
+
id: number;
|
|
51
|
+
email: string;
|
|
52
|
+
is_superuser: number;
|
|
53
|
+
is_active: number;
|
|
54
|
+
user_name: string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface IAllUsersResponse {
|
|
58
|
+
code: number;
|
|
59
|
+
msg: string;
|
|
60
|
+
data: {
|
|
61
|
+
count: number;
|
|
62
|
+
results: ISimpleUser[];
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export async function fetchAllUsers(params?: {
|
|
67
|
+
email?: string;
|
|
68
|
+
}): Promise<IAllUsersResponse> {
|
|
69
|
+
return request<IAllUsersResponse>('/api/user/all/', {
|
|
70
|
+
method: 'GET',
|
|
71
|
+
skipProxy: true,
|
|
72
|
+
params,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
31
76
|
/**
|
|
32
77
|
* 获取用户信息
|
|
33
78
|
* @returns 用户信息对象
|
|
34
79
|
* @throws 当接口返回非 200 code 时抛出错误
|
|
35
80
|
*/
|
|
36
|
-
export async function fetchUserInfo(
|
|
37
|
-
|
|
38
|
-
|
|
81
|
+
export async function fetchUserInfo(params?: {
|
|
82
|
+
lang?: number;
|
|
83
|
+
tenant_code?: string;
|
|
84
|
+
}): Promise<IUserInfo> {
|
|
85
|
+
const url = USER_INFO_API;
|
|
86
|
+
|
|
87
|
+
// 若未显式指定 tenant_code,则自动注入 localStorage 中的当前租户
|
|
88
|
+
// 单租户或首次进入时无值,后端会取默认租户并通过 current_tenant 回包
|
|
89
|
+
const tenantCode = params?.tenant_code ?? getStoredTenantCode() ?? undefined;
|
|
90
|
+
const requestParams = {
|
|
91
|
+
...params,
|
|
92
|
+
...(tenantCode ? { tenant_code: tenantCode } : {}),
|
|
93
|
+
};
|
|
39
94
|
|
|
40
95
|
const response = await request<IUserInfoResponse>(url, {
|
|
41
96
|
method: 'GET',
|
|
42
97
|
skipProxy: true,
|
|
98
|
+
params: requestParams,
|
|
43
99
|
});
|
|
44
100
|
if (response.code === 200 && response.data) {
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
101
|
+
const userInfo = normalizeUserInfo(response.data);
|
|
102
|
+
// 回写当前租户到本地存储,保证后续请求与 UI 展示一致
|
|
103
|
+
const currentTenantCode = userInfo.current_tenant;
|
|
104
|
+
if (currentTenantCode) {
|
|
105
|
+
setStoredTenantCode(currentTenantCode);
|
|
48
106
|
}
|
|
49
|
-
return
|
|
107
|
+
return userInfo;
|
|
50
108
|
}
|
|
51
109
|
throw new Error(response.msg || '获取用户信息失败');
|
|
52
110
|
}
|
|
@@ -1 +1,17 @@
|
|
|
1
1
|
import '@umijs/max/typings';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Window 上挂载的构建信息
|
|
5
|
+
*/
|
|
6
|
+
declare global {
|
|
7
|
+
interface Window {
|
|
8
|
+
__MICO_BUILD__?: {
|
|
9
|
+
branchOrTag?: string;
|
|
10
|
+
gitCommit?: string;
|
|
11
|
+
version?: string;
|
|
12
|
+
buildTime?: string;
|
|
13
|
+
/** Jenkins 等 CI 的构建号 */
|
|
14
|
+
buildNumber?: string;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# shared 共享包使用说明
|
|
2
|
+
|
|
3
|
+
> 创建时间:2026-04-23
|
|
4
|
+
|
|
5
|
+
## 功能概述
|
|
6
|
+
|
|
7
|
+
`<%= packageScope %>/shared` 是平台跨应用(主应用 + qiankun 子应用)复用的业务服务层骨架,当前对外暴露两个独立模块:
|
|
8
|
+
|
|
9
|
+
- **`./services`**
|
|
10
|
+
- `configureRequest` / `getRequest`:统一 request 注入器
|
|
11
|
+
- `common`:通用类型(分页、响应包装)与 `isSuccess`
|
|
12
|
+
- **`./timezone`**
|
|
13
|
+
- `TIMEZONE` / `TIMEZONE_HASH` / `TTimezone`:UTC 与 IANA 映射表
|
|
14
|
+
- `utcOffsetToTimezone` / `utcOffsetToTimeZoneStr`:纯转换
|
|
15
|
+
- `configureTimezone({ getTimezone })`:注入「当前 IANA 时区」获取器
|
|
16
|
+
- `parseDateInTimezone` / `getShortcutDateRange` / `formatTimestampToDateTime` / `formatTimestampToDateTimeWithTimezone`
|
|
17
|
+
|
|
18
|
+
业务接口、业务常量、业务工具等由各项目按需新增,本包只定义骨架与扩展规范。
|
|
19
|
+
|
|
20
|
+
## 包结构
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
packages/shared/
|
|
24
|
+
├── package.json # 仅导出 ./services 与 ./timezone
|
|
25
|
+
├── tsconfig.json
|
|
26
|
+
├── README.md
|
|
27
|
+
├── services/
|
|
28
|
+
│ ├── index.ts # services 域唯一对外 barrel
|
|
29
|
+
│ ├── request.ts # request 注入器
|
|
30
|
+
│ └── common/
|
|
31
|
+
│ └── index.ts # 通用类型与工具
|
|
32
|
+
└── timezone/
|
|
33
|
+
└── index.ts # 时区工具 + 时区获取器
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## 导出约定
|
|
37
|
+
|
|
38
|
+
| 约定 | 说明 |
|
|
39
|
+
|---|---|
|
|
40
|
+
| 一目录一入口 | 每个根目录(`services/`、`timezone/` 等)在 `exports` 中只对应一条入口 |
|
|
41
|
+
| 无根入口 | 不导出 `.`、不设置 `main`/`types`,消费方**不能** `import from '<%= packageScope %>/shared'` |
|
|
42
|
+
| 禁止深层路径 | 不允许 `./services/user`、`./services/common`、`./timezone/sub` 等子路径 |
|
|
43
|
+
| 同级扩展 | 新增共享模块时新建与 `services/`、`timezone/` 同级的目录 |
|
|
44
|
+
|
|
45
|
+
## 消费方使用
|
|
46
|
+
|
|
47
|
+
### 1. 初始化(必须,仅一次)
|
|
48
|
+
|
|
49
|
+
主应用与子应用都在 `app.tsx` 顶层注入本应用的 `request`,模板已默认接好:
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
// apps/layout/src/app.tsx
|
|
53
|
+
import { configureRequest } from '<%= packageScope %>/shared/services';
|
|
54
|
+
import { request as commonRequest } from './common/request';
|
|
55
|
+
|
|
56
|
+
configureRequest(commonRequest);
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
// apps/<subapp>/src/app.tsx
|
|
61
|
+
import { configureRequest } from '<%= packageScope %>/shared/services';
|
|
62
|
+
import { request } from './common/request';
|
|
63
|
+
|
|
64
|
+
// 子应用 request 内部已自动桥接主应用 / 独立 umi,
|
|
65
|
+
// 顶层注入即可,无需在 mount 里反复设置
|
|
66
|
+
configureRequest(request);
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
> 子应用 `./common/request` 的实现会在 qiankun 模式下走 `getMainAppRequest()`,独立运行时走 `umiRequest`,因此顶层注入的是同一个稳定函数引用,运行期才决定具体走哪条链路。
|
|
70
|
+
|
|
71
|
+
未初始化即调用 `getRequest()` 会抛出 `[shared/services] request 未初始化,请先调用 configureRequest()`,提示检查初始化时序。
|
|
72
|
+
|
|
73
|
+
### 2. 业务代码调用
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
import {
|
|
77
|
+
getRequest,
|
|
78
|
+
isSuccess,
|
|
79
|
+
type IPagedResponse,
|
|
80
|
+
} from '<%= packageScope %>/shared/services';
|
|
81
|
+
|
|
82
|
+
async function fetchUsers(): Promise<IPagedResponse<IUser>> {
|
|
83
|
+
const res = await getRequest()<{ code: number; data: IPagedResponse<IUser> }>(
|
|
84
|
+
'/api/user/',
|
|
85
|
+
{ method: 'GET' },
|
|
86
|
+
);
|
|
87
|
+
if (!isSuccess(res)) throw new Error('fetch users failed');
|
|
88
|
+
return res.data;
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### 3. 时区模块初始化
|
|
93
|
+
|
|
94
|
+
`./timezone` 不内置时区存储,由消费方注入「当前 IANA 时区获取器」(通常代理到主应用的时区管理模块):
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
// apps/layout/src/app.tsx
|
|
98
|
+
import { configureTimezone } from '<%= packageScope %>/shared/timezone';
|
|
99
|
+
import { getTimezone } from '@/common/helpers';
|
|
100
|
+
|
|
101
|
+
configureTimezone({ getTimezone });
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
依赖前置:本模块以 `peerDependencies` 声明 dayjs。**消费方需在入口扩展三个插件**(`utc / timezone / customParseFormat`):
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
import dayjs from 'dayjs';
|
|
108
|
+
import utc from 'dayjs/plugin/utc';
|
|
109
|
+
import timezone from 'dayjs/plugin/timezone';
|
|
110
|
+
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
|
111
|
+
dayjs.extend(utc);
|
|
112
|
+
dayjs.extend(timezone);
|
|
113
|
+
dayjs.extend(customParseFormat);
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
> 模板的 `apps/layout/src/common/helpers.ts` 已扩展 `utc / timezone`,仅需补 `customParseFormat`。
|
|
117
|
+
|
|
118
|
+
业务调用示例:
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
import {
|
|
122
|
+
TIMEZONE,
|
|
123
|
+
parseDateInTimezone,
|
|
124
|
+
getShortcutDateRange,
|
|
125
|
+
formatTimestampToDateTime,
|
|
126
|
+
formatTimestampToDateTimeWithTimezone,
|
|
127
|
+
} from '<%= packageScope %>/shared/timezone';
|
|
128
|
+
|
|
129
|
+
parseDateInTimezone('2025-11-04 16:20:21');
|
|
130
|
+
const [start, end] = getShortcutDateRange('week');
|
|
131
|
+
formatTimestampToDateTime(Date.now());
|
|
132
|
+
formatTimestampToDateTimeWithTimezone(Date.now(), TIMEZONE['UTC+8']);
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## 扩展规范
|
|
136
|
+
|
|
137
|
+
### 场景 A:新增业务接口(归属 services 域)
|
|
138
|
+
|
|
139
|
+
1. 新建子目录 `services/<module>/`
|
|
140
|
+
2. 在其中创建唯一对外入口 `index.ts`;如需细分,新增 `type.ts` 等文件但只由 `index.ts` re-export
|
|
141
|
+
3. 在 `services/<module>/index.ts` 中:
|
|
142
|
+
- 用 `export type {...}` 对外暴露类型
|
|
143
|
+
- 用 `getRequest()` 调后端,导出业务函数
|
|
144
|
+
4. 在 `services/index.ts` 追加一行聚合:`export * from './<module>';`
|
|
145
|
+
5. **不要**改动 `package.json` 的 `exports`
|
|
146
|
+
|
|
147
|
+
### 场景 B:新增非 services 共享模块(如 constants / utils)
|
|
148
|
+
|
|
149
|
+
当一类共享内容明显**不属于** services 域,新建与 `services/` 同级的目录,作为全新独立对外模块:
|
|
150
|
+
|
|
151
|
+
1. 在包根新建目录,例如 `constants/`
|
|
152
|
+
2. 创建唯一对外入口 `constants/index.ts`
|
|
153
|
+
3. 在 `package.json` 的 `exports` 中追加且仅追加一条:
|
|
154
|
+
|
|
155
|
+
```json
|
|
156
|
+
"./constants": "./constants/index.ts"
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
4. 在 `package.json` 的 `files` 数组追加目录名 `"constants"`
|
|
160
|
+
5. **禁止**新增任何 `./constants/<sub>` 深层路径
|
|
161
|
+
|
|
162
|
+
## 设计决策
|
|
163
|
+
|
|
164
|
+
| 决策点 | 选择 | 理由 |
|
|
165
|
+
|---|---|---|
|
|
166
|
+
| 包定位 | 仅骨架,无业务实现 | 模板场景下各项目业务差异大,留空可避免强耦合业务假设 |
|
|
167
|
+
| request 注入器 | 运行时注入而非直接依赖某 request 包 | 主应用 / 子应用在 qiankun 模式下共享同一请求实例,注入模式可一次定义、多处复用 |
|
|
168
|
+
| 仅 `./services` 入口 | 不开放 `.` 根入口与深层路径 | 强约束消费方统一从命名空间入口导入,内部重构不影响外部契约 |
|
|
169
|
+
| 一目录一模块 | 同级目录都只暴露 `index.ts` | 保持"外部可见面 = exports 列表",依赖图清晰,重构自由度高 |
|
|
170
|
+
| 保留 `common` 内联于 services | 不独立成 `common/` 同级目录 | 当前只有分页和响应结果等通用类型,体量小;后续若通用工具增多再拆 |
|
|
171
|
+
|
|
172
|
+
## 注意事项
|
|
173
|
+
|
|
174
|
+
- `configureRequest` 必须在任何业务调用**之前**执行。主应用与子应用模板均在 `app.tsx` 顶层注入;子应用注入的是本地的 `./common/request` 函数(运行期由它自动桥接主应用 / 独立 umi),所以无需在 `mount` 里重复注入 `props.request`。
|
|
175
|
+
- `RequestFn` 签名为 `<T = unknown>(url: string, options?: Record<string, unknown>) => Promise<T>`,各应用的 request 实例需兼容这一签名。
|
|
176
|
+
- 新增子目录时,如果消费方只依赖类型,也要通过 `services/index.ts` re-export,不要引导外部直接 import 内部 `type.ts`。
|
|
177
|
+
- 若后续需要支持多实例 request(例如不同域名的后端),可以在本包扩展成 `configureRequest(name, req)` + `getRequest(name)` 的多命名空间形式,当前版本按单实例设计。
|
|
178
|
+
|
|
179
|
+
## 相关文件
|
|
180
|
+
|
|
181
|
+
| 文件 | 说明 |
|
|
182
|
+
|---|---|
|
|
183
|
+
| [packages/shared/package.json](../packages/shared/package.json) | 导出声明,约束外部可见面 |
|
|
184
|
+
| [packages/shared/services/index.ts](../packages/shared/services/index.ts) | 对外 barrel 与扩展规范注释 |
|
|
185
|
+
| [packages/shared/services/request.ts](../packages/shared/services/request.ts) | request 注入器实现 |
|
|
186
|
+
| [packages/shared/services/common/index.ts](../packages/shared/services/common/index.ts) | 通用类型与 `isSuccess` |
|
|
187
|
+
| [packages/shared/timezone/index.ts](../packages/shared/timezone/index.ts) | 时区常量、纯转换、注入器与格式化函数 |
|
|
188
|
+
| [packages/shared/README.md](../packages/shared/README.md) | 包内使用文档 |
|
|
189
|
+
| [apps/layout/src/common/helpers.ts](../apps/layout/src/common/helpers.ts) | 主应用时区管理实现(被 `configureTimezone` 注入) |
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@commitlint/cli": "^19.5.0",
|
|
34
34
|
"@commitlint/config-conventional": "^19.5.0",
|
|
35
|
-
"@common-web/sentry": "
|
|
35
|
+
"@common-web/sentry": "0.0.7",
|
|
36
36
|
"@sentry/webpack-plugin": "^4.9.1",
|
|
37
37
|
"@typescript-eslint/eslint-plugin": "^8.54.0",
|
|
38
38
|
"@typescript-eslint/parser": "^8.54.0",
|