@appthen/cli 1.2.11 → 1.2.12
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/bin/main.js +47 -0
- package/dist/index.js +6165 -14980
- package/package.json +8 -1
- package/tests/test-app/.appthen/shadow-space-100001-test-app-e99876b1.json +1197 -741
- package/tests/test-app/.appthen/space-config.json +2 -2
- package/tests/test-app/src/components/MessageCenter.tsx +506 -0
- package/tests/test-app/src/pages/CustomerManagement.tsx +535 -0
- package/tests/test-app/src/pages/CyberpunkDashboard.tsx +348 -0
- package/tests/test-app/src/pages/CyberpunkProductManagement.tsx +637 -0
- package/tests/test-app/src/pages/CyberpunkUserList.tsx +316 -0
- package/tests/test-app/src/pages/DashboardV2.tsx +334 -0
- package/tests/test-app/src/pages/DataReport.tsx +298 -0
- package/tests/test-app/src/pages/DataStatistics.tsx +317 -0
- package/tests/test-app/src/pages/DepartmentManagement.tsx +503 -0
- package/tests/test-app/src/pages/FileExplorer.tsx +441 -0
- package/tests/test-app/src/pages/OrderDetail.tsx +393 -0
- package/tests/test-app/src/pages/ProductManagement.tsx +521 -0
- package/tests/test-app/src/pages/ProjectTimeline.tsx +395 -0
- package/tests/test-app/src/pages/RoleManagement.tsx +523 -0
- package/tests/test-app/src/pages/StaticCyberpunkDashboard.tsx +462 -0
- package/tests/test-app/src/pages/StaticCyberpunkUserList.tsx +567 -0
- package/tests/test-app/src/pages/StudentWeaknessList.tsx +547 -0
- package/tests/test-app/src/pages/SystemSettings.tsx +422 -0
- package/tests/test-app/src/pages/TaskManagement.tsx +467 -0
- package/tests/test-app/src/pages/TicketManagement.tsx +402 -0
- package/tests/test-app/src/pages/UserProfile.tsx +404 -0
- package/tests/test-app/src/pages/WorkflowDesigner.tsx +434 -0
- package/tests/test-app/src/pages/admin/dashboard.tsx +591 -0
- package/tests/test-app/src/pages/article-list.tsx +222 -0
- package/tests/test-app/src/pages/babyProductRecommendationPage.tsx +168 -0
- package/tests/test-app/src/pages/category-list.tsx +179 -0
- package/tests/test-app/src/pages/comment-list.tsx +194 -0
- package/tests/test-app/src/pages/cyberpunk/cyberpunkCRMPage.tsx +1299 -0
- package/tests/test-app/src/pages/data-analytics.tsx +1872 -0
- package/tests/test-app/src/pages/data-overview.tsx +600 -0
- package/tests/test-app/src/pages/demo-error-page.tsx +119 -0
- package/tests/test-app/src/pages/department-list.tsx +183 -0
- package/tests/test-app/src/pages/goods-list.tsx +233 -0
- package/tests/test-app/src/pages/housekeeping/adminDashboardPage.tsx +880 -0
- package/tests/test-app/src/pages/mobile_terminal/uiHandsOnPractice.tsx +1 -1
- package/tests/test-app/src/pages/notice-list.tsx +217 -0
- package/tests/test-app/src/pages/order-detail.tsx +330 -0
- package/tests/test-app/src/pages/order-list.tsx +195 -0
- package/tests/test-app/src/pages/order-management.tsx +563 -0
- package/tests/test-app/src/pages/page/OrderList.tsx +230 -0
- package/tests/test-app/src/pages/role-list.tsx +184 -0
- package/tests/test-app/src/pages/simple/simplePage.tsx +92 -0
- package/tests/test-app/src/pages/simple-page.tsx +43 -0
- package/tests/test-app/src/pages/test-destructure.tsx +44 -0
- package/tests/test-app/src/pages/test-error-page.tsx +75 -0
- package/tests/test-app/src/pages/test-page-with-errors.tsx +51 -0
- package/tests/test-app/src/pages/test-page.tsx +101 -0
- package/tests/test-app/src/pages/test-render.tsx +52 -0
- package/tests/test-app/src/pages/test-return-type.tsx +41 -0
- package/tests/test-app/src/pages/test-type-assertion.tsx +37 -0
- package/tests/test-app/src/pages/ui/styleSelectorPage.tsx +1554 -0
- package/tests/test-app/src/pages/user-list.tsx +212 -0
- package/tests/test-app/src/pages/wrong-page.tsx +50 -0
- package/tests/test-app/.appthen/shadow-space-unknown-user-test-app-e99876b1.json +0 -1060
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 数据报表
|
|
3
|
+
* 数据统计和分析报表
|
|
4
|
+
*
|
|
5
|
+
* @type Page
|
|
6
|
+
* @route /report
|
|
7
|
+
* @screen 1920w
|
|
8
|
+
* @frames web
|
|
9
|
+
*/
|
|
10
|
+
import React from 'react';
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class IProps {
|
|
15
|
+
reportType?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/*
|
|
19
|
+
* 数据与接口请求定义
|
|
20
|
+
*/
|
|
21
|
+
class IState {
|
|
22
|
+
reportData?: {
|
|
23
|
+
/* @example 1 */id?: number,
|
|
24
|
+
/* @example 2024-01-15 */date?: string,
|
|
25
|
+
/* @example 电子产品 */category?: string,
|
|
26
|
+
/* @example 12500 */revenue?: number,
|
|
27
|
+
/* @example 45 */orders?: number,
|
|
28
|
+
/* @example 23 */users?: number,
|
|
29
|
+
}[];
|
|
30
|
+
summary?: {
|
|
31
|
+
totalRevenue?: number,
|
|
32
|
+
totalOrders?: number,
|
|
33
|
+
totalUsers?: number,
|
|
34
|
+
conversionRate?: number,
|
|
35
|
+
};
|
|
36
|
+
loading?: boolean;
|
|
37
|
+
dateRange?: string;
|
|
38
|
+
reportType?: string;
|
|
39
|
+
selectedCategory?: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
class Document extends React.Component<IProps, IState> {
|
|
43
|
+
state = {
|
|
44
|
+
reportData: [
|
|
45
|
+
{
|
|
46
|
+
id: 1,
|
|
47
|
+
date: '2024-01-15',
|
|
48
|
+
category: '电子产品',
|
|
49
|
+
revenue: 12500,
|
|
50
|
+
orders: 45,
|
|
51
|
+
users: 23,
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: 2,
|
|
55
|
+
date: '2024-01-16',
|
|
56
|
+
category: '电子产品',
|
|
57
|
+
revenue: 15800,
|
|
58
|
+
orders: 52,
|
|
59
|
+
users: 28,
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
id: 3,
|
|
63
|
+
date: '2024-01-17',
|
|
64
|
+
category: '服装',
|
|
65
|
+
revenue: 9800,
|
|
66
|
+
orders: 38,
|
|
67
|
+
users: 19,
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
id: 4,
|
|
71
|
+
date: '2024-01-18',
|
|
72
|
+
category: '食品',
|
|
73
|
+
revenue: 6200,
|
|
74
|
+
orders: 85,
|
|
75
|
+
users: 42,
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
id: 5,
|
|
79
|
+
date: '2024-01-19',
|
|
80
|
+
category: '电子产品',
|
|
81
|
+
revenue: 18900,
|
|
82
|
+
orders: 67,
|
|
83
|
+
users: 35,
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
summary: {
|
|
87
|
+
totalRevenue: 63200,
|
|
88
|
+
totalOrders: 287,
|
|
89
|
+
totalUsers: 147,
|
|
90
|
+
conversionRate: 52.3,
|
|
91
|
+
},
|
|
92
|
+
loading: false,
|
|
93
|
+
dateRange: '2024-01-01,2024-01-31',
|
|
94
|
+
reportType: 'daily',
|
|
95
|
+
selectedCategory: 'all',
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
handleDateChange(dates) {
|
|
99
|
+
this.setState({
|
|
100
|
+
dateRange: dates,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
calculateTotal(data, field) {
|
|
105
|
+
return data.reduce((sum, item) => sum + (item[field] || 0), 0);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
formatCurrency(amount) {
|
|
109
|
+
return `¥${amount.toLocaleString()}`;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
getCategoryColor(category) {
|
|
113
|
+
const colors = {
|
|
114
|
+
电子产品: 'blue',
|
|
115
|
+
服装: 'green',
|
|
116
|
+
食品: 'orange',
|
|
117
|
+
家居: 'purple',
|
|
118
|
+
};
|
|
119
|
+
return colors[category] || 'default';
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
handleExport(format) {
|
|
123
|
+
console.log('导出报表:', format, this.state.reportData);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
render() {
|
|
127
|
+
return (
|
|
128
|
+
<Page className="p-[24px] bg-[var(--gray-50)] min-h-screen">
|
|
129
|
+
<View className="mb-[24px]">
|
|
130
|
+
<Text className="text-2xl font-bold text-[#1f2937]">数据报表</Text>
|
|
131
|
+
<Text className="text-[#6b7280] text-sm mt-[4px]">
|
|
132
|
+
数据统计和分析报表
|
|
133
|
+
</Text>
|
|
134
|
+
</View>
|
|
135
|
+
<Row gutter={16} className="mb-[24px]">
|
|
136
|
+
<Col span={6}>
|
|
137
|
+
<Card>
|
|
138
|
+
<Statistic
|
|
139
|
+
title="总收入"
|
|
140
|
+
value={this.state.summary.totalRevenue}
|
|
141
|
+
prefix="¥"
|
|
142
|
+
precision={2}
|
|
143
|
+
/>
|
|
144
|
+
</Card>
|
|
145
|
+
</Col>
|
|
146
|
+
<Col span={6}>
|
|
147
|
+
<Card>
|
|
148
|
+
<Statistic
|
|
149
|
+
title="总订单数"
|
|
150
|
+
value={this.state.summary.totalOrders}
|
|
151
|
+
suffix="单"
|
|
152
|
+
/>
|
|
153
|
+
</Card>
|
|
154
|
+
</Col>
|
|
155
|
+
<Col span={6}>
|
|
156
|
+
<Card>
|
|
157
|
+
<Statistic
|
|
158
|
+
title="总用户数"
|
|
159
|
+
value={this.state.summary.totalUsers}
|
|
160
|
+
suffix="人"
|
|
161
|
+
/>
|
|
162
|
+
</Card>
|
|
163
|
+
</Col>
|
|
164
|
+
<Col span={6}>
|
|
165
|
+
<Card>
|
|
166
|
+
<Statistic
|
|
167
|
+
title="转化率"
|
|
168
|
+
value={this.state.summary.conversionRate}
|
|
169
|
+
suffix="%"
|
|
170
|
+
precision={2}
|
|
171
|
+
/>
|
|
172
|
+
</Card>
|
|
173
|
+
</Col>
|
|
174
|
+
</Row>
|
|
175
|
+
<Card className="mb-[24px]">
|
|
176
|
+
<View className="gap-4 flex items-center">
|
|
177
|
+
<View>
|
|
178
|
+
<Text className="block mb-[8px]">日期范围</Text>
|
|
179
|
+
<DatePicker.RangePicker
|
|
180
|
+
value={this.state.dateRange}
|
|
181
|
+
onChange={dates => this.handleDateChange(dates)}
|
|
182
|
+
className=""
|
|
183
|
+
/>
|
|
184
|
+
</View>
|
|
185
|
+
<View>
|
|
186
|
+
<Text className="block mb-[8px]">报表类型</Text>
|
|
187
|
+
<Select
|
|
188
|
+
value={this.state.reportType}
|
|
189
|
+
onChange={value =>
|
|
190
|
+
this.setState({
|
|
191
|
+
reportType: value,
|
|
192
|
+
})
|
|
193
|
+
}
|
|
194
|
+
className=""
|
|
195
|
+
>
|
|
196
|
+
<Select.Option value="daily">日报表</Select.Option>
|
|
197
|
+
<Select.Option value="weekly">周报表</Select.Option>
|
|
198
|
+
<Select.Option value="monthly">月报表</Select.Option>
|
|
199
|
+
</Select>
|
|
200
|
+
</View>
|
|
201
|
+
<View>
|
|
202
|
+
<Text className="block mb-[8px]">分类筛选</Text>
|
|
203
|
+
<Select
|
|
204
|
+
value={this.state.selectedCategory}
|
|
205
|
+
onChange={value =>
|
|
206
|
+
this.setState({
|
|
207
|
+
selectedCategory: value,
|
|
208
|
+
})
|
|
209
|
+
}
|
|
210
|
+
className=""
|
|
211
|
+
>
|
|
212
|
+
<Select.Option value="all">全部</Select.Option>
|
|
213
|
+
<Select.Option value="电子产品">电子产品</Select.Option>
|
|
214
|
+
<Select.Option value="服装">服装</Select.Option>
|
|
215
|
+
<Select.Option value="食品">食品</Select.Option>
|
|
216
|
+
<Select.Option value="家居">家居</Select.Option>
|
|
217
|
+
</Select>
|
|
218
|
+
</View>
|
|
219
|
+
<View className="ml-[auto]">
|
|
220
|
+
<Button type="default" onClick={() => this.handleExport('excel')}>
|
|
221
|
+
导出 Excel
|
|
222
|
+
</Button>
|
|
223
|
+
<Button
|
|
224
|
+
type="primary"
|
|
225
|
+
onClick={() => this.handleExport('pdf')}
|
|
226
|
+
className="ml-[8px]"
|
|
227
|
+
>
|
|
228
|
+
导出 PDF
|
|
229
|
+
</Button>
|
|
230
|
+
</View>
|
|
231
|
+
</View>
|
|
232
|
+
</Card>
|
|
233
|
+
<Card>
|
|
234
|
+
<Table
|
|
235
|
+
loading={this.state.loading}
|
|
236
|
+
columns={[
|
|
237
|
+
{ title: '日期', dataIndex: 'date', key: 'date' },
|
|
238
|
+
{
|
|
239
|
+
title: '分类',
|
|
240
|
+
dataIndex: 'category',
|
|
241
|
+
key: 'category',
|
|
242
|
+
render: category => (
|
|
243
|
+
<Tag color={this.getCategoryColor(category)}>
|
|
244
|
+
<Text>{category}</Text>
|
|
245
|
+
</Tag>
|
|
246
|
+
),
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
title: '收入',
|
|
250
|
+
dataIndex: 'revenue',
|
|
251
|
+
key: 'revenue',
|
|
252
|
+
render: revenue => <Text>{this.formatCurrency(revenue)}</Text>,
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
title: '订单数',
|
|
256
|
+
dataIndex: 'orders',
|
|
257
|
+
key: 'orders',
|
|
258
|
+
render: orders => <Text>{orders}单</Text>,
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
title: '用户数',
|
|
262
|
+
dataIndex: 'users',
|
|
263
|
+
key: 'users',
|
|
264
|
+
render: users => <Text>{users}人</Text>,
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
title: '操作',
|
|
268
|
+
key: 'action',
|
|
269
|
+
render: (text, record) => (
|
|
270
|
+
<Button
|
|
271
|
+
type="link"
|
|
272
|
+
onClick={() => console.log('查看详情:', record)}
|
|
273
|
+
>
|
|
274
|
+
查看详情
|
|
275
|
+
</Button>
|
|
276
|
+
),
|
|
277
|
+
},
|
|
278
|
+
]}
|
|
279
|
+
dataSource={this.state.reportData?.filter(function (item) {
|
|
280
|
+
if (this.state.selectedCategory === 'all') return true;
|
|
281
|
+
return item?.category === this.state.selectedCategory;
|
|
282
|
+
})}
|
|
283
|
+
rowKey="id"
|
|
284
|
+
pagination={{
|
|
285
|
+
pageSize: 10,
|
|
286
|
+
showTotal: function (total) {
|
|
287
|
+
return `共 ${total} 条`;
|
|
288
|
+
},
|
|
289
|
+
}}
|
|
290
|
+
/>
|
|
291
|
+
</Card>
|
|
292
|
+
{!!this.state.loading && <View className="p-[24px]">加载中...</View>}
|
|
293
|
+
</Page>
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
export default Document;
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 数据统计
|
|
3
|
+
* 数据分析和统计展示
|
|
4
|
+
*
|
|
5
|
+
* @type Page
|
|
6
|
+
* @route /statistics
|
|
7
|
+
* @screen 1920w
|
|
8
|
+
* @frames web
|
|
9
|
+
*/
|
|
10
|
+
import React from 'react';
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class IProps {
|
|
15
|
+
userId?: number;
|
|
16
|
+
startDate?: string;
|
|
17
|
+
endDate?: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/*
|
|
21
|
+
* 数据与接口请求定义
|
|
22
|
+
*/
|
|
23
|
+
class IState {
|
|
24
|
+
statistics?: {
|
|
25
|
+
/* @example 1 */id?: number,
|
|
26
|
+
/* @example 总访问量 */name?: string,
|
|
27
|
+
/* @example 125860 */value?: number,
|
|
28
|
+
/* @example +12% */trend?: string,
|
|
29
|
+
/* @example up */status?: string,
|
|
30
|
+
/* @example 流量 */category?: string,
|
|
31
|
+
}[];
|
|
32
|
+
loading?: boolean;
|
|
33
|
+
chartData?: string[];
|
|
34
|
+
timeRange?: string;
|
|
35
|
+
selectedMetric?: string;
|
|
36
|
+
showComparison?: boolean;
|
|
37
|
+
summary?: {
|
|
38
|
+
totalUsers?: number,
|
|
39
|
+
activeUsers?: number,
|
|
40
|
+
conversionRate?: number,
|
|
41
|
+
revenue?: number,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
class Document extends React.Component<IProps, IState> {
|
|
46
|
+
state = {
|
|
47
|
+
statistics: [
|
|
48
|
+
{
|
|
49
|
+
id: 1,
|
|
50
|
+
name: '总访问量',
|
|
51
|
+
value: 125860,
|
|
52
|
+
trend: '+12%',
|
|
53
|
+
status: 'up',
|
|
54
|
+
category: '流量',
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: 2,
|
|
58
|
+
name: '独立访客',
|
|
59
|
+
value: 45230,
|
|
60
|
+
trend: '+8%',
|
|
61
|
+
status: 'up',
|
|
62
|
+
category: '流量',
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
id: 3,
|
|
66
|
+
name: '转化率',
|
|
67
|
+
value: 3.24,
|
|
68
|
+
trend: '+0.5%',
|
|
69
|
+
status: 'up',
|
|
70
|
+
category: '转化',
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
id: 4,
|
|
74
|
+
name: '客单价',
|
|
75
|
+
value: 286.5,
|
|
76
|
+
trend: '-2.3%',
|
|
77
|
+
status: 'down',
|
|
78
|
+
category: '转化',
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
id: 5,
|
|
82
|
+
name: '订单量',
|
|
83
|
+
value: 856,
|
|
84
|
+
trend: '+15%',
|
|
85
|
+
status: 'up',
|
|
86
|
+
category: '订单',
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
id: 6,
|
|
90
|
+
name: '退货率',
|
|
91
|
+
value: 2.8,
|
|
92
|
+
trend: '-0.5%',
|
|
93
|
+
status: 'up',
|
|
94
|
+
category: '订单',
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
loading: false,
|
|
98
|
+
chartData: [],
|
|
99
|
+
timeRange: '7d',
|
|
100
|
+
selectedMetric: 'all',
|
|
101
|
+
showComparison: true,
|
|
102
|
+
summary: {
|
|
103
|
+
totalUsers: 45230,
|
|
104
|
+
activeUsers: 32150,
|
|
105
|
+
conversionRate: 3.24,
|
|
106
|
+
revenue: 245680.5,
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
handleTimeRangeChange(range) {
|
|
111
|
+
this.setState({
|
|
112
|
+
timeRange: range,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
handleMetricChange(metric) {
|
|
117
|
+
this.setState({
|
|
118
|
+
selectedMetric: metric,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
toggleComparison() {
|
|
123
|
+
this.setState({
|
|
124
|
+
showComparison: !this.state.showComparison,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
refreshData() {
|
|
129
|
+
this.setState({
|
|
130
|
+
loading: true,
|
|
131
|
+
});
|
|
132
|
+
setTimeout(() => {
|
|
133
|
+
this.setState({
|
|
134
|
+
loading: false,
|
|
135
|
+
});
|
|
136
|
+
}, 1000);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
exportReport(format) {
|
|
140
|
+
console.log('导出报表:', format);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
render() {
|
|
144
|
+
// 💀 死亡:变量声明 - 解构赋值
|
|
145
|
+
const {
|
|
146
|
+
statistics,
|
|
147
|
+
loading,
|
|
148
|
+
timeRange,
|
|
149
|
+
selectedMetric,
|
|
150
|
+
showComparison,
|
|
151
|
+
summary,
|
|
152
|
+
} = this.state;
|
|
153
|
+
|
|
154
|
+
// 💀 死亡:变量声明 - 计算属性
|
|
155
|
+
// 💀 死亡:变量声明 - 计算属性
|
|
156
|
+
const totalVisits =
|
|
157
|
+
this.state.statistics.find(s => s.name === '总访问量')?.value || 0;
|
|
158
|
+
const totalRevenue =
|
|
159
|
+
this.state.statistics.find(s => s.name === '客单价')?.value *
|
|
160
|
+
this.state.statistics.find(s => s.name === '订单量')?.value || 0;
|
|
161
|
+
|
|
162
|
+
// 💀 死亡:变量声明 - 过滤后的数据
|
|
163
|
+
// 💀 死亡:变量声明 - 过滤后的数据
|
|
164
|
+
const filteredStats = this.state.statistics.filter(stat => {
|
|
165
|
+
if (selectedMetric === 'all') return true;
|
|
166
|
+
return stat.category === selectedMetric;
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// 💀 死亡:if 语句 - 条件渲染
|
|
170
|
+
// 💀 死亡:if 语句 - 条件渲染
|
|
171
|
+
if (loading) {
|
|
172
|
+
return <View className="p-6">加载中...</View>;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// 💀 死亡:变量声明 - JSX 片段
|
|
176
|
+
// 💀 死亡:变量声明 - JSX 片段
|
|
177
|
+
const statCard = stat => (
|
|
178
|
+
<Card className="hover:shadow-lg transition-shadow">
|
|
179
|
+
<View className="flex justify-between items-start">
|
|
180
|
+
<View>
|
|
181
|
+
<Text className="text-gray-500 text-sm">{stat.name}</Text>
|
|
182
|
+
<Text className="text-2xl font-bold mt-1">
|
|
183
|
+
{stat.value.toLocaleString()}
|
|
184
|
+
</Text>
|
|
185
|
+
</View>
|
|
186
|
+
<Tag color={stat.status === 'up' ? 'green' : 'red'}>{stat.trend}</Tag>
|
|
187
|
+
</View>
|
|
188
|
+
</Card>
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
// 💀 死亡:变量声明 - 指标类型
|
|
192
|
+
// 💀 死亡:变量声明 - 指标类型
|
|
193
|
+
const metricTypes = ['all', '流量', '转化', '订单'];
|
|
194
|
+
return (
|
|
195
|
+
<Page className="p-[24px] bg-[var(--gray-50)] min-h-screen">
|
|
196
|
+
<View className="mb-[24px]">
|
|
197
|
+
<Text className="text-2xl font-bold text-[#1f2937]">数据统计</Text>
|
|
198
|
+
<Text className="text-[#6b7280] text-sm mt-[4px]">
|
|
199
|
+
数据分析和统计展示
|
|
200
|
+
</Text>
|
|
201
|
+
</View>
|
|
202
|
+
<Card className="mb-[24px]">
|
|
203
|
+
<View className="flex items-center justify-between">
|
|
204
|
+
<View className="gap-4 flex items-center">
|
|
205
|
+
<Select
|
|
206
|
+
value={timeRange}
|
|
207
|
+
onChange={value => this.handleTimeRangeChange(value)}
|
|
208
|
+
className=""
|
|
209
|
+
>
|
|
210
|
+
<Select.Option value="7d">最近7天</Select.Option>
|
|
211
|
+
<Select.Option value="30d">最近30天</Select.Option>
|
|
212
|
+
<Select.Option value="90d">最近90天</Select.Option>
|
|
213
|
+
<Select.Option value="custom">自定义</Select.Option>
|
|
214
|
+
</Select>
|
|
215
|
+
<Select
|
|
216
|
+
value={selectedMetric}
|
|
217
|
+
onChange={value => this.handleMetricChange(value)}
|
|
218
|
+
className=""
|
|
219
|
+
>
|
|
220
|
+
{metricTypes.map((type, index) => (
|
|
221
|
+
<Select.Option key={type} value={type}>
|
|
222
|
+
{type === 'all' ? '全部指标' : type}
|
|
223
|
+
</Select.Option>
|
|
224
|
+
))}
|
|
225
|
+
</Select>
|
|
226
|
+
</View>
|
|
227
|
+
<View className="gap-2 flex items-center">
|
|
228
|
+
<Button onClick={() => this.toggleComparison()}>
|
|
229
|
+
{showComparison ? '隐藏对比' : '显示对比'}
|
|
230
|
+
</Button>
|
|
231
|
+
<Button onClick={() => this.refreshData()}>刷新数据</Button>
|
|
232
|
+
<Button type="primary" onClick={() => this.exportReport('excel')}>
|
|
233
|
+
导出报表
|
|
234
|
+
</Button>
|
|
235
|
+
</View>
|
|
236
|
+
</View>
|
|
237
|
+
</Card>
|
|
238
|
+
<Card className="mb-[24px]">
|
|
239
|
+
<Row gutter={16}>
|
|
240
|
+
<Col span={6}>
|
|
241
|
+
<Statistic
|
|
242
|
+
title="总用户数"
|
|
243
|
+
value={summary?.totalUsers}
|
|
244
|
+
suffix="人"
|
|
245
|
+
valueStyle={{ color: '#3f8600' }}
|
|
246
|
+
/>
|
|
247
|
+
</Col>
|
|
248
|
+
<Col span={6}>
|
|
249
|
+
<Statistic
|
|
250
|
+
title="活跃用户"
|
|
251
|
+
value={summary?.activeUsers}
|
|
252
|
+
suffix="人"
|
|
253
|
+
valueStyle={{ color: '#cf1322' }}
|
|
254
|
+
/>
|
|
255
|
+
</Col>
|
|
256
|
+
<Col span={6}>
|
|
257
|
+
<Statistic
|
|
258
|
+
title="转化率"
|
|
259
|
+
value={summary?.conversionRate}
|
|
260
|
+
suffix="%"
|
|
261
|
+
precision={2}
|
|
262
|
+
/>
|
|
263
|
+
</Col>
|
|
264
|
+
<Col span={6}>
|
|
265
|
+
<Statistic
|
|
266
|
+
title="总收入"
|
|
267
|
+
value={summary?.revenue}
|
|
268
|
+
prefix="¥"
|
|
269
|
+
precision={2}
|
|
270
|
+
/>
|
|
271
|
+
</Col>
|
|
272
|
+
</Row>
|
|
273
|
+
</Card>
|
|
274
|
+
<Card className="mb-[24px]">
|
|
275
|
+
<Row gutter={16}>
|
|
276
|
+
{filteredStats.map((stat, index) => (
|
|
277
|
+
<Col span={8} key={stat.id}>
|
|
278
|
+
<Text>{statCard(stat)}</Text>
|
|
279
|
+
</Col>
|
|
280
|
+
))}
|
|
281
|
+
</Row>
|
|
282
|
+
</Card>
|
|
283
|
+
<Card className="mb-[24px]">
|
|
284
|
+
<Text className="block text-lg font-bold mb-[16px]">
|
|
285
|
+
目标达成情况
|
|
286
|
+
</Text>
|
|
287
|
+
<View className="space-y-4">
|
|
288
|
+
{statistics.map((stat, index) => (
|
|
289
|
+
<View key={stat.id}>
|
|
290
|
+
<View className="flex justify-between mb-[8px]">
|
|
291
|
+
<Text>{stat.name}</Text>
|
|
292
|
+
<Text>{stat.trend}</Text>
|
|
293
|
+
</View>
|
|
294
|
+
<Progress
|
|
295
|
+
percent={Math.random() * 100}
|
|
296
|
+
status={stat.status === 'up' ? 'active' : 'exception'}
|
|
297
|
+
/>
|
|
298
|
+
</View>
|
|
299
|
+
))}
|
|
300
|
+
</View>
|
|
301
|
+
</Card>
|
|
302
|
+
{!!showComparison && (
|
|
303
|
+
<Card>
|
|
304
|
+
<Text className="block text-lg font-bold mb-[16px]">趋势对比</Text>
|
|
305
|
+
<View className="h-[400px] flex items-center justify-center bg-[#f3f4f6]">
|
|
306
|
+
<Text className="text-[#9ca3af]">
|
|
307
|
+
图表区域 - 实际项目中可集成 ECharts
|
|
308
|
+
</Text>
|
|
309
|
+
</View>
|
|
310
|
+
</Card>
|
|
311
|
+
)}
|
|
312
|
+
</Page>
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
export default Document;
|