whistle.mock-plugins 1.3.1 → 1.4.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.
Files changed (70) hide show
  1. package/VERSION.md +29 -0
  2. package/app/cgi-bin/interfaces.js +2 -0
  3. package/app/cgi-bin/settings.js +1 -0
  4. package/app/cgi-bin/stats.js +22 -12
  5. package/app/cgi-bin/webdav.js +56 -0
  6. package/app/public/index.html +1 -1
  7. package/app/public/js/11.index.js +2 -0
  8. package/app/public/js/11.index.js.LICENSE.txt +5 -0
  9. package/app/public/js/704.index.js +2 -0
  10. package/app/public/js/704.index.js.LICENSE.txt +1 -0
  11. package/app/public/js/798.index.js +2 -0
  12. package/app/public/js/798.index.js.LICENSE.txt +53 -0
  13. package/app/public/js/807.index.js +2 -0
  14. package/app/public/js/807.index.js.LICENSE.txt +1 -0
  15. package/app/public/js/968.index.js +2 -0
  16. package/app/public/js/968.index.js.LICENSE.txt +12 -0
  17. package/app/public/js/index.js +1 -1
  18. package/app/public/js/index.js.LICENSE.txt +0 -173
  19. package/lib/routes/settings.js +1 -0
  20. package/lib/webdav-sync.js +806 -0
  21. package/package.json +9 -2
  22. package/API.md +0 -247
  23. package/COLUMN_RESIZE_IMPLEMENTATION.md +0 -162
  24. package/FEATURE_ENHANCEMENT.md +0 -157
  25. package/TEST_GUIDE.md +0 -156
  26. package/data/features.json +0 -1
  27. package/data/interfaces.json +0 -1
  28. package/index.html +0 -52
  29. package/initialize.js +0 -32
  30. package/public/bundle.js +0 -2
  31. package/public/bundle.js.LICENSE.txt +0 -38
  32. package/public/index.html +0 -1
  33. package/public/plugin.mock-plugin.html +0 -14
  34. package/rules.txt +0 -22
  35. package/ui/src/App.css +0 -173
  36. package/ui/src/components/AppLayout.js +0 -407
  37. package/ui/src/components/FeatureCard.js +0 -58
  38. package/ui/src/components/KeyboardShortcutsHelp.js +0 -58
  39. package/ui/src/components/Layout.js +0 -94
  40. package/ui/src/components/MainNav.js +0 -42
  41. package/ui/src/components/PageContainer.js +0 -16
  42. package/ui/src/components/VersionModal.js +0 -99
  43. package/ui/src/components/interface-management/DataManagementDrawer.js +0 -115
  44. package/ui/src/components/interface-management/DataManagementModal.js +0 -110
  45. package/ui/src/components/interface-management/InterfaceTestModal.js +0 -313
  46. package/ui/src/components/interface-management/PreviewModal.js +0 -48
  47. package/ui/src/components/interface-management/README.md +0 -184
  48. package/ui/src/components/interface-management/RealResponseRecorder.js +0 -165
  49. package/ui/src/components/interface-management/ResponseContentEditor.js +0 -645
  50. package/ui/src/components/interface-management/constants.js +0 -36
  51. package/ui/src/components/interface-management/index.js +0 -7
  52. package/ui/src/components/interface-management/utils.js +0 -103
  53. package/ui/src/hooks/useKeyboardShortcuts.js +0 -99
  54. package/ui/src/index.html +0 -14
  55. package/ui/src/index.js +0 -50
  56. package/ui/src/pages/InterfaceManagementV2.js +0 -2351
  57. package/ui/src/pages/MockDataV2.js +0 -1089
  58. package/ui/src/pages/Settings.js +0 -299
  59. package/ui/src/pages/Sniffer.js +0 -521
  60. package/ui/src/pages/Stats.js +0 -288
  61. package/ui/src/services/del_api.js +0 -192
  62. package/ui/src/styles/app-layout.css +0 -373
  63. package/ui/src/styles/cyber-theme.css +0 -1234
  64. package/ui/src/styles/earth-theme.css +0 -618
  65. package/ui/src/styles/global.css +0 -224
  66. package/ui/src/styles/interface-management.css +0 -1321
  67. package/ui/src/styles/mock-data.css +0 -1185
  68. package/ui/src/styles/settings.css +0 -252
  69. package/ui/src/styles/version-modal.css +0 -116
  70. package/webpack.config.js +0 -54
