Sfoglia il codice sorgente

新增文件上传组件

mrh 9 mesi fa
parent
commit
a476fd832e

BIN
%SystemDrive%/ProgramData/SogouInput/Components/Picface/Cloud/sgim_picface_cloud.bin


BIN
%SystemDrive%/ProgramData/SogouInput/Components/Picface/Cloud/sgim_picface_cloud_bak.bin


+ 1 - 0
ui/fontend/src/components.d.ts

@@ -35,6 +35,7 @@ declare module 'vue' {
     ElText: typeof import('element-plus/es')['ElText']
     ElTooltip: typeof import('element-plus/es')['ElTooltip']
     ElUpload: typeof import('element-plus/es')['ElUpload']
+    FileUpload: typeof import('./components/FileUpload.vue')['default']
     Home: typeof import('./components/Home.vue')['default']
     Menu: typeof import('./components/Menu.vue')['default']
     Proxy: typeof import('./components/Proxy.vue')['default']

+ 102 - 0
ui/fontend/src/components/FileUpload.vue

@@ -0,0 +1,102 @@
+<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>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue'
+import { ElMessage } from 'element-plus'
+
+const props = defineProps<{
+  isWorkerAvailable: boolean;
+  serviceUrl: string;
+}>()
+
+const emit = defineEmits<{
+  (e: 'upload-result', result: any): void
+}>()
+
+const uploadResult = ref<{
+  name: string;
+  size: number;
+  uploadTime: string;
+  total_keywords?: number;
+  inserted_count?: number;
+  success?: boolean;
+  error?: string;
+} | null>(null)
+
+const handleUpload = async (options: any) => {
+  if (!props.isWorkerAvailable) {
+    ElMessage.warning('worker 服务不可用,无法上传文件')
+    return
+  }
+  
+  try {
+    const formData = new FormData()
+    formData.append('file', options.file)
+    
+    const response = await fetch(`${props.serviceUrl}/keywords/upload`, {
+      method: 'POST',
+      body: formData
+    })
+    
+    if (!response.ok) throw new Error('上传失败')
+    
+    const result = await response.json()
+    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
+    }
+    emit('upload-result', uploadResult.value)
+    ElMessage.success(`成功导入 ${result.inserted_count} 个关键词(共 ${result.total_keywords} 个)`)
+  } catch (error: any) {
+    uploadResult.value = {
+      name: options.file.name,
+      size: options.file.size,
+      uploadTime: new Date().toLocaleString(),
+      success: false,
+      error: error.message || '文件上传失败'
+    }
+    emit('upload-result', uploadResult.value)
+  }
+}
+</script>

+ 7 - 76
ui/fontend/src/components/Home.vue

@@ -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>
 

+ 11 - 1
ui/fontend/src/components/WorkerCtrl.vue

@@ -34,7 +34,6 @@
                 @click="sendRequest('search', 'submit_all')">提交所有未完成任务
               </el-button>
               <el-button type="primary" 
-                :disabled="!workerStatus.search || loadingStates.search"
                 @click="sendRequest('search', 'clean')">清空剩余任务
               </el-button>
             </el-row>
@@ -67,6 +66,16 @@
                 :loading="loadingStates.crawl"
                 @click="sendRequest('crawl', 'stop')">停止运行</el-button>
             </div>
+            <el-row>
+              <el-button type="primary" 
+                :disabled="!workerStatus.crawl || loadingStates.crawl"
+                @click="sendRequest('crawl', 'submit_all')">提交所有未完成任务
+              </el-button>
+              <el-button type="primary" 
+                @click="sendRequest('crawl', 'clean')">清空剩余任务
+              </el-button>
+            </el-row>
+
           </el-card>
         </el-col>
     
@@ -193,6 +202,7 @@ const sendRequest = async (workerName: string, action: string) => {
           }: {}),
           ...(workerName === 'crawl' ? {
             overwrite: false,
+            dry_run: dryRun.value,
             proxy_pool_url: store.selectedProxy
           } : {}),
           ...(workerName === 'convert' ? {