generator-mico-cli 0.2.13 → 0.2.14
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 +1 -1
- package/generators/micro-react/index.js +34 -10
- package/generators/micro-react/templates/.commitlintrc.js +1 -0
- package/generators/micro-react/templates/.cursor/rules/coding-conventions.mdc +1 -1
- package/generators/micro-react/templates/.cursor/rules/development-guide.mdc +1 -1
- package/generators/micro-react/templates/.cursor/rules/layout-app.mdc +2 -5
- package/generators/micro-react/templates/.cursor/rules/project-overview.mdc +2 -2
- package/generators/micro-react/templates/.cursor/rules/theme-system.mdc +10 -12
- package/generators/micro-react/templates/AGENTS.md +2 -2
- package/generators/micro-react/templates/CLAUDE.md +1 -2
- package/generators/micro-react/templates/README.md +2 -2
- package/generators/micro-react/templates/_npmrc +3 -0
- package/generators/micro-react/templates/apps/layout/config/config.dev.ts +15 -0
- package/generators/micro-react/templates/apps/layout/config/config.ts +4 -3
- package/generators/micro-react/templates/apps/layout/docs/common-intl.md +370 -0
- package/generators/micro-react/templates/apps/layout/docs/feature-404/351/241/265/351/235/242.md +2 -2
- 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 +21 -25
- 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 +15 -16
- 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 +1 -1
- package/generators/micro-react/templates/apps/layout/docs/utils-timezone.md +322 -0
- package/generators/micro-react/templates/apps/layout/mock/menus.ts +17 -1
- package/generators/micro-react/templates/apps/layout/package.json +5 -2
- package/generators/micro-react/templates/apps/layout/src/app.tsx +22 -10
- package/generators/micro-react/templates/apps/layout/src/common/auth/index.ts +3 -0
- package/generators/micro-react/templates/apps/layout/src/common/helpers.ts +177 -0
- package/generators/micro-react/templates/apps/layout/src/common/locale.ts +56 -4
- package/generators/micro-react/templates/apps/layout/src/common/menu/parser.ts +84 -5
- package/generators/micro-react/templates/apps/layout/src/common/menu/types.ts +13 -1
- package/generators/micro-react/templates/apps/layout/src/common/request/interceptors.ts +1 -1
- package/generators/micro-react/templates/apps/layout/src/common/request/sso.ts +7 -1
- package/generators/micro-react/templates/apps/layout/src/common/theme.ts +1 -1
- package/generators/micro-react/templates/apps/layout/src/common/upload/oss.ts +2 -3
- package/generators/micro-react/templates/apps/layout/src/components/AppTabs/index.less +8 -2
- package/generators/micro-react/templates/apps/layout/src/components/AppTabs/index.tsx +23 -6
- package/generators/micro-react/templates/apps/layout/src/components/HeaderDropdown/index.tsx +22 -0
- package/generators/micro-react/templates/apps/layout/src/components/IconFont/index.tsx +1 -1
- package/generators/micro-react/templates/apps/layout/src/components/MicroAppLoader/index.tsx +1 -1
- package/generators/micro-react/templates/apps/layout/src/components/RightContent/AvatarDropdown.tsx +388 -0
- package/generators/micro-react/templates/apps/layout/src/components/RightContent/avatar-dropdown.less +35 -0
- package/generators/micro-react/templates/apps/layout/src/components/RightContent/index.ts +2 -0
- package/generators/micro-react/templates/apps/layout/src/constants/index.ts +2 -0
- package/generators/micro-react/templates/apps/layout/src/global.less +3 -6
- package/generators/micro-react/templates/apps/layout/src/layouts/components/header/index.less +3 -1
- package/generators/micro-react/templates/apps/layout/src/layouts/components/header/index.tsx +9 -6
- package/generators/micro-react/templates/apps/layout/src/layouts/components/menu/index.less +3 -1
- package/generators/micro-react/templates/apps/layout/src/layouts/components/menu/index.tsx +4 -4
- package/generators/micro-react/templates/apps/layout/src/layouts/index.less +83 -13
- package/generators/micro-react/templates/apps/layout/src/layouts/index.tsx +40 -25
- package/generators/micro-react/templates/apps/layout/src/locales/en-US.ts +9 -0
- package/generators/micro-react/templates/apps/layout/src/locales/zh-CN.ts +9 -0
- package/generators/micro-react/templates/apps/layout/src/pages/403/index.tsx +2 -1
- package/generators/micro-react/templates/apps/layout/src/pages/404/index.tsx +1 -1
- package/generators/micro-react/templates/apps/layout/src/pages/Home/index.less +3 -0
- package/generators/micro-react/templates/apps/layout/src/pages/User/Login/index.less +1 -1
- package/generators/micro-react/templates/apps/layout/src/pages/User/Login/index.tsx +3 -3
- package/generators/micro-react/templates/apps/layout/src/requestErrorConfig.ts +1 -1
- package/generators/micro-react/templates/apps/layout/src/services/config/index.ts +63 -0
- package/generators/micro-react/templates/apps/layout/src/services/config/type.ts +32 -0
- package/generators/micro-react/templates/apps/layout/src/services/user.ts +23 -1
- package/generators/micro-react/templates/package.json +4 -1
- package/generators/micro-react/templates/packages/common-intl/.turbo/turbo-build.log +13 -0
- package/generators/micro-react/templates/packages/common-intl/README.md +428 -0
- package/generators/micro-react/templates/packages/common-intl/dist/index.d.ts +3 -0
- package/generators/micro-react/templates/packages/common-intl/dist/index.js +4388 -0
- package/generators/micro-react/templates/packages/common-intl/dist/indexedDBUtils.d.ts +13 -0
- package/generators/micro-react/templates/packages/common-intl/dist/intl.d.ts +1022 -0
- package/generators/micro-react/templates/packages/common-intl/dist/utils.d.ts +122 -0
- package/generators/micro-react/templates/packages/common-intl/package.json +34 -0
- package/generators/micro-react/templates/packages/common-intl/src/index.ts +7 -0
- package/generators/micro-react/templates/packages/common-intl/src/indexedDBUtils.ts +51 -0
- package/generators/micro-react/templates/packages/common-intl/src/intl.ts +5709 -0
- package/generators/micro-react/templates/packages/common-intl/src/utils.ts +481 -0
- package/generators/micro-react/templates/packages/common-intl/tsconfig.json +22 -0
- package/generators/micro-react/templates/packages/common-intl/vite.config.ts +25 -0
- package/generators/micro-react/templates/turbo.json +3 -0
- package/generators/subapp-react/index.js +13 -18
- package/generators/subapp-react/templates/homepage/README.md +3 -3
- package/generators/subapp-react/templates/homepage/config/config.dev.ts +8 -7
- package/generators/subapp-react/templates/homepage/config/config.prod.development.ts +2 -3
- package/generators/subapp-react/templates/homepage/config/config.prod.testing.ts +2 -3
- package/generators/subapp-react/templates/homepage/config/config.prod.ts +4 -5
- package/generators/subapp-react/templates/homepage/package.json +3 -2
- package/generators/subapp-react/templates/homepage/src/global.less +3 -3
- package/generators/subapp-react/templates/homepage/src/pages/index.less +2 -2
- package/generators/subapp-react/templates/homepage/src/pages/index.tsx +72 -33
- package/generators/subapp-react/templates/homepage/src/styles/theme.less +1 -1
- package/lib/utils.js +43 -0
- package/package.json +8 -11
- package/generators/micro-react/templates/packages/shared-styles/README.md +0 -124
- package/generators/micro-react/templates/packages/shared-styles/arco-design-mobile-override.less +0 -91
- package/generators/micro-react/templates/packages/shared-styles/arco-override.less +0 -119
- package/generators/micro-react/templates/packages/shared-styles/index.d.ts +0 -44
- package/generators/micro-react/templates/packages/shared-styles/index.less +0 -13
- package/generators/micro-react/templates/packages/shared-styles/package.json +0 -30
- package/generators/micro-react/templates/packages/shared-styles/theme-inject.less +0 -10
- package/generators/micro-react/templates/packages/shared-styles/themes/dark/custom-var.less +0 -290
- package/generators/micro-react/templates/packages/shared-styles/themes/normal/custom-var.less +0 -269
- package/generators/micro-react/templates/packages/shared-styles/variables-only.less +0 -433
- package/generators/micro-react/templates/packages/shared-styles/variables.less +0 -452
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
# 时区工具函数
|
|
2
|
+
|
|
3
|
+
> 创建时间:2025-01-27
|
|
4
|
+
|
|
5
|
+
## 概述
|
|
6
|
+
|
|
7
|
+
本模块提供时区管理工具函数,支持 UTC-12 到 UTC+14 的全时区范围。基于 `dayjs` 及其 `utc`、`timezone` 插件实现,时区偏移量存储在 `localStorage` 中,支持用户切换时区。
|
|
8
|
+
|
|
9
|
+
**文件位置**:`apps/layout/src/common/helpers.ts`
|
|
10
|
+
|
|
11
|
+
## 核心概念
|
|
12
|
+
|
|
13
|
+
### 时区表示法
|
|
14
|
+
|
|
15
|
+
本模块使用两种时区表示法:
|
|
16
|
+
|
|
17
|
+
| 表示法 | 格式 | 示例 | 说明 |
|
|
18
|
+
|--------|------|------|------|
|
|
19
|
+
| **UTC Offset** | `UTC+N` / `UTC-N` | `UTC+8`、`UTC-5` | 用于用户界面显示 |
|
|
20
|
+
| **IANA 时区** | `地区/城市` | `Asia/Shanghai`、`America/New_York` | 用于 dayjs 时区计算 |
|
|
21
|
+
|
|
22
|
+
### 存储机制
|
|
23
|
+
|
|
24
|
+
时区信息通过 `localStorage` 持久化:
|
|
25
|
+
|
|
26
|
+
| 存储键 | 常量 | 说明 |
|
|
27
|
+
|--------|------|------|
|
|
28
|
+
| `mico-cs-timezone` | `STORAGE_KEYS.TIMEZONE` | 存储数字(如 `8`)或字符串(如 `UTC+8`) |
|
|
29
|
+
| `mico-cs-timezone-region` | `STORAGE_KEYS.TIMEZONE_REGION` | 存储 IANA 时区标识(如 `Asia/Shanghai`) |
|
|
30
|
+
|
|
31
|
+
## 常量定义
|
|
32
|
+
|
|
33
|
+
### TIMEZONE
|
|
34
|
+
|
|
35
|
+
UTC 偏移量键的枚举映射,覆盖 UTC-12 到 UTC+14:
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
export const TIMEZONE = {
|
|
39
|
+
'UTC-12': 'UTC-12',
|
|
40
|
+
'UTC-11': 'UTC-11',
|
|
41
|
+
// ... 省略中间值
|
|
42
|
+
'UTC+12': 'UTC+12',
|
|
43
|
+
'UTC+13': 'UTC+13',
|
|
44
|
+
'UTC+14': 'UTC+14',
|
|
45
|
+
} as const;
|
|
46
|
+
|
|
47
|
+
export type TTimezone = keyof typeof TIMEZONE;
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### TIMEZONE_HASH
|
|
51
|
+
|
|
52
|
+
UTC 偏移量到 IANA 时区标识的映射表:
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
export const TIMEZONE_HASH: Record<TTimezone, string> = {
|
|
56
|
+
[TIMEZONE['UTC-12']]: 'Etc/GMT+12', // 无居住区
|
|
57
|
+
[TIMEZONE['UTC-11']]: 'Pacific/Pago_Pago', // 帕果帕果,美属萨摩亚
|
|
58
|
+
[TIMEZONE['UTC-10']]: 'Pacific/Honolulu', // 檀香山,夏威夷
|
|
59
|
+
[TIMEZONE['UTC-9']]: 'America/Anchorage', // 安克雷奇,阿拉斯加
|
|
60
|
+
[TIMEZONE['UTC-8']]: 'America/Los_Angeles', // 洛杉矶
|
|
61
|
+
[TIMEZONE['UTC-7']]: 'America/Denver', // 丹佛
|
|
62
|
+
[TIMEZONE['UTC-6']]: 'America/Chicago', // 芝加哥
|
|
63
|
+
[TIMEZONE['UTC-5']]: 'America/New_York', // 纽约
|
|
64
|
+
[TIMEZONE['UTC-4']]: 'America/Puerto_Rico', // 波多黎各
|
|
65
|
+
[TIMEZONE['UTC-3']]: 'America/Sao_Paulo', // 圣保罗
|
|
66
|
+
[TIMEZONE['UTC-2']]: 'America/Noronha', // 费尔南多岛
|
|
67
|
+
[TIMEZONE['UTC-1']]: 'Atlantic/Azores', // 亚速尔群岛
|
|
68
|
+
[TIMEZONE['UTC+0']]: 'Europe/London', // 伦敦
|
|
69
|
+
[TIMEZONE['UTC+1']]: 'Europe/Paris', // 巴黎
|
|
70
|
+
[TIMEZONE['UTC+2']]: 'Europe/Kyiv', // 基辅
|
|
71
|
+
[TIMEZONE['UTC+3']]: 'Europe/Moscow', // 莫斯科
|
|
72
|
+
[TIMEZONE['UTC+4']]: 'Asia/Dubai', // 迪拜
|
|
73
|
+
[TIMEZONE['UTC+5']]: 'Asia/Tashkent', // 塔什干
|
|
74
|
+
[TIMEZONE['UTC+6']]: 'Asia/Dhaka', // 达卡
|
|
75
|
+
[TIMEZONE['UTC+7']]: 'Asia/Bangkok', // 曼谷
|
|
76
|
+
[TIMEZONE['UTC+8']]: 'Asia/Shanghai', // 上海(默认)
|
|
77
|
+
[TIMEZONE['UTC+9']]: 'Asia/Tokyo', // 东京
|
|
78
|
+
[TIMEZONE['UTC+10']]: 'Australia/Sydney', // 悉尼
|
|
79
|
+
[TIMEZONE['UTC+11']]: 'Pacific/Noumea', // 努美阿
|
|
80
|
+
[TIMEZONE['UTC+12']]: 'Pacific/Auckland', // 奥克兰
|
|
81
|
+
[TIMEZONE['UTC+13']]: 'Pacific/Tongatapu', // 汤加
|
|
82
|
+
[TIMEZONE['UTC+14']]: 'Pacific/Kiritimati', // 基里巴斯圣诞岛
|
|
83
|
+
};
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
> **说明**:地理上有 24 个时区,但实际应用中存在 UTC+13 和 UTC+14(太平洋岛国),因此本模块覆盖 27 个时区。
|
|
87
|
+
|
|
88
|
+
## API 参考
|
|
89
|
+
|
|
90
|
+
### 时区转换函数
|
|
91
|
+
|
|
92
|
+
#### utcOffsetToTimezone
|
|
93
|
+
|
|
94
|
+
将 UTC 偏移量数字转换为 `UTC+N` 格式字符串。
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
function utcOffsetToTimezone(utcOffset: number): string;
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
| 参数 | 类型 | 说明 |
|
|
101
|
+
|------|------|------|
|
|
102
|
+
| `utcOffset` | `number` | UTC 偏移量,如 `8` 表示 UTC+8 |
|
|
103
|
+
|
|
104
|
+
**示例**:
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
utcOffsetToTimezone(8); // => 'UTC+8'
|
|
108
|
+
utcOffsetToTimezone(-5); // => 'UTC-5'
|
|
109
|
+
utcOffsetToTimezone(0); // => 'UTC+0'
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
#### utcOffsetToTimeZoneStr
|
|
113
|
+
|
|
114
|
+
将 UTC 偏移量转换为 IANA 时区标识。
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
function utcOffsetToTimeZoneStr(utcOffset: number): string;
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**回退逻辑**:
|
|
121
|
+
|
|
122
|
+
1. 查找 `TIMEZONE_HASH` 映射
|
|
123
|
+
2. 若无匹配,使用 `dayjs.tz.guess()` 推断浏览器时区
|
|
124
|
+
3. 最终回退到 `Asia/Shanghai`
|
|
125
|
+
|
|
126
|
+
**示例**:
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
utcOffsetToTimeZoneStr(8); // => 'Asia/Shanghai'
|
|
130
|
+
utcOffsetToTimeZoneStr(-5); // => 'America/New_York'
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 时区读写函数
|
|
134
|
+
|
|
135
|
+
#### getTimezoneOffset
|
|
136
|
+
|
|
137
|
+
从 `localStorage` 获取时区偏移量数字。
|
|
138
|
+
|
|
139
|
+
```typescript
|
|
140
|
+
function getTimezoneOffset(): number;
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**返回值**:偏移量数字,默认 `8`(UTC+8)
|
|
144
|
+
|
|
145
|
+
#### getTimezone
|
|
146
|
+
|
|
147
|
+
获取当前时区的 IANA 标识。
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
function getTimezone(): string;
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**返回值**:IANA 时区标识(如 `Asia/Shanghai`)
|
|
154
|
+
|
|
155
|
+
**回退逻辑**:
|
|
156
|
+
|
|
157
|
+
1. 从 `localStorage` 读取存储值
|
|
158
|
+
2. 若为数字字符串,转换为 `UTC+N` 格式后查找 IANA 映射
|
|
159
|
+
3. 若已是 `UTC+N` 格式,直接查找 IANA 映射
|
|
160
|
+
4. 若无匹配,使用 `dayjs.tz.guess()` 推断
|
|
161
|
+
5. 最终回退到 `Asia/Shanghai`
|
|
162
|
+
|
|
163
|
+
#### getCurrentTimezone
|
|
164
|
+
|
|
165
|
+
获取当前时区的 `UTC+N` 格式字符串。
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
function getCurrentTimezone(): string;
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**返回值**:UTC 偏移量字符串(如 `UTC+8`),默认 `UTC+8`
|
|
172
|
+
|
|
173
|
+
#### setTimezone
|
|
174
|
+
|
|
175
|
+
设置时区到 `localStorage`。
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
function setTimezone(timezone: string): void;
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
| 参数 | 类型 | 说明 |
|
|
182
|
+
|------|------|------|
|
|
183
|
+
| `timezone` | `string` | 时区字符串,如 `UTC+8` 或偏移量数字字符串如 `8` |
|
|
184
|
+
|
|
185
|
+
#### getTimezoneRegion
|
|
186
|
+
|
|
187
|
+
获取时区地区(IANA 标识)。
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
function getTimezoneRegion(): string;
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**返回值**:时区地区字符串(如 `Asia/Shanghai`),未设置则返回空字符串
|
|
194
|
+
|
|
195
|
+
#### setTimezoneRegion
|
|
196
|
+
|
|
197
|
+
设置时区地区到 `localStorage`。
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
function setTimezoneRegion(region: string): void;
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
| 参数 | 类型 | 说明 |
|
|
204
|
+
|------|------|------|
|
|
205
|
+
| `region` | `string` | IANA 时区标识,如 `Asia/Shanghai` |
|
|
206
|
+
|
|
207
|
+
## 使用示例
|
|
208
|
+
|
|
209
|
+
### 初始化时区
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
import { setTimezone, setTimezoneRegion } from '@/common/helpers';
|
|
213
|
+
|
|
214
|
+
// 用户选择 UTC+9 (东京)
|
|
215
|
+
setTimezone('9');
|
|
216
|
+
setTimezoneRegion('Asia/Tokyo');
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### 获取当前时区
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
import { getCurrentTimezone, getTimezoneRegion } from '@/common/helpers';
|
|
223
|
+
|
|
224
|
+
const timezone = getCurrentTimezone(); // => 'UTC+8'
|
|
225
|
+
const region = getTimezoneRegion(); // => 'Asia/Shanghai'
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### 用户时区切换(AvatarDropdown)
|
|
229
|
+
|
|
230
|
+
**文件**:`apps/layout/src/components/RightContent/AvatarDropdown.tsx`
|
|
231
|
+
|
|
232
|
+
用户头像下拉菜单中的时区选择器,允许用户切换时区并刷新页面:
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
import {
|
|
236
|
+
getCurrentTimezone,
|
|
237
|
+
getTimezoneRegion,
|
|
238
|
+
setTimezoneRegion as setTimezoneRegionToStorage,
|
|
239
|
+
setTimezone as setTimezoneToStorage,
|
|
240
|
+
utcOffsetToTimezone,
|
|
241
|
+
} from '@/common/helpers';
|
|
242
|
+
|
|
243
|
+
// 获取当前时区用于显示
|
|
244
|
+
const [currentTimezone, setCurrentTimezone] = useState(getCurrentTimezone());
|
|
245
|
+
|
|
246
|
+
// 用户切换时区时
|
|
247
|
+
const handleTimezoneChange = (key: string) => {
|
|
248
|
+
const lastSlashIndex = key.lastIndexOf('/');
|
|
249
|
+
const region = key.substring(0, lastSlashIndex); // 如 "Asia/Shanghai"
|
|
250
|
+
const utcOffsetStr = key.substring(lastSlashIndex + 1); // 如 "8"
|
|
251
|
+
|
|
252
|
+
// 保存到 localStorage
|
|
253
|
+
setTimezoneToStorage(utcOffsetStr);
|
|
254
|
+
setTimezoneRegionToStorage(region);
|
|
255
|
+
|
|
256
|
+
// 刷新页面使时区生效
|
|
257
|
+
window.location.reload();
|
|
258
|
+
};
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## 数据流
|
|
262
|
+
|
|
263
|
+
```
|
|
264
|
+
用户选择时区
|
|
265
|
+
↓
|
|
266
|
+
setTimezone('9') / setTimezoneRegion('Asia/Tokyo')
|
|
267
|
+
↓
|
|
268
|
+
localStorage 存储
|
|
269
|
+
↓
|
|
270
|
+
getCurrentTimezone() / getTimezone()
|
|
271
|
+
↓
|
|
272
|
+
返回 'UTC+9' / 'Asia/Tokyo'
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
## 注意事项
|
|
276
|
+
|
|
277
|
+
1. **默认时区为 UTC+8**:如果 `localStorage` 中没有存储时区信息,所有函数默认使用 `Asia/Shanghai`(UTC+8)。
|
|
278
|
+
|
|
279
|
+
2. **存储兼容性**:时区存储支持两种格式:
|
|
280
|
+
- 数字字符串(如 `"8"`):推荐格式
|
|
281
|
+
- UTC 格式(如 `"UTC+8"`):兼容格式
|
|
282
|
+
|
|
283
|
+
读取时会自动兼容两种格式。
|
|
284
|
+
|
|
285
|
+
3. **时区列表来源**:时区列表支持两种模式:
|
|
286
|
+
|
|
287
|
+
**模式一:静态列表(默认)**
|
|
288
|
+
|
|
289
|
+
未配置 `timezoneListUrl` 时,使用内置的静态时区列表(覆盖 UTC-12 到 UTC+14 共 27 个时区)。
|
|
290
|
+
|
|
291
|
+
**模式二:API 获取**
|
|
292
|
+
|
|
293
|
+
通过 `window.__MICO_CONFIG__.timezoneListUrl` 配置 API 地址:
|
|
294
|
+
|
|
295
|
+
```javascript
|
|
296
|
+
// 在 index.html 或应用初始化时配置
|
|
297
|
+
window.__MICO_CONFIG__ = {
|
|
298
|
+
timezoneListUrl: '/custom/api/getTimezoneList',
|
|
299
|
+
};
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
API 返回格式:
|
|
303
|
+
```typescript
|
|
304
|
+
interface ITimezone {
|
|
305
|
+
utc_offset: number; // UTC 偏移量
|
|
306
|
+
region: string; // IANA 时区标识
|
|
307
|
+
}
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
## 文件清单
|
|
311
|
+
|
|
312
|
+
| 文件路径 | 说明 |
|
|
313
|
+
|----------|------|
|
|
314
|
+
| `apps/layout/src/common/helpers.ts` | 时区工具函数实现 |
|
|
315
|
+
| `apps/layout/src/common/auth/type.ts` | 存储键常量定义(`STORAGE_KEYS.TIMEZONE` 等) |
|
|
316
|
+
| `apps/layout/src/services/config/index.ts` | 时区列表 API 服务 |
|
|
317
|
+
| `apps/layout/src/services/config/type.ts` | 时区类型定义 |
|
|
318
|
+
| `apps/layout/src/components/RightContent/AvatarDropdown.tsx` | 时区切换 UI 组件 |
|
|
319
|
+
|
|
320
|
+
## 相关文档
|
|
321
|
+
|
|
322
|
+
- [AvatarDropdown 组件](../apps/layout/docs/feature-avatar-dropdown.md)
|
|
@@ -23,16 +23,22 @@ import type { MenuItem, PageConfig } from '@/common/menu/types';
|
|
|
23
23
|
/** Mock 页面配置 - 只需要核心字段 */
|
|
24
24
|
type MockPageConfig = Pick<PageConfig, 'id' | 'name' | 'route' | 'enabled' | 'htmlUrl' | 'jsUrls' | 'cssUrls'>;
|
|
25
25
|
|
|
26
|
-
/** Mock 菜单项 - page
|
|
26
|
+
/** Mock 菜单项 - page 字段使用简化类型,包含多语言字段 */
|
|
27
27
|
type MockMenuItem = Omit<MenuItem, 'page' | 'children'> & {
|
|
28
28
|
page: MockPageConfig | null;
|
|
29
29
|
children: MockMenuItem[];
|
|
30
|
+
/** 英文名称(用于英文环境权限匹配) */
|
|
31
|
+
nameEn?: string;
|
|
32
|
+
/** 菜单唯一标识符(用于权限匹配的兜底) */
|
|
33
|
+
nameKey?: string;
|
|
30
34
|
};
|
|
31
35
|
|
|
32
36
|
const mockMenus: MockMenuItem[] = [
|
|
33
37
|
{
|
|
34
38
|
"id": 1,
|
|
35
39
|
"name": "首页",
|
|
40
|
+
"nameEn": "Home",
|
|
41
|
+
"nameKey": "cs_web_menu_home",
|
|
36
42
|
"type": "page",
|
|
37
43
|
"path": null,
|
|
38
44
|
"icon": "Home",
|
|
@@ -53,6 +59,8 @@ const mockMenus: MockMenuItem[] = [
|
|
|
53
59
|
{
|
|
54
60
|
"id": 2,
|
|
55
61
|
"name": "示例模块",
|
|
62
|
+
"nameEn": "Example Module",
|
|
63
|
+
"nameKey": "cs_web_menu_example_module",
|
|
56
64
|
"type": "group",
|
|
57
65
|
"path": null,
|
|
58
66
|
"icon": "List",
|
|
@@ -64,6 +72,8 @@ const mockMenus: MockMenuItem[] = [
|
|
|
64
72
|
{
|
|
65
73
|
"id": 3,
|
|
66
74
|
"name": "示例页面",
|
|
75
|
+
"nameEn": "Example Page",
|
|
76
|
+
"nameKey": "cs_web_menu_example_page",
|
|
67
77
|
"type": "page",
|
|
68
78
|
"path": "/example/page",
|
|
69
79
|
"icon": "File",
|
|
@@ -86,6 +96,8 @@ const mockMenus: MockMenuItem[] = [
|
|
|
86
96
|
{
|
|
87
97
|
"id": 5,
|
|
88
98
|
"name": "微应用示例",
|
|
99
|
+
"nameEn": "Microapp Example",
|
|
100
|
+
"nameKey": "cs_web_menu_microapp_example",
|
|
89
101
|
"type": "group",
|
|
90
102
|
"path": null,
|
|
91
103
|
"icon": "Apps",
|
|
@@ -97,6 +109,8 @@ const mockMenus: MockMenuItem[] = [
|
|
|
97
109
|
{
|
|
98
110
|
"id": 6,
|
|
99
111
|
"name": "子应用页面",
|
|
112
|
+
"nameEn": "Subapp Page",
|
|
113
|
+
"nameKey": "cs_web_menu_subapp_page",
|
|
100
114
|
"type": "page",
|
|
101
115
|
"path": null,
|
|
102
116
|
"icon": "Desktop",
|
|
@@ -119,6 +133,8 @@ const mockMenus: MockMenuItem[] = [
|
|
|
119
133
|
{
|
|
120
134
|
"id": 7,
|
|
121
135
|
"name": "外部链接",
|
|
136
|
+
"nameEn": "External Link",
|
|
137
|
+
"nameKey": "cs_web_menu_external_link",
|
|
122
138
|
"type": "link",
|
|
123
139
|
"path": "https://github.com",
|
|
124
140
|
"icon": "Link",
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"private": true,
|
|
4
4
|
"author": "Easton <easton@micous.com>",
|
|
5
5
|
"scripts": {
|
|
6
|
+
"check-types": "tsc --noEmit",
|
|
6
7
|
"build": "npm run build:production",
|
|
7
8
|
"build:development": "cross-env UMI_ENV=development max build",
|
|
8
9
|
"build:production": "cross-env UMI_ENV=production max build",
|
|
@@ -21,8 +22,9 @@
|
|
|
21
22
|
"test": "cross-env UMI_ENV=test max dev"
|
|
22
23
|
},
|
|
23
24
|
"dependencies": {
|
|
24
|
-
"
|
|
25
|
-
"
|
|
25
|
+
"<%= packageScope %>/common-intl": "workspace:*",
|
|
26
|
+
"@mico-platform/ui": "<%= micoUiVersion %>",
|
|
27
|
+
"@mico-platform/theme": "<%= themeVersion %>",
|
|
26
28
|
"@umijs/max": "^4.6.15",
|
|
27
29
|
"babel-plugin-dynamic-import-node": "^2.3.3",
|
|
28
30
|
"cross-env": "^10.1.0",
|
|
@@ -35,6 +37,7 @@
|
|
|
35
37
|
"devDependencies": {
|
|
36
38
|
"@types/react": "^18.0.33",
|
|
37
39
|
"@types/react-dom": "^18.0.11",
|
|
40
|
+
"@types/spark-md5": "^3.0.5",
|
|
38
41
|
"lint-staged": "^13.2.0",
|
|
39
42
|
"prettier": "^2.8.7",
|
|
40
43
|
"prettier-plugin-organize-imports": "^3.2.2",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { history, type RequestConfig } from '@umijs/max';
|
|
2
2
|
import { addGlobalUncaughtErrorHandler } from 'qiankun';
|
|
3
3
|
import { errorConfig } from './requestErrorConfig';
|
|
4
|
-
//
|
|
5
|
-
import * as
|
|
4
|
+
// 将 @mico-platform/ui 暴露到 window,供子应用 externals 使用
|
|
5
|
+
import * as micoUi from '@mico-platform/ui';
|
|
6
6
|
import React from 'react';
|
|
7
7
|
import ReactDOM from 'react-dom/client';
|
|
8
8
|
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
import { initTheme } from './common/theme';
|
|
23
23
|
import MicroAppLoader from './components/MicroAppLoader';
|
|
24
24
|
import { isNoAuthRoute } from '@/constants';
|
|
25
|
+
import { getUmiLocale } from '@/common/locale';
|
|
25
26
|
import './global.less';
|
|
26
27
|
|
|
27
28
|
// ==================== qiankun 全局错误处理 ====================
|
|
@@ -41,15 +42,15 @@ if (typeof window !== 'undefined') {
|
|
|
41
42
|
event instanceof ErrorEvent
|
|
42
43
|
? event.error
|
|
43
44
|
: event instanceof PromiseRejectionEvent
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
? event.reason
|
|
46
|
+
: event;
|
|
46
47
|
|
|
47
48
|
const errorMessage =
|
|
48
49
|
error instanceof Error
|
|
49
50
|
? error.message
|
|
50
51
|
: typeof error === 'string'
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
? error
|
|
53
|
+
: 'Unknown micro-app error';
|
|
53
54
|
|
|
54
55
|
console.error('[qiankun] Global uncaught error:', {
|
|
55
56
|
error,
|
|
@@ -85,12 +86,26 @@ if (typeof window !== 'undefined') {
|
|
|
85
86
|
const win = window as unknown as Record<string, unknown>;
|
|
86
87
|
win.React = React;
|
|
87
88
|
win.ReactDOM = ReactDOM;
|
|
88
|
-
win.
|
|
89
|
+
win.micoUi = micoUi;
|
|
89
90
|
}
|
|
90
91
|
|
|
91
92
|
// 初始化主题(在页面加载时立即执行,避免闪烁)
|
|
92
93
|
initTheme();
|
|
93
94
|
|
|
95
|
+
// ==================== 国际化运行时配置 ====================
|
|
96
|
+
// 使用 umi 本地文案,通过映射转换保持 localStorage 与 common-intl 统一
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* 运行时国际化配置
|
|
100
|
+
* 自定义 getLocale 函数,将 common-intl 格式 (zh_CN, en) 转换为 umi 格式 (zh-CN, en-US)
|
|
101
|
+
* @see https://umijs.org/docs/max/i18n#%E8%BF%90%E8%A1%8C%E6%97%B6%E9%85%8D%E7%BD%AE
|
|
102
|
+
*/
|
|
103
|
+
export const locale = {
|
|
104
|
+
getLocale() {
|
|
105
|
+
return getUmiLocale();
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
|
|
94
109
|
/**
|
|
95
110
|
* @see https://umijs.org/docs/api/runtime-config#getinitialstate
|
|
96
111
|
*/
|
|
@@ -144,8 +159,6 @@ export async function getInitialState(): Promise<{
|
|
|
144
159
|
fetchUserInfo: fetchUserInfoFn,
|
|
145
160
|
};
|
|
146
161
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
162
|
/**
|
|
150
163
|
* @name request 配置,可以配置错误处理
|
|
151
164
|
* 它基于 axios 和 ahooks 的 useRequest 提供了一套统一的网络请求和错误处理方案。
|
|
@@ -225,7 +238,6 @@ export function patchClientRoutes({ routes }: { routes: UmiRoute[] }) {
|
|
|
225
238
|
});
|
|
226
239
|
}
|
|
227
240
|
|
|
228
|
-
|
|
229
241
|
/**
|
|
230
242
|
* @name 路由变化处理
|
|
231
243
|
* @description 处理 defaultPath 重定向:访问 "/" 时自动跳转到配置的默认路径
|
|
@@ -3,6 +3,9 @@ import { checkStaffAuth } from '@/services/auth';
|
|
|
3
3
|
import { handleAuthFailureRedirect } from '../request';
|
|
4
4
|
import { clearStoredTokens, getAuthInfo } from './auth-manager';
|
|
5
5
|
|
|
6
|
+
// 导出 STORAGE_KEYS 常量
|
|
7
|
+
export { STORAGE_KEYS } from '../../constants';
|
|
8
|
+
|
|
6
9
|
export function logout(): void {
|
|
7
10
|
clearStoredTokens();
|
|
8
11
|
}
|