@@ -1,1185 +0,0 @@
1
- .mock-data-container {
2
- padding: 24px;
3
- background: #fff;
4
- border-radius: 8px;
5
- box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
6
- }
7
-
8
- .header {
9
- display: flex;
10
- justify-content: space-between;
11
- align-items: center;
12
- margin-bottom: 24px;
13
- padding-bottom: 16px;
14
- border-bottom: 1px solid #f0f0f0;
15
- }
16
-
17
- /* 页面标题区域样式 */
18
- .title-section {
19
- flex: 1;
20
- }
21
-
22
- .title-with-badge {
23
- display: flex;
24
- align-items: center;
25
- margin-bottom: 8px;
26
- }
27
-
28
- .page-title {
29
- margin: 0 !important;
30
- font-size: 24px;
31
- font-weight: 600;
32
- color: #262626;
33
- line-height: 1.2;
34
- }
35
-
36
- .page-description {
37
- color: #8c8c8c;
38
- font-size: 14px;
39
- line-height: 1.5;
40
- margin: 0;
41
- }
42
-
43
- /* 控制面板卡片样式 */
44
- .control-panel-card {
45
- border-radius: 12px;
46
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
47
- border: 1px solid #f0f0f0;
48
- }
49
-
50
- .control-panel-card .ant-card-body {
51
- padding: 20px 24px;
52
- }
53
-
54
- /* 统计信息区域 */
55
- .stats-section {
56
- display: flex;
57
- gap: 24px;
58
- align-items: center;
59
- }
60
-
61
- .stats-item {
62
- display: flex;
63
- flex-direction: column;
64
- align-items: center;
65
- text-align: center;
66
- }
67
-
68
- .stats-number {
69
- font-size: 24px;
70
- font-weight: 600;
71
- color: #1890ff;
72
- line-height: 1;
73
- margin-bottom: 4px;
74
- }
75
-
76
- .stats-label {
77
- font-size: 12px;
78
- color: #8c8c8c;
79
- line-height: 1;
80
- }
81
-
82
- /* 控制组样式 */
83
- .control-group {
84
- display: flex;
85
- align-items: center;
86
- gap: 12px;
87
- flex-wrap: wrap;
88
- }
89
-
90
- .control-label {
91
- font-size: 14px;
92
- color: #595959;
93
- white-space: nowrap;
94
- font-weight: 500;
95
- }
96
-
97
- .control-label .anticon {
98
- margin-right: 6px;
99
- color: #1890ff;
100
- }
101
-
102
- .page-info {
103
- font-size: 13px;
104
- color: #8c8c8c;
105
- white-space: nowrap;
106
- }
107
-
108
- /* 功能列表卡片样式 */
109
- .feature-list-card {
110
- border-radius: 12px;
111
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
112
- border: 1px solid #f0f0f0;
113
- min-height: 400px;
114
- }
115
-
116
- .feature-list-card .ant-card-body {
117
- padding: 24px;
118
- }
119
-
120
- .feature-grid {
121
- min-height: 300px;
122
- }
123
-
124
- .feature-card {
125
- position: relative;
126
- transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
127
- height: 100%;
128
- display: flex;
129
- flex-direction: column;
130
- border-radius: 12px;
131
- overflow: hidden;
132
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
133
- border: 1px solid #f0f0f0;
134
- cursor: pointer;
135
- background: #ffffff;
136
- }
137
-
138
- .feature-card:hover {
139
- transform: translateY(-4px);
140
- box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
141
- border-color: #d9d9d9;
142
- }
143
-
144
- .feature-card:active {
145
- transform: translateY(-2px);
146
- }
147
-
148
- /* 添加卡片悬浮效果 */
149
- .feature-card::before {
150
- content: '';
151
- position: absolute;
152
- top: 0;
153
- left: 0;
154
- right: 0;
155
- bottom: 0;
156
- background: linear-gradient(135deg, rgba(24, 144, 255, 0.02), rgba(24, 144, 255, 0.04));
157
- opacity: 0;
158
- transition: opacity 0.3s ease;
159
- pointer-events: none;
160
- z-index: 1;
161
- }
162
-
163
- .feature-card:hover::before {
164
- opacity: 1;
165
- }
166
-
167
- /* 为卡片内容添加相对定位,确保在渐变层之上 */
168
- .feature-card .ant-card-body {
169
- position: relative;
170
- z-index: 2;
171
- padding: 20px;
172
- }
173
-
174
- .feature-card .ant-card-actions {
175
- position: relative;
176
- z-index: 2;
177
- border-top: 1px solid #f0f0f0;
178
- background: #fafafa;
179
- }
180
-
181
- .feature-card .ant-card-actions li {
182
- transition: all 0.2s ease;
183
- }
184
-
185
- .feature-card .ant-card-actions li:hover {
186
- background: #f0f0f0;
187
- }
188
-
189
- /* 不活跃功能卡片样式 */
190
- .feature-card.inactive-feature {
191
- opacity: 0.7;
192
- filter: grayscale(0.3);
193
- }
194
-
195
- .feature-card.inactive-feature:hover {
196
- opacity: 0.9;
197
- filter: grayscale(0.1);
198
- }
199
-
200
- .feature-card-content {
201
- padding: 16px;
202
- height: 140px;
203
- display: flex;
204
- flex-direction: column;
205
- }
206
-
207
- .feature-name {
208
- display: flex;
209
- align-items: center;
210
- justify-content: space-between;
211
- margin-bottom: 10px;
212
- }
213
-
214
- .feature-name h4 {
215
- margin: 0;
216
- font-size: 18px;
217
- color: #1890ff;
218
- font-weight: 600;
219
- flex: 1;
220
- overflow: hidden;
221
- text-overflow: ellipsis;
222
- white-space: nowrap;
223
- }
224
-
225
- .status-tag {
226
- font-size: 12px;
227
- padding: 2px 8px;
228
- border-radius: 10px;
229
- display: inline-flex;
230
- align-items: center;
231
- justify-content: center;
232
- font-weight: 500;
233
- }
234
-
235
- .status-tag.inactive {
236
- background-color: #fff1f0;
237
- color: #f5222d;
238
- border: 1px solid #ffa39e;
239
- }
240
-
241
- .status-tag.active {
242
- background-color: #f6ffed;
243
- color: #52c41a;
244
- border: 1px solid #b7eb8f;
245
- }
246
-
247
- .feature-description {
248
- color: #666;
249
- font-size: 14px;
250
- margin-bottom: 16px;
251
- flex: 1;
252
- overflow: hidden;
253
- display: -webkit-box;
254
- -webkit-box-orient: vertical;
255
- -webkit-line-clamp: 2;
256
- }
257
-
258
- .feature-stat {
259
- margin-top: auto;
260
- color: #8c8c8c;
261
- font-size: 13px;
262
- display: flex;
263
- justify-content: space-between;
264
- align-items: center;
265
- }
266
-
267
- .feature-date {
268
- color: #999;
269
- font-size: 12px;
270
- }
271
-
272
- .inactive-feature {
273
- opacity: 0.75;
274
- background-color: #fafafa;
275
- }
276
-
277
- .inactive-feature .ant-card-meta-title {
278
- color: #999;
279
- }
280
-
281
- .empty-data {
282
- text-align: center;
283
- padding: 48px 0;
284
- background-color: #f9f9f9;
285
- border-radius: 8px;
286
- margin: 24px 0;
287
- }
288
-
289
- .loading {
290
- text-align: center;
291
- padding: 48px 0;
292
- }
293
-
294
- .mock-data-header {
295
- display: flex;
296
- justify-content: space-between;
297
- align-items: center;
298
- margin-bottom: 20px;
299
- }
300
-
301
- .mock-data-header h2 {
302
- font-size: 18px;
303
- margin: 0;
304
- color: #1890ff;
305
- }
306
-
307
- .add-mock-btn {
308
- background-color: #1890ff;
309
- color: white;
310
- border: none;
311
- border-radius: 4px;
312
- padding: 8px 16px;
313
- cursor: pointer;
314
- transition: background-color 0.3s;
315
- }
316
-
317
- .add-mock-btn:hover {
318
- background-color: #40a9ff;
319
- }
320
-
321
- .mock-editor {
322
- background-color: #f9f9f9;
323
- border-radius: 8px;
324
- padding: 20px;
325
- margin-bottom: 20px;
326
- }
327
-
328
- .mock-form {
329
- display: flex;
330
- flex-direction: column;
331
- gap: 15px;
332
- }
333
-
334
- .form-row {
335
- display: flex;
336
- gap: 15px;
337
- }
338
-
339
- .method-select {
340
- width: 120px;
341
- }
342
-
343
- .path-input {
344
- flex: 1;
345
- }
346
-
347
- .form-group {
348
- display: flex;
349
- flex-direction: column;
350
- gap: 5px;
351
- }
352
-
353
- .form-group label {
354
- font-weight: 500;
355
- color: #333;
356
- }
357
-
358
- .form-group input,
359
- .form-group select,
360
- .form-group textarea {
361
- padding: 8px 12px;
362
- border: 1px solid #d9d9d9;
363
- border-radius: 4px;
364
- font-size: 14px;
365
- transition: border-color 0.3s;
366
- font-family: inherit;
367
- }
368
-
369
- .form-group textarea {
370
- font-family: monospace;
371
- resize: vertical;
372
- min-height: 150px;
373
- }
374
-
375
- .form-group input:focus,
376
- .form-group select:focus,
377
- .form-group textarea:focus {
378
- border-color: #40a9ff;
379
- outline: none;
380
- box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
381
- }
382
-
383
- .form-actions {
384
- display: flex;
385
- justify-content: flex-end;
386
- gap: 10px;
387
- margin-top: 10px;
388
- }
389
-
390
- .cancel-btn {
391
- padding: 8px 16px;
392
- background-color: #f5f5f5;
393
- border: 1px solid #d9d9d9;
394
- border-radius: 4px;
395
- cursor: pointer;
396
- transition: all 0.3s;
397
- }
398
-
399
- .cancel-btn:hover {
400
- background-color: #e6e6e6;
401
- }
402
-
403
- .save-btn {
404
- padding: 8px 16px;
405
- background-color: #1890ff;
406
- color: white;
407
- border: none;
408
- border-radius: 4px;
409
- cursor: pointer;
410
- transition: background-color 0.3s;
411
- }
412
-
413
- .save-btn:hover {
414
- background-color: #40a9ff;
415
- }
416
-
417
- .mock-table {
418
- width: 100%;
419
- border-collapse: collapse;
420
- }
421
-
422
- .mock-table th,
423
- .mock-table td {
424
- padding: 12px 15px;
425
- text-align: left;
426
- border-bottom: 1px solid #eee;
427
- }
428
-
429
- .mock-table th {
430
- font-weight: 500;
431
- color: #666;
432
- background-color: #f9f9f9;
433
- }
434
-
435
- .mock-table tr.inactive {
436
- color: #999;
437
- background-color: #f9f9f9;
438
- }
439
-
440
- .mock-table tr:hover {
441
- background-color: #f5f5f5;
442
- }
443
-
444
- .toggle-switch {
445
- position: relative;
446
- display: inline-block;
447
- width: 40px;
448
- height: 20px;
449
- }
450
-
451
- .toggle-switch input {
452
- opacity: 0;
453
- width: 0;
454
- height: 0;
455
- }
456
-
457
- .toggle-slider {
458
- position: absolute;
459
- cursor: pointer;
460
- top: 0;
461
- left: 0;
462
- right: 0;
463
- bottom: 0;
464
- background-color: #ccc;
465
- transition: .4s;
466
- border-radius: 34px;
467
- }
468
-
469
- .toggle-slider:before {
470
- position: absolute;
471
- content: "";
472
- height: 16px;
473
- width: 16px;
474
- left: 2px;
475
- bottom: 2px;
476
- background-color: white;
477
- transition: .4s;
478
- border-radius: 50%;
479
- }
480
-
481
- input:checked + .toggle-slider {
482
- background-color: #1890ff;
483
- }
484
-
485
- input:checked + .toggle-slider:before {
486
- transform: translateX(20px);
487
- }
488
-
489
- .edit-btn,
490
- .delete-btn {
491
- padding: 5px 10px;
492
- border: none;
493
- border-radius: 4px;
494
- cursor: pointer;
495
- font-size: 13px;
496
- margin-right: 5px;
497
- }
498
-
499
- .edit-btn {
500
- background-color: #f0f7ff;
501
- color: #1890ff;
502
- }
503
-
504
- .delete-btn {
505
- background-color: #fff0f0;
506
- color: #ff4d4f;
507
- }
508
-
509
- .edit-btn:hover {
510
- background-color: #e6f7ff;
511
- }
512
-
513
- .delete-btn:hover {
514
- background-color: #ffd4d4;
515
- }
516
-
517
- .empty-list {
518
- text-align: center;
519
- padding: 30px;
520
- color: #999;
521
- font-style: italic;
522
- background-color: #f9f9f9;
523
- border-radius: 4px;
524
- }
525
-
526
- .page-header {
527
- display: flex;
528
- justify-content: space-between;
529
- align-items: center;
530
- margin-bottom: 24px;
531
- padding-bottom: 16px;
532
- border-bottom: 1px solid #f0f0f0;
533
- }
534
-
535
- .page-header h1 {
536
- font-size: 24px;
537
- font-weight: 600;
538
- color: #1890ff;
539
- margin: 0;
540
- }
541
-
542
- .header-actions {
543
- display: flex;
544
- gap: 12px;
545
- }
546
-
547
- .add-button, .import-button {
548
- height: 36px;
549
- padding: 0 16px;
550
- border-radius: 4px;
551
- cursor: pointer;
552
- font-size: 14px;
553
- display: flex;
554
- align-items: center;
555
- justify-content: center;
556
- border: none;
557
- font-weight: 500;
558
- transition: all 0.3s;
559
- }
560
-
561
- .add-button {
562
- background-color: #1890ff;
563
- color: white;
564
- }
565
-
566
- .add-button:hover {
567
- background-color: #40a9ff;
568
- box-shadow: 0 4px 12px rgba(24, 144, 255, 0.2);
569
- }
570
-
571
- .import-button {
572
- background-color: #52c41a;
573
- color: white;
574
- }
575
-
576
- .import-button:hover {
577
- background-color: #73d13d;
578
- box-shadow: 0 4px 12px rgba(82, 196, 26, 0.2);
579
- }
580
-
581
- .feature-list-container {
582
- background-color: white;
583
- border-radius: 4px;
584
- box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
585
- overflow: hidden;
586
- }
587
-
588
- .feature-table {
589
- width: 100%;
590
- border-collapse: collapse;
591
- }
592
-
593
- .feature-table th,
594
- .feature-table td {
595
- padding: 12px 16px;
596
- text-align: left;
597
- border-bottom: 1px solid #f0f0f0;
598
- }
599
-
600
- .feature-table th {
601
- background-color: #fafafa;
602
- color: #8c8c8c;
603
- font-weight: 500;
604
- font-size: 14px;
605
- }
606
-
607
- .feature-table tr:hover {
608
- background-color: #fafafa;
609
- }
610
-
611
- .feature-table tr.inactive {
612
- color: #a6a6a6;
613
- background-color: #f9f9f9;
614
- }
615
-
616
- .action-buttons {
617
- display: flex;
618
- gap: 8px;
619
- }
620
-
621
- .edit-button,
622
- .delete-button,
623
- .interface-button,
624
- .export-button {
625
- border: none;
626
- border-radius: 4px;
627
- padding: 4px 8px;
628
- cursor: pointer;
629
- font-size: 12px;
630
- }
631
-
632
- .interface-button {
633
- background-color: #e6f7ff;
634
- color: #1890ff;
635
- }
636
-
637
- .interface-button:hover {
638
- background-color: #bae7ff;
639
- }
640
-
641
- .export-button {
642
- background-color: #f6ffed;
643
- color: #52c41a;
644
- }
645
-
646
- .export-button:hover {
647
- background-color: #d9f7be;
648
- }
649
-
650
- .edit-button {
651
- background-color: #f0f5ff;
652
- color: #597ef7;
653
- }
654
-
655
- .edit-button:hover {
656
- background-color: #d6e4ff;
657
- }
658
-
659
- .delete-button {
660
- background-color: #fff1f0;
661
- color: #f5222d;
662
- }
663
-
664
- .delete-button:hover {
665
- background-color: #ffccc7;
666
- }
667
-
668
- /* 切换开关样式 */
669
- .switch {
670
- position: relative;
671
- display: inline-block;
672
- width: 36px;
673
- height: 20px;
674
- }
675
-
676
- .switch input {
677
- opacity: 0;
678
- width: 0;
679
- height: 0;
680
- }
681
-
682
- .slider {
683
- position: absolute;
684
- cursor: pointer;
685
- top: 0;
686
- left: 0;
687
- right: 0;
688
- bottom: 0;
689
- background-color: #ccc;
690
- transition: .4s;
691
- border-radius: 20px;
692
- }
693
-
694
- .slider:before {
695
- position: absolute;
696
- content: "";
697
- height: 16px;
698
- width: 16px;
699
- left: 2px;
700
- bottom: 2px;
701
- background-color: white;
702
- transition: .4s;
703
- border-radius: 50%;
704
- }
705
-
706
- input:checked + .slider {
707
- background-color: #1890ff;
708
- }
709
-
710
- input:checked + .slider:before {
711
- transform: translateX(16px);
712
- }
713
-
714
- /* 空数据样式 */
715
- .empty-data {
716
- display: flex;
717
- flex-direction: column;
718
- align-items: center;
719
- justify-content: center;
720
- padding: 60px 0;
721
- color: #8c8c8c;
722
- }
723
-
724
- .empty-icon {
725
- font-size: 48px;
726
- margin-bottom: 16px;
727
- color: #d9d9d9;
728
- }
729
-
730
- .empty-text {
731
- font-size: 16px;
732
- margin-bottom: 24px;
733
- color: #8c8c8c;
734
- }
735
-
736
- .empty-actions {
737
- display: flex;
738
- gap: 16px;
739
- }
740
-
741
- .create-button, .import-button-large {
742
- height: 36px;
743
- padding: 0 20px;
744
- border-radius: 4px;
745
- cursor: pointer;
746
- font-size: 14px;
747
- border: none;
748
- display: flex;
749
- align-items: center;
750
- justify-content: center;
751
- }
752
-
753
- .create-button {
754
- background-color: #1890ff;
755
- color: white;
756
- }
757
-
758
- .create-button:hover {
759
- background-color: #40a9ff;
760
- }
761
-
762
- .import-button-large {
763
- background-color: #52c41a;
764
- color: white;
765
- }
766
-
767
- .import-button-large:hover {
768
- background-color: #73d13d;
769
- }
770
-
771
- /* 模态框样式 */
772
- .modal-overlay {
773
- position: fixed;
774
- top: 0;
775
- left: 0;
776
- right: 0;
777
- bottom: 0;
778
- background-color: rgba(0, 0, 0, 0.5);
779
- display: flex;
780
- align-items: center;
781
- justify-content: center;
782
- z-index: 1000;
783
- animation: fadeIn 0.3s;
784
- }
785
-
786
- .modal {
787
- background-color: white;
788
- border-radius: 8px;
789
- box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
790
- width: 500px;
791
- max-width: 90%;
792
- max-height: 90vh;
793
- overflow-y: auto;
794
- animation: slideIn 0.3s;
795
- }
796
-
797
- @keyframes fadeIn {
798
- from {
799
- opacity: 0;
800
- }
801
- to {
802
- opacity: 1;
803
- }
804
- }
805
-
806
- @keyframes slideIn {
807
- from {
808
- transform: translateY(-20px);
809
- opacity: 0;
810
- }
811
- to {
812
- transform: translateY(0);
813
- opacity: 1;
814
- }
815
- }
816
-
817
- .modal-header {
818
- display: flex;
819
- justify-content: space-between;
820
- align-items: center;
821
- padding: 16px 24px;
822
- border-bottom: 1px solid #f0f0f0;
823
- }
824
-
825
- .modal-header h2 {
826
- margin: 0;
827
- font-size: 18px;
828
- font-weight: 600;
829
- color: #1890ff;
830
- }
831
-
832
- .close-button {
833
- background: none;
834
- border: none;
835
- font-size: 20px;
836
- color: #999;
837
- cursor: pointer;
838
- width: 32px;
839
- height: 32px;
840
- display: flex;
841
- align-items: center;
842
- justify-content: center;
843
- border-radius: 50%;
844
- transition: all 0.3s;
845
- }
846
-
847
- .close-button:hover {
848
- background-color: #f5f5f5;
849
- color: #555;
850
- }
851
-
852
- .feature-form {
853
- padding: 24px;
854
- }
855
-
856
- .form-group {
857
- margin-bottom: 20px;
858
- }
859
-
860
- .form-group label {
861
- display: block;
862
- margin-bottom: 8px;
863
- font-weight: 500;
864
- color: #333;
865
- }
866
-
867
- .checkbox-label {
868
- display: flex;
869
- align-items: center;
870
- gap: 8px;
871
- font-weight: 500;
872
- color: #333;
873
- cursor: pointer;
874
- }
875
-
876
- .form-group input[type="text"] {
877
- width: 100%;
878
- height: 40px;
879
- padding: 0 12px;
880
- border: 1px solid #d9d9d9;
881
- border-radius: 4px;
882
- font-size: 14px;
883
- transition: all 0.3s;
884
- }
885
-
886
- .form-group input[type="text"]:focus {
887
- border-color: #40a9ff;
888
- box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
889
- outline: none;
890
- }
891
-
892
- .form-group input[type="checkbox"] {
893
- width: 16px;
894
- height: 16px;
895
- margin: 0;
896
- }
897
-
898
- .form-actions {
899
- display: flex;
900
- justify-content: flex-end;
901
- gap: 12px;
902
- margin-top: 24px;
903
- }
904
-
905
- .cancel-button {
906
- height: 40px;
907
- padding: 0 16px;
908
- background-color: white;
909
- border: 1px solid #d9d9d9;
910
- border-radius: 4px;
911
- cursor: pointer;
912
- font-size: 14px;
913
- transition: all 0.3s;
914
- }
915
-
916
- .cancel-button:hover {
917
- background-color: #f5f5f5;
918
- }
919
-
920
- .submit-button {
921
- height: 40px;
922
- padding: 0 24px;
923
- background-color: #1890ff;
924
- color: white;
925
- border: none;
926
- border-radius: 4px;
927
- cursor: pointer;
928
- font-size: 14px;
929
- transition: all 0.3s;
930
- }
931
-
932
- .submit-button:hover {
933
- background-color: #40a9ff;
934
- }
935
-
936
- /* 加载中样式 */
937
- /* 加载状态样式 */
938
- .loading-state {
939
- display: flex;
940
- flex-direction: column;
941
- align-items: center;
942
- justify-content: center;
943
- height: 300px;
944
- gap: 16px;
945
- }
946
-
947
- .loading-text {
948
- color: #8c8c8c;
949
- font-size: 16px;
950
- }
951
-
952
- /* 空状态样式 */
953
- .custom-empty {
954
- padding: 60px 20px;
955
- }
956
-
957
- .empty-image {
958
- margin-bottom: 16px;
959
- }
960
-
961
- .empty-description {
962
- margin-bottom: 24px;
963
- }
964
-
965
- .empty-title {
966
- font-size: 16px;
967
- font-weight: 500;
968
- color: #262626;
969
- margin-bottom: 8px;
970
- }
971
-
972
- .empty-subtitle {
973
- font-size: 14px;
974
- color: #8c8c8c;
975
- line-height: 1.5;
976
- }
977
-
978
- .empty-actions {
979
- display: flex;
980
- gap: 12px;
981
- justify-content: center;
982
- flex-wrap: wrap;
983
- }
984
-
985
- /* 分页组件样式 */
986
- .pagination-wrapper {
987
- margin-top: 32px;
988
- padding-top: 24px;
989
- border-top: 1px solid #f0f0f0;
990
- display: flex;
991
- justify-content: center;
992
- }
993
-
994
- .custom-pagination {
995
- display: flex;
996
- justify-content: center;
997
- }
998
-
999
- .custom-pagination .ant-pagination-total-text {
1000
- color: #8c8c8c;
1001
- font-size: 14px;
1002
- }
1003
-
1004
- /* 响应式调整 */
1005
- @media (max-width: 768px) {
1006
- .mock-data-container {
1007
- padding: 16px;
1008
- }
1009
-
1010
- .page-title-bar {
1011
- flex-direction: column;
1012
- align-items: flex-start;
1013
- gap: 16px;
1014
- }
1015
-
1016
- .page-actions {
1017
- width: 100%;
1018
- justify-content: flex-start;
1019
- }
1020
-
1021
- .stats-section {
1022
- justify-content: space-around;
1023
- gap: 16px;
1024
- }
1025
-
1026
- .control-group {
1027
- justify-content: flex-start;
1028
- }
1029
-
1030
- .control-panel-card .ant-card-body {
1031
- padding: 16px;
1032
- }
1033
-
1034
- .feature-list-card .ant-card-body {
1035
- padding: 16px;
1036
- }
1037
-
1038
- .feature-card-content {
1039
- height: auto;
1040
- }
1041
-
1042
- .form-actions {
1043
- flex-direction: column;
1044
- }
1045
-
1046
- .cancel-button, .submit-button {
1047
- width: 100%;
1048
- }
1049
-
1050
- .empty-actions {
1051
- flex-direction: column;
1052
- align-items: center;
1053
- }
1054
-
1055
- .empty-actions .ant-btn {
1056
- width: 200px;
1057
- }
1058
- }
1059
-
1060
- @media (max-width: 576px) {
1061
- .stats-section {
1062
- flex-direction: column;
1063
- gap: 12px;
1064
- align-items: stretch;
1065
- }
1066
-
1067
- .stats-item {
1068
- flex-direction: row;
1069
- justify-content: space-between;
1070
- align-items: center;
1071
- padding: 8px 12px;
1072
- background: #fafafa;
1073
- border-radius: 6px;
1074
- }
1075
-
1076
- .stats-number {
1077
- font-size: 20px;
1078
- }
1079
-
1080
- .stats-label {
1081
- font-size: 13px;
1082
- }
1083
-
1084
- .control-group {
1085
- flex-direction: column;
1086
- align-items: flex-start;
1087
- gap: 8px;
1088
- }
1089
-
1090
- .page-info {
1091
- order: -1;
1092
- font-weight: 500;
1093
- }
1094
- }
1095
-
1096
- /* 修复功能模块状态标记(ribbon)与按钮的重叠问题 */
1097
- .ant-ribbon.ant-ribbon-placement-end {
1098
- top: 5px; /* 向下调整 ribbon 位置 */
1099
- right: 0px;
1100
- z-index: 5;
1101
- }
1102
-
1103
- /* 确保功能卡片右上角有足够空间容纳 ribbon */
1104
- .ant-card-extra {
1105
- margin-right: 70px; /* 为 ribbon 提供足够空间 */
1106
- }
1107
-
1108
- /* 当屏幕宽度较小时调整 ribbon 位置 */
1109
- @media (max-width: 576px) {
1110
- .ant-ribbon.ant-ribbon-placement-end {
1111
- top: 3px;
1112
- z-index: 5;
1113
- }
1114
-
1115
- .ant-card-extra {
1116
- margin-right: 60px;
1117
- }
1118
- }
1119
-
1120
- /* 视图切换控制样式 */
1121
- .view-mode-controls {
1122
- display: flex;
1123
- justify-content: flex-end;
1124
- align-items: center;
1125
- }
1126
-
1127
- .view-mode-controls .ant-btn-group {
1128
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
1129
- }
1130
-
1131
- /* 列表视图样式 */
1132
- .feature-list-card .ant-table-wrapper {
1133
- margin-top: 0;
1134
- }
1135
-
1136
- .feature-list-card .ant-table {
1137
- font-size: 14px;
1138
- }
1139
-
1140
- .feature-list-card .ant-table-thead > tr > th {
1141
- background-color: #fafafa;
1142
- font-weight: 600;
1143
- color: #262626;
1144
- padding: 16px;
1145
- }
1146
-
1147
- .feature-list-card .ant-table-tbody > tr > td {
1148
- padding: 16px;
1149
- }
1150
-
1151
- .feature-list-card .ant-table-tbody > tr:hover {
1152
- background-color: #f5f5f5;
1153
- }
1154
-
1155
- .feature-list-card .ant-table-tbody > tr.inactive-row {
1156
- background-color: #fafafa;
1157
- opacity: 0.7;
1158
- }
1159
-
1160
- .feature-list-card .ant-table-tbody > tr.inactive-row:hover {
1161
- background-color: #f0f0f0;
1162
- }
1163
-
1164
- /* 列表视图中的操作按钮样式 */
1165
- .feature-list-card .ant-btn-link {
1166
- padding: 4px 8px;
1167
- height: auto;
1168
- }
1169
-
1170
- /* 响应式调整 */
1171
- @media (max-width: 768px) {
1172
- .view-mode-controls {
1173
- justify-content: center;
1174
- margin-top: 12px;
1175
- }
1176
-
1177
- .feature-list-card .ant-table {
1178
- font-size: 13px;
1179
- }
1180
-
1181
- .feature-list-card .ant-table-thead > tr > th,
1182
- .feature-list-card .ant-table-tbody > tr > td {
1183
- padding: 12px 8px;
1184
- }
1185
- }