whistle.mock-plugins 1.1.3-dev.9 → 1.2.0-beta.10
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 +14 -0
- package/app/public/js/index.js +1 -1
- package/app/public/js/index.js.LICENSE.txt +4 -2
- package/package.json +1 -1
- package/ui/src/components/AppLayout.js +5 -3
- package/ui/src/pages/InterfaceManagement.js +53 -13
- package/ui/src/pages/InterfaceManagementV2.js +231 -186
- package/ui/src/pages/MockDataV2.js +256 -100
- package/ui/src/styles/app-layout.css +38 -2
- package/ui/src/styles/interface-management.css +156 -220
- package/ui/src/styles/mock-data.css +399 -22
|
@@ -10,12 +10,12 @@ import AppLayout from '../components/AppLayout';
|
|
|
10
10
|
import {
|
|
11
11
|
Table, Button, Modal, Form, Input, Select, message, Switch,
|
|
12
12
|
Popconfirm, Alert, Space, Card, Badge, Tooltip, Row, Col,
|
|
13
|
-
Popover, Checkbox, Tag, Input as AntInput, Radio, Drawer, Dropdown, Menu
|
|
13
|
+
Popover, Checkbox, Tag, Input as AntInput, Radio, Drawer, Dropdown, Menu, Collapse, Divider
|
|
14
14
|
} from 'antd';
|
|
15
15
|
import {
|
|
16
16
|
PlusOutlined, EditOutlined, DeleteOutlined,
|
|
17
17
|
FileTextOutlined, PlusCircleOutlined, SettingOutlined,
|
|
18
|
-
SearchOutlined, FilterOutlined, ReloadOutlined, DownOutlined
|
|
18
|
+
SearchOutlined, FilterOutlined, ReloadOutlined, DownOutlined, QuestionCircleOutlined
|
|
19
19
|
} from '@ant-design/icons';
|
|
20
20
|
import '../styles/interface-management.css';
|
|
21
21
|
import axios from 'axios';
|
|
@@ -70,6 +70,7 @@ const InterfaceManagement = () => {
|
|
|
70
70
|
const [groups, setGroups] = useState([]);
|
|
71
71
|
const [selectedGroup, setSelectedGroup] = useState(null);
|
|
72
72
|
const [groupActionLoading, setGroupActionLoading] = useState(false);
|
|
73
|
+
const [newGroupName, setNewGroupName] = useState('');
|
|
73
74
|
|
|
74
75
|
// 模态框状态
|
|
75
76
|
const [modalVisible, setModalVisible] = useState(false);
|
|
@@ -222,6 +223,17 @@ const InterfaceManagement = () => {
|
|
|
222
223
|
setSelectedGroup(null);
|
|
223
224
|
}
|
|
224
225
|
};
|
|
226
|
+
|
|
227
|
+
// 添加新分组
|
|
228
|
+
const addNewGroup = () => {
|
|
229
|
+
if (newGroupName.trim() && !groups.includes(newGroupName.trim())) {
|
|
230
|
+
const updatedGroups = [...groups, newGroupName.trim()].sort();
|
|
231
|
+
setGroups(updatedGroups);
|
|
232
|
+
setNewGroupName('');
|
|
233
|
+
return newGroupName.trim();
|
|
234
|
+
}
|
|
235
|
+
return null;
|
|
236
|
+
};
|
|
225
237
|
|
|
226
238
|
// 根据分组和搜索关键词筛选接口
|
|
227
239
|
const getFilteredInterfaces = () => {
|
|
@@ -679,40 +691,10 @@ const InterfaceManagement = () => {
|
|
|
679
691
|
},
|
|
680
692
|
render: (group) => {
|
|
681
693
|
if (!group) {
|
|
682
|
-
return
|
|
683
|
-
<span style={{
|
|
684
|
-
color: '#a0aec0',
|
|
685
|
-
fontStyle: 'italic',
|
|
686
|
-
fontSize: '12px'
|
|
687
|
-
}}>
|
|
688
|
-
未分组
|
|
689
|
-
</span>
|
|
690
|
-
);
|
|
694
|
+
return <span style={{ color: '#999', fontStyle: 'italic' }}>未分组</span>;
|
|
691
695
|
}
|
|
692
696
|
return (
|
|
693
|
-
<Tag
|
|
694
|
-
style={{
|
|
695
|
-
cursor: 'pointer',
|
|
696
|
-
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
|
|
697
|
-
border: 'none',
|
|
698
|
-
borderRadius: '12px',
|
|
699
|
-
color: '#ffffff',
|
|
700
|
-
fontWeight: '600',
|
|
701
|
-
fontSize: '11px',
|
|
702
|
-
padding: '2px 8px',
|
|
703
|
-
boxShadow: '0 2px 4px rgba(102, 126, 234, 0.3)',
|
|
704
|
-
transition: 'all 0.2s ease'
|
|
705
|
-
}}
|
|
706
|
-
onClick={() => setSelectedGroup(group)}
|
|
707
|
-
onMouseEnter={(e) => {
|
|
708
|
-
e.target.style.transform = 'translateY(-1px)';
|
|
709
|
-
e.target.style.boxShadow = '0 4px 8px rgba(102, 126, 234, 0.4)';
|
|
710
|
-
}}
|
|
711
|
-
onMouseLeave={(e) => {
|
|
712
|
-
e.target.style.transform = 'translateY(0)';
|
|
713
|
-
e.target.style.boxShadow = '0 2px 4px rgba(102, 126, 234, 0.3)';
|
|
714
|
-
}}
|
|
715
|
-
>
|
|
697
|
+
<Tag color="blue" style={{ cursor: 'pointer' }} onClick={() => setSelectedGroup(group)}>
|
|
716
698
|
{group}
|
|
717
699
|
</Tag>
|
|
718
700
|
);
|
|
@@ -732,31 +714,11 @@ const InterfaceManagement = () => {
|
|
|
732
714
|
width: 120,
|
|
733
715
|
render: (text) => {
|
|
734
716
|
const proxyType = proxyTypes.find(item => item.value === text);
|
|
735
|
-
const color = proxyType?.color || '#999';
|
|
736
|
-
const label = proxyType?.label || text;
|
|
737
|
-
|
|
738
717
|
return (
|
|
739
|
-
<
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
padding: '4px 10px',
|
|
744
|
-
borderRadius: '12px',
|
|
745
|
-
fontSize: '12px',
|
|
746
|
-
fontWeight: '600',
|
|
747
|
-
backgroundColor: color === '#1890ff' ? '#ebf8ff' :
|
|
748
|
-
color === '#52c41a' ? '#f0fff4' :
|
|
749
|
-
color === '#faad14' ? '#fffbf0' : '#f5f5f5',
|
|
750
|
-
color: color === '#1890ff' ? '#3182ce' :
|
|
751
|
-
color === '#52c41a' ? '#38a169' :
|
|
752
|
-
color === '#faad14' ? '#d69e2e' : '#718096',
|
|
753
|
-
border: `1px solid ${color === '#1890ff' ? '#bee3f8' :
|
|
754
|
-
color === '#52c41a' ? '#c6f6d5' :
|
|
755
|
-
color === '#faad14' ? '#feebc8' : '#e2e8f0'}`
|
|
756
|
-
}}
|
|
757
|
-
>
|
|
758
|
-
{label}
|
|
759
|
-
</span>
|
|
718
|
+
<Badge
|
|
719
|
+
color={proxyType?.color || '#999'}
|
|
720
|
+
text={proxyType?.label || text}
|
|
721
|
+
/>
|
|
760
722
|
);
|
|
761
723
|
},
|
|
762
724
|
},
|
|
@@ -780,22 +742,13 @@ const InterfaceManagement = () => {
|
|
|
780
742
|
return (
|
|
781
743
|
<Select
|
|
782
744
|
value={activeResponseId || record.responses[0]?.id}
|
|
783
|
-
style={{
|
|
784
|
-
width: '100%',
|
|
785
|
-
borderRadius: '6px'
|
|
786
|
-
}}
|
|
745
|
+
style={{ width: '100%' }}
|
|
787
746
|
onChange={(value) => handleResponseSwitch(record.id, value)}
|
|
788
747
|
disabled={record.proxyType !== 'response'}
|
|
789
|
-
size="small"
|
|
790
748
|
>
|
|
791
749
|
{record.responses.map(resp => (
|
|
792
750
|
<Option key={resp.id} value={resp.id}>
|
|
793
|
-
|
|
794
|
-
fontSize: '12px',
|
|
795
|
-
fontWeight: '500'
|
|
796
|
-
}}>
|
|
797
|
-
{resp.name}
|
|
798
|
-
</span>
|
|
751
|
+
{resp.name}
|
|
799
752
|
</Option>
|
|
800
753
|
))}
|
|
801
754
|
</Select>
|
|
@@ -973,28 +926,18 @@ const InterfaceManagement = () => {
|
|
|
973
926
|
width: 180,
|
|
974
927
|
render: (_, record) => (
|
|
975
928
|
<div className="action-buttons">
|
|
976
|
-
<
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
aria-label="编辑接口"
|
|
982
|
-
/>
|
|
983
|
-
</Tooltip>
|
|
929
|
+
<Button
|
|
930
|
+
type="text"
|
|
931
|
+
icon={<EditOutlined />}
|
|
932
|
+
onClick={() => handleEditInterface(record)}
|
|
933
|
+
/>
|
|
984
934
|
<Popconfirm
|
|
985
935
|
title="确定要删除此接口吗?"
|
|
986
936
|
onConfirm={() => handleDeleteInterface(record.id)}
|
|
987
937
|
okText="确定"
|
|
988
938
|
cancelText="取消"
|
|
989
939
|
>
|
|
990
|
-
<
|
|
991
|
-
<Button
|
|
992
|
-
type="text"
|
|
993
|
-
danger
|
|
994
|
-
icon={<DeleteOutlined />}
|
|
995
|
-
aria-label="删除接口"
|
|
996
|
-
/>
|
|
997
|
-
</Tooltip>
|
|
940
|
+
<Button type="text" danger icon={<DeleteOutlined />} />
|
|
998
941
|
</Popconfirm>
|
|
999
942
|
</div>
|
|
1000
943
|
),
|
|
@@ -1045,6 +988,27 @@ const InterfaceManagement = () => {
|
|
|
1045
988
|
重构后版本 V2
|
|
1046
989
|
</div>
|
|
1047
990
|
|
|
991
|
+
{/* 警告信息置顶显示 */}
|
|
992
|
+
{!features.length && (
|
|
993
|
+
<Alert
|
|
994
|
+
message="未找到功能模块"
|
|
995
|
+
description="请先在模拟数据页面创建功能模块,然后再添加接口"
|
|
996
|
+
type="warning"
|
|
997
|
+
showIcon
|
|
998
|
+
style={{ marginBottom: 16 }}
|
|
999
|
+
/>
|
|
1000
|
+
)}
|
|
1001
|
+
|
|
1002
|
+
{selectedFeature?.active === false && (
|
|
1003
|
+
<Alert
|
|
1004
|
+
message="功能模块已禁用"
|
|
1005
|
+
description="当前功能模块已被禁用,所有关联接口不会生效。您可以在模拟数据页面启用此功能模块。"
|
|
1006
|
+
type="warning"
|
|
1007
|
+
showIcon
|
|
1008
|
+
style={{ marginBottom: 16 }}
|
|
1009
|
+
/>
|
|
1010
|
+
)}
|
|
1011
|
+
|
|
1048
1012
|
<Card className="interface-control-panel">
|
|
1049
1013
|
<div className="control-panel-header">
|
|
1050
1014
|
<div className="control-left">
|
|
@@ -1135,14 +1099,9 @@ const InterfaceManagement = () => {
|
|
|
1135
1099
|
<div className="control-panel-stats">
|
|
1136
1100
|
<div className="stats-left">
|
|
1137
1101
|
<Space size="large">
|
|
1138
|
-
<span className="stat-item">
|
|
1139
|
-
<span className="stat-label">功能模块:</span>
|
|
1140
|
-
<span className="stat-value">{selectedFeature?.name}</span>
|
|
1141
|
-
</span>
|
|
1142
|
-
|
|
1143
1102
|
{selectedGroup && (
|
|
1144
1103
|
<span className="stat-item">
|
|
1145
|
-
<span className="stat-label"
|
|
1104
|
+
<span className="stat-label">当前分组:</span>
|
|
1146
1105
|
<Tag color="blue">{selectedGroup}</Tag>
|
|
1147
1106
|
</span>
|
|
1148
1107
|
)}
|
|
@@ -1268,16 +1227,13 @@ const InterfaceManagement = () => {
|
|
|
1268
1227
|
</div>
|
|
1269
1228
|
}
|
|
1270
1229
|
>
|
|
1271
|
-
<Tooltip title="
|
|
1230
|
+
<Tooltip title="自定义表格显示列">
|
|
1272
1231
|
<Button
|
|
1273
1232
|
icon={<SettingOutlined />}
|
|
1274
1233
|
type="text"
|
|
1275
|
-
size="
|
|
1276
|
-
className="column-settings-btn"
|
|
1277
|
-
style={{
|
|
1278
|
-
marginLeft: (selectedRowKeys.length > 0 || selectedGroup) ? 16 : 0,
|
|
1279
|
-
color: '#666'
|
|
1280
|
-
}}
|
|
1234
|
+
size="small"
|
|
1235
|
+
className="inline-column-settings-btn"
|
|
1236
|
+
style={{ marginLeft: (selectedRowKeys.length > 0 || selectedGroup) ? 16 : 0 }}
|
|
1281
1237
|
>
|
|
1282
1238
|
列设置
|
|
1283
1239
|
</Button>
|
|
@@ -1287,29 +1243,7 @@ const InterfaceManagement = () => {
|
|
|
1287
1243
|
</div>
|
|
1288
1244
|
</Card>
|
|
1289
1245
|
|
|
1290
|
-
{
|
|
1291
|
-
<Alert
|
|
1292
|
-
message="未找到功能模块"
|
|
1293
|
-
description="请先在模拟数据页面创建功能模块,然后再添加接口"
|
|
1294
|
-
type="warning"
|
|
1295
|
-
showIcon
|
|
1296
|
-
style={{ marginBottom: 16 }}
|
|
1297
|
-
/>
|
|
1298
|
-
)}
|
|
1299
|
-
|
|
1300
|
-
{selectedFeature?.active === false && (
|
|
1301
|
-
<Alert
|
|
1302
|
-
message="功能模块已禁用"
|
|
1303
|
-
description="当前功能模块已被禁用,所有关联接口不会生效。您可以在模拟数据页面启用此功能模块。"
|
|
1304
|
-
type="warning"
|
|
1305
|
-
showIcon
|
|
1306
|
-
style={{ marginBottom: 16 }}
|
|
1307
|
-
/>
|
|
1308
|
-
)}
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
<Card className="list-container-card" bordered={false} bodyStyle={{ padding: 0 }}>
|
|
1246
|
+
<Card className="list-container-card" bordered={false} bodyStyle={{ padding: 0 }}>
|
|
1313
1247
|
<div className="interface-list-container">
|
|
1314
1248
|
<Table
|
|
1315
1249
|
columns={columns}
|
|
@@ -1340,36 +1274,81 @@ const InterfaceManagement = () => {
|
|
|
1340
1274
|
|
|
1341
1275
|
{/* 接口编辑/创建模态框 */}
|
|
1342
1276
|
<Modal
|
|
1343
|
-
title={
|
|
1277
|
+
title={
|
|
1278
|
+
<div style={{
|
|
1279
|
+
fontSize: '18px',
|
|
1280
|
+
fontWeight: 600,
|
|
1281
|
+
color: '#262626',
|
|
1282
|
+
display: 'flex',
|
|
1283
|
+
alignItems: 'center',
|
|
1284
|
+
gap: '8px'
|
|
1285
|
+
}}>
|
|
1286
|
+
<span>{editingInterface ? '编辑接口' : '添加接口'}</span>
|
|
1287
|
+
<Badge
|
|
1288
|
+
count="配置向导"
|
|
1289
|
+
style={{
|
|
1290
|
+
backgroundColor: '#f0f9ff',
|
|
1291
|
+
color: '#1677ff',
|
|
1292
|
+
fontSize: '11px',
|
|
1293
|
+
fontWeight: 'normal'
|
|
1294
|
+
}}
|
|
1295
|
+
/>
|
|
1296
|
+
</div>
|
|
1297
|
+
}
|
|
1344
1298
|
open={modalVisible}
|
|
1345
1299
|
onOk={handleSubmit}
|
|
1346
1300
|
onCancel={handleCancel}
|
|
1347
|
-
width={
|
|
1301
|
+
width={1200}
|
|
1348
1302
|
destroyOnClose
|
|
1349
1303
|
okText={editingInterface ? '保存' : '创建'}
|
|
1350
1304
|
cancelText="取消"
|
|
1351
|
-
bodyStyle={{
|
|
1305
|
+
bodyStyle={{
|
|
1306
|
+
maxHeight: '75vh',
|
|
1307
|
+
overflow: 'auto',
|
|
1308
|
+
padding: '0',
|
|
1309
|
+
background: '#fafafa'
|
|
1310
|
+
}}
|
|
1311
|
+
className="interface-modal"
|
|
1352
1312
|
>
|
|
1353
|
-
<
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1313
|
+
<div style={{ padding: '24px' }}>
|
|
1314
|
+
<Form
|
|
1315
|
+
form={form}
|
|
1316
|
+
layout="vertical"
|
|
1317
|
+
initialValues={{
|
|
1318
|
+
name: '',
|
|
1319
|
+
group: '',
|
|
1320
|
+
pattern: '',
|
|
1321
|
+
proxyType: 'response',
|
|
1322
|
+
statusCode: '200',
|
|
1323
|
+
contentType: 'application/json; charset=utf-8',
|
|
1324
|
+
responses: [],
|
|
1325
|
+
httpMethod: 'ALL',
|
|
1326
|
+
targetUrl: '',
|
|
1327
|
+
headerItems: [],
|
|
1328
|
+
paramMatchers: [],
|
|
1329
|
+
responseDelay: '0'
|
|
1330
|
+
}}
|
|
1331
|
+
>
|
|
1332
|
+
<Collapse
|
|
1333
|
+
defaultActiveKey={
|
|
1334
|
+
editingInterface && editingInterface.proxyType === 'response'
|
|
1335
|
+
? ['3']
|
|
1336
|
+
: ['1', '2', '3']
|
|
1337
|
+
}
|
|
1338
|
+
style={{ marginBottom: '16px' }}
|
|
1339
|
+
ghost
|
|
1340
|
+
>
|
|
1341
|
+
{/* 第一步:基础信息 */}
|
|
1342
|
+
<Collapse.Panel
|
|
1343
|
+
header={
|
|
1344
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
|
1345
|
+
<Badge count="1" style={{ backgroundColor: '#1677ff' }} />
|
|
1346
|
+
<span>基础信息</span>
|
|
1347
|
+
</div>
|
|
1348
|
+
}
|
|
1349
|
+
key="1"
|
|
1350
|
+
>
|
|
1351
|
+
<div style={{ display: 'flex', flexDirection: 'row', gap: '16px' }}>
|
|
1373
1352
|
<div style={{ flex: 1 }}>
|
|
1374
1353
|
<Form.Item
|
|
1375
1354
|
name="name"
|
|
@@ -1386,37 +1365,76 @@ const InterfaceManagement = () => {
|
|
|
1386
1365
|
tooltip="为接口设置分组,便于管理和批量操作"
|
|
1387
1366
|
>
|
|
1388
1367
|
<Select
|
|
1389
|
-
placeholder="
|
|
1368
|
+
placeholder="选择或输入新分组名称"
|
|
1390
1369
|
showSearch
|
|
1391
1370
|
allowClear
|
|
1392
1371
|
style={{ width: '100%' }}
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
// 如果值是数组(tags模式),只取第一个元素
|
|
1398
|
-
if (Array.isArray(value) && value.length > 0) {
|
|
1399
|
-
// 如果第一个元素是空字符串,则设置为undefined
|
|
1400
|
-
const groupValue = value[0] === '' ? undefined : value[0];
|
|
1401
|
-
form.setFieldsValue({ group: groupValue });
|
|
1402
|
-
}
|
|
1403
|
-
}}
|
|
1372
|
+
dropdownMatchSelectWidth={false}
|
|
1373
|
+
filterOption={(input, option) =>
|
|
1374
|
+
option?.children?.toLowerCase()?.indexOf(input.toLowerCase()) >= 0
|
|
1375
|
+
}
|
|
1404
1376
|
onInputKeyDown={(e) => {
|
|
1405
1377
|
// 防止回车键提交表单
|
|
1406
1378
|
if (e.key === 'Enter') {
|
|
1407
1379
|
e.stopPropagation();
|
|
1408
1380
|
}
|
|
1409
1381
|
}}
|
|
1382
|
+
dropdownRender={(menu) => (
|
|
1383
|
+
<div>
|
|
1384
|
+
{menu}
|
|
1385
|
+
<Divider style={{ margin: '4px 0' }} />
|
|
1386
|
+
<div style={{ display: 'flex', flexWrap: 'nowrap', padding: 8 }}>
|
|
1387
|
+
<Input
|
|
1388
|
+
style={{ flex: 'auto' }}
|
|
1389
|
+
value={newGroupName}
|
|
1390
|
+
onChange={(e) => setNewGroupName(e.target.value)}
|
|
1391
|
+
placeholder="输入新分组名称"
|
|
1392
|
+
onPressEnter={(e) => {
|
|
1393
|
+
e.stopPropagation();
|
|
1394
|
+
const groupName = addNewGroup();
|
|
1395
|
+
if (groupName) {
|
|
1396
|
+
form.setFieldsValue({ group: groupName });
|
|
1397
|
+
}
|
|
1398
|
+
}}
|
|
1399
|
+
/>
|
|
1400
|
+
<Button
|
|
1401
|
+
type="text"
|
|
1402
|
+
icon={<PlusOutlined />}
|
|
1403
|
+
style={{ flex: 'none', padding: '4px 8px', cursor: 'pointer' }}
|
|
1404
|
+
onClick={(e) => {
|
|
1405
|
+
e.stopPropagation();
|
|
1406
|
+
const groupName = addNewGroup();
|
|
1407
|
+
if (groupName) {
|
|
1408
|
+
form.setFieldsValue({ group: groupName });
|
|
1409
|
+
}
|
|
1410
|
+
}}
|
|
1411
|
+
>
|
|
1412
|
+
添加
|
|
1413
|
+
</Button>
|
|
1414
|
+
</div>
|
|
1415
|
+
</div>
|
|
1416
|
+
)}
|
|
1410
1417
|
>
|
|
1411
1418
|
{Array.from(new Set(interfaces.map(item => item.group).filter(Boolean))).map(group => (
|
|
1412
1419
|
<Option key={group} value={group}>{group}</Option>
|
|
1413
1420
|
))}
|
|
1414
1421
|
</Select>
|
|
1415
1422
|
</Form.Item>
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1423
|
+
</div>
|
|
1424
|
+
</div>
|
|
1425
|
+
</Collapse.Panel>
|
|
1426
|
+
|
|
1427
|
+
{/* 第二步:URL配置 */}
|
|
1428
|
+
<Collapse.Panel
|
|
1429
|
+
header={
|
|
1430
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
|
1431
|
+
<Badge count="2" style={{ backgroundColor: '#1677ff' }} />
|
|
1432
|
+
<span>URL配置</span>
|
|
1433
|
+
</div>
|
|
1434
|
+
}
|
|
1435
|
+
key="2"
|
|
1436
|
+
>
|
|
1437
|
+
<div style={{ display: 'flex', flexDirection: 'row', gap: '16px' }}>
|
|
1420
1438
|
<div style={{ flex: 1 }}>
|
|
1421
1439
|
<Form.Item
|
|
1422
1440
|
name="pattern"
|
|
@@ -1556,7 +1574,19 @@ const InterfaceManagement = () => {
|
|
|
1556
1574
|
<div style={{ flex: 1 }}>
|
|
1557
1575
|
{/* 这里可以留空或添加其他字段 */}
|
|
1558
1576
|
</div>
|
|
1559
|
-
|
|
1577
|
+
</div>
|
|
1578
|
+
</Collapse.Panel>
|
|
1579
|
+
|
|
1580
|
+
{/* 第三步:高级配置 */}
|
|
1581
|
+
<Collapse.Panel
|
|
1582
|
+
header={
|
|
1583
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
|
1584
|
+
<Badge count="3" style={{ backgroundColor: '#1677ff' }} />
|
|
1585
|
+
<span>高级配置</span>
|
|
1586
|
+
</div>
|
|
1587
|
+
}
|
|
1588
|
+
key="3"
|
|
1589
|
+
>
|
|
1560
1590
|
|
|
1561
1591
|
{/* 根据proxyType显示不同的表单项 */}
|
|
1562
1592
|
<Form.Item noStyle shouldUpdate={(prevValues, currentValues) => prevValues.proxyType !== currentValues.proxyType}>
|
|
@@ -1670,30 +1700,42 @@ const InterfaceManagement = () => {
|
|
|
1670
1700
|
/>
|
|
1671
1701
|
</div>
|
|
1672
1702
|
))}
|
|
1673
|
-
<
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
<
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1703
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: '8px', marginTop: '8px' }}>
|
|
1704
|
+
<Button
|
|
1705
|
+
type="dashed"
|
|
1706
|
+
onClick={() => add()}
|
|
1707
|
+
icon={<PlusOutlined />}
|
|
1708
|
+
style={{ flex: 1 }}
|
|
1709
|
+
>
|
|
1710
|
+
添加参数匹配规则
|
|
1711
|
+
</Button>
|
|
1712
|
+
<Popover
|
|
1713
|
+
content={
|
|
1714
|
+
<div style={{ maxWidth: '300px' }}>
|
|
1715
|
+
<div style={{ marginBottom: '8px', fontWeight: 'bold' }}>匹配规则说明:</div>
|
|
1716
|
+
<div style={{ lineHeight: '1.6' }}>
|
|
1717
|
+
<div>• <strong>精确匹配</strong>:参数值完全相等</div>
|
|
1718
|
+
<div>• <strong>包含</strong>:参数值包含指定内容</div>
|
|
1719
|
+
<div>• <strong>正则</strong>:参数值符合正则表达式</div>
|
|
1720
|
+
<div>• <strong>嵌套路径</strong>:使用点号分隔,如 data.user.id</div>
|
|
1721
|
+
</div>
|
|
1722
|
+
</div>
|
|
1723
|
+
}
|
|
1724
|
+
title="参数匹配规则"
|
|
1725
|
+
trigger="click"
|
|
1726
|
+
placement="top"
|
|
1727
|
+
>
|
|
1728
|
+
<Button
|
|
1729
|
+
type="text"
|
|
1730
|
+
icon={<QuestionCircleOutlined />}
|
|
1731
|
+
style={{
|
|
1732
|
+
color: '#999',
|
|
1733
|
+
padding: '4px'
|
|
1734
|
+
}}
|
|
1735
|
+
size="small"
|
|
1736
|
+
/>
|
|
1737
|
+
</Popover>
|
|
1738
|
+
</div>
|
|
1697
1739
|
</>
|
|
1698
1740
|
)}
|
|
1699
1741
|
</Form.List>
|
|
@@ -1817,7 +1859,10 @@ const InterfaceManagement = () => {
|
|
|
1817
1859
|
return null;
|
|
1818
1860
|
}}
|
|
1819
1861
|
</Form.Item>
|
|
1820
|
-
|
|
1862
|
+
</Collapse.Panel>
|
|
1863
|
+
</Collapse>
|
|
1864
|
+
</Form>
|
|
1865
|
+
</div>
|
|
1821
1866
|
</Modal>
|
|
1822
1867
|
|
|
1823
1868
|
{/* 使用拆分后的预览模态框组件 */}
|