@pactor-app/skills 1.24.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.
Files changed (80) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +40 -0
  3. package/package.json +26 -0
  4. package/pactor/SKILL.md +373 -0
  5. package/pactor/references/dsl-authoring.md +448 -0
  6. package/prd-to-app/SKILL.md +75 -0
  7. package/prd-to-app/references/acceptance-checklist.md +47 -0
  8. package/prd-to-app/references/component-mapping.md +41 -0
  9. package/prd-to-app/references/mock-data-routes.md +66 -0
  10. package/prd-to-app/references/page-templates.md +274 -0
  11. package/prd-to-app/references/project-structure.md +89 -0
  12. package/prd-to-app/references/theme-and-style.md +41 -0
  13. package/prd-to-app/template/README.md +26 -0
  14. package/prd-to-app/template/app/[[...slug]]/page.tsx +7 -0
  15. package/prd-to-app/template/app/api/auth/login/route.ts +32 -0
  16. package/prd-to-app/template/app/api/auth/logout/route.ts +22 -0
  17. package/prd-to-app/template/app/api/data/[...parts]/route.ts +118 -0
  18. package/prd-to-app/template/app/api/public/pages/[id]/route.ts +40 -0
  19. package/prd-to-app/template/app/api/sitemap/route.ts +21 -0
  20. package/prd-to-app/template/app/api/users/route.ts +57 -0
  21. package/prd-to-app/template/app/favicon.ico +0 -0
  22. package/prd-to-app/template/app/globals.css +248 -0
  23. package/prd-to-app/template/app/layout.tsx +49 -0
  24. package/prd-to-app/template/app/login.css +122 -0
  25. package/prd-to-app/template/eslint.config.mjs +18 -0
  26. package/prd-to-app/template/next-env.d.ts +7 -0
  27. package/prd-to-app/template/next.config.js +32 -0
  28. package/prd-to-app/template/package.json +34 -0
  29. package/prd-to-app/template/pnpm-lock.yaml +6854 -0
  30. package/prd-to-app/template/pnpm-workspace.yaml +7 -0
  31. package/prd-to-app/template/postcss.config.mjs +7 -0
  32. package/prd-to-app/template/public/file.svg +1 -0
  33. package/prd-to-app/template/public/globe.svg +1 -0
  34. package/prd-to-app/template/public/next.svg +1 -0
  35. package/prd-to-app/template/public/skins/chenwunaifu.css +111 -0
  36. package/prd-to-app/template/public/skins/taijingshenlin.css +109 -0
  37. package/prd-to-app/template/public/skins/xuanzhimoyun.css +110 -0
  38. package/prd-to-app/template/public/vercel.svg +1 -0
  39. package/prd-to-app/template/public/window.svg +1 -0
  40. package/prd-to-app/template/scripts/build.mjs +35 -0
  41. package/prd-to-app/template/src/pactor/App.tsx +55 -0
  42. package/prd-to-app/template/src/pactor/actions.ts +438 -0
  43. package/prd-to-app/template/src/pactor/components/card-links.tsx +86 -0
  44. package/prd-to-app/template/src/pactor/components/chip-filter.tsx +89 -0
  45. package/prd-to-app/template/src/pactor/components/chip-node.tsx +46 -0
  46. package/prd-to-app/template/src/pactor/components/debug-chat.tsx +189 -0
  47. package/prd-to-app/template/src/pactor/components/index.ts +28 -0
  48. package/prd-to-app/template/src/pactor/components/log-status.tsx +64 -0
  49. package/prd-to-app/template/src/pactor/components/status-badge.tsx +46 -0
  50. package/prd-to-app/template/src/pactor/components/theme-switcher.tsx +136 -0
  51. package/prd-to-app/template/src/pactor/config.ts +28 -0
  52. package/prd-to-app/template/src/pactor/mocks/audit-mock.ts +403 -0
  53. package/prd-to-app/template/src/pactor/mocks/call-logs-mock.ts +875 -0
  54. package/prd-to-app/template/src/pactor/mocks/client-debug-mock.ts +188 -0
  55. package/prd-to-app/template/src/pactor/mocks/client-templates-mock.ts +497 -0
  56. package/prd-to-app/template/src/pactor/mocks/clients-mock.ts +483 -0
  57. package/prd-to-app/template/src/pactor/mocks/costs-mock.ts +406 -0
  58. package/prd-to-app/template/src/pactor/mocks/dashboard-mock.ts +192 -0
  59. package/prd-to-app/template/src/pactor/mocks/model-debug-mock.ts +144 -0
  60. package/prd-to-app/template/src/pactor/mocks/models-mock.ts +799 -0
  61. package/prd-to-app/template/src/pactor/mocks/ops-usage-mock.ts +806 -0
  62. package/prd-to-app/template/src/pactor/mocks/providers-mock.ts +424 -0
  63. package/prd-to-app/template/src/pactor/mocks/routes-mock.ts +604 -0
  64. package/prd-to-app/template/src/pactor/services.ts +185 -0
  65. package/prd-to-app/template/src/pactor/skin.ts +52 -0
  66. package/prd-to-app/template/src/server/accounts.ts +63 -0
  67. package/prd-to-app/template/src/server/cors.ts +34 -0
  68. package/prd-to-app/template/src/server/sitemap.ts +176 -0
  69. package/prd-to-app/template/src/server/yaml/common/dashboard.yaml +498 -0
  70. package/prd-to-app/template/src/server/yaml/common/login.yaml +84 -0
  71. package/prd-to-app/template/src/server/yaml/provider/provider-create.yaml +340 -0
  72. package/prd-to-app/template/src/server/yaml/provider/provider-detail.yaml +780 -0
  73. package/prd-to-app/template/src/server/yaml/provider/provider-edit.yaml +366 -0
  74. package/prd-to-app/template/src/server/yaml/provider/provider-list.yaml +1989 -0
  75. package/prd-to-app/template/src/server/yaml/route/route-create.yaml +511 -0
  76. package/prd-to-app/template/src/server/yaml/route/route-detail.yaml +610 -0
  77. package/prd-to-app/template/src/server/yaml/route/route-edit.yaml +809 -0
  78. package/prd-to-app/template/src/server/yaml/route/route-list.yaml +1793 -0
  79. package/prd-to-app/template/src/server/yaml/sitemap.yaml +250 -0
  80. package/prd-to-app/template/tsconfig.json +34 -0
