|
538 | 538 | {{ t('admin.accounts.headerOverride.bulkReplaceHint') }} |
539 | 539 | </p> |
540 | 540 |
|
541 | | - <div v-if="headerOverrideRows.length > 0" class="space-y-2"> |
542 | | - <div |
543 | | - v-for="(row, index) in headerOverrideRows" |
544 | | - :key="getHeaderOverrideRowKey(row)" |
545 | | - class="flex items-center gap-2" |
546 | | - > |
547 | | - <input |
548 | | - v-model="row.name" |
549 | | - type="text" |
550 | | - class="input flex-1" |
551 | | - :placeholder="t('admin.accounts.headerOverride.namePlaceholder')" |
552 | | - /> |
553 | | - <input |
554 | | - v-model="row.value" |
555 | | - type="text" |
556 | | - class="input flex-1" |
557 | | - :placeholder="t('admin.accounts.headerOverride.valuePlaceholder')" |
558 | | - /> |
559 | | - <button |
560 | | - type="button" |
561 | | - class="rounded-lg p-2 text-red-500 transition-colors hover:bg-red-50 hover:text-red-600 dark:hover:bg-red-900/20" |
562 | | - @click="removeHeaderOverrideRow(index)" |
563 | | - > |
564 | | - <svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"> |
565 | | - <path |
566 | | - stroke-linecap="round" |
567 | | - stroke-linejoin="round" |
568 | | - stroke-width="2" |
569 | | - d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" |
570 | | - /> |
571 | | - </svg> |
572 | | - </button> |
573 | | - </div> |
574 | | - </div> |
575 | | - |
576 | | - <button |
577 | | - type="button" |
578 | | - class="w-full rounded-lg border-2 border-dashed border-gray-300 px-4 py-2 text-gray-600 transition-colors hover:border-gray-400 hover:text-gray-700 dark:border-dark-500 dark:text-gray-400 dark:hover:border-dark-400 dark:hover:text-gray-300" |
579 | | - @click="addHeaderOverrideRow" |
580 | | - > |
581 | | - <svg class="mr-1 inline h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"> |
582 | | - <path |
583 | | - stroke-linecap="round" |
584 | | - stroke-linejoin="round" |
585 | | - stroke-width="2" |
586 | | - d="M12 4v16m8-8H4" |
587 | | - /> |
588 | | - </svg> |
589 | | - {{ t('admin.accounts.headerOverride.addRow') }} |
590 | | - </button> |
591 | | - |
592 | | - <div class="flex flex-wrap gap-2"> |
593 | | - <button |
594 | | - v-if="headerOverrideTemplatePlatform" |
595 | | - type="button" |
596 | | - class="rounded-lg bg-primary-50 px-3 py-1 text-xs text-primary-700 transition-colors hover:bg-primary-100 dark:bg-primary-900/30 dark:text-primary-400 dark:hover:bg-primary-900/50" |
597 | | - @click="fillHeaderOverrideTemplate" |
598 | | - > |
599 | | - + {{ t('admin.accounts.headerOverride.fillTemplate') }} |
600 | | - </button> |
601 | | - <HeaderOverrideJsonTools |
602 | | - :rows="headerOverrideRows" |
603 | | - @update:rows="headerOverrideRows = $event" |
604 | | - /> |
605 | | - </div> |
606 | | - |
607 | | - <p class="text-xs text-gray-500 dark:text-gray-400"> |
608 | | - {{ t('admin.accounts.headerOverride.emptyValueHint') }} |
609 | | - </p> |
| 541 | + <HeaderOverrideEditor |
| 542 | + :rows="headerOverrideRows" |
| 543 | + @update:rows="headerOverrideRows = $event" |
| 544 | + /> |
610 | 545 | </div> |
611 | 546 | <p v-else class="text-xs text-gray-500 dark:text-gray-400"> |
612 | 547 | {{ t('admin.accounts.headerOverride.bulkDisableHint') }} |
@@ -1277,17 +1212,15 @@ import { |
1277 | 1212 | buildModelMappingObject as buildModelMappingPayload, |
1278 | 1213 | getPresetMappingsByPlatform |
1279 | 1214 | } from '@/composables/useModelWhitelist' |
1280 | | -import HeaderOverrideJsonTools from '@/components/account/HeaderOverrideJsonTools.vue' |
| 1215 | +import HeaderOverrideEditor from '@/components/account/HeaderOverrideEditor.vue' |
1281 | 1216 | import { |
1282 | 1217 | buildHeaderOverridesObject, |
1283 | | - getHeaderOverrideTemplate, |
1284 | 1218 | isHeaderOverrideCapable, |
1285 | 1219 | validateHeaderOverrideRows, |
1286 | 1220 | HEADER_OVERRIDE_ENABLED_CREDENTIAL_KEY, |
1287 | 1221 | HEADER_OVERRIDES_CREDENTIAL_KEY, |
1288 | 1222 | type HeaderOverrideRow |
1289 | 1223 | } from '@/components/account/credentialsBuilder' |
1290 | | -import { createStableObjectKeyResolver } from '@/utils/stableObjectKey' |
1291 | 1224 | import { |
1292 | 1225 | OPENAI_WS_MODE_CTX_POOL, |
1293 | 1226 | OPENAI_WS_MODE_OFF, |
@@ -1436,37 +1369,6 @@ const customErrorCodeInput = ref<number | null>(null) |
1436 | 1369 | const interceptWarmupRequests = ref(false) |
1437 | 1370 | const headerOverrideEnabled = ref(false) |
1438 | 1371 | const headerOverrideRows = ref<HeaderOverrideRow[]>([]) |
1439 | | -const getHeaderOverrideRowKey = createStableObjectKeyResolver<HeaderOverrideRow>('bulk-header-override-row') |
1440 | | -
|
1441 | | -const addHeaderOverrideRow = () => { |
1442 | | - headerOverrideRows.value.push({ name: '', value: '' }) |
1443 | | -} |
1444 | | -
|
1445 | | -const removeHeaderOverrideRow = (index: number) => { |
1446 | | - headerOverrideRows.value.splice(index, 1) |
1447 | | -} |
1448 | | -
|
1449 | | -// 模板仅在所选账号平台唯一时可用:混合 anthropic+openai 选择无法确定用哪套模板, |
1450 | | -// 误填会把另一平台的专有头写进所有所选账号 |
1451 | | -const headerOverrideTemplatePlatform = computed(() => { |
1452 | | - return targetSelectedPlatforms.value.length === 1 ? targetSelectedPlatforms.value[0] : null |
1453 | | -}) |
1454 | | -
|
1455 | | -// 模板按钮:填入所选平台的标准客户端请求头名称(值留空),跳过已存在的同名行 |
1456 | | -const fillHeaderOverrideTemplate = () => { |
1457 | | - const platform = headerOverrideTemplatePlatform.value |
1458 | | - if (!platform) return |
1459 | | - const existing = new Set( |
1460 | | - headerOverrideRows.value.map((row) => row.name.trim().toLowerCase()).filter(Boolean) |
1461 | | - ) |
1462 | | - const rows = headerOverrideRows.value.filter((row) => row.name.trim() || row.value.trim()) |
1463 | | - for (const row of getHeaderOverrideTemplate(platform)) { |
1464 | | - if (!existing.has(row.name)) { |
1465 | | - rows.push(row) |
1466 | | - } |
1467 | | - } |
1468 | | - headerOverrideRows.value = rows |
1469 | | -} |
1470 | 1372 | const proxyId = ref<number | null>(null) |
1471 | 1373 | const concurrency = ref(1) |
1472 | 1374 | const loadFactor = ref<number | null>(null) |
|
0 commit comments