whistle.mock-plugins 1.2.0-beta.9 → 1.2.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/VERSION.md +9 -6
- package/app/public/js/index.js +1 -1
- package/app/public/js/index.js.LICENSE.txt +0 -2
- package/package.json +1 -1
- package/ui/src/pages/InterfaceManagement.js +131 -76
- package/ui/src/pages/InterfaceManagementV2.js +133 -78
- package/ui/src/pages/MockDataV2.js +6 -134
- package/ui/src/styles/mock-data.css +0 -139
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
import React, { useState, useEffect } from 'react';
|
|
7
7
|
import { useHistory } from 'react-router-dom';
|
|
8
8
|
import AppLayout from '../components/AppLayout';
|
|
9
|
-
import { Card, Row, Col, Button, Modal, Form, Input, message, Switch, Empty, Spin, Typography, Tooltip, Badge, Select, Pagination
|
|
10
|
-
import { PlusOutlined, EditOutlined, DeleteOutlined, ApiOutlined, ExportOutlined, InfoCircleOutlined, CalendarOutlined, SortAscendingOutlined
|
|
9
|
+
import { Card, Row, Col, Button, Modal, Form, Input, message, Switch, Empty, Spin, Typography, Tooltip, Badge, Select, Pagination } from 'antd';
|
|
10
|
+
import { PlusOutlined, EditOutlined, DeleteOutlined, ApiOutlined, ExportOutlined, InfoCircleOutlined, CalendarOutlined, SortAscendingOutlined } from '@ant-design/icons';
|
|
11
11
|
import '../styles/mock-data.css';
|
|
12
12
|
import axios from 'axios';
|
|
13
13
|
|
|
@@ -34,12 +34,6 @@ const MockData = () => {
|
|
|
34
34
|
const [loading, setLoading] = useState(true);
|
|
35
35
|
const [form] = Form.useForm();
|
|
36
36
|
|
|
37
|
-
// 视图模式配置(卡片/列表)
|
|
38
|
-
const [viewMode, setViewMode] = useState(() => {
|
|
39
|
-
const savedViewMode = localStorage.getItem('feature-view-mode');
|
|
40
|
-
return savedViewMode === 'list' ? 'list' : 'card'; // 默认为卡片视图
|
|
41
|
-
});
|
|
42
|
-
|
|
43
37
|
// 排序和分页配置(支持缓存)
|
|
44
38
|
const [listConfig, setListConfig] = useState(() => {
|
|
45
39
|
const cached = localStorage.getItem('feature-list-config');
|
|
@@ -57,13 +51,6 @@ const MockData = () => {
|
|
|
57
51
|
setListConfig(newConfig);
|
|
58
52
|
localStorage.setItem('feature-list-config', JSON.stringify(newConfig));
|
|
59
53
|
};
|
|
60
|
-
|
|
61
|
-
// 切换视图模式(卡片/列表)
|
|
62
|
-
const toggleViewMode = () => {
|
|
63
|
-
const newMode = viewMode === 'card' ? 'list' : 'card';
|
|
64
|
-
setViewMode(newMode);
|
|
65
|
-
localStorage.setItem('feature-view-mode', newMode);
|
|
66
|
-
};
|
|
67
54
|
|
|
68
55
|
// 加载功能列表
|
|
69
56
|
useEffect(() => {
|
|
@@ -426,98 +413,6 @@ const MockData = () => {
|
|
|
426
413
|
return sortedFeatures.slice(startIndex, endIndex);
|
|
427
414
|
};
|
|
428
415
|
|
|
429
|
-
// 渲染功能模块列表项
|
|
430
|
-
const renderFeatureListItem = (feature) => {
|
|
431
|
-
const formattedDate = feature.createdAt
|
|
432
|
-
? new Date(feature.createdAt).toLocaleDateString()
|
|
433
|
-
: '未知日期';
|
|
434
|
-
|
|
435
|
-
return (
|
|
436
|
-
<div
|
|
437
|
-
key={feature.id}
|
|
438
|
-
className={`feature-list-item ${!feature.active ? 'inactive-feature' : ''}`}
|
|
439
|
-
onClick={() => viewInterfaces(feature)}
|
|
440
|
-
>
|
|
441
|
-
<div className="feature-list-content">
|
|
442
|
-
<div className="feature-list-main">
|
|
443
|
-
<div className="feature-list-name">
|
|
444
|
-
<h3>{feature.name}</h3>
|
|
445
|
-
{!feature.active && <Tag color="red">已禁用</Tag>}
|
|
446
|
-
{feature.active && <Tag color="green">已启用</Tag>}
|
|
447
|
-
</div>
|
|
448
|
-
<div className="feature-list-description">
|
|
449
|
-
{feature.description || '无描述'}
|
|
450
|
-
</div>
|
|
451
|
-
</div>
|
|
452
|
-
|
|
453
|
-
<div className="feature-list-meta">
|
|
454
|
-
<div className="feature-list-stats">
|
|
455
|
-
<span><InfoCircleOutlined /> {feature.interfaceCount || 0} 个接口</span>
|
|
456
|
-
<span><CalendarOutlined /> {formattedDate}</span>
|
|
457
|
-
</div>
|
|
458
|
-
</div>
|
|
459
|
-
</div>
|
|
460
|
-
|
|
461
|
-
<div className="feature-list-actions">
|
|
462
|
-
<Switch
|
|
463
|
-
checked={feature.active}
|
|
464
|
-
onChange={(checked, e) => {
|
|
465
|
-
e.stopPropagation();
|
|
466
|
-
handleToggleActive(feature.id, feature.active);
|
|
467
|
-
}}
|
|
468
|
-
onClick={(e) => e.stopPropagation()}
|
|
469
|
-
size="small"
|
|
470
|
-
/>
|
|
471
|
-
<Tooltip title="管理接口">
|
|
472
|
-
<Button
|
|
473
|
-
icon={<ApiOutlined />}
|
|
474
|
-
size="small"
|
|
475
|
-
type="text"
|
|
476
|
-
onClick={(e) => {
|
|
477
|
-
e.stopPropagation();
|
|
478
|
-
viewInterfaces(feature);
|
|
479
|
-
}}
|
|
480
|
-
/>
|
|
481
|
-
</Tooltip>
|
|
482
|
-
<Tooltip title="编辑功能">
|
|
483
|
-
<Button
|
|
484
|
-
icon={<EditOutlined />}
|
|
485
|
-
size="small"
|
|
486
|
-
type="text"
|
|
487
|
-
onClick={(e) => {
|
|
488
|
-
e.stopPropagation();
|
|
489
|
-
openModal(feature);
|
|
490
|
-
}}
|
|
491
|
-
/>
|
|
492
|
-
</Tooltip>
|
|
493
|
-
<Tooltip title="删除功能">
|
|
494
|
-
<Button
|
|
495
|
-
icon={<DeleteOutlined />}
|
|
496
|
-
size="small"
|
|
497
|
-
type="text"
|
|
498
|
-
danger
|
|
499
|
-
onClick={(e) => {
|
|
500
|
-
e.stopPropagation();
|
|
501
|
-
deleteFeature(feature.id);
|
|
502
|
-
}}
|
|
503
|
-
/>
|
|
504
|
-
</Tooltip>
|
|
505
|
-
<Tooltip title="导出配置">
|
|
506
|
-
<Button
|
|
507
|
-
icon={<ExportOutlined />}
|
|
508
|
-
size="small"
|
|
509
|
-
type="text"
|
|
510
|
-
onClick={(e) => {
|
|
511
|
-
e.stopPropagation();
|
|
512
|
-
exportFeatureConfig(feature);
|
|
513
|
-
}}
|
|
514
|
-
/>
|
|
515
|
-
</Tooltip>
|
|
516
|
-
</div>
|
|
517
|
-
</div>
|
|
518
|
-
);
|
|
519
|
-
};
|
|
520
|
-
|
|
521
416
|
// 渲染功能模块卡片
|
|
522
417
|
const renderFeatureCard = (feature) => {
|
|
523
418
|
const formattedDate = feature.createdAt
|
|
@@ -722,7 +617,7 @@ const MockData = () => {
|
|
|
722
617
|
</Col>
|
|
723
618
|
|
|
724
619
|
{/* 分页控制区域 */}
|
|
725
|
-
<Col xs={24} sm={
|
|
620
|
+
<Col xs={24} sm={24} md={8} lg={9}>
|
|
726
621
|
<div className="pagination-controls">
|
|
727
622
|
<div className="control-group">
|
|
728
623
|
<span className="control-label">每页显示</span>
|
|
@@ -743,22 +638,6 @@ const MockData = () => {
|
|
|
743
638
|
</div>
|
|
744
639
|
</div>
|
|
745
640
|
</Col>
|
|
746
|
-
|
|
747
|
-
{/* 视图切换按钮区域 */}
|
|
748
|
-
<Col xs={24} sm={12} md={3} lg={3}>
|
|
749
|
-
<div className="view-toggle-controls">
|
|
750
|
-
<Tooltip title={viewMode === 'card' ? '切换到列表视图' : '切换到卡片视图'}>
|
|
751
|
-
<Button
|
|
752
|
-
type="default"
|
|
753
|
-
icon={viewMode === 'card' ? <UnorderedListOutlined /> : <AppstoreOutlined />}
|
|
754
|
-
onClick={toggleViewMode}
|
|
755
|
-
className="view-toggle-button"
|
|
756
|
-
>
|
|
757
|
-
{viewMode === 'card' ? '列表视图' : '卡片视图'}
|
|
758
|
-
</Button>
|
|
759
|
-
</Tooltip>
|
|
760
|
-
</div>
|
|
761
|
-
</Col>
|
|
762
641
|
</Row>
|
|
763
642
|
</Card>
|
|
764
643
|
)}
|
|
@@ -771,16 +650,9 @@ const MockData = () => {
|
|
|
771
650
|
</div>
|
|
772
651
|
) : mockFeatures.length > 0 ? (
|
|
773
652
|
<>
|
|
774
|
-
{
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
{getPaginatedFeatures().map(feature => renderFeatureCard(feature))}
|
|
778
|
-
</Row>
|
|
779
|
-
) : (
|
|
780
|
-
<div className="feature-list-view">
|
|
781
|
-
{getPaginatedFeatures().map(feature => renderFeatureListItem(feature))}
|
|
782
|
-
</div>
|
|
783
|
-
)}
|
|
653
|
+
<Row gutter={[20, 20]} className="feature-grid">
|
|
654
|
+
{getPaginatedFeatures().map(feature => renderFeatureCard(feature))}
|
|
655
|
+
</Row>
|
|
784
656
|
|
|
785
657
|
{/* 分页组件 */}
|
|
786
658
|
{mockFeatures.length > listConfig.pageSize && (
|
|
@@ -121,118 +121,6 @@
|
|
|
121
121
|
min-height: 300px;
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
/* 视图切换按钮样式 */
|
|
125
|
-
.view-toggle-controls {
|
|
126
|
-
display: flex;
|
|
127
|
-
justify-content: flex-end;
|
|
128
|
-
align-items: center;
|
|
129
|
-
height: 100%;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
.view-toggle-button {
|
|
133
|
-
border-radius: 4px;
|
|
134
|
-
border: 1px solid #e8e8e8;
|
|
135
|
-
background: #fafafa;
|
|
136
|
-
transition: all 0.3s;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
.view-toggle-button:hover {
|
|
140
|
-
border-color: #1890ff;
|
|
141
|
-
color: #1890ff;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/* 列表视图样式 */
|
|
145
|
-
.feature-list-view {
|
|
146
|
-
display: flex;
|
|
147
|
-
flex-direction: column;
|
|
148
|
-
gap: 16px;
|
|
149
|
-
min-height: 300px;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
.feature-list-item {
|
|
153
|
-
display: flex;
|
|
154
|
-
justify-content: space-between;
|
|
155
|
-
align-items: center;
|
|
156
|
-
padding: 16px 20px;
|
|
157
|
-
border-radius: 8px;
|
|
158
|
-
border: 1px solid #f0f0f0;
|
|
159
|
-
background: #ffffff;
|
|
160
|
-
transition: all 0.3s;
|
|
161
|
-
cursor: pointer;
|
|
162
|
-
position: relative;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
.feature-list-item:hover {
|
|
166
|
-
border-color: #d9d9d9;
|
|
167
|
-
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.09);
|
|
168
|
-
transform: translateY(-2px);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
.feature-list-item.inactive-feature {
|
|
172
|
-
opacity: 0.7;
|
|
173
|
-
background-color: #fafafa;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
.feature-list-content {
|
|
177
|
-
flex: 1;
|
|
178
|
-
display: flex;
|
|
179
|
-
flex-direction: column;
|
|
180
|
-
gap: 8px;
|
|
181
|
-
overflow: hidden;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
.feature-list-main {
|
|
185
|
-
display: flex;
|
|
186
|
-
flex-direction: column;
|
|
187
|
-
gap: 4px;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
.feature-list-name {
|
|
191
|
-
display: flex;
|
|
192
|
-
align-items: center;
|
|
193
|
-
gap: 12px;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
.feature-list-name h3 {
|
|
197
|
-
margin: 0;
|
|
198
|
-
font-size: 16px;
|
|
199
|
-
font-weight: 600;
|
|
200
|
-
color: #1890ff;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
.feature-list-description {
|
|
204
|
-
color: #666;
|
|
205
|
-
font-size: 14px;
|
|
206
|
-
max-width: 80%;
|
|
207
|
-
overflow: hidden;
|
|
208
|
-
white-space: nowrap;
|
|
209
|
-
text-overflow: ellipsis;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
.feature-list-meta {
|
|
213
|
-
display: flex;
|
|
214
|
-
justify-content: space-between;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
.feature-list-stats {
|
|
218
|
-
display: flex;
|
|
219
|
-
gap: 16px;
|
|
220
|
-
color: #8c8c8c;
|
|
221
|
-
font-size: 13px;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
.feature-list-stats span {
|
|
225
|
-
display: flex;
|
|
226
|
-
align-items: center;
|
|
227
|
-
gap: 4px;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
.feature-list-actions {
|
|
231
|
-
display: flex;
|
|
232
|
-
align-items: center;
|
|
233
|
-
gap: 8px;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
124
|
.feature-card {
|
|
237
125
|
position: relative;
|
|
238
126
|
transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
|
|
@@ -1151,33 +1039,6 @@ input:checked + .slider:before {
|
|
|
1151
1039
|
height: auto;
|
|
1152
1040
|
}
|
|
1153
1041
|
|
|
1154
|
-
.feature-list-item {
|
|
1155
|
-
flex-direction: column;
|
|
1156
|
-
align-items: flex-start;
|
|
1157
|
-
gap: 16px;
|
|
1158
|
-
padding: 16px;
|
|
1159
|
-
}
|
|
1160
|
-
|
|
1161
|
-
.feature-list-content {
|
|
1162
|
-
width: 100%;
|
|
1163
|
-
}
|
|
1164
|
-
|
|
1165
|
-
.feature-list-description {
|
|
1166
|
-
max-width: 100%;
|
|
1167
|
-
}
|
|
1168
|
-
|
|
1169
|
-
.feature-list-actions {
|
|
1170
|
-
width: 100%;
|
|
1171
|
-
justify-content: flex-end;
|
|
1172
|
-
border-top: 1px solid #f0f0f0;
|
|
1173
|
-
padding-top: 12px;
|
|
1174
|
-
}
|
|
1175
|
-
|
|
1176
|
-
.view-toggle-controls {
|
|
1177
|
-
justify-content: flex-start;
|
|
1178
|
-
margin-top: 12px;
|
|
1179
|
-
}
|
|
1180
|
-
|
|
1181
1042
|
.form-actions {
|
|
1182
1043
|
flex-direction: column;
|
|
1183
1044
|
}
|