@@ -0,0 +1,1989 @@
1
+ dsl: "1.0"
2
+ page:
3
+ id: provider-list
4
+ title: 供应商
5
+ name: providerList
6
+ description: 模型资产 / Provider:上游 AI 供应商端点管理(卡片式列表)
7
+ state:
8
+ keyword: ""
9
+ statusChip: all
10
+ typeChips: []
11
+ dataSources:
12
+ providers:
13
+ type: http
14
+ autoLoad: true
15
+ request:
16
+ method: GET
17
+ url: /api/data/providers
18
+ params:
19
+ keyword: ${state.keyword}
20
+ status: ${state.statusChip}
21
+ types: ${state.typeChips}
22
+ body:
23
+ type: Page
24
+ children:
25
+ - type: Breadcrumb
26
+ props:
27
+ items:
28
+ - label: 模型资产
29
+ - label: Provider
30
+ - type: Flex
31
+ props:
32
+ align: baseline
33
+ gap: middle
34
+ children:
35
+ - type: Typography
36
+ props:
37
+ variant: h3
38
+ text: 供应商
39
+ - type: Typography
40
+ props:
41
+ variant: muted
42
+ text: 上游 AI 供应商端点。导入模板后,请填入你的 API Key。
43
+ - type: Card
44
+ children:
45
+ - type: Flex
46
+ props:
47
+ align: center
48
+ gap: middle
49
+ children:
50
+ - type: Flex
51
+ props:
52
+ align: center
53
+ gap: small
54
+ className: h-9 rounded-md border bg-background px-3
55
+ style:
56
+ flex: 1
57
+ children:
58
+ - type: Icon
59
+ props:
60
+ name: search
61
+ className: text-muted-foreground
62
+ - type: Input
63
+ props:
64
+ value: ${state.keyword}
65
+ placeholder: 搜索供应商、ID、端点或能力
66
+ className: border-0 bg-transparent px-0 shadow-none focus-visible:ring-0
67
+ style:
68
+ flex: 1
69
+ events:
70
+ onChange:
71
+ - action: setState
72
+ params:
73
+ keyword: ${event}
74
+ - action: reload
75
+ params:
76
+ dataSource: providers
77
+ - type: Text
78
+ props:
79
+ text: 显示 ${data.providers.items.length} / ${data.providers.total}
80
+ type: secondary
81
+ className: tabular-nums text-sm
82
+ - type: Flex
83
+ props:
84
+ align: center
85
+ gap: small
86
+ style:
87
+ flexWrap: wrap
88
+ className: mt-2
89
+ children:
90
+ - type: ChipFilter
91
+ props:
92
+ mode: single
93
+ value: ${state.statusChip}
94
+ items: ${data.providers.filters.status}
95
+ events:
96
+ onChange:
97
+ - action: setState
98
+ params:
99
+ statusChip: ${event}
100
+ - action: reload
101
+ params:
102
+ dataSource: providers
103
+ - type: ChipFilter
104
+ props:
105
+ mode: multi
106
+ value: ${state.typeChips}
107
+ items: ${data.providers.filters.types}
108
+ events:
109
+ onChange:
110
+ - action: setState
111
+ params:
112
+ typeChips: ${event}
113
+ - action: reload
114
+ params:
115
+ dataSource: providers
116
+ - type: Grid
117
+ props:
118
+ columns: 3
119
+ gap: 16
120
+ children:
121
+ - type: Card
122
+ props:
123
+ className: border-dashed h-full bg-(--muted) border-2
124
+ border-[color-mix(in_srgb,var(--foreground)_30%,transparent)]
125
+ children:
126
+ - type: Flex
127
+ props:
128
+ direction: vertical
129
+ gap: large
130
+ align: stretch
131
+ children:
132
+ - type: Flex
133
+ props:
134
+ align: center
135
+ gap: middle
136
+ children:
137
+ - type: Flex
138
+ props:
139
+ align: center
140
+ justify: center
141
+ className: size-10 shrink-0 rounded-full bg-primary
142
+ children:
143
+ - type: Icon
144
+ props:
145
+ name: plus
146
+ size: 28
147
+ color: var(--primary-foreground)
148
+ - type: Flex
149
+ props:
150
+ direction: vertical
151
+ gap: 2
152
+ children:
153
+ - type: Text
154
+ props:
155
+ text: 添加供应商
156
+ strong: true
157
+ className: text-base
158
+ - type: Text
159
+ props:
160
+ text: 从模板导入,或新建空白供应商
161
+ type: secondary
162
+ className: text-sm
163
+ - type: Flex
164
+ props:
165
+ align: center
166
+ gap: middle
167
+ children:
168
+ - type: Button
169
+ props:
170
+ text: 导入
171
+ icon: download
172
+ variant: default
173
+ style:
174
+ flex: 1
175
+ events:
176
+ onClick:
177
+ - action: message
178
+ params:
179
+ messageType: info
180
+ text: 模板导入流程(演示:选择内置/社区模板 → 生成草稿 → 引导填密钥)
181
+ - type: Button
182
+ props:
183
+ text: 新建
184
+ icon: plus
185
+ variant: primary
186
+ style:
187
+ flex: 1
188
+ events:
189
+ onClick:
190
+ - action: navigate
191
+ params:
192
+ to: /providers/new
193
+ - type: ProviderCardLink
194
+ when: ${data.providers.items[0] != null}
195
+ props:
196
+ href: /providers/${data.providers.items[0].code}
197
+ children:
198
+ - type: Card
199
+ props:
200
+ className: h-full provider-card relative
201
+ children:
202
+ - type: Flex
203
+ props:
204
+ align: center
205
+ gap: middle
206
+ children:
207
+ - type: Flex
208
+ props:
209
+ align: center
210
+ justify: center
211
+ className: size-14 shrink-0 rounded-full bg-(--muted)
212
+ children:
213
+ - type: Icon
214
+ props:
215
+ name: ${data.providers.items[0].icon}
216
+ size: 28
217
+ - type: Flex
218
+ props:
219
+ direction: vertical
220
+ gap: 0
221
+ style:
222
+ alignItems: flex-start
223
+ flex: 1
224
+ children:
225
+ - type: Button
226
+ props:
227
+ text: ${data.providers.items[0].displayName}
228
+ variant: link
229
+ className: p-0 font-semibold text-base
230
+ events:
231
+ onClick:
232
+ - action: navigate
233
+ params:
234
+ to: /providers/${data.providers.items[0].code}
235
+ - type: Flex
236
+ props:
237
+ justify: space-between
238
+ align: center
239
+ style:
240
+ width: 100%
241
+ marginTop: 2
242
+ children:
243
+ - type: TextLink
244
+ props:
245
+ text: ${data.providers.items[0].routeSummary}
246
+ className: text-sm text-(--muted-foreground) underline-offset-4 hover:underline
247
+ events:
248
+ onClick:
249
+ - action: navigate
250
+ params:
251
+ to: /routes
252
+ - type: Text
253
+ when: ${data.providers.items[0].keyStatus != 'configured'}
254
+ props:
255
+ text: "${data.providers.items[0].keyStatus == 'pending' ? '● 待填密钥' : '● 无密钥'}"
256
+ type: "${data.providers.items[0].keyStatus == 'pending' ? 'warning' : 'danger'}"
257
+ className: text-xs
258
+ - type: Text
259
+ when: ${data.providers.items[0].keyStatus == 'configured'}
260
+ props:
261
+ text: ""
262
+ - type: Flex
263
+ props:
264
+ align: center
265
+ gap: 2
266
+ className: absolute right-3 top-3 provider-card-actions
267
+ children:
268
+ - type: Tooltip
269
+ props:
270
+ content: "${data.providers.items[0].status == 'enabled' ? '停用' : '启用'}"
271
+ children:
272
+ - type: Button
273
+ props:
274
+ variant: text
275
+ size: small
276
+ className: size-6 p-0
277
+ children:
278
+ - type: StatusToggleIcon
279
+ props:
280
+ enabled: ${data.providers.items[0].status == 'enabled'}
281
+ events:
282
+ onClick:
283
+ - id: statusCfm
284
+ action: overlay.open
285
+ params:
286
+ overlay:
287
+ type: modal
288
+ title: "${data.providers.items[0].status == 'enabled' ? '确认停用 Provider' : '确认启用
289
+ Provider'}"
290
+ width: 480
291
+ content:
292
+ type: Flex
293
+ props:
294
+ direction: vertical
295
+ gap: middle
296
+ children:
297
+ - type: Text
298
+ props:
299
+ size: small
300
+ text: "${data.providers.items[0].status == 'enabled' ? '停用后,该 Provider 将无法被新建
301
+ Model / Target 引用。' : '启用后,该
302
+ Provider 可被 Model / Target 引用。'}"
303
+ - type: Flex
304
+ props:
305
+ direction: vertical
306
+ gap: small
307
+ children:
308
+ - type: Text
309
+ props:
310
+ text: 影响范围:
311
+ strong: true
312
+ - type: Text
313
+ props:
314
+ text: · Model:${data.providers.items[0].modelCount}
315
+ 个(${data.providers.items[0].enabledModelCount}
316
+ 个启用)
317
+ type: secondary
318
+ - type: Text
319
+ props:
320
+ text: · Route Target 引用:${data.providers.items[0].routes.total} 个
321
+ type: secondary
322
+ - type: Text
323
+ when: ${data.providers.items[0].status == 'enabled'}
324
+ props:
325
+ size: small
326
+ text: ⚠ 存在 ONLINE Target 引用时,建议先完成切换再停用。
327
+ type: warning
328
+ - type: Flex
329
+ props:
330
+ justify: end
331
+ gap: middle
332
+ children:
333
+ - type: Button
334
+ props:
335
+ text: 取消
336
+ events:
337
+ onClick:
338
+ - action: overlay.close
339
+ - type: Button
340
+ props:
341
+ text: "${data.providers.items[0].status == 'enabled' ? '确认停用' : '确认启用'}"
342
+ variant: primary
343
+ danger: ${data.providers.items[0].status == 'enabled'}
344
+ events:
345
+ onClick:
346
+ - action: overlay.close
347
+ params:
348
+ payload:
349
+ ok: true
350
+ - action: if
351
+ params:
352
+ condition: ${actions.statusCfm.ok}
353
+ then:
354
+ - action: message
355
+ params:
356
+ messageType: success
357
+ text: "${data.providers.items[0].status == 'enabled' ? '已停用' :
358
+ '已启用'}(演示:静态页面不落库)"
359
+ - type: Tooltip
360
+ props:
361
+ content: 编辑
362
+ children:
363
+ - type: Button
364
+ props:
365
+ icon: pencil
366
+ variant: text
367
+ size: small
368
+ className: size-6 p-0
369
+ events:
370
+ onClick:
371
+ - action: navigate
372
+ params:
373
+ to: /providers/${data.providers.items[0].code}/edit
374
+ - type: Tooltip
375
+ when: ${data.providers.items[0].keyStatus != 'configured'}
376
+ props:
377
+ content: 填写密钥
378
+ children:
379
+ - type: Button
380
+ props:
381
+ icon: key
382
+ variant: text
383
+ size: small
384
+ className: size-6 p-0
385
+ events:
386
+ onClick:
387
+ - action: navigate
388
+ params:
389
+ to: /providers/${data.providers.items[0].code}/edit
390
+ - type: Flex
391
+ props:
392
+ align: center
393
+ gap: small
394
+ style:
395
+ flexWrap: wrap
396
+ children:
397
+ - type: Badge
398
+ when: ${data.providers.items[0].capabilities[0] != null}
399
+ props:
400
+ text: ${data.providers.items[0].capabilities[0]}
401
+ variant: outline
402
+ - type: Badge
403
+ when: ${data.providers.items[0].capabilities[1] != null}
404
+ props:
405
+ text: ${data.providers.items[0].capabilities[1]}
406
+ variant: outline
407
+ - type: Badge
408
+ when: ${data.providers.items[0].capabilities[2] != null}
409
+ props:
410
+ text: ${data.providers.items[0].capabilities[2]}
411
+ variant: outline
412
+ - type: Text
413
+ when: ${data.providers.items[0].capabilities.length > 3}
414
+ props:
415
+ text: +${data.providers.items[0].capabilities.length - 3}
416
+ type: secondary
417
+ - type: ProviderCardLink
418
+ when: ${data.providers.items[1] != null}
419
+ props:
420
+ href: /providers/${data.providers.items[1].code}
421
+ children:
422
+ - type: Card
423
+ props:
424
+ className: h-full provider-card relative
425
+ children:
426
+ - type: Flex
427
+ props:
428
+ align: center
429
+ gap: middle
430
+ children:
431
+ - type: Flex
432
+ props:
433
+ align: center
434
+ justify: center
435
+ className: size-14 shrink-0 rounded-full bg-(--muted)
436
+ children:
437
+ - type: Icon
438
+ props:
439
+ name: ${data.providers.items[1].icon}
440
+ size: 28
441
+ - type: Flex
442
+ props:
443
+ direction: vertical
444
+ gap: 0
445
+ style:
446
+ alignItems: flex-start
447
+ flex: 1
448
+ children:
449
+ - type: Button
450
+ props:
451
+ text: ${data.providers.items[1].displayName}
452
+ variant: link
453
+ className: p-0 font-semibold text-base
454
+ events:
455
+ onClick:
456
+ - action: navigate
457
+ params:
458
+ to: /providers/${data.providers.items[1].code}
459
+ - type: Flex
460
+ props:
461
+ justify: space-between
462
+ align: center
463
+ style:
464
+ width: 100%
465
+ marginTop: 2
466
+ children:
467
+ - type: TextLink
468
+ props:
469
+ text: ${data.providers.items[1].routeSummary}
470
+ className: text-sm text-(--muted-foreground) underline-offset-4 hover:underline
471
+ events:
472
+ onClick:
473
+ - action: navigate
474
+ params:
475
+ to: /routes
476
+ - type: Text
477
+ when: ${data.providers.items[1].keyStatus != 'configured'}
478
+ props:
479
+ text: "${data.providers.items[1].keyStatus == 'pending' ? '● 待填密钥' : '● 无密钥'}"
480
+ type: "${data.providers.items[1].keyStatus == 'pending' ? 'warning' : 'danger'}"
481
+ className: text-xs
482
+ - type: Text
483
+ when: ${data.providers.items[1].keyStatus == 'configured'}
484
+ props:
485
+ text: ""
486
+ - type: Flex
487
+ props:
488
+ align: center
489
+ gap: 2
490
+ className: absolute right-3 top-3 provider-card-actions
491
+ children:
492
+ - type: Tooltip
493
+ props:
494
+ content: "${data.providers.items[1].status == 'enabled' ? '停用' : '启用'}"
495
+ children:
496
+ - type: Button
497
+ props:
498
+ variant: text
499
+ size: small
500
+ className: size-6 p-0
501
+ children:
502
+ - type: StatusToggleIcon
503
+ props:
504
+ enabled: ${data.providers.items[1].status == 'enabled'}
505
+ events:
506
+ onClick:
507
+ - id: statusCfm
508
+ action: overlay.open
509
+ params:
510
+ overlay:
511
+ type: modal
512
+ title: "${data.providers.items[1].status == 'enabled' ? '确认停用 Provider' : '确认启用
513
+ Provider'}"
514
+ width: 480
515
+ content:
516
+ type: Flex
517
+ props:
518
+ direction: vertical
519
+ gap: middle
520
+ children:
521
+ - type: Text
522
+ props:
523
+ size: small
524
+ text: "${data.providers.items[1].status == 'enabled' ? '停用后,该 Provider 将无法被新建
525
+ Model / Target 引用。' : '启用后,该
526
+ Provider 可被 Model / Target 引用。'}"
527
+ - type: Flex
528
+ props:
529
+ direction: vertical
530
+ gap: small
531
+ children:
532
+ - type: Text
533
+ props:
534
+ text: 影响范围:
535
+ strong: true
536
+ - type: Text
537
+ props:
538
+ text: · Model:${data.providers.items[1].modelCount}
539
+ 个(${data.providers.items[1].enabledModelCount}
540
+ 个启用)
541
+ type: secondary
542
+ - type: Text
543
+ props:
544
+ text: · Route Target 引用:${data.providers.items[1].routes.total} 个
545
+ type: secondary
546
+ - type: Text
547
+ when: ${data.providers.items[1].status == 'enabled'}
548
+ props:
549
+ size: small
550
+ text: ⚠ 存在 ONLINE Target 引用时,建议先完成切换再停用。
551
+ type: warning
552
+ - type: Flex
553
+ props:
554
+ justify: end
555
+ gap: middle
556
+ children:
557
+ - type: Button
558
+ props:
559
+ text: 取消
560
+ events:
561
+ onClick:
562
+ - action: overlay.close
563
+ - type: Button
564
+ props:
565
+ text: "${data.providers.items[1].status == 'enabled' ? '确认停用' : '确认启用'}"
566
+ variant: primary
567
+ danger: ${data.providers.items[1].status == 'enabled'}
568
+ events:
569
+ onClick:
570
+ - action: overlay.close
571
+ params:
572
+ payload:
573
+ ok: true
574
+ - action: if
575
+ params:
576
+ condition: ${actions.statusCfm.ok}
577
+ then:
578
+ - action: message
579
+ params:
580
+ messageType: success
581
+ text: "${data.providers.items[1].status == 'enabled' ? '已停用' :
582
+ '已启用'}(演示:静态页面不落库)"
583
+ - type: Tooltip
584
+ props:
585
+ content: 编辑
586
+ children:
587
+ - type: Button
588
+ props:
589
+ icon: pencil
590
+ variant: text
591
+ size: small
592
+ className: size-6 p-0
593
+ events:
594
+ onClick:
595
+ - action: navigate
596
+ params:
597
+ to: /providers/${data.providers.items[1].code}/edit
598
+ - type: Tooltip
599
+ when: ${data.providers.items[1].keyStatus != 'configured'}
600
+ props:
601
+ content: 填写密钥
602
+ children:
603
+ - type: Button
604
+ props:
605
+ icon: key
606
+ variant: text
607
+ size: small
608
+ className: size-6 p-0
609
+ events:
610
+ onClick:
611
+ - action: navigate
612
+ params:
613
+ to: /providers/${data.providers.items[1].code}/edit
614
+ - type: Flex
615
+ props:
616
+ align: center
617
+ gap: small
618
+ style:
619
+ flexWrap: wrap
620
+ children:
621
+ - type: Badge
622
+ when: ${data.providers.items[1].capabilities[0] != null}
623
+ props:
624
+ text: ${data.providers.items[1].capabilities[0]}
625
+ variant: outline
626
+ - type: Badge
627
+ when: ${data.providers.items[1].capabilities[1] != null}
628
+ props:
629
+ text: ${data.providers.items[1].capabilities[1]}
630
+ variant: outline
631
+ - type: Badge
632
+ when: ${data.providers.items[1].capabilities[2] != null}
633
+ props:
634
+ text: ${data.providers.items[1].capabilities[2]}
635
+ variant: outline
636
+ - type: Text
637
+ when: ${data.providers.items[1].capabilities.length > 3}
638
+ props:
639
+ text: +${data.providers.items[1].capabilities.length - 3}
640
+ type: secondary
641
+ - type: ProviderCardLink
642
+ when: ${data.providers.items[2] != null}
643
+ props:
644
+ href: /providers/${data.providers.items[2].code}
645
+ children:
646
+ - type: Card
647
+ props:
648
+ className: h-full provider-card relative
649
+ children:
650
+ - type: Flex
651
+ props:
652
+ align: center
653
+ gap: middle
654
+ children:
655
+ - type: Flex
656
+ props:
657
+ align: center
658
+ justify: center
659
+ className: size-14 shrink-0 rounded-full bg-(--muted)
660
+ children:
661
+ - type: Icon
662
+ props:
663
+ name: ${data.providers.items[2].icon}
664
+ size: 28
665
+ - type: Flex
666
+ props:
667
+ direction: vertical
668
+ gap: 0
669
+ style:
670
+ alignItems: flex-start
671
+ flex: 1
672
+ children:
673
+ - type: Button
674
+ props:
675
+ text: ${data.providers.items[2].displayName}
676
+ variant: link
677
+ className: p-0 font-semibold text-base
678
+ events:
679
+ onClick:
680
+ - action: navigate
681
+ params:
682
+ to: /providers/${data.providers.items[2].code}
683
+ - type: Flex
684
+ props:
685
+ justify: space-between
686
+ align: center
687
+ style:
688
+ width: 100%
689
+ marginTop: 2
690
+ children:
691
+ - type: TextLink
692
+ props:
693
+ text: ${data.providers.items[2].routeSummary}
694
+ className: text-sm text-(--muted-foreground) underline-offset-4 hover:underline
695
+ events:
696
+ onClick:
697
+ - action: navigate
698
+ params:
699
+ to: /routes
700
+ - type: Text
701
+ when: ${data.providers.items[2].keyStatus != 'configured'}
702
+ props:
703
+ text: "${data.providers.items[2].keyStatus == 'pending' ? '● 待填密钥' : '● 无密钥'}"
704
+ type: "${data.providers.items[2].keyStatus == 'pending' ? 'warning' : 'danger'}"
705
+ className: text-xs
706
+ - type: Text
707
+ when: ${data.providers.items[2].keyStatus == 'configured'}
708
+ props:
709
+ text: ""
710
+ - type: Flex
711
+ props:
712
+ align: center
713
+ gap: 2
714
+ className: absolute right-3 top-3 provider-card-actions
715
+ children:
716
+ - type: Tooltip
717
+ props:
718
+ content: "${data.providers.items[2].status == 'enabled' ? '停用' : '启用'}"
719
+ children:
720
+ - type: Button
721
+ props:
722
+ variant: text
723
+ size: small
724
+ className: size-6 p-0
725
+ children:
726
+ - type: StatusToggleIcon
727
+ props:
728
+ enabled: ${data.providers.items[2].status == 'enabled'}
729
+ events:
730
+ onClick:
731
+ - id: statusCfm
732
+ action: overlay.open
733
+ params:
734
+ overlay:
735
+ type: modal
736
+ title: "${data.providers.items[2].status == 'enabled' ? '确认停用 Provider' : '确认启用
737
+ Provider'}"
738
+ width: 480
739
+ content:
740
+ type: Flex
741
+ props:
742
+ direction: vertical
743
+ gap: middle
744
+ children:
745
+ - type: Text
746
+ props:
747
+ size: small
748
+ text: "${data.providers.items[2].status == 'enabled' ? '停用后,该 Provider 将无法被新建
749
+ Model / Target 引用。' : '启用后,该
750
+ Provider 可被 Model / Target 引用。'}"
751
+ - type: Flex
752
+ props:
753
+ direction: vertical
754
+ gap: small
755
+ children:
756
+ - type: Text
757
+ props:
758
+ text: 影响范围:
759
+ strong: true
760
+ - type: Text
761
+ props:
762
+ text: · Model:${data.providers.items[2].modelCount}
763
+ 个(${data.providers.items[2].enabledModelCount}
764
+ 个启用)
765
+ type: secondary
766
+ - type: Text
767
+ props:
768
+ text: · Route Target 引用:${data.providers.items[2].routes.total} 个
769
+ type: secondary
770
+ - type: Text
771
+ when: ${data.providers.items[2].status == 'enabled'}
772
+ props:
773
+ size: small
774
+ text: ⚠ 存在 ONLINE Target 引用时,建议先完成切换再停用。
775
+ type: warning
776
+ - type: Flex
777
+ props:
778
+ justify: end
779
+ gap: middle
780
+ children:
781
+ - type: Button
782
+ props:
783
+ text: 取消
784
+ events:
785
+ onClick:
786
+ - action: overlay.close
787
+ - type: Button
788
+ props:
789
+ text: "${data.providers.items[2].status == 'enabled' ? '确认停用' : '确认启用'}"
790
+ variant: primary
791
+ danger: ${data.providers.items[2].status == 'enabled'}
792
+ events:
793
+ onClick:
794
+ - action: overlay.close
795
+ params:
796
+ payload:
797
+ ok: true
798
+ - action: if
799
+ params:
800
+ condition: ${actions.statusCfm.ok}
801
+ then:
802
+ - action: message
803
+ params:
804
+ messageType: success
805
+ text: "${data.providers.items[2].status == 'enabled' ? '已停用' :
806
+ '已启用'}(演示:静态页面不落库)"
807
+ - type: Tooltip
808
+ props:
809
+ content: 编辑
810
+ children:
811
+ - type: Button
812
+ props:
813
+ icon: pencil
814
+ variant: text
815
+ size: small
816
+ className: size-6 p-0
817
+ events:
818
+ onClick:
819
+ - action: navigate
820
+ params:
821
+ to: /providers/${data.providers.items[2].code}/edit
822
+ - type: Tooltip
823
+ when: ${data.providers.items[2].keyStatus != 'configured'}
824
+ props:
825
+ content: 填写密钥
826
+ children:
827
+ - type: Button
828
+ props:
829
+ icon: key
830
+ variant: text
831
+ size: small
832
+ className: size-6 p-0
833
+ events:
834
+ onClick:
835
+ - action: navigate
836
+ params:
837
+ to: /providers/${data.providers.items[2].code}/edit
838
+ - type: Flex
839
+ props:
840
+ align: center
841
+ gap: small
842
+ style:
843
+ flexWrap: wrap
844
+ children:
845
+ - type: Badge
846
+ when: ${data.providers.items[2].capabilities[0] != null}
847
+ props:
848
+ text: ${data.providers.items[2].capabilities[0]}
849
+ variant: outline
850
+ - type: Badge
851
+ when: ${data.providers.items[2].capabilities[1] != null}
852
+ props:
853
+ text: ${data.providers.items[2].capabilities[1]}
854
+ variant: outline
855
+ - type: Badge
856
+ when: ${data.providers.items[2].capabilities[2] != null}
857
+ props:
858
+ text: ${data.providers.items[2].capabilities[2]}
859
+ variant: outline
860
+ - type: Text
861
+ when: ${data.providers.items[2].capabilities.length > 3}
862
+ props:
863
+ text: +${data.providers.items[2].capabilities.length - 3}
864
+ type: secondary
865
+ - type: ProviderCardLink
866
+ when: ${data.providers.items[3] != null}
867
+ props:
868
+ href: /providers/${data.providers.items[3].code}
869
+ children:
870
+ - type: Card
871
+ props:
872
+ className: h-full provider-card relative
873
+ children:
874
+ - type: Flex
875
+ props:
876
+ align: center
877
+ gap: middle
878
+ children:
879
+ - type: Flex
880
+ props:
881
+ align: center
882
+ justify: center
883
+ className: size-14 shrink-0 rounded-full bg-(--muted)
884
+ children:
885
+ - type: Icon
886
+ props:
887
+ name: ${data.providers.items[3].icon}
888
+ size: 28
889
+ - type: Flex
890
+ props:
891
+ direction: vertical
892
+ gap: 0
893
+ style:
894
+ alignItems: flex-start
895
+ flex: 1
896
+ children:
897
+ - type: Button
898
+ props:
899
+ text: ${data.providers.items[3].displayName}
900
+ variant: link
901
+ className: p-0 font-semibold text-base
902
+ events:
903
+ onClick:
904
+ - action: navigate
905
+ params:
906
+ to: /providers/${data.providers.items[3].code}
907
+ - type: Flex
908
+ props:
909
+ justify: space-between
910
+ align: center
911
+ style:
912
+ width: 100%
913
+ marginTop: 2
914
+ children:
915
+ - type: TextLink
916
+ props:
917
+ text: ${data.providers.items[3].routeSummary}
918
+ className: text-sm text-(--muted-foreground) underline-offset-4 hover:underline
919
+ events:
920
+ onClick:
921
+ - action: navigate
922
+ params:
923
+ to: /routes
924
+ - type: Text
925
+ when: ${data.providers.items[3].keyStatus != 'configured'}
926
+ props:
927
+ text: "${data.providers.items[3].keyStatus == 'pending' ? '● 待填密钥' : '● 无密钥'}"
928
+ type: "${data.providers.items[3].keyStatus == 'pending' ? 'warning' : 'danger'}"
929
+ className: text-xs
930
+ - type: Text
931
+ when: ${data.providers.items[3].keyStatus == 'configured'}
932
+ props:
933
+ text: ""
934
+ - type: Flex
935
+ props:
936
+ align: center
937
+ gap: 2
938
+ className: absolute right-3 top-3 provider-card-actions
939
+ children:
940
+ - type: Tooltip
941
+ props:
942
+ content: "${data.providers.items[3].status == 'enabled' ? '停用' : '启用'}"
943
+ children:
944
+ - type: Button
945
+ props:
946
+ variant: text
947
+ size: small
948
+ className: size-6 p-0
949
+ children:
950
+ - type: StatusToggleIcon
951
+ props:
952
+ enabled: ${data.providers.items[3].status == 'enabled'}
953
+ events:
954
+ onClick:
955
+ - id: statusCfm
956
+ action: overlay.open
957
+ params:
958
+ overlay:
959
+ type: modal
960
+ title: "${data.providers.items[3].status == 'enabled' ? '确认停用 Provider' : '确认启用
961
+ Provider'}"
962
+ width: 480
963
+ content:
964
+ type: Flex
965
+ props:
966
+ direction: vertical
967
+ gap: middle
968
+ children:
969
+ - type: Text
970
+ props:
971
+ size: small
972
+ text: "${data.providers.items[3].status == 'enabled' ? '停用后,该 Provider 将无法被新建
973
+ Model / Target 引用。' : '启用后,该
974
+ Provider 可被 Model / Target 引用。'}"
975
+ - type: Flex
976
+ props:
977
+ direction: vertical
978
+ gap: small
979
+ children:
980
+ - type: Text
981
+ props:
982
+ text: 影响范围:
983
+ strong: true
984
+ - type: Text
985
+ props:
986
+ text: · Model:${data.providers.items[3].modelCount}
987
+ 个(${data.providers.items[3].enabledModelCount}
988
+ 个启用)
989
+ type: secondary
990
+ - type: Text
991
+ props:
992
+ text: · Route Target 引用:${data.providers.items[3].routes.total} 个
993
+ type: secondary
994
+ - type: Text
995
+ when: ${data.providers.items[3].status == 'enabled'}
996
+ props:
997
+ size: small
998
+ text: ⚠ 存在 ONLINE Target 引用时,建议先完成切换再停用。
999
+ type: warning
1000
+ - type: Flex
1001
+ props:
1002
+ justify: end
1003
+ gap: middle
1004
+ children:
1005
+ - type: Button
1006
+ props:
1007
+ text: 取消
1008
+ events:
1009
+ onClick:
1010
+ - action: overlay.close
1011
+ - type: Button
1012
+ props:
1013
+ text: "${data.providers.items[3].status == 'enabled' ? '确认停用' : '确认启用'}"
1014
+ variant: primary
1015
+ danger: ${data.providers.items[3].status == 'enabled'}
1016
+ events:
1017
+ onClick:
1018
+ - action: overlay.close
1019
+ params:
1020
+ payload:
1021
+ ok: true
1022
+ - action: if
1023
+ params:
1024
+ condition: ${actions.statusCfm.ok}
1025
+ then:
1026
+ - action: message
1027
+ params:
1028
+ messageType: success
1029
+ text: "${data.providers.items[3].status == 'enabled' ? '已停用' :
1030
+ '已启用'}(演示:静态页面不落库)"
1031
+ - type: Tooltip
1032
+ props:
1033
+ content: 编辑
1034
+ children:
1035
+ - type: Button
1036
+ props:
1037
+ icon: pencil
1038
+ variant: text
1039
+ size: small
1040
+ className: size-6 p-0
1041
+ events:
1042
+ onClick:
1043
+ - action: navigate
1044
+ params:
1045
+ to: /providers/${data.providers.items[3].code}/edit
1046
+ - type: Tooltip
1047
+ when: ${data.providers.items[3].keyStatus != 'configured'}
1048
+ props:
1049
+ content: 填写密钥
1050
+ children:
1051
+ - type: Button
1052
+ props:
1053
+ icon: key
1054
+ variant: text
1055
+ size: small
1056
+ className: size-6 p-0
1057
+ events:
1058
+ onClick:
1059
+ - action: navigate
1060
+ params:
1061
+ to: /providers/${data.providers.items[3].code}/edit
1062
+ - type: Flex
1063
+ props:
1064
+ align: center
1065
+ gap: small
1066
+ style:
1067
+ flexWrap: wrap
1068
+ children:
1069
+ - type: Badge
1070
+ when: ${data.providers.items[3].capabilities[0] != null}
1071
+ props:
1072
+ text: ${data.providers.items[3].capabilities[0]}
1073
+ variant: outline
1074
+ - type: Badge
1075
+ when: ${data.providers.items[3].capabilities[1] != null}
1076
+ props:
1077
+ text: ${data.providers.items[3].capabilities[1]}
1078
+ variant: outline
1079
+ - type: Badge
1080
+ when: ${data.providers.items[3].capabilities[2] != null}
1081
+ props:
1082
+ text: ${data.providers.items[3].capabilities[2]}
1083
+ variant: outline
1084
+ - type: Text
1085
+ when: ${data.providers.items[3].capabilities.length > 3}
1086
+ props:
1087
+ text: +${data.providers.items[3].capabilities.length - 3}
1088
+ type: secondary
1089
+ - type: ProviderCardLink
1090
+ when: ${data.providers.items[4] != null}
1091
+ props:
1092
+ href: /providers/${data.providers.items[4].code}
1093
+ children:
1094
+ - type: Card
1095
+ props:
1096
+ className: h-full provider-card relative
1097
+ children:
1098
+ - type: Flex
1099
+ props:
1100
+ align: center
1101
+ gap: middle
1102
+ children:
1103
+ - type: Flex
1104
+ props:
1105
+ align: center
1106
+ justify: center
1107
+ className: size-14 shrink-0 rounded-full bg-(--muted)
1108
+ children:
1109
+ - type: Icon
1110
+ props:
1111
+ name: ${data.providers.items[4].icon}
1112
+ size: 28
1113
+ - type: Flex
1114
+ props:
1115
+ direction: vertical
1116
+ gap: 0
1117
+ style:
1118
+ alignItems: flex-start
1119
+ flex: 1
1120
+ children:
1121
+ - type: Button
1122
+ props:
1123
+ text: ${data.providers.items[4].displayName}
1124
+ variant: link
1125
+ className: p-0 font-semibold text-base
1126
+ events:
1127
+ onClick:
1128
+ - action: navigate
1129
+ params:
1130
+ to: /providers/${data.providers.items[4].code}
1131
+ - type: Flex
1132
+ props:
1133
+ justify: space-between
1134
+ align: center
1135
+ style:
1136
+ width: 100%
1137
+ marginTop: 2
1138
+ children:
1139
+ - type: TextLink
1140
+ props:
1141
+ text: ${data.providers.items[4].routeSummary}
1142
+ className: text-sm text-(--muted-foreground) underline-offset-4 hover:underline
1143
+ events:
1144
+ onClick:
1145
+ - action: navigate
1146
+ params:
1147
+ to: /routes
1148
+ - type: Text
1149
+ when: ${data.providers.items[4].keyStatus != 'configured'}
1150
+ props:
1151
+ text: "${data.providers.items[4].keyStatus == 'pending' ? '● 待填密钥' : '● 无密钥'}"
1152
+ type: "${data.providers.items[4].keyStatus == 'pending' ? 'warning' : 'danger'}"
1153
+ className: text-xs
1154
+ - type: Text
1155
+ when: ${data.providers.items[4].keyStatus == 'configured'}
1156
+ props:
1157
+ text: ""
1158
+ - type: Flex
1159
+ props:
1160
+ align: center
1161
+ gap: 2
1162
+ className: absolute right-3 top-3 provider-card-actions
1163
+ children:
1164
+ - type: Tooltip
1165
+ props:
1166
+ content: "${data.providers.items[4].status == 'enabled' ? '停用' : '启用'}"
1167
+ children:
1168
+ - type: Button
1169
+ props:
1170
+ variant: text
1171
+ size: small
1172
+ className: size-6 p-0
1173
+ children:
1174
+ - type: StatusToggleIcon
1175
+ props:
1176
+ enabled: ${data.providers.items[4].status == 'enabled'}
1177
+ events:
1178
+ onClick:
1179
+ - id: statusCfm
1180
+ action: overlay.open
1181
+ params:
1182
+ overlay:
1183
+ type: modal
1184
+ title: "${data.providers.items[4].status == 'enabled' ? '确认停用 Provider' : '确认启用
1185
+ Provider'}"
1186
+ width: 480
1187
+ content:
1188
+ type: Flex
1189
+ props:
1190
+ direction: vertical
1191
+ gap: middle
1192
+ children:
1193
+ - type: Text
1194
+ props:
1195
+ size: small
1196
+ text: "${data.providers.items[4].status == 'enabled' ? '停用后,该 Provider 将无法被新建
1197
+ Model / Target 引用。' : '启用后,该
1198
+ Provider 可被 Model / Target 引用。'}"
1199
+ - type: Flex
1200
+ props:
1201
+ direction: vertical
1202
+ gap: small
1203
+ children:
1204
+ - type: Text
1205
+ props:
1206
+ text: 影响范围:
1207
+ strong: true
1208
+ - type: Text
1209
+ props:
1210
+ text: · Model:${data.providers.items[4].modelCount}
1211
+ 个(${data.providers.items[4].enabledModelCount}
1212
+ 个启用)
1213
+ type: secondary
1214
+ - type: Text
1215
+ props:
1216
+ text: · Route Target 引用:${data.providers.items[4].routes.total} 个
1217
+ type: secondary
1218
+ - type: Text
1219
+ when: ${data.providers.items[4].status == 'enabled'}
1220
+ props:
1221
+ size: small
1222
+ text: ⚠ 存在 ONLINE Target 引用时,建议先完成切换再停用。
1223
+ type: warning
1224
+ - type: Flex
1225
+ props:
1226
+ justify: end
1227
+ gap: middle
1228
+ children:
1229
+ - type: Button
1230
+ props:
1231
+ text: 取消
1232
+ events:
1233
+ onClick:
1234
+ - action: overlay.close
1235
+ - type: Button
1236
+ props:
1237
+ text: "${data.providers.items[4].status == 'enabled' ? '确认停用' : '确认启用'}"
1238
+ variant: primary
1239
+ danger: ${data.providers.items[4].status == 'enabled'}
1240
+ events:
1241
+ onClick:
1242
+ - action: overlay.close
1243
+ params:
1244
+ payload:
1245
+ ok: true
1246
+ - action: if
1247
+ params:
1248
+ condition: ${actions.statusCfm.ok}
1249
+ then:
1250
+ - action: message
1251
+ params:
1252
+ messageType: success
1253
+ text: "${data.providers.items[4].status == 'enabled' ? '已停用' :
1254
+ '已启用'}(演示:静态页面不落库)"
1255
+ - type: Tooltip
1256
+ props:
1257
+ content: 编辑
1258
+ children:
1259
+ - type: Button
1260
+ props:
1261
+ icon: pencil
1262
+ variant: text
1263
+ size: small
1264
+ className: size-6 p-0
1265
+ events:
1266
+ onClick:
1267
+ - action: navigate
1268
+ params:
1269
+ to: /providers/${data.providers.items[4].code}/edit
1270
+ - type: Tooltip
1271
+ when: ${data.providers.items[4].keyStatus != 'configured'}
1272
+ props:
1273
+ content: 填写密钥
1274
+ children:
1275
+ - type: Button
1276
+ props:
1277
+ icon: key
1278
+ variant: text
1279
+ size: small
1280
+ className: size-6 p-0
1281
+ events:
1282
+ onClick:
1283
+ - action: navigate
1284
+ params:
1285
+ to: /providers/${data.providers.items[4].code}/edit
1286
+ - type: Flex
1287
+ props:
1288
+ align: center
1289
+ gap: small
1290
+ style:
1291
+ flexWrap: wrap
1292
+ children:
1293
+ - type: Badge
1294
+ when: ${data.providers.items[4].capabilities[0] != null}
1295
+ props:
1296
+ text: ${data.providers.items[4].capabilities[0]}
1297
+ variant: outline
1298
+ - type: Badge
1299
+ when: ${data.providers.items[4].capabilities[1] != null}
1300
+ props:
1301
+ text: ${data.providers.items[4].capabilities[1]}
1302
+ variant: outline
1303
+ - type: Badge
1304
+ when: ${data.providers.items[4].capabilities[2] != null}
1305
+ props:
1306
+ text: ${data.providers.items[4].capabilities[2]}
1307
+ variant: outline
1308
+ - type: Text
1309
+ when: ${data.providers.items[4].capabilities.length > 3}
1310
+ props:
1311
+ text: +${data.providers.items[4].capabilities.length - 3}
1312
+ type: secondary
1313
+ - type: ProviderCardLink
1314
+ when: ${data.providers.items[5] != null}
1315
+ props:
1316
+ href: /providers/${data.providers.items[5].code}
1317
+ children:
1318
+ - type: Card
1319
+ props:
1320
+ className: h-full provider-card relative
1321
+ children:
1322
+ - type: Flex
1323
+ props:
1324
+ align: center
1325
+ gap: middle
1326
+ children:
1327
+ - type: Flex
1328
+ props:
1329
+ align: center
1330
+ justify: center
1331
+ className: size-14 shrink-0 rounded-full bg-(--muted)
1332
+ children:
1333
+ - type: Icon
1334
+ props:
1335
+ name: ${data.providers.items[5].icon}
1336
+ size: 28
1337
+ - type: Flex
1338
+ props:
1339
+ direction: vertical
1340
+ gap: 0
1341
+ style:
1342
+ alignItems: flex-start
1343
+ flex: 1
1344
+ children:
1345
+ - type: Button
1346
+ props:
1347
+ text: ${data.providers.items[5].displayName}
1348
+ variant: link
1349
+ className: p-0 font-semibold text-base
1350
+ events:
1351
+ onClick:
1352
+ - action: navigate
1353
+ params:
1354
+ to: /providers/${data.providers.items[5].code}
1355
+ - type: Flex
1356
+ props:
1357
+ justify: space-between
1358
+ align: center
1359
+ style:
1360
+ width: 100%
1361
+ marginTop: 2
1362
+ children:
1363
+ - type: TextLink
1364
+ props:
1365
+ text: ${data.providers.items[5].routeSummary}
1366
+ className: text-sm text-(--muted-foreground) underline-offset-4 hover:underline
1367
+ events:
1368
+ onClick:
1369
+ - action: navigate
1370
+ params:
1371
+ to: /routes
1372
+ - type: Text
1373
+ when: ${data.providers.items[5].keyStatus != 'configured'}
1374
+ props:
1375
+ text: "${data.providers.items[5].keyStatus == 'pending' ? '● 待填密钥' : '● 无密钥'}"
1376
+ type: "${data.providers.items[5].keyStatus == 'pending' ? 'warning' : 'danger'}"
1377
+ className: text-xs
1378
+ - type: Text
1379
+ when: ${data.providers.items[5].keyStatus == 'configured'}
1380
+ props:
1381
+ text: ""
1382
+ - type: Flex
1383
+ props:
1384
+ align: center
1385
+ gap: 2
1386
+ className: absolute right-3 top-3 provider-card-actions
1387
+ children:
1388
+ - type: Tooltip
1389
+ props:
1390
+ content: "${data.providers.items[5].status == 'enabled' ? '停用' : '启用'}"
1391
+ children:
1392
+ - type: Button
1393
+ props:
1394
+ variant: text
1395
+ size: small
1396
+ className: size-6 p-0
1397
+ children:
1398
+ - type: StatusToggleIcon
1399
+ props:
1400
+ enabled: ${data.providers.items[5].status == 'enabled'}
1401
+ events:
1402
+ onClick:
1403
+ - id: statusCfm
1404
+ action: overlay.open
1405
+ params:
1406
+ overlay:
1407
+ type: modal
1408
+ title: "${data.providers.items[5].status == 'enabled' ? '确认停用 Provider' : '确认启用
1409
+ Provider'}"
1410
+ width: 480
1411
+ content:
1412
+ type: Flex
1413
+ props:
1414
+ direction: vertical
1415
+ gap: middle
1416
+ children:
1417
+ - type: Text
1418
+ props:
1419
+ size: small
1420
+ text: "${data.providers.items[5].status == 'enabled' ? '停用后,该 Provider 将无法被新建
1421
+ Model / Target 引用。' : '启用后,该
1422
+ Provider 可被 Model / Target 引用。'}"
1423
+ - type: Flex
1424
+ props:
1425
+ direction: vertical
1426
+ gap: small
1427
+ children:
1428
+ - type: Text
1429
+ props:
1430
+ text: 影响范围:
1431
+ strong: true
1432
+ - type: Text
1433
+ props:
1434
+ text: · Model:${data.providers.items[5].modelCount}
1435
+ 个(${data.providers.items[5].enabledModelCount}
1436
+ 个启用)
1437
+ type: secondary
1438
+ - type: Text
1439
+ props:
1440
+ text: · Route Target 引用:${data.providers.items[5].routes.total} 个
1441
+ type: secondary
1442
+ - type: Text
1443
+ when: ${data.providers.items[5].status == 'enabled'}
1444
+ props:
1445
+ size: small
1446
+ text: ⚠ 存在 ONLINE Target 引用时,建议先完成切换再停用。
1447
+ type: warning
1448
+ - type: Flex
1449
+ props:
1450
+ justify: end
1451
+ gap: middle
1452
+ children:
1453
+ - type: Button
1454
+ props:
1455
+ text: 取消
1456
+ events:
1457
+ onClick:
1458
+ - action: overlay.close
1459
+ - type: Button
1460
+ props:
1461
+ text: "${data.providers.items[5].status == 'enabled' ? '确认停用' : '确认启用'}"
1462
+ variant: primary
1463
+ danger: ${data.providers.items[5].status == 'enabled'}
1464
+ events:
1465
+ onClick:
1466
+ - action: overlay.close
1467
+ params:
1468
+ payload:
1469
+ ok: true
1470
+ - action: if
1471
+ params:
1472
+ condition: ${actions.statusCfm.ok}
1473
+ then:
1474
+ - action: message
1475
+ params:
1476
+ messageType: success
1477
+ text: "${data.providers.items[5].status == 'enabled' ? '已停用' :
1478
+ '已启用'}(演示:静态页面不落库)"
1479
+ - type: Tooltip
1480
+ props:
1481
+ content: 编辑
1482
+ children:
1483
+ - type: Button
1484
+ props:
1485
+ icon: pencil
1486
+ variant: text
1487
+ size: small
1488
+ className: size-6 p-0
1489
+ events:
1490
+ onClick:
1491
+ - action: navigate
1492
+ params:
1493
+ to: /providers/${data.providers.items[5].code}/edit
1494
+ - type: Tooltip
1495
+ when: ${data.providers.items[5].keyStatus != 'configured'}
1496
+ props:
1497
+ content: 填写密钥
1498
+ children:
1499
+ - type: Button
1500
+ props:
1501
+ icon: key
1502
+ variant: text
1503
+ size: small
1504
+ className: size-6 p-0
1505
+ events:
1506
+ onClick:
1507
+ - action: navigate
1508
+ params:
1509
+ to: /providers/${data.providers.items[5].code}/edit
1510
+ - type: Flex
1511
+ props:
1512
+ align: center
1513
+ gap: small
1514
+ style:
1515
+ flexWrap: wrap
1516
+ children:
1517
+ - type: Badge
1518
+ when: ${data.providers.items[5].capabilities[0] != null}
1519
+ props:
1520
+ text: ${data.providers.items[5].capabilities[0]}
1521
+ variant: outline
1522
+ - type: Badge
1523
+ when: ${data.providers.items[5].capabilities[1] != null}
1524
+ props:
1525
+ text: ${data.providers.items[5].capabilities[1]}
1526
+ variant: outline
1527
+ - type: Badge
1528
+ when: ${data.providers.items[5].capabilities[2] != null}
1529
+ props:
1530
+ text: ${data.providers.items[5].capabilities[2]}
1531
+ variant: outline
1532
+ - type: Text
1533
+ when: ${data.providers.items[5].capabilities.length > 3}
1534
+ props:
1535
+ text: +${data.providers.items[5].capabilities.length - 3}
1536
+ type: secondary
1537
+ - type: ProviderCardLink
1538
+ when: ${data.providers.items[6] != null}
1539
+ props:
1540
+ href: /providers/${data.providers.items[6].code}
1541
+ children:
1542
+ - type: Card
1543
+ props:
1544
+ className: h-full provider-card relative
1545
+ children:
1546
+ - type: Flex
1547
+ props:
1548
+ align: center
1549
+ gap: middle
1550
+ children:
1551
+ - type: Flex
1552
+ props:
1553
+ align: center
1554
+ justify: center
1555
+ className: size-14 shrink-0 rounded-full bg-(--muted)
1556
+ children:
1557
+ - type: Icon
1558
+ props:
1559
+ name: ${data.providers.items[6].icon}
1560
+ size: 28
1561
+ - type: Flex
1562
+ props:
1563
+ direction: vertical
1564
+ gap: 0
1565
+ style:
1566
+ alignItems: flex-start
1567
+ flex: 1
1568
+ children:
1569
+ - type: Button
1570
+ props:
1571
+ text: ${data.providers.items[6].displayName}
1572
+ variant: link
1573
+ className: p-0 font-semibold text-base
1574
+ events:
1575
+ onClick:
1576
+ - action: navigate
1577
+ params:
1578
+ to: /providers/${data.providers.items[6].code}
1579
+ - type: Flex
1580
+ props:
1581
+ justify: space-between
1582
+ align: center
1583
+ style:
1584
+ width: 100%
1585
+ marginTop: 2
1586
+ children:
1587
+ - type: TextLink
1588
+ props:
1589
+ text: ${data.providers.items[6].routeSummary}
1590
+ className: text-sm text-(--muted-foreground) underline-offset-4 hover:underline
1591
+ events:
1592
+ onClick:
1593
+ - action: navigate
1594
+ params:
1595
+ to: /routes
1596
+ - type: Text
1597
+ when: ${data.providers.items[6].keyStatus != 'configured'}
1598
+ props:
1599
+ text: "${data.providers.items[6].keyStatus == 'pending' ? '● 待填密钥' : '● 无密钥'}"
1600
+ type: "${data.providers.items[6].keyStatus == 'pending' ? 'warning' : 'danger'}"
1601
+ className: text-xs
1602
+ - type: Text
1603
+ when: ${data.providers.items[6].keyStatus == 'configured'}
1604
+ props:
1605
+ text: ""
1606
+ - type: Flex
1607
+ props:
1608
+ align: center
1609
+ gap: 2
1610
+ className: absolute right-3 top-3 provider-card-actions
1611
+ children:
1612
+ - type: Tooltip
1613
+ props:
1614
+ content: "${data.providers.items[6].status == 'enabled' ? '停用' : '启用'}"
1615
+ children:
1616
+ - type: Button
1617
+ props:
1618
+ variant: text
1619
+ size: small
1620
+ className: size-6 p-0
1621
+ children:
1622
+ - type: StatusToggleIcon
1623
+ props:
1624
+ enabled: ${data.providers.items[6].status == 'enabled'}
1625
+ events:
1626
+ onClick:
1627
+ - id: statusCfm
1628
+ action: overlay.open
1629
+ params:
1630
+ overlay:
1631
+ type: modal
1632
+ title: "${data.providers.items[6].status == 'enabled' ? '确认停用 Provider' : '确认启用
1633
+ Provider'}"
1634
+ width: 480
1635
+ content:
1636
+ type: Flex
1637
+ props:
1638
+ direction: vertical
1639
+ gap: middle
1640
+ children:
1641
+ - type: Text
1642
+ props:
1643
+ size: small
1644
+ text: "${data.providers.items[6].status == 'enabled' ? '停用后,该 Provider 将无法被新建
1645
+ Model / Target 引用。' : '启用后,该
1646
+ Provider 可被 Model / Target 引用。'}"
1647
+ - type: Flex
1648
+ props:
1649
+ direction: vertical
1650
+ gap: small
1651
+ children:
1652
+ - type: Text
1653
+ props:
1654
+ text: 影响范围:
1655
+ strong: true
1656
+ - type: Text
1657
+ props:
1658
+ text: · Model:${data.providers.items[6].modelCount}
1659
+ 个(${data.providers.items[6].enabledModelCount}
1660
+ 个启用)
1661
+ type: secondary
1662
+ - type: Text
1663
+ props:
1664
+ text: · Route Target 引用:${data.providers.items[6].routes.total} 个
1665
+ type: secondary
1666
+ - type: Text
1667
+ when: ${data.providers.items[6].status == 'enabled'}
1668
+ props:
1669
+ size: small
1670
+ text: ⚠ 存在 ONLINE Target 引用时,建议先完成切换再停用。
1671
+ type: warning
1672
+ - type: Flex
1673
+ props:
1674
+ justify: end
1675
+ gap: middle
1676
+ children:
1677
+ - type: Button
1678
+ props:
1679
+ text: 取消
1680
+ events:
1681
+ onClick:
1682
+ - action: overlay.close
1683
+ - type: Button
1684
+ props:
1685
+ text: "${data.providers.items[6].status == 'enabled' ? '确认停用' : '确认启用'}"
1686
+ variant: primary
1687
+ danger: ${data.providers.items[6].status == 'enabled'}
1688
+ events:
1689
+ onClick:
1690
+ - action: overlay.close
1691
+ params:
1692
+ payload:
1693
+ ok: true
1694
+ - action: if
1695
+ params:
1696
+ condition: ${actions.statusCfm.ok}
1697
+ then:
1698
+ - action: message
1699
+ params:
1700
+ messageType: success
1701
+ text: "${data.providers.items[6].status == 'enabled' ? '已停用' :
1702
+ '已启用'}(演示:静态页面不落库)"
1703
+ - type: Tooltip
1704
+ props:
1705
+ content: 编辑
1706
+ children:
1707
+ - type: Button
1708
+ props:
1709
+ icon: pencil
1710
+ variant: text
1711
+ size: small
1712
+ className: size-6 p-0
1713
+ events:
1714
+ onClick:
1715
+ - action: navigate
1716
+ params:
1717
+ to: /providers/${data.providers.items[6].code}/edit
1718
+ - type: Tooltip
1719
+ when: ${data.providers.items[6].keyStatus != 'configured'}
1720
+ props:
1721
+ content: 填写密钥
1722
+ children:
1723
+ - type: Button
1724
+ props:
1725
+ icon: key
1726
+ variant: text
1727
+ size: small
1728
+ className: size-6 p-0
1729
+ events:
1730
+ onClick:
1731
+ - action: navigate
1732
+ params:
1733
+ to: /providers/${data.providers.items[6].code}/edit
1734
+ - type: Flex
1735
+ props:
1736
+ align: center
1737
+ gap: small
1738
+ style:
1739
+ flexWrap: wrap
1740
+ children:
1741
+ - type: Badge
1742
+ when: ${data.providers.items[6].capabilities[0] != null}
1743
+ props:
1744
+ text: ${data.providers.items[6].capabilities[0]}
1745
+ variant: outline
1746
+ - type: Badge
1747
+ when: ${data.providers.items[6].capabilities[1] != null}
1748
+ props:
1749
+ text: ${data.providers.items[6].capabilities[1]}
1750
+ variant: outline
1751
+ - type: Badge
1752
+ when: ${data.providers.items[6].capabilities[2] != null}
1753
+ props:
1754
+ text: ${data.providers.items[6].capabilities[2]}
1755
+ variant: outline
1756
+ - type: Text
1757
+ when: ${data.providers.items[6].capabilities.length > 3}
1758
+ props:
1759
+ text: +${data.providers.items[6].capabilities.length - 3}
1760
+ type: secondary
1761
+ - type: ProviderCardLink
1762
+ when: ${data.providers.items[7] != null}
1763
+ props:
1764
+ href: /providers/${data.providers.items[7].code}
1765
+ children:
1766
+ - type: Card
1767
+ props:
1768
+ className: h-full provider-card relative
1769
+ children:
1770
+ - type: Flex
1771
+ props:
1772
+ align: center
1773
+ gap: middle
1774
+ children:
1775
+ - type: Flex
1776
+ props:
1777
+ align: center
1778
+ justify: center
1779
+ className: size-14 shrink-0 rounded-full bg-(--muted)
1780
+ children:
1781
+ - type: Icon
1782
+ props:
1783
+ name: ${data.providers.items[7].icon}
1784
+ size: 28
1785
+ - type: Flex
1786
+ props:
1787
+ direction: vertical
1788
+ gap: 0
1789
+ style:
1790
+ alignItems: flex-start
1791
+ flex: 1
1792
+ children:
1793
+ - type: Button
1794
+ props:
1795
+ text: ${data.providers.items[7].displayName}
1796
+ variant: link
1797
+ className: p-0 font-semibold text-base
1798
+ events:
1799
+ onClick:
1800
+ - action: navigate
1801
+ params:
1802
+ to: /providers/${data.providers.items[7].code}
1803
+ - type: Flex
1804
+ props:
1805
+ justify: space-between
1806
+ align: center
1807
+ style:
1808
+ width: 100%
1809
+ marginTop: 2
1810
+ children:
1811
+ - type: TextLink
1812
+ props:
1813
+ text: ${data.providers.items[7].routeSummary}
1814
+ className: text-sm text-(--muted-foreground) underline-offset-4 hover:underline
1815
+ events:
1816
+ onClick:
1817
+ - action: navigate
1818
+ params:
1819
+ to: /routes
1820
+ - type: Text
1821
+ when: ${data.providers.items[7].keyStatus != 'configured'}
1822
+ props:
1823
+ text: "${data.providers.items[7].keyStatus == 'pending' ? '● 待填密钥' : '● 无密钥'}"
1824
+ type: "${data.providers.items[7].keyStatus == 'pending' ? 'warning' : 'danger'}"
1825
+ className: text-xs
1826
+ - type: Text
1827
+ when: ${data.providers.items[7].keyStatus == 'configured'}
1828
+ props:
1829
+ text: ""
1830
+ - type: Flex
1831
+ props:
1832
+ align: center
1833
+ gap: 2
1834
+ className: absolute right-3 top-3 provider-card-actions
1835
+ children:
1836
+ - type: Tooltip
1837
+ props:
1838
+ content: "${data.providers.items[7].status == 'enabled' ? '停用' : '启用'}"
1839
+ children:
1840
+ - type: Button
1841
+ props:
1842
+ variant: text
1843
+ size: small
1844
+ className: size-6 p-0
1845
+ children:
1846
+ - type: StatusToggleIcon
1847
+ props:
1848
+ enabled: ${data.providers.items[7].status == 'enabled'}
1849
+ events:
1850
+ onClick:
1851
+ - id: statusCfm
1852
+ action: overlay.open
1853
+ params:
1854
+ overlay:
1855
+ type: modal
1856
+ title: "${data.providers.items[7].status == 'enabled' ? '确认停用 Provider' : '确认启用
1857
+ Provider'}"
1858
+ width: 480
1859
+ content:
1860
+ type: Flex
1861
+ props:
1862
+ direction: vertical
1863
+ gap: middle
1864
+ children:
1865
+ - type: Text
1866
+ props:
1867
+ size: small
1868
+ text: "${data.providers.items[7].status == 'enabled' ? '停用后,该 Provider 将无法被新建
1869
+ Model / Target 引用。' : '启用后,该
1870
+ Provider 可被 Model / Target 引用。'}"
1871
+ - type: Flex
1872
+ props:
1873
+ direction: vertical
1874
+ gap: small
1875
+ children:
1876
+ - type: Text
1877
+ props:
1878
+ text: 影响范围:
1879
+ strong: true
1880
+ - type: Text
1881
+ props:
1882
+ text: · Model:${data.providers.items[7].modelCount}
1883
+ 个(${data.providers.items[7].enabledModelCount}
1884
+ 个启用)
1885
+ type: secondary
1886
+ - type: Text
1887
+ props:
1888
+ text: · Route Target 引用:${data.providers.items[7].routes.total} 个
1889
+ type: secondary
1890
+ - type: Text
1891
+ when: ${data.providers.items[7].status == 'enabled'}
1892
+ props:
1893
+ size: small
1894
+ text: ⚠ 存在 ONLINE Target 引用时,建议先完成切换再停用。
1895
+ type: warning
1896
+ - type: Flex
1897
+ props:
1898
+ justify: end
1899
+ gap: middle
1900
+ children:
1901
+ - type: Button
1902
+ props:
1903
+ text: 取消
1904
+ events:
1905
+ onClick:
1906
+ - action: overlay.close
1907
+ - type: Button
1908
+ props:
1909
+ text: "${data.providers.items[7].status == 'enabled' ? '确认停用' : '确认启用'}"
1910
+ variant: primary
1911
+ danger: ${data.providers.items[7].status == 'enabled'}
1912
+ events:
1913
+ onClick:
1914
+ - action: overlay.close
1915
+ params:
1916
+ payload:
1917
+ ok: true
1918
+ - action: if
1919
+ params:
1920
+ condition: ${actions.statusCfm.ok}
1921
+ then:
1922
+ - action: message
1923
+ params:
1924
+ messageType: success
1925
+ text: "${data.providers.items[7].status == 'enabled' ? '已停用' :
1926
+ '已启用'}(演示:静态页面不落库)"
1927
+ - type: Tooltip
1928
+ props:
1929
+ content: 编辑
1930
+ children:
1931
+ - type: Button
1932
+ props:
1933
+ icon: pencil
1934
+ variant: text
1935
+ size: small
1936
+ className: size-6 p-0
1937
+ events:
1938
+ onClick:
1939
+ - action: navigate
1940
+ params:
1941
+ to: /providers/${data.providers.items[7].code}/edit
1942
+ - type: Tooltip
1943
+ when: ${data.providers.items[7].keyStatus != 'configured'}
1944
+ props:
1945
+ content: 填写密钥
1946
+ children:
1947
+ - type: Button
1948
+ props:
1949
+ icon: key
1950
+ variant: text
1951
+ size: small
1952
+ className: size-6 p-0
1953
+ events:
1954
+ onClick:
1955
+ - action: navigate
1956
+ params:
1957
+ to: /providers/${data.providers.items[7].code}/edit
1958
+ - type: Flex
1959
+ props:
1960
+ align: center
1961
+ gap: small
1962
+ style:
1963
+ flexWrap: wrap
1964
+ children:
1965
+ - type: Badge
1966
+ when: ${data.providers.items[7].capabilities[0] != null}
1967
+ props:
1968
+ text: ${data.providers.items[7].capabilities[0]}
1969
+ variant: outline
1970
+ - type: Badge
1971
+ when: ${data.providers.items[7].capabilities[1] != null}
1972
+ props:
1973
+ text: ${data.providers.items[7].capabilities[1]}
1974
+ variant: outline
1975
+ - type: Badge
1976
+ when: ${data.providers.items[7].capabilities[2] != null}
1977
+ props:
1978
+ text: ${data.providers.items[7].capabilities[2]}
1979
+ variant: outline
1980
+ - type: Text
1981
+ when: ${data.providers.items[7].capabilities.length > 3}
1982
+ props:
1983
+ text: +${data.providers.items[7].capabilities.length - 3}
1984
+ type: secondary
1985
+ - type: Empty
1986
+ when: ${data.providers.items != null && data.providers.items.length == 0}
1987
+ props:
1988
+ title: 无匹配供应商
1989
+ description: 调整搜索关键词或筛选条件后重试