whistle.mockbubu 2.2.0-beta.1 → 2.2.0-beta.2
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/lib/core/server-entry/response-handler.js +22 -10
- package/lib/core/server-entry/server.js +15 -0
- package/package.json +1 -1
- package/public/js/app.js +130 -54
- package/public/js/app.js.map +1 -1
|
@@ -124,7 +124,6 @@ async function matchByConditions(params) {
|
|
|
124
124
|
|
|
125
125
|
const allMatch = rule.conditions.every((cond) => {
|
|
126
126
|
const sourceParams = cond.source === 'query' ? queryParams : payloadParams
|
|
127
|
-
// 精确匹配:参数名和参数值必须完全相等(都转为字符串比较)
|
|
128
127
|
return String(sourceParams[cond.key]) === String(cond.value)
|
|
129
128
|
})
|
|
130
129
|
|
|
@@ -182,11 +181,9 @@ function extractQueryParams(originalReq) {
|
|
|
182
181
|
}
|
|
183
182
|
|
|
184
183
|
/**
|
|
185
|
-
* 从原始请求中提取 payload
|
|
184
|
+
* 从原始请求中提取 payload 参数(支持 JSON 和 x-www-form-urlencoded,只提取第一层 key-value)
|
|
186
185
|
* 来源:req.originalReq.body
|
|
187
186
|
*
|
|
188
|
-
* 非 JSON payload 时返回空对象,条件匹配只会比较 query 部分。
|
|
189
|
-
*
|
|
190
187
|
* @param {Object} originalReq - Whistle 原始请求对象
|
|
191
188
|
* @returns {Object} payload 参数 key-value 对(值统一转为字符串)
|
|
192
189
|
*/
|
|
@@ -194,14 +191,15 @@ function extractPayloadParams(originalReq) {
|
|
|
194
191
|
if (!originalReq) return {}
|
|
195
192
|
|
|
196
193
|
try {
|
|
197
|
-
|
|
194
|
+
// 优先使用 mock 路径预缓冲的请求体,fallback 到 Whistle 预解析的 body
|
|
195
|
+
let body = originalReq._reqBody || originalReq.body || ''
|
|
198
196
|
|
|
199
197
|
// Buffer 转字符串
|
|
200
198
|
if (Buffer.isBuffer(body)) {
|
|
201
199
|
body = body.toString('utf8')
|
|
202
200
|
}
|
|
203
201
|
|
|
204
|
-
//
|
|
202
|
+
// body 可能已被 Whistle 预解析为对象,直接提取
|
|
205
203
|
if (typeof body === 'object' && body !== null) {
|
|
206
204
|
return extractFlatParams(body)
|
|
207
205
|
}
|
|
@@ -210,12 +208,26 @@ function extractPayloadParams(originalReq) {
|
|
|
210
208
|
return {}
|
|
211
209
|
}
|
|
212
210
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
211
|
+
// 尝试 JSON 格式
|
|
212
|
+
try {
|
|
213
|
+
const parsed = JSON.parse(body)
|
|
214
|
+
if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {
|
|
215
|
+
return extractFlatParams(parsed)
|
|
216
|
+
}
|
|
217
|
+
} catch {
|
|
218
|
+
// 不是 JSON,继续尝试
|
|
216
219
|
}
|
|
217
220
|
|
|
218
|
-
|
|
221
|
+
// 尝试 application/x-www-form-urlencoded 格式
|
|
222
|
+
if (body.includes('=')) {
|
|
223
|
+
const result = {}
|
|
224
|
+
new URLSearchParams(body).forEach((value, key) => {
|
|
225
|
+
result[key] = value
|
|
226
|
+
})
|
|
227
|
+
if (Object.keys(result).length > 0) return result
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return {}
|
|
219
231
|
} catch {
|
|
220
232
|
return {}
|
|
221
233
|
}
|
|
@@ -23,6 +23,19 @@ const {
|
|
|
23
23
|
} = require('./capture-handler')
|
|
24
24
|
const pluginModeManager = require('../plugin-mode-manager')
|
|
25
25
|
|
|
26
|
+
/**
|
|
27
|
+
* 从 req 流缓冲请求体,供条件匹配使用
|
|
28
|
+
* 仅在 mock 路径调用,此时 req 流未被 pipe,可安全读取
|
|
29
|
+
*/
|
|
30
|
+
function bufferReqBody(req) {
|
|
31
|
+
return new Promise((resolve) => {
|
|
32
|
+
const chunks = []
|
|
33
|
+
req.on('data', chunk => chunks.push(chunk))
|
|
34
|
+
req.on('end', () => resolve(Buffer.concat(chunks)))
|
|
35
|
+
req.on('error', () => resolve(Buffer.alloc(0)))
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
|
|
26
39
|
module.exports = (server, options) => {
|
|
27
40
|
console.log('[mockbubu] 🚀 server.js 模块已加载!')
|
|
28
41
|
const { storage } = options
|
|
@@ -101,6 +114,7 @@ module.exports = (server, options) => {
|
|
|
101
114
|
|
|
102
115
|
// 有 mock 且有数据 → 返回 mock(不捕获)
|
|
103
116
|
console.log(`[mockbubu] ✅ Mock-Only 模式: 返回 Mock 数据(不捕获) | URL: ${url}`)
|
|
117
|
+
originalReq._reqBody = await bufferReqBody(req)
|
|
104
118
|
const mockOnlyResult = await sendMockResponse(res, sourceData, {
|
|
105
119
|
mockVersion,
|
|
106
120
|
groupManager,
|
|
@@ -117,6 +131,7 @@ module.exports = (server, options) => {
|
|
|
117
131
|
|
|
118
132
|
// 场景 1: Mock 启用 + 有源数据 → 返回 Mock 数据
|
|
119
133
|
if (mock && sourceData) {
|
|
134
|
+
originalReq._reqBody = await bufferReqBody(req)
|
|
120
135
|
const mockResult = await sendMockResponse(res, sourceData, {
|
|
121
136
|
mockVersion,
|
|
122
137
|
groupManager,
|
package/package.json
CHANGED
package/public/js/app.js
CHANGED
|
@@ -2173,10 +2173,19 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
2173
2173
|
/* harmony import */ var core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_map_js__WEBPACK_IMPORTED_MODULE_7__);
|
|
2174
2174
|
/* harmony import */ var core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! core-js/modules/es.iterator.some.js */ "./node_modules/core-js/modules/es.iterator.some.js");
|
|
2175
2175
|
/* harmony import */ var core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_iterator_some_js__WEBPACK_IMPORTED_MODULE_8__);
|
|
2176
|
-
/* harmony import */ var
|
|
2177
|
-
/* harmony import */ var
|
|
2178
|
-
/* harmony import */ var
|
|
2179
|
-
/* harmony import */ var
|
|
2176
|
+
/* harmony import */ var core_js_modules_web_url_search_params_delete_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! core-js/modules/web.url-search-params.delete.js */ "./node_modules/core-js/modules/web.url-search-params.delete.js");
|
|
2177
|
+
/* harmony import */ var core_js_modules_web_url_search_params_delete_js__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_web_url_search_params_delete_js__WEBPACK_IMPORTED_MODULE_9__);
|
|
2178
|
+
/* harmony import */ var core_js_modules_web_url_search_params_has_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! core-js/modules/web.url-search-params.has.js */ "./node_modules/core-js/modules/web.url-search-params.has.js");
|
|
2179
|
+
/* harmony import */ var core_js_modules_web_url_search_params_has_js__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_web_url_search_params_has_js__WEBPACK_IMPORTED_MODULE_10__);
|
|
2180
|
+
/* harmony import */ var core_js_modules_web_url_search_params_size_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! core-js/modules/web.url-search-params.size.js */ "./node_modules/core-js/modules/web.url-search-params.size.js");
|
|
2181
|
+
/* harmony import */ var core_js_modules_web_url_search_params_size_js__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_web_url_search_params_size_js__WEBPACK_IMPORTED_MODULE_11__);
|
|
2182
|
+
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm.js");
|
|
2183
|
+
/* harmony import */ var _common_JsonEditor_vue__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../common/JsonEditor.vue */ "./src/components/common/JsonEditor.vue");
|
|
2184
|
+
/* harmony import */ var _MatchConditionEditor_vue__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./MatchConditionEditor.vue */ "./src/components/content/MatchConditionEditor.vue");
|
|
2185
|
+
/* harmony import */ var _service__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../../service */ "./src/service/index.js");
|
|
2186
|
+
|
|
2187
|
+
|
|
2188
|
+
|
|
2180
2189
|
|
|
2181
2190
|
|
|
2182
2191
|
|
|
@@ -2214,17 +2223,17 @@ const __default__ = {
|
|
|
2214
2223
|
}) {
|
|
2215
2224
|
const props = __props;
|
|
2216
2225
|
const MATCH_MODE_VALUE = '__match_mode__';
|
|
2217
|
-
const editRef = (0,
|
|
2218
|
-
const fullScreenEditorRef = (0,
|
|
2219
|
-
const versionNameInput = (0,
|
|
2220
|
-
const matchRuleNameInput = (0,
|
|
2221
|
-
const responseList = (0,
|
|
2222
|
-
const currentFile = (0,
|
|
2226
|
+
const editRef = (0,vue__WEBPACK_IMPORTED_MODULE_12__.ref)(null);
|
|
2227
|
+
const fullScreenEditorRef = (0,vue__WEBPACK_IMPORTED_MODULE_12__.ref)(null);
|
|
2228
|
+
const versionNameInput = (0,vue__WEBPACK_IMPORTED_MODULE_12__.ref)(null);
|
|
2229
|
+
const matchRuleNameInput = (0,vue__WEBPACK_IMPORTED_MODULE_12__.ref)(null);
|
|
2230
|
+
const responseList = (0,vue__WEBPACK_IMPORTED_MODULE_12__.ref)([]);
|
|
2231
|
+
const currentFile = (0,vue__WEBPACK_IMPORTED_MODULE_12__.ref)({
|
|
2223
2232
|
content: {}
|
|
2224
2233
|
});
|
|
2225
|
-
const hasJsonError = (0,
|
|
2226
|
-
const hasFullScreenJsonError = (0,
|
|
2227
|
-
const versionModal = (0,
|
|
2234
|
+
const hasJsonError = (0,vue__WEBPACK_IMPORTED_MODULE_12__.ref)(false); // JSON 格式错误标志
|
|
2235
|
+
const hasFullScreenJsonError = (0,vue__WEBPACK_IMPORTED_MODULE_12__.ref)(false); // 全屏编辑器 JSON 格式错误标志
|
|
2236
|
+
const versionModal = (0,vue__WEBPACK_IMPORTED_MODULE_12__.reactive)({
|
|
2228
2237
|
visible: false,
|
|
2229
2238
|
status: 'create',
|
|
2230
2239
|
// 'create' | 'edit'
|
|
@@ -2232,24 +2241,24 @@ const __default__ = {
|
|
|
2232
2241
|
description: '',
|
|
2233
2242
|
editingVersion: null // 正在编辑的版本对象
|
|
2234
2243
|
});
|
|
2235
|
-
const fullScreenModal = (0,
|
|
2244
|
+
const fullScreenModal = (0,vue__WEBPACK_IMPORTED_MODULE_12__.reactive)({
|
|
2236
2245
|
visible: false,
|
|
2237
2246
|
content: {}
|
|
2238
2247
|
});
|
|
2239
2248
|
|
|
2240
2249
|
// ========== 条件匹配模式状态 ==========
|
|
2241
2250
|
// 当前显示模式:'version' = 版本直选,'match' = 条件匹配
|
|
2242
|
-
const mockMode = (0,
|
|
2251
|
+
const mockMode = (0,vue__WEBPACK_IMPORTED_MODULE_12__.ref)('version');
|
|
2243
2252
|
// 模式下拉是否展开
|
|
2244
|
-
const modeDropdownVisible = (0,
|
|
2253
|
+
const modeDropdownVisible = (0,vue__WEBPACK_IMPORTED_MODULE_12__.ref)(false);
|
|
2245
2254
|
// 匹配规则列表
|
|
2246
|
-
const matchRuleList = (0,
|
|
2255
|
+
const matchRuleList = (0,vue__WEBPACK_IMPORTED_MODULE_12__.ref)([]);
|
|
2247
2256
|
// 当前选中的匹配规则(深拷贝,供编辑用)
|
|
2248
|
-
const currentMatchRule = (0,
|
|
2257
|
+
const currentMatchRule = (0,vue__WEBPACK_IMPORTED_MODULE_12__.ref)(null);
|
|
2249
2258
|
// 条件或内容是否有变更(控制保存按钮显示)
|
|
2250
|
-
const matchRuleChanged = (0,
|
|
2259
|
+
const matchRuleChanged = (0,vue__WEBPACK_IMPORTED_MODULE_12__.ref)(false);
|
|
2251
2260
|
// 匹配规则创建/编辑弹窗
|
|
2252
|
-
const matchRuleModal = (0,
|
|
2261
|
+
const matchRuleModal = (0,vue__WEBPACK_IMPORTED_MODULE_12__.reactive)({
|
|
2253
2262
|
visible: false,
|
|
2254
2263
|
status: 'create',
|
|
2255
2264
|
// 'create' | 'edit'
|
|
@@ -2258,19 +2267,63 @@ const __default__ = {
|
|
|
2258
2267
|
editingRule: null
|
|
2259
2268
|
});
|
|
2260
2269
|
// 捕获到的参数(来自 file.json session,用于"从捕获参数选择")
|
|
2261
|
-
const capturedQuery = (0,
|
|
2262
|
-
const capturedPayload = (0,
|
|
2270
|
+
const capturedQuery = (0,vue__WEBPACK_IMPORTED_MODULE_12__.computed)(() => props.api.query || {});
|
|
2271
|
+
const capturedPayload = (0,vue__WEBPACK_IMPORTED_MODULE_12__.computed)(() => {
|
|
2263
2272
|
const payload = props.api.payload;
|
|
2264
2273
|
if (!payload) return {};
|
|
2265
|
-
//
|
|
2266
|
-
|
|
2274
|
+
// 结构化对象格式: { raw, parsed: { type, data } }
|
|
2275
|
+
if (typeof payload === 'object' && payload.parsed?.data) {
|
|
2276
|
+
return payload.parsed.data;
|
|
2277
|
+
}
|
|
2278
|
+
// 普通对象(Whistle 预解析),提取第一层 string/number/boolean
|
|
2279
|
+
if (typeof payload === 'object' && !Array.isArray(payload)) {
|
|
2280
|
+
const result = {};
|
|
2281
|
+
Object.keys(payload).forEach(key => {
|
|
2282
|
+
const val = payload[key];
|
|
2283
|
+
if (typeof val === 'string' || typeof val === 'number' || typeof val === 'boolean') {
|
|
2284
|
+
result[key] = String(val);
|
|
2285
|
+
}
|
|
2286
|
+
});
|
|
2287
|
+
return result;
|
|
2288
|
+
}
|
|
2289
|
+
if (typeof payload === 'string') {
|
|
2290
|
+
// JSON 格式
|
|
2291
|
+
try {
|
|
2292
|
+
const parsed = JSON.parse(payload);
|
|
2293
|
+
if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {
|
|
2294
|
+
const result = {};
|
|
2295
|
+
Object.keys(parsed).forEach(key => {
|
|
2296
|
+
const val = parsed[key];
|
|
2297
|
+
if (typeof val === 'string' || typeof val === 'number' || typeof val === 'boolean') {
|
|
2298
|
+
result[key] = String(val);
|
|
2299
|
+
}
|
|
2300
|
+
});
|
|
2301
|
+
return result;
|
|
2302
|
+
}
|
|
2303
|
+
} catch {
|
|
2304
|
+
// 不是 JSON,继续尝试
|
|
2305
|
+
}
|
|
2306
|
+
// application/x-www-form-urlencoded 格式
|
|
2307
|
+
if (payload.includes('=')) {
|
|
2308
|
+
try {
|
|
2309
|
+
const result = {};
|
|
2310
|
+
new URLSearchParams(payload).forEach((value, key) => {
|
|
2311
|
+
result[key] = value;
|
|
2312
|
+
});
|
|
2313
|
+
if (Object.keys(result).length > 0) return result;
|
|
2314
|
+
} catch {
|
|
2315
|
+
// 解析失败
|
|
2316
|
+
}
|
|
2317
|
+
}
|
|
2318
|
+
}
|
|
2319
|
+
return {};
|
|
2267
2320
|
});
|
|
2268
|
-
const name = (0,
|
|
2269
|
-
const mock = (0,
|
|
2270
|
-
const mockVersion = (0,
|
|
2271
|
-
const date = (0,
|
|
2272
|
-
const isSourceReadonly = (0,
|
|
2273
|
-
const activeEditorContent = (0,
|
|
2321
|
+
const name = (0,vue__WEBPACK_IMPORTED_MODULE_12__.computed)(() => props.api.name);
|
|
2322
|
+
const mock = (0,vue__WEBPACK_IMPORTED_MODULE_12__.computed)(() => props.api.mock);
|
|
2323
|
+
const mockVersion = (0,vue__WEBPACK_IMPORTED_MODULE_12__.computed)(() => props.api.mockVersion);
|
|
2324
|
+
const date = (0,vue__WEBPACK_IMPORTED_MODULE_12__.computed)(() => props.api.date);
|
|
2325
|
+
const isSourceReadonly = (0,vue__WEBPACK_IMPORTED_MODULE_12__.computed)(() => mockMode.value === 'version' && currentFile.value.type === 'source');
|
|
2326
|
+
const activeEditorContent = (0,vue__WEBPACK_IMPORTED_MODULE_12__.computed)(() => mockMode.value === 'match' ? currentMatchRule.value?.content : currentFile.value.content);
|
|
2274
2327
|
|
|
2275
2328
|
/**
|
|
2276
2329
|
* 获取 source 版本数据(仅用于未保存文件)
|
|
@@ -2335,7 +2388,7 @@ const __default__ = {
|
|
|
2335
2388
|
*/
|
|
2336
2389
|
const getHistoryVersions = () => {
|
|
2337
2390
|
const fileId = props.api.id;
|
|
2338
|
-
return (0,
|
|
2391
|
+
return (0,_service__WEBPACK_IMPORTED_MODULE_15__.getVersions)({
|
|
2339
2392
|
fileId
|
|
2340
2393
|
}).then(res => {
|
|
2341
2394
|
console.log('[ResponsePanel] 后端返回的版本数据:', res);
|
|
@@ -2414,7 +2467,7 @@ const __default__ = {
|
|
|
2414
2467
|
}
|
|
2415
2468
|
};
|
|
2416
2469
|
const deleteVersionHandler = (item, index) => {
|
|
2417
|
-
(0,
|
|
2470
|
+
(0,_service__WEBPACK_IMPORTED_MODULE_15__.deleteVersion)({
|
|
2418
2471
|
url: props.api.name,
|
|
2419
2472
|
fileId: props.api.id,
|
|
2420
2473
|
versionId: item.id
|
|
@@ -2489,7 +2542,7 @@ const __default__ = {
|
|
|
2489
2542
|
// 未保存文件:先保存文件,再创建版本
|
|
2490
2543
|
console.log('[ResponsePanel] 文件未保存,先保存文件');
|
|
2491
2544
|
try {
|
|
2492
|
-
const saveResult = await (0,
|
|
2545
|
+
const saveResult = await (0,_service__WEBPACK_IMPORTED_MODULE_15__.saveFile)({
|
|
2493
2546
|
url: props.api.url,
|
|
2494
2547
|
method: props.api.method,
|
|
2495
2548
|
status: props.api.status,
|
|
@@ -2520,7 +2573,7 @@ const __default__ = {
|
|
|
2520
2573
|
return;
|
|
2521
2574
|
}
|
|
2522
2575
|
}
|
|
2523
|
-
(0,
|
|
2576
|
+
(0,_service__WEBPACK_IMPORTED_MODULE_15__.addVersion)({
|
|
2524
2577
|
versionName: versionModal.name,
|
|
2525
2578
|
fileId,
|
|
2526
2579
|
description: versionModal.description,
|
|
@@ -2550,7 +2603,7 @@ const __default__ = {
|
|
|
2550
2603
|
// 添加版本成功后,重新获取版本列表(确保数据同步)
|
|
2551
2604
|
// ⚠️ 关键修复:使用保存的 fileId,而不是 props.api.id(可能仍是 undefined)
|
|
2552
2605
|
console.log('[ResponsePanel] 使用 fileId 刷新版本列表:', fileId);
|
|
2553
|
-
(0,
|
|
2606
|
+
(0,_service__WEBPACK_IMPORTED_MODULE_15__.getVersions)({
|
|
2554
2607
|
fileId
|
|
2555
2608
|
}).then(versionRes => {
|
|
2556
2609
|
console.log('[ResponsePanel] 后端返回的版本数据:', versionRes);
|
|
@@ -2621,7 +2674,7 @@ const __default__ = {
|
|
|
2621
2674
|
}
|
|
2622
2675
|
|
|
2623
2676
|
// 调用后端API更新版本元信息
|
|
2624
|
-
(0,
|
|
2677
|
+
(0,_service__WEBPACK_IMPORTED_MODULE_15__.updateVersionMeta)({
|
|
2625
2678
|
url: props.api.name,
|
|
2626
2679
|
fileId: props.api.id,
|
|
2627
2680
|
versionId: currentFile.value.id,
|
|
@@ -2691,7 +2744,7 @@ const __default__ = {
|
|
|
2691
2744
|
effect: tempEffect
|
|
2692
2745
|
};
|
|
2693
2746
|
const versionName = item.type === 'history' ? item.filename : '';
|
|
2694
|
-
(0,
|
|
2747
|
+
(0,_service__WEBPACK_IMPORTED_MODULE_15__.setMockVersion)({
|
|
2695
2748
|
url: props.api.name,
|
|
2696
2749
|
versionName
|
|
2697
2750
|
}) // Changed from name to url
|
|
@@ -2713,7 +2766,7 @@ const __default__ = {
|
|
|
2713
2766
|
currentFile.value.effect = true;
|
|
2714
2767
|
};
|
|
2715
2768
|
const updateHistory = () => {
|
|
2716
|
-
(0,
|
|
2769
|
+
(0,_service__WEBPACK_IMPORTED_MODULE_15__.updateVersionContent)({
|
|
2717
2770
|
versionId: currentFile.value.id,
|
|
2718
2771
|
content: currentFile.value.content,
|
|
2719
2772
|
fileId: props.api.id
|
|
@@ -2757,7 +2810,7 @@ const __default__ = {
|
|
|
2757
2810
|
responseList.value = source ? [source, ...versions] : versions;
|
|
2758
2811
|
};
|
|
2759
2812
|
const updateApiDataHandler = () => {
|
|
2760
|
-
(0,
|
|
2813
|
+
(0,_service__WEBPACK_IMPORTED_MODULE_15__.updateApiData)(props.api.name, currentFile.value.content).then(res => {
|
|
2761
2814
|
const {
|
|
2762
2815
|
code
|
|
2763
2816
|
} = res;
|
|
@@ -2818,7 +2871,7 @@ const __default__ = {
|
|
|
2818
2871
|
/** 保存当前匹配规则(条件 + 内容) */
|
|
2819
2872
|
const updateMatchRuleHandler = async () => {
|
|
2820
2873
|
if (!currentMatchRule.value) return;
|
|
2821
|
-
const res = await (0,
|
|
2874
|
+
const res = await (0,_service__WEBPACK_IMPORTED_MODULE_15__.updateMatchVersion)({
|
|
2822
2875
|
url: props.api.name,
|
|
2823
2876
|
matchVersionId: currentMatchRule.value.id,
|
|
2824
2877
|
conditions: currentMatchRule.value.conditions,
|
|
@@ -3023,13 +3076,36 @@ const __default__ = {
|
|
|
3023
3076
|
const switchMode = async targetMode => {
|
|
3024
3077
|
modeDropdownVisible.value = false;
|
|
3025
3078
|
if (targetMode === mockMode.value) return;
|
|
3026
|
-
if (!props.api.id) {
|
|
3027
|
-
element_ui_lib_message__WEBPACK_IMPORTED_MODULE_2___default().warning('未保存的文件需要先保存后才能使用条件匹配');
|
|
3028
|
-
return;
|
|
3029
|
-
}
|
|
3030
3079
|
if (targetMode === 'match') {
|
|
3080
|
+
// 未保存文件:先自动保存,再切换
|
|
3081
|
+
if (!props.api.id) {
|
|
3082
|
+
try {
|
|
3083
|
+
const saveResult = await (0,_service__WEBPACK_IMPORTED_MODULE_15__.saveFile)({
|
|
3084
|
+
url: props.api.url,
|
|
3085
|
+
method: props.api.method,
|
|
3086
|
+
status: props.api.status,
|
|
3087
|
+
session: props.api.session,
|
|
3088
|
+
config: {
|
|
3089
|
+
mock: props.api.mock || false,
|
|
3090
|
+
locked: props.api.locked || false
|
|
3091
|
+
}
|
|
3092
|
+
});
|
|
3093
|
+
if (saveResult.code !== 200) {
|
|
3094
|
+
element_ui_lib_message__WEBPACK_IMPORTED_MODULE_2___default().error(`保存文件失败: ${saveResult.msg || '未知错误'}`);
|
|
3095
|
+
return;
|
|
3096
|
+
}
|
|
3097
|
+
emit('fileSaved', {
|
|
3098
|
+
url: props.api.url,
|
|
3099
|
+
savedFile: saveResult.data.file
|
|
3100
|
+
});
|
|
3101
|
+
} catch (err) {
|
|
3102
|
+
element_ui_lib_message__WEBPACK_IMPORTED_MODULE_2___default().error(`保存文件失败: ${err.message || '未知错误'}`);
|
|
3103
|
+
return;
|
|
3104
|
+
}
|
|
3105
|
+
}
|
|
3106
|
+
|
|
3031
3107
|
// 切换为条件匹配
|
|
3032
|
-
const res = await (0,
|
|
3108
|
+
const res = await (0,_service__WEBPACK_IMPORTED_MODULE_15__.setMatchMode)({
|
|
3033
3109
|
url: props.api.name,
|
|
3034
3110
|
enable: true
|
|
3035
3111
|
});
|
|
@@ -3046,7 +3122,7 @@ const __default__ = {
|
|
|
3046
3122
|
emit('changeMockVersion', MATCH_MODE_VALUE);
|
|
3047
3123
|
} else {
|
|
3048
3124
|
// 切换回版本直选
|
|
3049
|
-
const res = await (0,
|
|
3125
|
+
const res = await (0,_service__WEBPACK_IMPORTED_MODULE_15__.setMatchMode)({
|
|
3050
3126
|
url: props.api.name,
|
|
3051
3127
|
enable: false
|
|
3052
3128
|
});
|
|
@@ -3070,7 +3146,7 @@ const __default__ = {
|
|
|
3070
3146
|
/** 加载匹配规则列表 */
|
|
3071
3147
|
const loadMatchVersions = async () => {
|
|
3072
3148
|
if (!props.api.id || !props.api.name) return;
|
|
3073
|
-
const res = await (0,
|
|
3149
|
+
const res = await (0,_service__WEBPACK_IMPORTED_MODULE_15__.getMatchVersions)({
|
|
3074
3150
|
url: props.api.name
|
|
3075
3151
|
});
|
|
3076
3152
|
if (res.code !== 200) {
|
|
@@ -3150,7 +3226,7 @@ const __default__ = {
|
|
|
3150
3226
|
return;
|
|
3151
3227
|
}
|
|
3152
3228
|
if (matchRuleModal.status === 'create') {
|
|
3153
|
-
const res = await (0,
|
|
3229
|
+
const res = await (0,_service__WEBPACK_IMPORTED_MODULE_15__.addMatchVersion)({
|
|
3154
3230
|
url: props.api.name,
|
|
3155
3231
|
name: matchRuleModal.name.trim(),
|
|
3156
3232
|
description: matchRuleModal.description
|
|
@@ -3169,7 +3245,7 @@ const __default__ = {
|
|
|
3169
3245
|
element_ui_lib_message__WEBPACK_IMPORTED_MODULE_2___default().success('创建成功');
|
|
3170
3246
|
} else {
|
|
3171
3247
|
// 编辑元信息
|
|
3172
|
-
const res = await (0,
|
|
3248
|
+
const res = await (0,_service__WEBPACK_IMPORTED_MODULE_15__.updateMatchVersionMeta)({
|
|
3173
3249
|
url: props.api.name,
|
|
3174
3250
|
matchVersionId: matchRuleModal.editingRule.id,
|
|
3175
3251
|
name: matchRuleModal.name.trim(),
|
|
@@ -3203,7 +3279,7 @@ const __default__ = {
|
|
|
3203
3279
|
} catch {
|
|
3204
3280
|
return; // 取消
|
|
3205
3281
|
}
|
|
3206
|
-
const res = await (0,
|
|
3282
|
+
const res = await (0,_service__WEBPACK_IMPORTED_MODULE_15__.deleteMatchVersion)({
|
|
3207
3283
|
url: props.api.name,
|
|
3208
3284
|
matchVersionId: rule.id
|
|
3209
3285
|
});
|
|
@@ -3238,7 +3314,7 @@ const __default__ = {
|
|
|
3238
3314
|
* - 已保存文件: file-${id}
|
|
3239
3315
|
* - 未保存文件: cache-${url}-${captureTime}
|
|
3240
3316
|
*/
|
|
3241
|
-
(0,
|
|
3317
|
+
(0,vue__WEBPACK_IMPORTED_MODULE_12__.watch)(() => props.rowKey, (newRowKey, oldRowKey) => {
|
|
3242
3318
|
// 判断是否为已保存文件(已保存文件有 id,未保存文件没有)
|
|
3243
3319
|
const isSavedFile = !!props.api.id;
|
|
3244
3320
|
|
|
@@ -3384,8 +3460,8 @@ const __default__ = {
|
|
|
3384
3460
|
handleMatchRuleConfirm,
|
|
3385
3461
|
deleteMatchRuleHandler,
|
|
3386
3462
|
refreshVersions,
|
|
3387
|
-
JsonEditor:
|
|
3388
|
-
MatchConditionEditor:
|
|
3463
|
+
JsonEditor: _common_JsonEditor_vue__WEBPACK_IMPORTED_MODULE_13__["default"],
|
|
3464
|
+
MatchConditionEditor: _MatchConditionEditor_vue__WEBPACK_IMPORTED_MODULE_14__["default"]
|
|
3389
3465
|
};
|
|
3390
3466
|
}
|
|
3391
3467
|
}));
|
|
@@ -5274,7 +5350,7 @@ var render = function render() {
|
|
|
5274
5350
|
staticClass: "response-panel"
|
|
5275
5351
|
}, [_c("div", {
|
|
5276
5352
|
staticClass: "response-panel__header"
|
|
5277
|
-
}, [_setup.props.api
|
|
5353
|
+
}, [_setup.props.api ? _c("div", {
|
|
5278
5354
|
staticClass: "response-panel__mode-selector"
|
|
5279
5355
|
}, [_c("div", {
|
|
5280
5356
|
staticClass: "response-panel__mode-btn",
|