feat(proxy): 持久化质量检测结果并在列表展示
This commit is contained in:
@@ -160,20 +160,32 @@
|
||||
</template>
|
||||
|
||||
<template #cell-latency="{ row }">
|
||||
<span
|
||||
v-if="row.latency_status === 'failed'"
|
||||
class="badge badge-danger"
|
||||
:title="row.latency_message || undefined"
|
||||
>
|
||||
{{ t('admin.proxies.latencyFailed') }}
|
||||
</span>
|
||||
<span
|
||||
v-else-if="typeof row.latency_ms === 'number'"
|
||||
:class="['badge', row.latency_ms < 200 ? 'badge-success' : 'badge-warning']"
|
||||
>
|
||||
{{ row.latency_ms }}ms
|
||||
</span>
|
||||
<span v-else class="text-sm text-gray-400">-</span>
|
||||
<div class="flex flex-col gap-1">
|
||||
<span
|
||||
v-if="row.latency_status === 'failed'"
|
||||
class="badge badge-danger"
|
||||
:title="row.latency_message || undefined"
|
||||
>
|
||||
{{ t('admin.proxies.latencyFailed') }}
|
||||
</span>
|
||||
<span
|
||||
v-else-if="typeof row.latency_ms === 'number'"
|
||||
:class="['badge', row.latency_ms < 200 ? 'badge-success' : 'badge-warning']"
|
||||
>
|
||||
{{ row.latency_ms }}ms
|
||||
</span>
|
||||
<span v-else class="text-sm text-gray-400">-</span>
|
||||
<div
|
||||
v-if="typeof row.quality_checked === 'number'"
|
||||
class="flex items-center gap-1 text-xs text-gray-500 dark:text-gray-400"
|
||||
:title="row.quality_summary || undefined"
|
||||
>
|
||||
<span>{{ t('admin.proxies.qualityInline', { grade: row.quality_grade || '-', score: row.quality_score ?? '-' }) }}</span>
|
||||
<span class="badge" :class="qualityOverallClass(row.quality_status)">
|
||||
{{ qualityOverallLabel(row.quality_status) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #cell-status="{ value }">
|
||||
@@ -1250,6 +1262,23 @@ const applyLatencyResult = (
|
||||
target.latency_message = result.message
|
||||
}
|
||||
|
||||
const summarizeQualityStatus = (result: ProxyQualityCheckResult): Proxy['quality_status'] => {
|
||||
if (result.challenge_count > 0) return 'challenge'
|
||||
if (result.failed_count > 0) return 'failed'
|
||||
if (result.warn_count > 0) return 'warn'
|
||||
return 'healthy'
|
||||
}
|
||||
|
||||
const applyQualityResult = (proxyId: number, result: ProxyQualityCheckResult) => {
|
||||
const target = proxies.value.find((proxy) => proxy.id === proxyId)
|
||||
if (!target) return
|
||||
target.quality_status = summarizeQualityStatus(result)
|
||||
target.quality_score = result.score
|
||||
target.quality_grade = result.grade
|
||||
target.quality_summary = result.summary
|
||||
target.quality_checked = result.checked_at
|
||||
}
|
||||
|
||||
const formatLocation = (proxy: Proxy) => {
|
||||
const parts = [proxy.country, proxy.city].filter(Boolean) as string[]
|
||||
return parts.join(' · ')
|
||||
@@ -1330,6 +1359,7 @@ const handleQualityCheck = async (proxy: Proxy) => {
|
||||
country_code: result.country_code
|
||||
})
|
||||
}
|
||||
applyQualityResult(proxy.id, result)
|
||||
|
||||
appStore.showSuccess(
|
||||
t('admin.proxies.qualityCheckDone', { score: result.score, grade: result.grade })
|
||||
@@ -1374,6 +1404,7 @@ const runBatchProxyQualityChecks = async (ids: number[]) => {
|
||||
})
|
||||
}
|
||||
}
|
||||
applyQualityResult(current, result)
|
||||
if (result.challenge_count > 0) {
|
||||
challenge++
|
||||
} else if (result.failed_count > 0) {
|
||||
@@ -1422,6 +1453,20 @@ const qualityStatusLabel = (status: string) => {
|
||||
return t('admin.proxies.qualityStatusFail')
|
||||
}
|
||||
|
||||
const qualityOverallClass = (status?: string) => {
|
||||
if (status === 'healthy') return 'badge-success'
|
||||
if (status === 'warn') return 'badge-warning'
|
||||
if (status === 'challenge') return 'badge-danger'
|
||||
return 'badge-danger'
|
||||
}
|
||||
|
||||
const qualityOverallLabel = (status?: string) => {
|
||||
if (status === 'healthy') return t('admin.proxies.qualityStatusHealthy')
|
||||
if (status === 'warn') return t('admin.proxies.qualityStatusWarn')
|
||||
if (status === 'challenge') return t('admin.proxies.qualityStatusChallenge')
|
||||
return t('admin.proxies.qualityStatusFail')
|
||||
}
|
||||
|
||||
const qualityTargetLabel = (target: string) => {
|
||||
switch (target) {
|
||||
case 'base_connectivity':
|
||||
|
||||
Reference in New Issue
Block a user