mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-31 08:25:35 +00:00
fix(grok): gateway media/voice routing, models, and status UI polish
Align gateway Grok media/voice paths and model lists, harden upstream failure and quota handling, clear non-Grok video generation config migration, and polish temp-unsched/status indicators with model whitelist updates.
This commit is contained in:
@@ -14,15 +14,19 @@
|
||||
|
||||
<!-- Main Status Badge (shown when not rate limited/overloaded) -->
|
||||
<template v-else>
|
||||
<button
|
||||
v-if="isTempUnschedulable"
|
||||
type="button"
|
||||
:class="['badge text-xs', statusClass, 'cursor-pointer']"
|
||||
:title="t('admin.accounts.status.viewTempUnschedDetails')"
|
||||
@click="handleTempUnschedClick"
|
||||
>
|
||||
{{ statusText }}
|
||||
</button>
|
||||
<div v-if="isTempUnschedulable" class="flex flex-col items-center gap-1">
|
||||
<button
|
||||
type="button"
|
||||
:class="['badge text-xs', statusClass, 'cursor-pointer']"
|
||||
:title="t('admin.accounts.status.viewTempUnschedDetails')"
|
||||
@click="handleTempUnschedClick"
|
||||
>
|
||||
{{ statusText }}
|
||||
</button>
|
||||
<span class="max-w-[180px] text-center text-[11px] leading-4 text-gray-500 dark:text-gray-400">
|
||||
{{ tempUnschedRecoveryText }}
|
||||
</span>
|
||||
</div>
|
||||
<span v-else :class="['badge text-xs', statusClass]">
|
||||
{{ statusText }}
|
||||
</span>
|
||||
@@ -302,6 +306,13 @@ const overloadCountdown = computed(() => {
|
||||
return formatCountdownWithSuffix(props.account.overload_until)
|
||||
})
|
||||
|
||||
const tempUnschedRecoveryText = computed(() => {
|
||||
if (!isTempUnschedulable.value || !props.account.temp_unschedulable_until) return ''
|
||||
return t('admin.accounts.status.tempUnschedulableUntil', {
|
||||
time: formatDateTime(props.account.temp_unschedulable_until)
|
||||
})
|
||||
})
|
||||
|
||||
// Computed: status badge class
|
||||
const statusClass = computed(() => {
|
||||
if (hasError.value) {
|
||||
|
||||
@@ -101,6 +101,14 @@
|
||||
{{ state?.error_message || '-' }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="hasThresholdEvidence"
|
||||
class="rounded-lg border border-blue-200 bg-blue-50 p-3 text-sm text-blue-800 dark:border-blue-500/30 dark:bg-blue-500/10 dark:text-blue-300"
|
||||
data-testid="temp-unsched-trigger-evidence"
|
||||
>
|
||||
{{ triggerEvidenceText }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -176,10 +184,28 @@ const isActive = computed(() => {
|
||||
})
|
||||
|
||||
const ruleIndexDisplay = computed(() => {
|
||||
if (!state.value) return '-'
|
||||
if (!state.value || !state.value.matched_keyword || state.value.rule_index < 0) return '-'
|
||||
return state.value.rule_index + 1
|
||||
})
|
||||
|
||||
const hasThresholdEvidence = computed(() => (state.value?.trigger_count || 0) > 1)
|
||||
|
||||
const triggerEvidenceText = computed(() => {
|
||||
const count = state.value?.trigger_count || 0
|
||||
const threshold = state.value?.trigger_threshold || 0
|
||||
const minutes = state.value?.trigger_window_minutes || 0
|
||||
if (threshold > 0 && minutes > 0) {
|
||||
return t('admin.accounts.tempUnschedulable.multipleErrorTrigger', { count, threshold, minutes })
|
||||
}
|
||||
if (threshold > 0) {
|
||||
return t('admin.accounts.tempUnschedulable.multipleErrorTriggerNoWindow', { count, threshold })
|
||||
}
|
||||
if (minutes > 0) {
|
||||
return t('admin.accounts.tempUnschedulable.multipleErrorCountInWindow', { count, minutes })
|
||||
}
|
||||
return t('admin.accounts.tempUnschedulable.multipleErrorCount', { count })
|
||||
})
|
||||
|
||||
const triggeredAtText = computed(() => {
|
||||
if (!state.value?.triggered_at_unix) return '-'
|
||||
return formatDateTime(new Date(state.value.triggered_at_unix * 1000))
|
||||
|
||||
Reference in New Issue
Block a user