|
|
@@ -1,39 +1,10 @@
|
|
|
<template>
|
|
|
<div>
|
|
|
- <el-row :span="8" justify="center" style="gap: 16px">
|
|
|
- <el-upload
|
|
|
- action="#"
|
|
|
- :http-request="handleUpload"
|
|
|
- :show-file-list="false"
|
|
|
- accept=".xlsx,.xls,.csv"
|
|
|
- :disabled="!isWorkerAvailable"
|
|
|
- >
|
|
|
- <el-button
|
|
|
- type="primary"
|
|
|
- :disabled="!isWorkerAvailable"
|
|
|
- class="mr-12"
|
|
|
- >
|
|
|
- {{ isWorkerAvailable ? '导入关键词' : '服务不可用' }}
|
|
|
- </el-button>
|
|
|
- </el-upload>
|
|
|
- </el-row>
|
|
|
-
|
|
|
- <!-- 显示上传结果 -->
|
|
|
- <el-descriptions v-if="uploadResult" title="导入结果" :column="1" border class="mt-4">
|
|
|
- <el-descriptions-item label="文件名">{{ uploadResult.name }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="文件大小">{{ (uploadResult.size / 1024).toFixed(2) }} KB</el-descriptions-item>
|
|
|
- <el-descriptions-item label="上传时间">{{ uploadResult.uploadTime }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="关键词总数">{{ uploadResult.total_keywords }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="导入关键词个数">{{ uploadResult.inserted_count }} (如果存在则跳过)</el-descriptions-item>
|
|
|
- <el-descriptions-item label="状态">
|
|
|
- <el-tag :type="uploadResult.success ? 'success' : 'danger'">
|
|
|
- {{ uploadResult.success ? '导入成功' : '导入失败' }}
|
|
|
- </el-tag>
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item v-if="uploadResult.error" label="错误信息">
|
|
|
- <el-text type="danger">{{ uploadResult.error }}</el-text>
|
|
|
- </el-descriptions-item>
|
|
|
- </el-descriptions>
|
|
|
+ <FileUpload
|
|
|
+ :is-worker-available="isWorkerAvailable"
|
|
|
+ :service-url="workerEndpoint.serviceUrl"
|
|
|
+ @upload-result="handleUploadResult"
|
|
|
+ />
|
|
|
|
|
|
<h2>运行状态总览</h2>
|
|
|
<el-descriptions border>
|
|
|
@@ -130,10 +101,10 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
-import { provide, ref, onMounted } from 'vue'
|
|
|
+import { provide, ref, onMounted, computed } from 'vue'
|
|
|
import { ElMessage } from 'element-plus'
|
|
|
import { useProxyStore } from '../stores/proxyStore'
|
|
|
-
|
|
|
+import FileUpload from './FileUpload.vue'
|
|
|
import WorkerCtrl from './WorkerCtrl.vue'
|
|
|
import type { CeleryStatusResponse, WorkerEndpoint } from '../api-types'
|
|
|
|
|
|
@@ -298,47 +269,7 @@ const copyToClipboard = async (text: string) => {
|
|
|
ElMessage.error('复制失败');
|
|
|
}
|
|
|
};
|
|
|
-const handleUpload = async (options: any) => {
|
|
|
- if (!isWorkerAvailable.value) {
|
|
|
- ElMessage.warning(`worker 服务不可用,无法上传文件。状态码: ${store.workerHealth?.err}`)
|
|
|
- return
|
|
|
- }
|
|
|
- try {
|
|
|
- const formData = new FormData()
|
|
|
- formData.append('file', options.file)
|
|
|
-
|
|
|
- const response = await fetch(`${workerEndpoint.value.serviceUrl}/keywords/upload`, {
|
|
|
- method: 'POST',
|
|
|
- body: formData
|
|
|
- })
|
|
|
-
|
|
|
- if (!response.ok) throw new Error('上传失败')
|
|
|
-
|
|
|
- const result = await response.json()
|
|
|
- console.log('上传成功:', result)
|
|
|
|
|
|
- // 显示上传结果
|
|
|
- uploadResult.value = {
|
|
|
- name: options.file.name,
|
|
|
- size: options.file.size,
|
|
|
- uploadTime: new Date().toLocaleString(),
|
|
|
- total_keywords: result.total_keywords,
|
|
|
- inserted_count: result.inserted_count,
|
|
|
- success: true
|
|
|
- }
|
|
|
-
|
|
|
- ElMessage.success(`成功导入 ${result.inserted_count} 个关键词(共 ${result.total_keywords} 个)`)
|
|
|
- } catch (error: any) {
|
|
|
- console.error('上传错误:', error)
|
|
|
- uploadResult.value = {
|
|
|
- name: options.file.name,
|
|
|
- size: options.file.size,
|
|
|
- uploadTime: new Date().toLocaleString(),
|
|
|
- success: false,
|
|
|
- error: error.message || '文件上传失败'
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
provide('celeryStatus', celeryStatus)
|
|
|
</script>
|
|
|
|