|
|
@@ -1,6 +1,6 @@
|
|
|
<template>
|
|
|
<div>
|
|
|
- <el-row :span="8" class="child mb-5" justify="center">
|
|
|
+ <el-row :span="8" justify="center" style="gap: 16px">
|
|
|
<el-upload
|
|
|
action="#"
|
|
|
:http-request="handleUpload"
|
|
|
@@ -11,10 +11,14 @@
|
|
|
<el-button
|
|
|
type="primary"
|
|
|
:disabled="!isWorkerAvailable"
|
|
|
+ class="mr-12"
|
|
|
>
|
|
|
- {{ isWorkerAvailable ? '选择并上传文件' : '服务不可用' }}
|
|
|
+ {{ isWorkerAvailable ? '导入关键词' : '服务不可用' }}
|
|
|
</el-button>
|
|
|
</el-upload>
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ >开始运行</el-button>
|
|
|
</el-row>
|
|
|
|
|
|
<!-- 显示上传结果 -->
|
|
|
@@ -34,15 +38,26 @@
|
|
|
</el-descriptions-item>
|
|
|
</el-descriptions>
|
|
|
|
|
|
- <h2>系统状态总览</h2>
|
|
|
- <el-descriptions :column="3" border>
|
|
|
+ <h2>运行状态总览</h2>
|
|
|
+ <el-descriptions border>
|
|
|
<!-- 代理信息 -->
|
|
|
- <el-descriptions-item label="代理类型">
|
|
|
+ <el-descriptions-item :span="1" label="代理类型">
|
|
|
<template v-if="store.selectedProxy === 'poll'">
|
|
|
- 代理池状态 {{ store.proxiesCache?.data?.filter((p: any) => p.reachable).length || 0 }}/{{ store.proxiesCache?.data?.length || 0 }}
|
|
|
+ 代理池
|
|
|
</template>
|
|
|
<template v-else-if="store.selectedProxy === 'system'">
|
|
|
- 系统代理 {{ store.sysProxyCache?.data?.sys_open ? '已启用' : '未启用' }}
|
|
|
+ 系统代理
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ {{ store.selectedProxy }}
|
|
|
+ </template>
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item :span="2" label="状态">
|
|
|
+ <template v-if="store.selectedProxy === 'poll'">
|
|
|
+ {{ store.proxiesCache?.data?.filter((p: any) => p.reachable).length || 0 }}/{{ store.proxiesCache?.data?.length || 0 }}
|
|
|
+ </template>
|
|
|
+ <template v-else-if="store.selectedProxy === 'system'">
|
|
|
+ {{ store.sysProxyCache?.data?.sys_open ? '已启用' : '未启用' }}
|
|
|
</template>
|
|
|
<template v-else>
|
|
|
{{ store.selectedProxy }}
|
|
|
@@ -51,15 +66,30 @@
|
|
|
|
|
|
<!-- 数据库任务 -->
|
|
|
<el-descriptions-item label="总关键词数">{{ taskStats.total_tasks ?? '-' }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="已完成关键词">{{ taskStats.completed_tasks ?? '-' }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="未完成关键词">{{ taskStats.pending_tasks ?? '-' }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="已完成">{{ taskStats.completed_tasks ?? '-' }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="未完成">{{ taskStats.pending_tasks ?? '-' }}</el-descriptions-item>
|
|
|
|
|
|
<!-- 执行状态 -->
|
|
|
- <el-descriptions-item label="工作服务状态">
|
|
|
+ <el-descriptions-item :span="1" label="工作服务状态">
|
|
|
<el-tag :type="isWorkerAvailable ? 'success' : 'danger'">
|
|
|
{{ isWorkerAvailable ? '在线' : '离线' }}
|
|
|
</el-tag>
|
|
|
</el-descriptions-item>
|
|
|
+ <el-descriptions-item :span="1" label="数据库路径">
|
|
|
+ <el-tooltip :content="dbUrl" placement="top">
|
|
|
+ <el-button @click="copyToClipboard(dbUrl)" >
|
|
|
+ 复制
|
|
|
+ </el-button>
|
|
|
+ </el-tooltip>
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item :span="1" label="保存路径">
|
|
|
+ <el-tooltip :content="SearchResultDir" placement="top">
|
|
|
+ <el-button @click="copyToClipboard(SearchResultDir)" >
|
|
|
+ 复制
|
|
|
+ </el-button>
|
|
|
+ </el-tooltip>
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item :span="3" label="浏览器路径"></el-descriptions-item>
|
|
|
</el-descriptions>
|
|
|
</div>
|
|
|
</template>
|
|
|
@@ -73,7 +103,8 @@ import { useProxyStore } from '../stores/proxyStore'
|
|
|
const workerServer = ref('')
|
|
|
const isWorkerAvailable = ref(false)
|
|
|
const workerHealth = ref<{err: number, msg: string} | null>(null)
|
|
|
-
|
|
|
+const dbUrl = ref('')
|
|
|
+const SearchResultDir = ref('')
|
|
|
const backendBaseUrl = import.meta.env.VITE_API_BASE_URL || ''
|
|
|
const serverApiFileUrl = `${backendBaseUrl}/worker`
|
|
|
const store = useProxyStore()
|
|
|
@@ -126,6 +157,8 @@ const fetchWorkerEndpoint = async () => {
|
|
|
console.log('worker endpoint:', data)
|
|
|
workerServer.value = data.service_url
|
|
|
workerHealth.value = data.health
|
|
|
+ dbUrl.value = data.health.db_url
|
|
|
+ SearchResultDir.value = data.health.google_search_dir
|
|
|
// 根据 health 状态判断服务是否可用
|
|
|
isWorkerAvailable.value = data.health && data.health.err === 0
|
|
|
} catch (error) {
|
|
|
@@ -159,6 +192,14 @@ onMounted(async () => {
|
|
|
}
|
|
|
})
|
|
|
|
|
|
+const copyToClipboard = async (text: string) => {
|
|
|
+ try {
|
|
|
+ await navigator.clipboard.writeText(text);
|
|
|
+ ElMessage.success('复制成功');
|
|
|
+ } catch (err) {
|
|
|
+ ElMessage.error('复制失败');
|
|
|
+ }
|
|
|
+};
|
|
|
const handleUpload = async (options: any) => {
|
|
|
if (!isWorkerAvailable.value) {
|
|
|
ElMessage.warning(`worker 服务不可用,无法上传文件。状态码: ${store.workerHealth?.err}`)
|
|
|
@@ -203,7 +244,5 @@ const handleUpload = async (options: any) => {
|
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
|
|
-.child {
|
|
|
- margin-bottom: 20px;
|
|
|
-}
|
|
|
+
|
|
|
</style>
|