mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-07 01:47:47 +08:00
feat(routing): consolidate scheduling strategy configuration
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -37,6 +37,7 @@
|
||||
:provider-proxy-node-name="getProviderProxyNodeName()"
|
||||
:saving-provider-proxy="savingProviderProxy"
|
||||
@toggle-format-conversion="toggleFormatConversion"
|
||||
@toggle-keep-priority-on-conversion="toggleKeepPriorityOnConversion"
|
||||
@open-failover-rules="failoverRulesDialogOpen = true"
|
||||
@set-provider-proxy="setProviderProxy"
|
||||
@clear-provider-proxy="clearProviderProxy"
|
||||
@@ -1412,6 +1413,24 @@ async function toggleFormatConversion() {
|
||||
}
|
||||
}
|
||||
|
||||
async function toggleKeepPriorityOnConversion() {
|
||||
if (!provider.value) return
|
||||
const formatConversionAvailable =
|
||||
provider.value.enable_format_conversion || systemFormatConversionEnabled.value
|
||||
if (!formatConversionAvailable) return
|
||||
const newValue = !provider.value.keep_priority_on_conversion
|
||||
try {
|
||||
const updated = await updateProvider(provider.value.id, {
|
||||
keep_priority_on_conversion: newValue,
|
||||
})
|
||||
applyProviderSnapshot(updated)
|
||||
showSuccess(legacyT(newValue ? '已启用格式转换保持优先级' : '已禁用格式转换保持优先级'))
|
||||
emit('refresh')
|
||||
} catch {
|
||||
showError(legacyT('切换格式转换保持优先级失败'))
|
||||
}
|
||||
}
|
||||
|
||||
function getProviderProxyNodeName(): string {
|
||||
const nodeId = provider.value?.proxy?.node_id
|
||||
if (!nodeId) return legacyT('未知节点')
|
||||
|
||||
@@ -24,6 +24,17 @@
|
||||
<Shuffle class="w-4 h-4" />
|
||||
</Button>
|
||||
</span>
|
||||
<span :title="keepPriorityTitle">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
:class="provider.keep_priority_on_conversion ? 'text-primary' : ''"
|
||||
:disabled="!formatConversionAvailable"
|
||||
@click="$emit('toggleKeepPriorityOnConversion')"
|
||||
>
|
||||
<Layers class="w-4 h-4" />
|
||||
</Button>
|
||||
</span>
|
||||
<span :title="legacyT(hasFailoverRules ? '已配置故障转移规则(点击编辑)' : '配置故障转移规则')">
|
||||
<Button
|
||||
variant="ghost"
|
||||
@@ -163,7 +174,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { Edit, GitBranch, Globe, Loader2, Plus, Power, Shuffle, X } from 'lucide-vue-next'
|
||||
import { Edit, GitBranch, Globe, Layers, Loader2, Plus, Power, Shuffle, X } from 'lucide-vue-next'
|
||||
import Button from '@/components/ui/button.vue'
|
||||
import Badge from '@/components/ui/badge.vue'
|
||||
import { Popover, PopoverTrigger, PopoverContent } from '@/components/ui'
|
||||
@@ -185,6 +196,7 @@ const props = defineProps<{
|
||||
|
||||
defineEmits<{
|
||||
(e: 'toggleFormatConversion'): void
|
||||
(e: 'toggleKeepPriorityOnConversion'): void
|
||||
(e: 'openFailoverRules'): void
|
||||
(e: 'update:providerProxyPopoverOpen', value: boolean): void
|
||||
(e: 'setProviderProxy', value: string): void
|
||||
@@ -203,4 +215,15 @@ const formatConversionTitle = computed(() => {
|
||||
if (props.provider.enable_format_conversion) return legacyT('已启用格式转换(点击关闭)')
|
||||
return legacyT('启用格式转换')
|
||||
})
|
||||
|
||||
const formatConversionAvailable = computed(() => (
|
||||
props.provider.enable_format_conversion || props.systemFormatConversionEnabled
|
||||
))
|
||||
|
||||
const keepPriorityTitle = computed(() => {
|
||||
if (!formatConversionAvailable.value) return legacyT('请先启用格式转换')
|
||||
return props.provider.keep_priority_on_conversion
|
||||
? legacyT('已启用格式转换保持优先级(点击关闭)')
|
||||
: legacyT('启用格式转换保持优先级')
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -280,19 +280,6 @@
|
||||
{{ legacyT('功能开关') }}
|
||||
</h3>
|
||||
|
||||
<div class="flex items-center justify-between p-3 border rounded-lg bg-muted/50">
|
||||
<div class="space-y-0.5">
|
||||
<span class="text-sm font-medium">{{ legacyT('格式转换保持优先级') }}</span>
|
||||
<p class="text-xs text-muted-foreground">
|
||||
{{ legacyT('跨格式请求时保持原优先级排名,不降级到格式匹配的提供商之后') }}
|
||||
</p>
|
||||
</div>
|
||||
<Switch
|
||||
:model-value="form.keep_priority_on_conversion"
|
||||
@update:model-value="(v: boolean) => form.keep_priority_on_conversion = v"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-between p-3 border rounded-lg bg-muted/50">
|
||||
<div class="space-y-0.5">
|
||||
<span class="text-sm font-medium">{{ legacyT('号池调度模式') }}</span>
|
||||
@@ -475,7 +462,6 @@ const form = ref({
|
||||
quota_last_reset_at: '', // 周期开始时间
|
||||
quota_expires_at: '',
|
||||
provider_priority: 100,
|
||||
keep_priority_on_conversion: false, // 格式转换时是否保持优先级
|
||||
// 状态配置
|
||||
is_active: true,
|
||||
rate_limit: undefined as number | undefined,
|
||||
@@ -510,7 +496,6 @@ function resetForm() {
|
||||
quota_last_reset_at: '',
|
||||
quota_expires_at: '',
|
||||
provider_priority: defaultPriority.value,
|
||||
keep_priority_on_conversion: false,
|
||||
is_active: true,
|
||||
rate_limit: undefined,
|
||||
concurrent_limit: undefined,
|
||||
@@ -548,7 +533,6 @@ function loadProviderData() {
|
||||
quota_last_reset_at: formatDateTimeLocalInput(props.provider.quota_last_reset_at),
|
||||
quota_expires_at: formatDateTimeLocalInput(props.provider.quota_expires_at),
|
||||
provider_priority: props.provider.provider_priority || 999,
|
||||
keep_priority_on_conversion: props.provider.keep_priority_on_conversion ?? false,
|
||||
is_active: props.provider.is_active,
|
||||
rate_limit: undefined,
|
||||
concurrent_limit: undefined,
|
||||
@@ -625,7 +609,6 @@ const handleSubmit = async () => {
|
||||
quota_reset_day: form.value.quota_reset_day,
|
||||
quota_last_reset_at: quotaLastResetAt,
|
||||
quota_expires_at: quotaExpiresAt,
|
||||
keep_priority_on_conversion: form.value.keep_priority_on_conversion,
|
||||
responses_websocket_enabled: form.value.responses_websocket_enabled,
|
||||
is_active: form.value.is_active,
|
||||
// 请求配置
|
||||
|
||||
@@ -98,19 +98,6 @@
|
||||
|
||||
<div class="hidden sm:block h-4 w-px bg-border" />
|
||||
|
||||
<!-- 调度策略 -->
|
||||
<button
|
||||
class="group inline-flex items-center gap-1.5 px-2.5 h-8 rounded-md border border-border/50 bg-muted/20 hover:bg-muted/40 hover:border-primary/40 transition-all duration-200 text-xs"
|
||||
:title="legacyT('点击调整调度策略')"
|
||||
@click="$emit('openPriorityDialog')"
|
||||
>
|
||||
<span class="text-muted-foreground/80 hidden sm:inline">{{ legacyT('调度:') }}</span>
|
||||
<span class="font-medium text-foreground/90">{{ priorityModeLabel }}</span>
|
||||
<ChevronDown class="w-3 h-3 text-muted-foreground/70 group-hover:text-foreground transition-colors" />
|
||||
</button>
|
||||
|
||||
<div class="hidden sm:block h-4 w-px bg-border" />
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<Button
|
||||
variant="ghost"
|
||||
@@ -141,7 +128,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Search, Plus, ChevronDown, FilterX, Users } from 'lucide-vue-next'
|
||||
import { Search, Plus, FilterX, Users } from 'lucide-vue-next'
|
||||
import Button from '@/components/ui/button.vue'
|
||||
import Input from '@/components/ui/input.vue'
|
||||
import Select from '@/components/ui/select.vue'
|
||||
@@ -162,7 +149,6 @@ defineProps<{
|
||||
apiFormatFilters: FilterOption[]
|
||||
modelFilters: FilterOption[]
|
||||
hasActiveFilters: boolean
|
||||
priorityModeLabel: string
|
||||
loading: boolean
|
||||
}>()
|
||||
|
||||
@@ -172,7 +158,6 @@ defineEmits<{
|
||||
'update:filterApiFormat': [value: string]
|
||||
'update:filterModel': [value: string]
|
||||
'resetFilters': []
|
||||
'openPriorityDialog': []
|
||||
'batchProcess': []
|
||||
'addProvider': []
|
||||
'refresh': []
|
||||
|
||||
@@ -9,7 +9,6 @@ export { default as EndpointFormDialog } from './EndpointFormDialog.vue'
|
||||
export { default as KeyFormDialog } from './KeyFormDialog.vue'
|
||||
export { default as KeyAllowedModelsDialog } from './KeyAllowedModelsDialog.vue'
|
||||
export { default as KeyAllowedModelsEditDialog } from './KeyAllowedModelsEditDialog.vue'
|
||||
export { default as PriorityManagementDialog } from './PriorityManagementDialog.vue'
|
||||
export { default as ProviderModelFormDialog } from './ProviderModelFormDialog.vue'
|
||||
export { default as ProviderDetailDrawer } from './ProviderDetailDrawer.vue'
|
||||
export { default as EndpointHealthTimeline } from './EndpointHealthTimeline.vue'
|
||||
|
||||
Reference in New Issue
Block a user