whistle.mock-plugins 1.2.2-beta.8 → 1.2.2-beta.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "whistle.mock-plugins",
3
- "version": "1.2.2-beta.8",
3
+ "version": "1.2.2-beta.9",
4
4
  "description": "Whistle 插件,用于快速创建 API 模拟数据",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
@@ -209,6 +209,111 @@ const ResponseContentEditor = ({
209
209
  updateActiveResponseParamMatchers(currentMatchers);
210
210
  };
211
211
 
212
+ // 渲染入参匹配规则编辑区域
213
+ const renderParamMatchersSection = () => {
214
+ // 整个接口中是否有任意响应含有匹配规则
215
+ const anyHasMatchers = responses.some(
216
+ r => r.paramMatchers && Array.isArray(r.paramMatchers) && r.paramMatchers.length > 0
217
+ );
218
+ const currentHasMatchers = activeResponse.paramMatchers && activeResponse.paramMatchers.length > 0;
219
+ // 只有当接口中存在规则时,无规则的响应才叫"兜底"
220
+ const isFallback = anyHasMatchers && !currentHasMatchers;
221
+
222
+ return (
223
+ <div style={{
224
+ marginBottom: '16px',
225
+ border: '1px solid #e8e8e8',
226
+ borderRadius: '6px',
227
+ padding: '12px',
228
+ background: '#fafafa'
229
+ }}>
230
+ <div style={{
231
+ display: 'flex',
232
+ alignItems: 'center',
233
+ justifyContent: 'space-between',
234
+ marginBottom: '10px'
235
+ }}>
236
+ <div style={{ display: 'flex', alignItems: 'center', gap: '6px' }}>
237
+ <FilterOutlined style={{ color: '#1890ff' }} />
238
+ <label style={{ fontSize: '12px', color: '#333', fontWeight: 'bold' }}>
239
+ 入参匹配规则
240
+ </label>
241
+ {currentHasMatchers ? (
242
+ <Tag color="blue" style={{ fontSize: '11px', lineHeight: '18px', padding: '0 6px' }}>
243
+ {activeResponse.paramMatchers.length}条
244
+ </Tag>
245
+ ) : isFallback ? (
246
+ <Tag color="default" style={{ fontSize: '11px', lineHeight: '18px', padding: '0 6px' }}>
247
+ 兜底响应
248
+ </Tag>
249
+ ) : null}
250
+ </div>
251
+ <Button
252
+ type="dashed"
253
+ size="small"
254
+ icon={<PlusCircleOutlined />}
255
+ onClick={handleAddMatcher}
256
+ style={{ fontSize: '12px' }}
257
+ >
258
+ 添加规则
259
+ </Button>
260
+ </div>
261
+
262
+ {isFallback && (
263
+ <div style={{
264
+ color: '#999',
265
+ fontSize: '12px',
266
+ textAlign: 'center',
267
+ padding: '8px 0'
268
+ }}>
269
+ 无匹配规则,当其他响应均不匹配时作为兜底返回
270
+ </div>
271
+ )}
272
+
273
+ {activeResponse.paramMatchers && activeResponse.paramMatchers.map((matcher, index) => (
274
+ <Row key={index} gutter={8} style={{ marginBottom: '8px' }} align="middle">
275
+ <Col span={8}>
276
+ <Input
277
+ size="small"
278
+ placeholder="参数路径,如 data.type"
279
+ value={matcher.paramPath}
280
+ onChange={(e) => handleMatcherChange(index, 'paramPath', e.target.value)}
281
+ />
282
+ </Col>
283
+ <Col span={5}>
284
+ <Select
285
+ size="small"
286
+ style={{ width: '100%' }}
287
+ value={matcher.matchType || 'exact'}
288
+ onChange={(val) => handleMatcherChange(index, 'matchType', val)}
289
+ >
290
+ <Option value="exact">精确匹配</Option>
291
+ <Option value="contains">包含</Option>
292
+ <Option value="regex">正则</Option>
293
+ </Select>
294
+ </Col>
295
+ <Col span={9}>
296
+ <Input
297
+ size="small"
298
+ placeholder="期望值"
299
+ value={matcher.paramValue}
300
+ onChange={(e) => handleMatcherChange(index, 'paramValue', e.target.value)}
301
+ />
302
+ </Col>
303
+ <Col span={2} style={{ textAlign: 'center' }}>
304
+ <Tooltip title="删除此规则">
305
+ <MinusCircleOutlined
306
+ style={{ color: '#ff4d4f', cursor: 'pointer', fontSize: '16px' }}
307
+ onClick={() => handleDeleteMatcher(index)}
308
+ />
309
+ </Tooltip>
310
+ </Col>
311
+ </Row>
312
+ ))}
313
+ </div>
314
+ );
315
+ };
316
+
212
317
  // 格式化JSON内容
213
318
  const formatJsonContent = () => {
214
319
  if (!activeResponse || !activeResponse.content) {
@@ -538,99 +643,7 @@ const ResponseContentEditor = ({
538
643
  </div>
539
644
 
540
645
  {/* 入参匹配规则编辑区域 */}
541
- {activeResponse && (
542
- <div style={{
543
- marginBottom: '16px',
544
- border: '1px solid #e8e8e8',
545
- borderRadius: '6px',
546
- padding: '12px',
547
- background: '#fafafa'
548
- }}>
549
- <div style={{
550
- display: 'flex',
551
- alignItems: 'center',
552
- justifyContent: 'space-between',
553
- marginBottom: '10px'
554
- }}>
555
- <div style={{ display: 'flex', alignItems: 'center', gap: '6px' }}>
556
- <FilterOutlined style={{ color: '#1890ff' }} />
557
- <label style={{ fontSize: '12px', color: '#333', fontWeight: 'bold' }}>
558
- 入参匹配规则
559
- </label>
560
- {activeResponse.paramMatchers && activeResponse.paramMatchers.length > 0 ? (
561
- <Tag color="blue" style={{ fontSize: '11px', lineHeight: '18px', padding: '0 6px' }}>
562
- {activeResponse.paramMatchers.length}条
563
- </Tag>
564
- ) : (
565
- <Tag color="default" style={{ fontSize: '11px', lineHeight: '18px', padding: '0 6px' }}>
566
- 兜底响应
567
- </Tag>
568
- )}
569
- </div>
570
- <Button
571
- type="dashed"
572
- size="small"
573
- icon={<PlusCircleOutlined />}
574
- onClick={handleAddMatcher}
575
- style={{ fontSize: '12px' }}
576
- >
577
- 添加规则
578
- </Button>
579
- </div>
580
-
581
- {(!activeResponse.paramMatchers || activeResponse.paramMatchers.length === 0) && (
582
- <div style={{
583
- color: '#999',
584
- fontSize: '12px',
585
- textAlign: 'center',
586
- padding: '8px 0'
587
- }}>
588
- 无匹配规则,当其他响应均不匹配时作为兜底返回
589
- </div>
590
- )}
591
-
592
- {activeResponse.paramMatchers && activeResponse.paramMatchers.map((matcher, index) => (
593
- <Row key={index} gutter={8} style={{ marginBottom: '8px' }} align="middle">
594
- <Col span={8}>
595
- <Input
596
- size="small"
597
- placeholder="参数路径,如 data.type"
598
- value={matcher.paramPath}
599
- onChange={(e) => handleMatcherChange(index, 'paramPath', e.target.value)}
600
- />
601
- </Col>
602
- <Col span={5}>
603
- <Select
604
- size="small"
605
- style={{ width: '100%' }}
606
- value={matcher.matchType || 'exact'}
607
- onChange={(val) => handleMatcherChange(index, 'matchType', val)}
608
- >
609
- <Option value="exact">精确匹配</Option>
610
- <Option value="contains">包含</Option>
611
- <Option value="regex">正则</Option>
612
- </Select>
613
- </Col>
614
- <Col span={9}>
615
- <Input
616
- size="small"
617
- placeholder="期望值"
618
- value={matcher.paramValue}
619
- onChange={(e) => handleMatcherChange(index, 'paramValue', e.target.value)}
620
- />
621
- </Col>
622
- <Col span={2} style={{ textAlign: 'center' }}>
623
- <Tooltip title="删除此规则">
624
- <MinusCircleOutlined
625
- style={{ color: '#ff4d4f', cursor: 'pointer', fontSize: '16px' }}
626
- onClick={() => handleDeleteMatcher(index)}
627
- />
628
- </Tooltip>
629
- </Col>
630
- </Row>
631
- ))}
632
- </div>
633
- )}
646
+ {activeResponse && renderParamMatchersSection()}
634
647
 
635
648
  {/* 响应内容编辑区域 */}
636
649
  {activeResponse && (
@@ -816,8 +816,26 @@ const InterfaceManagement = () => {
816
816
  const hasSmartMatch = record.responses.some(
817
817
  r => r.paramMatchers && Array.isArray(r.paramMatchers) && r.paramMatchers.length > 0
818
818
  );
819
- const fallbackResp = record.responses.find(r => r.id === activeResponseId) || record.responses[0];
820
819
 
820
+ // 场景一:所有响应都没有规则 → 显示 Select 快捷切换
821
+ if (!hasSmartMatch) {
822
+ return (
823
+ <Select
824
+ value={activeResponseId || record.responses[0]?.id}
825
+ style={{ width: '100%' }}
826
+ size="small"
827
+ onChange={(value) => handleResponseSwitch(record.id, value)}
828
+ >
829
+ {record.responses.map(resp => (
830
+ <Option key={resp.id} value={resp.id}>
831
+ {resp.name}
832
+ </Option>
833
+ ))}
834
+ </Select>
835
+ );
836
+ }
837
+
838
+ // 场景二/三:有响应含规则 → 显示 Tag 摘要
821
839
  const tooltipContent = (
822
840
  <div style={{ maxWidth: 260 }}>
823
841
  {record.responses.map((resp) => {
@@ -854,19 +872,9 @@ const InterfaceManagement = () => {
854
872
 
855
873
  return (
856
874
  <Tooltip title={tooltipContent} placement="left">
857
- {hasSmartMatch ? (
858
- <Tag color="blue" style={{ cursor: 'default' }}>
859
- 智能匹配 · {total}个响应
860
- </Tag>
861
- ) : total > 1 ? (
862
- <Tag color="orange" style={{ cursor: 'default' }}>
863
- 手动切换 · {total}个响应
864
- </Tag>
865
- ) : (
866
- <span style={{ color: '#999', fontSize: '12px' }}>
867
- {fallbackResp?.name || '1个响应'}
868
- </span>
869
- )}
875
+ <Tag color="blue" style={{ cursor: 'default' }}>
876
+ 智能匹配 · {total}个响应
877
+ </Tag>
870
878
  </Tooltip>
871
879
  );
872
880
  },