generator-mico-cli 0.1.0
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 +65 -0
- package/bin/mico.js +81 -0
- package/generators/subapp-react/ignore-list.json +7 -0
- package/generators/subapp-react/index.js +131 -0
- package/generators/subapp-react/templates/homepage/.env +4 -0
- package/generators/subapp-react/templates/homepage/config/config.dev.ts +50 -0
- package/generators/subapp-react/templates/homepage/config/config.prod.ts +41 -0
- package/generators/subapp-react/templates/homepage/config/config.testing.ts +8 -0
- package/generators/subapp-react/templates/homepage/config/config.ts +102 -0
- package/generators/subapp-react/templates/homepage/config/routes.ts +7 -0
- package/generators/subapp-react/templates/homepage/mock/api.mock.ts +59 -0
- package/generators/subapp-react/templates/homepage/package.json +30 -0
- package/generators/subapp-react/templates/homepage/src/app.tsx +80 -0
- package/generators/subapp-react/templates/homepage/src/assets/yay.jpg +0 -0
- package/generators/subapp-react/templates/homepage/src/common/logger.ts +42 -0
- package/generators/subapp-react/templates/homepage/src/common/mainApp.ts +53 -0
- package/generators/subapp-react/templates/homepage/src/common/request.ts +49 -0
- package/generators/subapp-react/templates/homepage/src/global.less +26 -0
- package/generators/subapp-react/templates/homepage/src/pages/index.less +139 -0
- package/generators/subapp-react/templates/homepage/src/pages/index.tsx +342 -0
- package/generators/subapp-react/templates/homepage/src/styles/theme.less +6 -0
- package/generators/subapp-react/templates/homepage/tsconfig.json +3 -0
- package/generators/subapp-react/templates/homepage/typings.d.ts +17 -0
- package/package.json +28 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 日志工具
|
|
3
|
+
* 仅在开发环境下输出日志,生产环境自动静默
|
|
4
|
+
*
|
|
5
|
+
* 使用 bind 保持原始调用位置,避免错误栈指向 logger 内部
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const isDev = process.env.NODE_ENV === 'development';
|
|
9
|
+
|
|
10
|
+
// 空操作函数(生产环境使用)
|
|
11
|
+
const noop = (): void => {};
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 创建带前缀的日志函数
|
|
15
|
+
* 使用 bind 绑定前缀,保持控制台显示正确的调用位置
|
|
16
|
+
*/
|
|
17
|
+
const createLogger = (prefix: string) => {
|
|
18
|
+
if (!isDev) {
|
|
19
|
+
// 生产环境返回空操作
|
|
20
|
+
return {
|
|
21
|
+
log: noop,
|
|
22
|
+
info: noop,
|
|
23
|
+
warn: noop,
|
|
24
|
+
error: noop,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const formattedPrefix = `[${prefix}]`;
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
log: console.log.bind(console, formattedPrefix),
|
|
32
|
+
info: console.info.bind(console, formattedPrefix),
|
|
33
|
+
warn: console.warn.bind(console, formattedPrefix),
|
|
34
|
+
error: console.error.bind(console, formattedPrefix),
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// 预定义的日志实例
|
|
39
|
+
export const appLogger = createLogger('<%= appName %>');
|
|
40
|
+
|
|
41
|
+
// 导出创建器供自定义使用
|
|
42
|
+
export { createLogger };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @name 主应用共享依赖管理
|
|
3
|
+
* @description 存储和获取主应用传递的 props
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 主应用传递的 props 类型定义
|
|
8
|
+
*/
|
|
9
|
+
export interface IMicroAppProps {
|
|
10
|
+
/** 主应用标识 */
|
|
11
|
+
mainApp: string;
|
|
12
|
+
/** 主应用共享的 request 实例 */
|
|
13
|
+
request: <T = any>(url: string, options?: any) => Promise<T>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** 存储主应用传递的 props */
|
|
17
|
+
let mainAppProps: IMicroAppProps | null = null;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 设置主应用 props(由 qiankun 生命周期调用)
|
|
21
|
+
* @internal
|
|
22
|
+
*/
|
|
23
|
+
export const setMainAppProps = (props: IMicroAppProps | null) => {
|
|
24
|
+
mainAppProps = props;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* 获取主应用共享的 request 实例
|
|
29
|
+
* 子应用内部使用此方法获取 request,确保复用主应用的认证和拦截器
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```tsx
|
|
33
|
+
* import { getMainAppRequest } from '@/common/mainApp';
|
|
34
|
+
*
|
|
35
|
+
* const request = getMainAppRequest();
|
|
36
|
+
* if (request) {
|
|
37
|
+
* const data = await request('/api/xxx');
|
|
38
|
+
* }
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export const getMainAppRequest = () => mainAppProps?.request;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* 判断是否作为微前端子应用运行
|
|
45
|
+
*/
|
|
46
|
+
export const isRunningInQiankun = () => !!mainAppProps;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* 获取主应用标识
|
|
50
|
+
*/
|
|
51
|
+
export const getMainAppName = () => mainAppProps?.mainApp;
|
|
52
|
+
|
|
53
|
+
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @name 统一请求封装
|
|
3
|
+
* @description 优先使用主应用的 request,独立运行时使用 umi request
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { getMainAppRequest } from '@/common/mainApp';
|
|
7
|
+
import { request as umiRequest } from '@umijs/max';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* 统一请求方法
|
|
11
|
+
* - 作为微前端子应用时:使用主应用传递的 request(共享认证和拦截器)
|
|
12
|
+
* - 独立运行时:使用 umi 内置的 request
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* import { request } from '@/common/request';
|
|
17
|
+
*
|
|
18
|
+
* const data = await request('/api/user/info');
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export async function request<T = any>(
|
|
22
|
+
url: string,
|
|
23
|
+
options?: any,
|
|
24
|
+
): Promise<T> {
|
|
25
|
+
const mainAppRequest = getMainAppRequest();
|
|
26
|
+
|
|
27
|
+
if (mainAppRequest) {
|
|
28
|
+
// 微前端模式:使用主应用的 request
|
|
29
|
+
console.log('[homepage] Using main app request:', url);
|
|
30
|
+
return mainAppRequest<T>(url, options);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// 独立运行模式:使用 umi request
|
|
34
|
+
console.log('[homepage] Using umi request:', url);
|
|
35
|
+
// umi request 默认返回 data,skipErrorHandler 可选
|
|
36
|
+
return umiRequest<T>(url, {
|
|
37
|
+
skipErrorHandler: true,
|
|
38
|
+
...options,
|
|
39
|
+
}) as Promise<T>;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* 判断当前使用的是哪个 request
|
|
44
|
+
*/
|
|
45
|
+
export function getRequestSource(): 'main-app' | 'umi' {
|
|
46
|
+
return getMainAppRequest() ? 'main-app' : 'umi';
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @name 全局样式
|
|
3
|
+
* @description homepage 子应用的全局样式
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// 仅导入 Less 变量(不包含 CSS 变量定义,避免重复打包)
|
|
7
|
+
// CSS 变量由主应用(layout)注入到 body 上
|
|
8
|
+
// Less 变量通过 var(--xxx) 引用 CSS 变量,自动适配主题
|
|
9
|
+
@import '@audit-center/shared-styles/variables-only';
|
|
10
|
+
|
|
11
|
+
* {
|
|
12
|
+
box-sizing: border-box;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
html,
|
|
16
|
+
body {
|
|
17
|
+
margin: 0;
|
|
18
|
+
padding: 0;
|
|
19
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial,
|
|
20
|
+
'Noto Sans', sans-serif;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
#homepage-root {
|
|
24
|
+
width: 100%;
|
|
25
|
+
height: 100%;
|
|
26
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @name 首页样式
|
|
3
|
+
* @description 使用主题色变量的示例
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// 导入共享样式变量
|
|
7
|
+
@import '@audit-center/shared-styles/variables-only';
|
|
8
|
+
|
|
9
|
+
.homepage {
|
|
10
|
+
padding: @spacing-lg;
|
|
11
|
+
min-height: 100vh;
|
|
12
|
+
// 使用主题色变量 - 背景色会随主题切换自动变化
|
|
13
|
+
background-color: @color-fill-1;
|
|
14
|
+
transition: background-color 0.3s ease;
|
|
15
|
+
|
|
16
|
+
&-title {
|
|
17
|
+
font-size: @font-size-xxl;
|
|
18
|
+
font-weight: @font-weight-bold;
|
|
19
|
+
// 主要文字色 - 亮色模式为深色,暗色模式为浅色
|
|
20
|
+
color: @color-text-1;
|
|
21
|
+
margin-bottom: @spacing-md;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
&-subtitle {
|
|
25
|
+
font-size: @font-size-md;
|
|
26
|
+
// 次要文字色
|
|
27
|
+
color: @color-text-2;
|
|
28
|
+
margin-bottom: @spacing-lg;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
&-card {
|
|
32
|
+
padding: @card-padding;
|
|
33
|
+
// 卡片背景色 - 使用 color-text-5(亮色模式为白色)
|
|
34
|
+
background-color: @color-text-5;
|
|
35
|
+
border-radius: @border-radius-card;
|
|
36
|
+
// 边框色
|
|
37
|
+
border: 1px solid @color-border-2;
|
|
38
|
+
box-shadow: @shadow-card;
|
|
39
|
+
margin-bottom: @spacing-md;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
&-colors {
|
|
43
|
+
display: flex;
|
|
44
|
+
flex-wrap: wrap;
|
|
45
|
+
gap: @spacing-md;
|
|
46
|
+
margin-top: @spacing-lg;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
&-color-item {
|
|
50
|
+
display: flex;
|
|
51
|
+
flex-direction: column;
|
|
52
|
+
align-items: center;
|
|
53
|
+
gap: @spacing-xs;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
&-color-box {
|
|
57
|
+
width: 60px;
|
|
58
|
+
height: 60px;
|
|
59
|
+
border-radius: @border-radius-md;
|
|
60
|
+
border: 1px solid @color-border-2;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
&-color-label {
|
|
64
|
+
font-size: @font-size-sm;
|
|
65
|
+
color: @color-text-3;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// 品牌色示例
|
|
69
|
+
.brand-1 { background-color: @Brand1-6; }
|
|
70
|
+
.brand-2 { background-color: @Brand2-6; }
|
|
71
|
+
|
|
72
|
+
// 功能色示例
|
|
73
|
+
.success { background-color: @Success-6; }
|
|
74
|
+
.warning { background-color: @Warning-6; }
|
|
75
|
+
.danger { background-color: @Danger-6; }
|
|
76
|
+
|
|
77
|
+
// 中性色示例
|
|
78
|
+
.fill-1 { background-color: @color-fill-1; }
|
|
79
|
+
.fill-2 { background-color: @color-fill-2; }
|
|
80
|
+
.fill-3 { background-color: @color-fill-3; }
|
|
81
|
+
|
|
82
|
+
// 按钮示例
|
|
83
|
+
&-button {
|
|
84
|
+
display: inline-flex;
|
|
85
|
+
align-items: center;
|
|
86
|
+
justify-content: center;
|
|
87
|
+
padding: @spacing-sm @spacing-md;
|
|
88
|
+
font-size: @font-size-base;
|
|
89
|
+
border-radius: @border-radius-button;
|
|
90
|
+
cursor: pointer;
|
|
91
|
+
transition: all 0.2s ease;
|
|
92
|
+
|
|
93
|
+
&--primary {
|
|
94
|
+
background-color: @Brand1-6;
|
|
95
|
+
color: @color-text-5;
|
|
96
|
+
border: none;
|
|
97
|
+
|
|
98
|
+
&:hover {
|
|
99
|
+
background-color: @Brand1-5;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
&--secondary {
|
|
104
|
+
background-color: transparent;
|
|
105
|
+
color: @Brand1-6;
|
|
106
|
+
border: 1px solid @Brand1-6;
|
|
107
|
+
|
|
108
|
+
&:hover {
|
|
109
|
+
background-color: @Brand1-1;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// 提示信息示例
|
|
115
|
+
&-tip {
|
|
116
|
+
padding: @spacing-md;
|
|
117
|
+
border-radius: @border-radius-md;
|
|
118
|
+
margin-top: @spacing-lg;
|
|
119
|
+
|
|
120
|
+
&--info {
|
|
121
|
+
background-color: @Brand2-1;
|
|
122
|
+
border: 1px solid @Brand2-3;
|
|
123
|
+
color: @Brand2-7;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
&--success {
|
|
127
|
+
background-color: @Success-1;
|
|
128
|
+
border: 1px solid @Success-3;
|
|
129
|
+
color: @Success-7;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
&--warning {
|
|
133
|
+
background-color: @Warning-1;
|
|
134
|
+
border: 1px solid @Warning-3;
|
|
135
|
+
color: @Warning-7;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
import { getRequestSource, request } from '@/common/request';
|
|
2
|
+
import {
|
|
3
|
+
Alert,
|
|
4
|
+
Button,
|
|
5
|
+
Card,
|
|
6
|
+
Descriptions,
|
|
7
|
+
Divider,
|
|
8
|
+
Message,
|
|
9
|
+
Space,
|
|
10
|
+
Spin,
|
|
11
|
+
Switch,
|
|
12
|
+
Table,
|
|
13
|
+
Tag,
|
|
14
|
+
Typography,
|
|
15
|
+
} from '@arco-design/web-react';
|
|
16
|
+
import { IconMoon, IconRefresh, IconSun } from '@arco-design/web-react/icon';
|
|
17
|
+
import { useState } from 'react';
|
|
18
|
+
import './index.less';
|
|
19
|
+
|
|
20
|
+
const { Title, Paragraph, Text } = Typography;
|
|
21
|
+
|
|
22
|
+
// 定义响应类型
|
|
23
|
+
interface IUserInfo {
|
|
24
|
+
id: number;
|
|
25
|
+
name: string;
|
|
26
|
+
email: string;
|
|
27
|
+
avatar: string;
|
|
28
|
+
role: string;
|
|
29
|
+
department: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface IStatsData {
|
|
33
|
+
totalUsers: number;
|
|
34
|
+
activeUsers: number;
|
|
35
|
+
pendingTasks: number;
|
|
36
|
+
completedTasks: number;
|
|
37
|
+
lastUpdated: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
interface IListItem {
|
|
41
|
+
id: number;
|
|
42
|
+
title: string;
|
|
43
|
+
status: 'pending' | 'approved' | 'rejected';
|
|
44
|
+
createdAt: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* 主题色变量 & Arco Design 组件使用示例
|
|
49
|
+
*
|
|
50
|
+
* 子应用使用主题色变量和 Arco Design 的方式:
|
|
51
|
+
* 1. 在 config.ts 中配置 externals,将 react/react-dom/@arco-design/web-react 排除打包
|
|
52
|
+
* 2. 运行时从主应用的 window.React / window.arco 获取
|
|
53
|
+
* 3. 在 global.less 中导入 @import '@audit-center/shared-styles/variables-only';
|
|
54
|
+
* 4. Less 变量自动适配主应用的主题切换
|
|
55
|
+
*/
|
|
56
|
+
export default function HomePage() {
|
|
57
|
+
const [loading, setLoading] = useState(false);
|
|
58
|
+
const [userInfo, setUserInfo] = useState<IUserInfo | null>(null);
|
|
59
|
+
const [stats, setStats] = useState<IStatsData | null>(null);
|
|
60
|
+
const [listData, setListData] = useState<IListItem[]>([]);
|
|
61
|
+
|
|
62
|
+
// 获取用户信息
|
|
63
|
+
const fetchUserInfo = async () => {
|
|
64
|
+
setLoading(true);
|
|
65
|
+
try {
|
|
66
|
+
const res = await request<{ success: boolean; data: IUserInfo }>('/api/user/info');
|
|
67
|
+
if (res.success) {
|
|
68
|
+
setUserInfo(res.data);
|
|
69
|
+
Message.success('获取用户信息成功');
|
|
70
|
+
}
|
|
71
|
+
} catch (err) {
|
|
72
|
+
Message.error('获取用户信息失败');
|
|
73
|
+
console.error(err);
|
|
74
|
+
} finally {
|
|
75
|
+
setLoading(false);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// 获取统计数据
|
|
80
|
+
const fetchStats = async () => {
|
|
81
|
+
setLoading(true);
|
|
82
|
+
try {
|
|
83
|
+
const res = await request<{ success: boolean; data: IStatsData }>('/api/dashboard/stats');
|
|
84
|
+
if (res.success) {
|
|
85
|
+
setStats(res.data);
|
|
86
|
+
Message.success('获取统计数据成功');
|
|
87
|
+
}
|
|
88
|
+
} catch (err) {
|
|
89
|
+
Message.error('获取统计数据失败');
|
|
90
|
+
console.error(err);
|
|
91
|
+
} finally {
|
|
92
|
+
setLoading(false);
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
// 获取列表数据
|
|
97
|
+
const fetchList = async () => {
|
|
98
|
+
setLoading(true);
|
|
99
|
+
try {
|
|
100
|
+
const res = await request<{ success: boolean; data: { list: IListItem[] } }>('/api/items');
|
|
101
|
+
if (res.success) {
|
|
102
|
+
setListData(res.data.list);
|
|
103
|
+
Message.success('获取列表数据成功');
|
|
104
|
+
}
|
|
105
|
+
} catch (err) {
|
|
106
|
+
Message.error('获取列表数据失败');
|
|
107
|
+
console.error(err);
|
|
108
|
+
} finally {
|
|
109
|
+
setLoading(false);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
// 状态颜色映射
|
|
114
|
+
const statusColorMap = {
|
|
115
|
+
pending: 'orange',
|
|
116
|
+
approved: 'green',
|
|
117
|
+
rejected: 'red',
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const statusTextMap = {
|
|
121
|
+
pending: '待审核',
|
|
122
|
+
approved: '已通过',
|
|
123
|
+
rejected: '已拒绝',
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const showMessage = () => {
|
|
127
|
+
Message.success('Arco Design Message 组件正常工作!');
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
return (
|
|
131
|
+
<div className="homepage">
|
|
132
|
+
<Title heading={2}>🎨 子应用主题 & 组件示例</Title>
|
|
133
|
+
<Paragraph type="secondary">
|
|
134
|
+
子应用复用主应用的 React 和 Arco Design,无重复打包,主题自动同步
|
|
135
|
+
</Paragraph>
|
|
136
|
+
|
|
137
|
+
<Divider />
|
|
138
|
+
|
|
139
|
+
{/* 请求示例 */}
|
|
140
|
+
<Spin loading={loading} style={{ display: 'block' }}>
|
|
141
|
+
<Card
|
|
142
|
+
title="🔗 Request 请求示例"
|
|
143
|
+
style={{ marginBottom: 16 }}
|
|
144
|
+
extra={
|
|
145
|
+
<Tag color={getRequestSource() === 'main-app' ? 'green' : 'blue'}>
|
|
146
|
+
{getRequestSource() === 'main-app' ? '使用主应用 Request' : '使用 Umi Request'}
|
|
147
|
+
</Tag>
|
|
148
|
+
}
|
|
149
|
+
>
|
|
150
|
+
<Paragraph>
|
|
151
|
+
子应用优先使用主应用传递的 <Text code>request</Text> 实例,独立运行时使用 Umi
|
|
152
|
+
内置的 request。两种模式都支持 Mock。
|
|
153
|
+
</Paragraph>
|
|
154
|
+
|
|
155
|
+
<Space size="medium" style={{ marginTop: 16 }}>
|
|
156
|
+
<Button type="primary" icon={<IconRefresh />} onClick={fetchUserInfo}>
|
|
157
|
+
获取用户信息
|
|
158
|
+
</Button>
|
|
159
|
+
<Button type="secondary" icon={<IconRefresh />} onClick={fetchStats}>
|
|
160
|
+
获取统计数据
|
|
161
|
+
</Button>
|
|
162
|
+
<Button type="outline" icon={<IconRefresh />} onClick={fetchList}>
|
|
163
|
+
获取列表数据
|
|
164
|
+
</Button>
|
|
165
|
+
</Space>
|
|
166
|
+
|
|
167
|
+
{/* 用户信息展示 */}
|
|
168
|
+
{userInfo && (
|
|
169
|
+
<>
|
|
170
|
+
<Divider />
|
|
171
|
+
<Title heading={6}>用户信息</Title>
|
|
172
|
+
<Descriptions
|
|
173
|
+
column={2}
|
|
174
|
+
data={[
|
|
175
|
+
{ label: 'ID', value: userInfo.id },
|
|
176
|
+
{ label: '姓名', value: userInfo.name },
|
|
177
|
+
{ label: '邮箱', value: userInfo.email },
|
|
178
|
+
{ label: '角色', value: <Tag color="arcoblue">{userInfo.role}</Tag> },
|
|
179
|
+
{ label: '部门', value: userInfo.department },
|
|
180
|
+
]}
|
|
181
|
+
/>
|
|
182
|
+
</>
|
|
183
|
+
)}
|
|
184
|
+
|
|
185
|
+
{/* 统计数据展示 */}
|
|
186
|
+
{stats && (
|
|
187
|
+
<>
|
|
188
|
+
<Divider />
|
|
189
|
+
<Title heading={6}>统计数据</Title>
|
|
190
|
+
<Descriptions
|
|
191
|
+
column={2}
|
|
192
|
+
data={[
|
|
193
|
+
{ label: '总用户数', value: stats.totalUsers.toLocaleString() },
|
|
194
|
+
{ label: '活跃用户', value: stats.activeUsers.toLocaleString() },
|
|
195
|
+
{ label: '待处理任务', value: <Tag color="orange">{stats.pendingTasks}</Tag> },
|
|
196
|
+
{ label: '已完成任务', value: <Tag color="green">{stats.completedTasks}</Tag> },
|
|
197
|
+
{ label: '更新时间', value: new Date(stats.lastUpdated).toLocaleString() },
|
|
198
|
+
]}
|
|
199
|
+
/>
|
|
200
|
+
</>
|
|
201
|
+
)}
|
|
202
|
+
|
|
203
|
+
{/* 列表数据展示 */}
|
|
204
|
+
{listData.length > 0 && (
|
|
205
|
+
<>
|
|
206
|
+
<Divider />
|
|
207
|
+
<Title heading={6}>列表数据</Title>
|
|
208
|
+
<Table
|
|
209
|
+
size="small"
|
|
210
|
+
pagination={false}
|
|
211
|
+
columns={[
|
|
212
|
+
{ title: 'ID', dataIndex: 'id', width: 80 },
|
|
213
|
+
{ title: '标题', dataIndex: 'title' },
|
|
214
|
+
{
|
|
215
|
+
title: '状态',
|
|
216
|
+
dataIndex: 'status',
|
|
217
|
+
width: 100,
|
|
218
|
+
render: (status: keyof typeof statusColorMap) => (
|
|
219
|
+
<Tag color={statusColorMap[status]}>{statusTextMap[status]}</Tag>
|
|
220
|
+
),
|
|
221
|
+
},
|
|
222
|
+
{ title: '创建时间', dataIndex: 'createdAt', width: 180 },
|
|
223
|
+
]}
|
|
224
|
+
data={listData}
|
|
225
|
+
/>
|
|
226
|
+
</>
|
|
227
|
+
)}
|
|
228
|
+
</Card>
|
|
229
|
+
</Spin>
|
|
230
|
+
|
|
231
|
+
{/* Arco Design 组件示例 */}
|
|
232
|
+
<Card title="📦 Arco Design 组件" style={{ marginBottom: 16 }}>
|
|
233
|
+
<Paragraph>
|
|
234
|
+
子应用通过 <Text code>externals</Text> 配置复用主应用的 Arco Design,
|
|
235
|
+
避免重复打包(节省 ~800KB)。
|
|
236
|
+
</Paragraph>
|
|
237
|
+
|
|
238
|
+
<Space size="medium" style={{ marginTop: 16 }}>
|
|
239
|
+
<Button type="primary" onClick={showMessage}>
|
|
240
|
+
主要按钮
|
|
241
|
+
</Button>
|
|
242
|
+
<Button type="secondary">次要按钮</Button>
|
|
243
|
+
<Button type="outline">线框按钮</Button>
|
|
244
|
+
<Button type="text">文字按钮</Button>
|
|
245
|
+
</Space>
|
|
246
|
+
|
|
247
|
+
<Divider />
|
|
248
|
+
|
|
249
|
+
<Space size="medium">
|
|
250
|
+
<Tag color="arcoblue">Arco Blue</Tag>
|
|
251
|
+
<Tag color="green">Success</Tag>
|
|
252
|
+
<Tag color="gold">Warning</Tag>
|
|
253
|
+
<Tag color="red">Danger</Tag>
|
|
254
|
+
<Tag color="purple">Purple</Tag>
|
|
255
|
+
</Space>
|
|
256
|
+
|
|
257
|
+
<Divider />
|
|
258
|
+
|
|
259
|
+
<Space size="medium" align="center">
|
|
260
|
+
<Text>主题切换:</Text>
|
|
261
|
+
<Switch
|
|
262
|
+
checkedIcon={<IconMoon />}
|
|
263
|
+
uncheckedIcon={<IconSun />}
|
|
264
|
+
onChange={(checked: boolean) => {
|
|
265
|
+
Message.info(`切换到 ${checked ? '暗色' : '亮色'} 模式(需在主应用操作)`);
|
|
266
|
+
}}
|
|
267
|
+
/>
|
|
268
|
+
<Text type="secondary">(实际切换请在主应用 Header 操作)</Text>
|
|
269
|
+
</Space>
|
|
270
|
+
</Card>
|
|
271
|
+
|
|
272
|
+
{/* 自定义主题色示例 */}
|
|
273
|
+
<Card title="🎨 自定义主题色变量" style={{ marginBottom: 16 }}>
|
|
274
|
+
<Paragraph>
|
|
275
|
+
在 Less 中使用 <Text code>@audit-center/shared-styles/variables-only</Text>{' '}
|
|
276
|
+
导入主题变量,自动适配亮色/暗色主题。
|
|
277
|
+
</Paragraph>
|
|
278
|
+
|
|
279
|
+
<Title heading={6}>品牌色 & 功能色</Title>
|
|
280
|
+
<div className="homepage-colors">
|
|
281
|
+
<div className="homepage-color-item">
|
|
282
|
+
<div className="homepage-color-box brand-1" />
|
|
283
|
+
<span className="homepage-color-label">@Brand1-6</span>
|
|
284
|
+
</div>
|
|
285
|
+
<div className="homepage-color-item">
|
|
286
|
+
<div className="homepage-color-box brand-2" />
|
|
287
|
+
<span className="homepage-color-label">@Brand2-6</span>
|
|
288
|
+
</div>
|
|
289
|
+
<div className="homepage-color-item">
|
|
290
|
+
<div className="homepage-color-box success" />
|
|
291
|
+
<span className="homepage-color-label">@Success-6</span>
|
|
292
|
+
</div>
|
|
293
|
+
<div className="homepage-color-item">
|
|
294
|
+
<div className="homepage-color-box warning" />
|
|
295
|
+
<span className="homepage-color-label">@Warning-6</span>
|
|
296
|
+
</div>
|
|
297
|
+
<div className="homepage-color-item">
|
|
298
|
+
<div className="homepage-color-box danger" />
|
|
299
|
+
<span className="homepage-color-label">@Danger-6</span>
|
|
300
|
+
</div>
|
|
301
|
+
</div>
|
|
302
|
+
|
|
303
|
+
<Title heading={6} style={{ marginTop: 16 }}>
|
|
304
|
+
中性色(随主题自动切换)
|
|
305
|
+
</Title>
|
|
306
|
+
<div className="homepage-colors">
|
|
307
|
+
<div className="homepage-color-item">
|
|
308
|
+
<div className="homepage-color-box fill-1" />
|
|
309
|
+
<span className="homepage-color-label">@color-fill-1</span>
|
|
310
|
+
</div>
|
|
311
|
+
<div className="homepage-color-item">
|
|
312
|
+
<div className="homepage-color-box fill-2" />
|
|
313
|
+
<span className="homepage-color-label">@color-fill-2</span>
|
|
314
|
+
</div>
|
|
315
|
+
<div className="homepage-color-item">
|
|
316
|
+
<div className="homepage-color-box fill-3" />
|
|
317
|
+
<span className="homepage-color-label">@color-fill-3</span>
|
|
318
|
+
</div>
|
|
319
|
+
</div>
|
|
320
|
+
</Card>
|
|
321
|
+
|
|
322
|
+
{/* 提示信息 */}
|
|
323
|
+
<Space direction="vertical" style={{ width: '100%' }}>
|
|
324
|
+
<Alert
|
|
325
|
+
type="info"
|
|
326
|
+
title="依赖共享"
|
|
327
|
+
content="通过 externals 配置,子应用复用主应用的 React 和 Arco Design,打包体积减少 ~1MB"
|
|
328
|
+
/>
|
|
329
|
+
<Alert
|
|
330
|
+
type="success"
|
|
331
|
+
title="主题同步"
|
|
332
|
+
content="子应用的 Arco 组件和自定义样式自动跟随主应用主题切换"
|
|
333
|
+
/>
|
|
334
|
+
<Alert
|
|
335
|
+
type="warning"
|
|
336
|
+
title="注意事项"
|
|
337
|
+
content="使用 variables-only 导入,避免重复打包 CSS 变量定义"
|
|
338
|
+
/>
|
|
339
|
+
</Space>
|
|
340
|
+
</div>
|
|
341
|
+
);
|
|
342
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import '@umijs/max/typings';
|
|
2
|
+
|
|
3
|
+
declare global {
|
|
4
|
+
interface Window {
|
|
5
|
+
/**
|
|
6
|
+
* @name qiankun 环境标识
|
|
7
|
+
* @description 当应用作为 qiankun 子应用运行时为 true
|
|
8
|
+
*/
|
|
9
|
+
__POWERED_BY_QIANKUN__?: boolean;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @name qiankun 注入的公共路径
|
|
13
|
+
* @description qiankun 运行时注入的资源路径前缀
|
|
14
|
+
*/
|
|
15
|
+
__INJECTED_PUBLIC_PATH_BY_QIANKUN__?: string;
|
|
16
|
+
}
|
|
17
|
+
}
|