whistle.mock-plugins 1.0.5 → 1.0.6-beta.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/app/cgi-bin/test-interface.js +264 -261
- package/app/public/js/index.js +1 -1
- package/lib/rules-server.js +246 -140
- package/package.json +1 -1
- package/ui/src/pages/InterfaceManagement.js +69 -29
- package/ui/src/pages/MockData.js +32 -0
|
@@ -167,6 +167,9 @@ const InterfaceManagement = () => {
|
|
|
167
167
|
if (response.data && response.data.code === 0) {
|
|
168
168
|
message.success('接口删除成功');
|
|
169
169
|
fetchInterfaces();
|
|
170
|
+
|
|
171
|
+
// 刷新规则缓存
|
|
172
|
+
refreshCacheAfterUpdate();
|
|
170
173
|
} else {
|
|
171
174
|
throw new Error(response.data?.message || '接口删除失败');
|
|
172
175
|
}
|
|
@@ -214,6 +217,28 @@ const InterfaceManagement = () => {
|
|
|
214
217
|
}
|
|
215
218
|
};
|
|
216
219
|
|
|
220
|
+
// 缓存刷新服务
|
|
221
|
+
const flushCache = async () => {
|
|
222
|
+
try {
|
|
223
|
+
const response = await axios.get('/_flush_cache');
|
|
224
|
+
return response.data;
|
|
225
|
+
} catch (error) {
|
|
226
|
+
console.error('刷新缓存失败:', error);
|
|
227
|
+
throw error;
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
// 更新成功后刷新缓存
|
|
232
|
+
const refreshCacheAfterUpdate = async () => {
|
|
233
|
+
try {
|
|
234
|
+
await flushCache();
|
|
235
|
+
// 这里不需要显示提示,因为主要操作会有自己的提示
|
|
236
|
+
} catch (error) {
|
|
237
|
+
// 如果刷新缓存失败,记录错误但不影响用户体验
|
|
238
|
+
console.error('刷新缓存失败,可能需要等待缓存自动过期:', error);
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
|
|
217
242
|
const handleSubmit = async () => {
|
|
218
243
|
try {
|
|
219
244
|
const values = await form.validateFields();
|
|
@@ -256,30 +281,28 @@ const InterfaceManagement = () => {
|
|
|
256
281
|
active: true
|
|
257
282
|
};
|
|
258
283
|
|
|
284
|
+
let response;
|
|
259
285
|
if (editingInterface) {
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
message.success('接口更新成功');
|
|
263
|
-
} else {
|
|
264
|
-
throw new Error(response.data?.message || '接口更新失败');
|
|
265
|
-
}
|
|
286
|
+
// 更新现有接口
|
|
287
|
+
response = await axios.put(`/cgi-bin/interfaces?id=${editingInterface.id}`, interfaceData);
|
|
266
288
|
} else {
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
message.success('接口添加成功');
|
|
270
|
-
} else {
|
|
271
|
-
throw new Error(response.data?.message || '接口添加失败');
|
|
272
|
-
}
|
|
289
|
+
// 创建新接口
|
|
290
|
+
response = await axios.post('/cgi-bin/interfaces', interfaceData);
|
|
273
291
|
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
292
|
+
|
|
293
|
+
if (response.data && response.data.code === 0) {
|
|
294
|
+
message.success(editingInterface ? '接口更新成功' : '接口创建成功');
|
|
295
|
+
setModalVisible(false);
|
|
296
|
+
fetchInterfaces();
|
|
297
|
+
|
|
298
|
+
// 刷新规则缓存
|
|
299
|
+
refreshCacheAfterUpdate();
|
|
300
|
+
} else {
|
|
301
|
+
throw new Error(response.data?.message || '操作失败');
|
|
280
302
|
}
|
|
303
|
+
} catch (error) {
|
|
281
304
|
console.error('操作失败:', error);
|
|
282
|
-
message.error(error.response?.data?.message || error.message || '
|
|
305
|
+
message.error(error.response?.data?.message || error.message || '操作失败');
|
|
283
306
|
}
|
|
284
307
|
};
|
|
285
308
|
|
|
@@ -287,10 +310,11 @@ const InterfaceManagement = () => {
|
|
|
287
310
|
setModalVisible(false);
|
|
288
311
|
};
|
|
289
312
|
|
|
290
|
-
const handleTestInterface = (record) => {
|
|
313
|
+
const handleTestInterface = async (record) => {
|
|
291
314
|
setEditingInterface(record);
|
|
292
315
|
setTestUrl('');
|
|
293
316
|
setTestResult(null);
|
|
317
|
+
setTestLoading(false);
|
|
294
318
|
setTestModalVisible(true);
|
|
295
319
|
testForm.resetFields();
|
|
296
320
|
};
|
|
@@ -337,11 +361,26 @@ const InterfaceManagement = () => {
|
|
|
337
361
|
const handleTestSubmit = async () => {
|
|
338
362
|
try {
|
|
339
363
|
const values = await testForm.validateFields();
|
|
364
|
+
const { testUrl } = values;
|
|
365
|
+
|
|
366
|
+
if (!testUrl) {
|
|
367
|
+
message.error('请输入测试URL');
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
|
|
340
371
|
setTestLoading(true);
|
|
341
372
|
|
|
373
|
+
try {
|
|
374
|
+
// 测试前刷新缓存,确保使用最新的接口定义
|
|
375
|
+
await refreshCacheAfterUpdate();
|
|
376
|
+
} catch (error) {
|
|
377
|
+
// 即使刷新缓存失败,也继续测试
|
|
378
|
+
console.warn('刷新缓存失败,将使用现有的缓存数据:', error);
|
|
379
|
+
}
|
|
380
|
+
|
|
342
381
|
try {
|
|
343
382
|
// 验证测试 URL 是否匹配当前接口的匹配规则
|
|
344
|
-
if (!isUrlMatchPattern(
|
|
383
|
+
if (!isUrlMatchPattern(testUrl, editingInterface.urlPattern, editingInterface.proxyType)) {
|
|
345
384
|
let errorMessage = '测试URL与接口匹配规则不匹配';
|
|
346
385
|
|
|
347
386
|
// 根据不同的代理类型提供更具体的错误信息
|
|
@@ -356,27 +395,26 @@ const InterfaceManagement = () => {
|
|
|
356
395
|
error: errorMessage
|
|
357
396
|
});
|
|
358
397
|
message.error(errorMessage);
|
|
398
|
+
setTestLoading(false);
|
|
359
399
|
return;
|
|
360
400
|
}
|
|
361
401
|
|
|
362
402
|
// 调用实际测试接口
|
|
363
403
|
const response = await axios.post(`/cgi-bin/test-interface`, {
|
|
364
|
-
url:
|
|
404
|
+
url: testUrl,
|
|
365
405
|
interfaceId: editingInterface.id
|
|
366
406
|
});
|
|
367
|
-
|
|
368
|
-
if (response.data && response.data.code === 0
|
|
407
|
+
|
|
408
|
+
if (response.data && response.data.code === 0) {
|
|
409
|
+
// 设置测试结果
|
|
369
410
|
setTestResult({
|
|
370
411
|
success: true,
|
|
371
|
-
|
|
372
|
-
contentType: response.data.data.contentType,
|
|
373
|
-
responseBody: response.data.data.responseBody,
|
|
412
|
+
...response.data.data,
|
|
374
413
|
matchedRule: editingInterface.urlPattern,
|
|
375
414
|
httpMethod: editingInterface.httpMethod,
|
|
376
|
-
requestUrl:
|
|
415
|
+
requestUrl: testUrl,
|
|
377
416
|
mockInfo: response.data.data.mockInfo
|
|
378
417
|
});
|
|
379
|
-
message.success('测试成功');
|
|
380
418
|
} else {
|
|
381
419
|
throw new Error(response.data?.message || '测试响应格式不正确');
|
|
382
420
|
}
|
|
@@ -393,6 +431,8 @@ const InterfaceManagement = () => {
|
|
|
393
431
|
if (error.errorFields) {
|
|
394
432
|
return; // 表单验证错误
|
|
395
433
|
}
|
|
434
|
+
console.error('测试失败:', error);
|
|
435
|
+
message.error(error.message || '测试失败');
|
|
396
436
|
setTestLoading(false);
|
|
397
437
|
}
|
|
398
438
|
};
|
package/ui/src/pages/MockData.js
CHANGED
|
@@ -4,10 +4,22 @@ import AppLayout from '../components/AppLayout';
|
|
|
4
4
|
import { Card, Row, Col, Button, Modal, Form, Input, message, Switch, Empty, Spin, Typography, Tooltip, Badge } from 'antd';
|
|
5
5
|
import { PlusOutlined, EditOutlined, DeleteOutlined, ApiOutlined, ExportOutlined, InfoCircleOutlined, CalendarOutlined } from '@ant-design/icons';
|
|
6
6
|
import '../styles/mock-data.css';
|
|
7
|
+
import axios from 'axios';
|
|
7
8
|
|
|
8
9
|
const { Text, Title, Paragraph } = Typography;
|
|
9
10
|
const { TextArea } = Input;
|
|
10
11
|
|
|
12
|
+
// 刷新缓存服务
|
|
13
|
+
const flushCache = async () => {
|
|
14
|
+
try {
|
|
15
|
+
const response = await axios.get(`/_flush_cache`);
|
|
16
|
+
return response.data;
|
|
17
|
+
} catch (error) {
|
|
18
|
+
console.error('刷新缓存失败:', error);
|
|
19
|
+
throw error;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
11
23
|
const MockData = () => {
|
|
12
24
|
const history = useHistory();
|
|
13
25
|
const [mockFeatures, setMockFeatures] = useState([]);
|
|
@@ -69,6 +81,17 @@ const MockData = () => {
|
|
|
69
81
|
setShowModal(false);
|
|
70
82
|
};
|
|
71
83
|
|
|
84
|
+
// 更新成功后刷新缓存
|
|
85
|
+
const refreshCacheAfterUpdate = async () => {
|
|
86
|
+
try {
|
|
87
|
+
await flushCache();
|
|
88
|
+
// 不显示提示,避免干扰主操作的反馈
|
|
89
|
+
} catch (error) {
|
|
90
|
+
// 记录错误但不影响用户体验
|
|
91
|
+
console.error('刷新缓存失败,可能需要等待缓存自动过期:', error);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
72
95
|
const handleSubmit = async (values) => {
|
|
73
96
|
try {
|
|
74
97
|
const featureData = {
|
|
@@ -96,6 +119,9 @@ const MockData = () => {
|
|
|
96
119
|
message.success(currentFeature ? '功能模块更新成功' : '功能模块创建成功');
|
|
97
120
|
fetchFeatures();
|
|
98
121
|
closeModal();
|
|
122
|
+
|
|
123
|
+
// 刷新缓存
|
|
124
|
+
refreshCacheAfterUpdate();
|
|
99
125
|
} else {
|
|
100
126
|
message.error('操作失败: ' + result.message);
|
|
101
127
|
}
|
|
@@ -127,6 +153,9 @@ const MockData = () => {
|
|
|
127
153
|
setMockFeatures(mockFeatures.map(feature =>
|
|
128
154
|
feature.id === id ? { ...feature, active: !currentActive } : feature
|
|
129
155
|
));
|
|
156
|
+
|
|
157
|
+
// 刷新缓存 - 功能启用状态变化是最关键的需要刷新缓存的操作
|
|
158
|
+
refreshCacheAfterUpdate();
|
|
130
159
|
} else {
|
|
131
160
|
message.error(`${currentActive ? '禁用' : '启用'}功能模块失败: ${result.message}`);
|
|
132
161
|
}
|
|
@@ -156,6 +185,9 @@ const MockData = () => {
|
|
|
156
185
|
message.success('功能模块已成功删除');
|
|
157
186
|
// 更新本地状态
|
|
158
187
|
setMockFeatures(mockFeatures.filter(f => f.id !== id));
|
|
188
|
+
|
|
189
|
+
// 刷新缓存
|
|
190
|
+
refreshCacheAfterUpdate();
|
|
159
191
|
} else {
|
|
160
192
|
message.error('删除失败: ' + result.message);
|
|
161
193
|
}
|