feat(provider): 完成阶段E协议适配、国内预设与模型路由
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import type { ProviderPreset } from '@/contracts'
|
||||
import ProviderLogo from './ProviderLogo.vue'
|
||||
|
||||
const props = defineProps<{ presets: ProviderPreset[]; modelValue: string }>()
|
||||
const emit = defineEmits<{ 'update:modelValue': [value: string] }>()
|
||||
const search = ref('')
|
||||
const filtered = computed(() => {
|
||||
const query = search.value.trim().toLocaleLowerCase()
|
||||
return props.presets.filter(preset => [preset.name, preset.preset_id, preset.description, preset.base_url]
|
||||
.some(value => value?.toLocaleLowerCase().includes(query)))
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="preset-selector">
|
||||
<label class="field" for="provider-search"><span>提供商预设</span><input id="provider-search" v-model="search" class="input" type="search" placeholder="搜索提供商,例如 通义千问 / DeepSeek" /></label>
|
||||
<div class="preset-grid" role="group" aria-label="提供商预设">
|
||||
<button type="button" class="preset-chip" :class="{ selected: !modelValue }" :aria-pressed="!modelValue" @click="emit('update:modelValue', '')"><ProviderLogo /><span>自定义</span></button>
|
||||
<button v-for="preset in filtered" :key="preset.preset_id" type="button" class="preset-chip" :class="{ selected: modelValue === preset.preset_id }" :aria-pressed="modelValue === preset.preset_id" :title="preset.description || preset.name" :data-preset="preset.preset_id" @click="emit('update:modelValue', preset.preset_id)">
|
||||
<ProviderLogo :logo-id="preset.logo_id || preset.preset_id" /><span>{{ preset.name }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<p v-if="search && !filtered.length" class="subtle" role="status">没有匹配的预设,可以使用自定义服务。</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.preset-selector { display: grid; gap: var(--space-sm); }
|
||||
.preset-grid { display: flex; flex-wrap: wrap; gap: 8px; max-height: 220px; overflow-y: auto; padding: 3px; }
|
||||
.preset-chip { display: inline-flex; align-items: center; gap: 7px; padding: 6px 10px; border: 1px solid var(--color-border-default); border-radius: 11px; background: var(--color-surface-primary); color: var(--color-text-primary); cursor: pointer; font: inherit; font-size: 13px; }
|
||||
.preset-chip:hover { background: var(--color-background-hover); }
|
||||
.preset-chip.selected { border-color: #377cf6; background: color-mix(in srgb, #377cf6 12%, var(--color-surface-primary)); color: #377cf6; box-shadow: 0 0 0 1px #377cf6; }
|
||||
.preset-chip:focus-visible { outline: 2px solid var(--color-border-focus); outline-offset: 2px; }
|
||||
</style>
|
||||
Reference in New Issue
Block a user