Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d03644e69f |
@@ -89,3 +89,10 @@ export async function fetchPriorityStatus() {
|
|||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function fetchCrawlStatus() {
|
||||||
|
const { data } = await axios.get(`${BASE}/admin/crawl/status`, {
|
||||||
|
timeout: 10000,
|
||||||
|
})
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
+101
-34
@@ -1,6 +1,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, onUnmounted } from 'vue'
|
import { ref, onMounted, onUnmounted } from 'vue'
|
||||||
import { fetchStats, flushIndex, fetchFlushStatus, fetchWorkers, setWorkers, fetchBacklink, triggerBacklink, fetchPriorityStatus } from '../api.js'
|
import { fetchStats, flushIndex, fetchFlushStatus, fetchWorkers, setWorkers, fetchBacklink, triggerBacklink, fetchPriorityStatus, fetchCrawlStatus } from '../api.js'
|
||||||
|
|
||||||
const stats = ref(null)
|
const stats = ref(null)
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
@@ -15,15 +15,19 @@ const workersInput = ref(0)
|
|||||||
const workersSaving = ref(false)
|
const workersSaving = ref(false)
|
||||||
|
|
||||||
// Priority 相关状态
|
// Priority 相关状态
|
||||||
const priorityStatus = ref(null) // { pending, active, max_workers }
|
const priorityStatus = ref(null) // { pending, active, max_workers, children_queue }
|
||||||
|
|
||||||
|
// 爬取状态
|
||||||
|
const crawlStatus = ref(null) // { current_epoch, max_epoch, queue_length, completed_count, visited_total, is_running }
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await Promise.all([loadStats(), loadWorkers(), loadBacklink(), loadPriorityStatus()])
|
await Promise.all([loadStats(), loadWorkers(), loadBacklink(), loadPriorityStatus(), loadCrawlStatus()])
|
||||||
refreshInterval = setInterval(() => {
|
refreshInterval = setInterval(() => {
|
||||||
loadStats()
|
loadStats()
|
||||||
loadWorkers()
|
loadWorkers()
|
||||||
loadBacklink()
|
loadBacklink()
|
||||||
loadPriorityStatus()
|
loadPriorityStatus()
|
||||||
|
loadCrawlStatus()
|
||||||
}, 5000)
|
}, 5000)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -90,6 +94,14 @@ async function loadPriorityStatus() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function loadCrawlStatus() {
|
||||||
|
try {
|
||||||
|
crawlStatus.value = await fetchCrawlStatus()
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Failed to load crawl status:', e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function doTriggerBacklink() {
|
async function doTriggerBacklink() {
|
||||||
backlinkTriggering.value = true
|
backlinkTriggering.value = true
|
||||||
try {
|
try {
|
||||||
@@ -212,6 +224,92 @@ function langColor(lang) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 优先爬取队列 -->
|
||||||
|
<div v-if="priorityStatus" class="bg-gray-900 border border-gray-800 rounded-xl p-4 md:p-5 mb-6 md:mb-8">
|
||||||
|
<h2 class="text-sm font-semibold text-gray-300 uppercase tracking-wider mb-4">优先爬取队列</h2>
|
||||||
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
||||||
|
<!-- 优先子链接 -->
|
||||||
|
<div class="bg-gray-800/50 rounded-lg p-4 text-center">
|
||||||
|
<div class="text-xs text-gray-500 mb-1">优先子链接</div>
|
||||||
|
<div class="text-2xl font-bold" :class="(priorityStatus.children_queue || 0) > 0 ? 'text-yellow-400' : 'text-gray-500'">
|
||||||
|
{{ fmt(priorityStatus.children_queue || 0) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 手动待爬 -->
|
||||||
|
<div class="bg-gray-800/50 rounded-lg p-4 text-center">
|
||||||
|
<div class="text-xs text-gray-500 mb-1">手动待爬</div>
|
||||||
|
<div class="text-2xl font-bold" :class="priorityStatus.pending > 0 ? 'text-yellow-400' : 'text-gray-500'">
|
||||||
|
{{ fmt(priorityStatus.pending) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 手动爬取中 -->
|
||||||
|
<div class="bg-gray-800/50 rounded-lg p-4 text-center">
|
||||||
|
<div class="text-xs text-gray-500 mb-1">手动爬取中</div>
|
||||||
|
<div class="text-2xl font-bold" :class="priorityStatus.active > 0 ? 'text-orange-400' : 'text-gray-500'">
|
||||||
|
{{ fmt(priorityStatus.active) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 优先上限 -->
|
||||||
|
<div class="bg-gray-800/50 rounded-lg p-4 text-center">
|
||||||
|
<div class="text-xs text-gray-500 mb-1">优先上限</div>
|
||||||
|
<div class="text-2xl font-bold text-blue-400">{{ priorityStatus.max_workers }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 爬取进度 -->
|
||||||
|
<div v-if="crawlStatus && crawlStatus.max_epoch > 0" class="bg-gray-900 border border-gray-800 rounded-xl p-4 md:p-5 mb-6 md:mb-8">
|
||||||
|
<div class="flex flex-col md:flex-row md:items-center md:justify-between gap-4 mb-4">
|
||||||
|
<h2 class="text-sm font-semibold text-gray-300 uppercase tracking-wider">爬取进度</h2>
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<span class="text-xs text-gray-500">状态:</span>
|
||||||
|
<span class="px-2 py-0.5 rounded text-xs font-medium" :class="crawlStatus.is_running ? 'bg-green-900/50 text-green-400' : 'bg-gray-800 text-gray-500'">
|
||||||
|
{{ crawlStatus.is_running ? '运行中' : '已停止' }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
||||||
|
<!-- 当前轮次 -->
|
||||||
|
<div class="text-center">
|
||||||
|
<div class="text-xs text-gray-500 mb-1">当前轮次</div>
|
||||||
|
<div class="text-3xl font-bold text-white">
|
||||||
|
{{ crawlStatus.current_epoch }}<span class="text-lg text-gray-500">/{{ crawlStatus.max_epoch }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 本轮队列 -->
|
||||||
|
<div class="text-center">
|
||||||
|
<div class="text-xs text-gray-500 mb-1">本轮队列</div>
|
||||||
|
<div class="text-3xl font-bold" :class="crawlStatus.queue_length > 0 ? 'text-blue-400' : 'text-gray-500'">
|
||||||
|
{{ fmt(crawlStatus.queue_length) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 已完成 -->
|
||||||
|
<div class="text-center">
|
||||||
|
<div class="text-xs text-gray-500 mb-1">已完成</div>
|
||||||
|
<div class="text-3xl font-bold text-green-400">
|
||||||
|
{{ fmt(crawlStatus.completed_count) }}
|
||||||
|
</div>
|
||||||
|
<div class="text-xs text-gray-600 mt-1">
|
||||||
|
{{ crawlStatus.queue_length > 0 ? Math.round(crawlStatus.completed_count / crawlStatus.queue_length * 100) + '%' : '--' }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 已收录总计 -->
|
||||||
|
<div class="text-center">
|
||||||
|
<div class="text-xs text-gray-500 mb-1">已收录总计</div>
|
||||||
|
<div class="text-3xl font-bold text-white">{{ fmt(crawlStatus.visited_total) }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 进度条 -->
|
||||||
|
<div v-if="crawlStatus.queue_length > 0" class="mt-4">
|
||||||
|
<div class="bg-gray-800 rounded-full h-2 overflow-hidden">
|
||||||
|
<div
|
||||||
|
class="h-full bg-gradient-to-r from-blue-600 to-green-500 rounded-full transition-all duration-500"
|
||||||
|
:style="{ width: `${(crawlStatus.completed_count / crawlStatus.queue_length) * 100}%` }"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Workers Control -->
|
<!-- Workers Control -->
|
||||||
<div class="bg-gray-900 border border-gray-800 rounded-xl p-4 md:p-5 mb-6 md:mb-8">
|
<div class="bg-gray-900 border border-gray-800 rounded-xl p-4 md:p-5 mb-6 md:mb-8">
|
||||||
<div class="flex flex-col md:flex-row md:items-center md:justify-between gap-4">
|
<div class="flex flex-col md:flex-row md:items-center md:justify-between gap-4">
|
||||||
@@ -230,37 +328,6 @@ function langColor(lang) {
|
|||||||
<div class="text-xs text-gray-500 mb-0.5">设定上限</div>
|
<div class="text-xs text-gray-500 mb-0.5">设定上限</div>
|
||||||
<div class="text-3xl font-bold text-white">{{ configuredWorkers }}</div>
|
<div class="text-3xl font-bold text-white">{{ configuredWorkers }}</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 新增:超出部分 -->
|
|
||||||
<div v-if="priorityStatus && priorityStatus.active > 0" class="ml-2">
|
|
||||||
<div class="text-xs text-orange-400 mb-0.5">优先线程</div>
|
|
||||||
<div class="text-3xl font-bold text-orange-400">+{{ priorityStatus.active }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 右侧:Priority 队列状态 -->
|
|
||||||
<div v-if="priorityStatus" class="flex items-center gap-6 text-sm">
|
|
||||||
<div class="text-center">
|
|
||||||
<div class="text-xs text-gray-500 mb-1">优先子链接</div>
|
|
||||||
<div class="text-2xl font-bold" :class="(priorityStatus.children_queue || 0) > 0 ? 'text-yellow-400' : 'text-gray-500'">
|
|
||||||
{{ priorityStatus.children_queue || 0 }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="text-center">
|
|
||||||
<div class="text-xs text-gray-500 mb-1">手动待爬</div>
|
|
||||||
<div class="text-2xl font-bold" :class="priorityStatus.pending > 0 ? 'text-yellow-400' : 'text-gray-500'">
|
|
||||||
{{ priorityStatus.pending }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="text-center">
|
|
||||||
<div class="text-xs text-gray-500 mb-1">手动爬取中</div>
|
|
||||||
<div class="text-2xl font-bold" :class="priorityStatus.active > 0 ? 'text-orange-400' : 'text-gray-500'">
|
|
||||||
{{ priorityStatus.active }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="text-center">
|
|
||||||
<div class="text-xs text-gray-500 mb-1">优先上限</div>
|
|
||||||
<div class="text-2xl font-bold text-gray-400">{{ priorityStatus.max_workers }}</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user