chenkun 2 هفته پیش
والد
کامیت
1bd6c57557
1فایلهای تغییر یافته به همراه66 افزوده شده و 7 حذف شده
  1. 66 7
      src/views/admin/TaskManagement.vue

+ 66 - 7
src/views/admin/TaskManagement.vue

@@ -27,6 +27,14 @@
               </template>
             </el-table-column>
             <el-table-column prop="file_count" label="文件数量" width="100" align="center" />
+            <el-table-column label="标注进度" min-width="150" align="center">
+              <template #default="{ row }">
+                <el-progress 
+                  :percentage="Math.min(100, Math.round((row.completed_count || 0) / (row.file_count || 1) * 100))" 
+                  :status="(row.completed_count || 0) >= (row.file_count || 1) ? 'success' : ''"
+                />
+              </template>
+            </el-table-column>
             <el-table-column prop="task_id" label="标注平台任务ID" min-width="200">
               <template #default="{ row }">
                 <el-tag v-if="row.task_id" type="info">{{ row.task_id }}</el-tag>
@@ -84,6 +92,14 @@
               </template>
             </el-table-column>
             <el-table-column prop="file_count" label="文件数量" width="100" align="center" />
+            <el-table-column label="标注进度" min-width="150" align="center">
+              <template #default="{ row }">
+                <el-progress 
+                  :percentage="Math.min(100, Math.round((row.completed_count || 0) / (row.file_count || 1) * 100))" 
+                  :status="(row.completed_count || 0) >= (row.file_count || 1) ? 'success' : ''"
+                />
+              </template>
+            </el-table-column>
             <el-table-column prop="task_id" label="标注平台任务ID" min-width="200">
               <template #default="{ row }">
                 <el-tag v-if="row.task_id" type="info">{{ row.task_id }}</el-tag>
@@ -188,6 +204,7 @@ interface TaskItem {
   type: string
   name: string
   file_count: number
+  completed_count: number
   status: string
   tag?: string
   image_url?: string
@@ -302,8 +319,13 @@ const handleCheckProgress = async (row: TaskItem) => {
 
 // 导出结果
 const handleExportData = async (row: TaskItem) => {
+  let loadingMsg: any = null
   try {
-    ElMessage.info('正在请求导出,请稍候...')
+    loadingMsg = ElMessage.info({
+      message: '正在请求导出,请稍候...',
+      duration: 0 // 不自动关闭
+    })
+    
     const response = await request.post<any, ApiResponse<any>>('/api/v1/sample/external/projects/export', {
       project_id: row.project_id,
       format: 'json'
@@ -311,20 +333,57 @@ const handleExportData = async (row: TaskItem) => {
     
     if (response.code === 0) {
       const fileUrl = response.data.file_url
+      const fileName = response.data.file_name || `export_${row.project_name || row.project_id}.json`
+      
       if (fileUrl) {
-        ElMessage.success('导出成功,即将开始下载')
-        // 如果是相对路径,可能需要拼接基础 URL
-        const downloadUrl = fileUrl.startsWith('http') ? fileUrl : `http://192.168.92.61:9003${fileUrl}`
-        window.open(downloadUrl, '_blank')
+        // 先关闭之前的“正在请求”消息
+        if (loadingMsg) loadingMsg.close()
+        
+        loadingMsg = ElMessage.success({
+          message: '导出成功,正在准备下载...',
+          duration: 3000
+        })
+        
+        // 使用我们自己的后端中转接口进行下载,彻底解决跨域和 Token 携带问题
+        // 构建中转下载链接
+        const proxyDownloadUrl = `/api/v1/sample/external/download-proxy?url=${encodeURIComponent(fileUrl)}&filename=${encodeURIComponent(fileName)}`
+        
+        // 发起下载请求
+        const fileData = await request.get(proxyDownloadUrl, {
+          responseType: 'blob'
+        }) as unknown as Blob
+        
+        // 创建本地下载链接并触发下载
+        const blob = new Blob([fileData])
+        const url = window.URL.createObjectURL(blob)
+        const link = document.createElement('a')
+        link.href = url
+        link.setAttribute('download', fileName)
+        document.body.appendChild(link)
+        link.click()
+        
+        // 清理
+        document.body.removeChild(link)
+        window.URL.revokeObjectURL(url)
       } else {
+        if (loadingMsg) loadingMsg.close()
         ElMessage.warning('导出成功但未获取到下载链接')
       }
     } else {
+      if (loadingMsg) loadingMsg.close()
       ElMessage.error(response.message || '导出失败')
     }
-  } catch (error) {
+  } catch (error: any) {
+    if (loadingMsg) loadingMsg.close()
     console.error('导出数据出错:', error)
-    ElMessage.error('导出失败')
+    
+    // 如果是业务错误且已经弹过窗了,就不要再弹了
+    if (error.isBusinessError) return
+    
+    ElMessage.error({
+      message: '导出失败:网络连接异常或权限不足',
+      duration: 5000
+    })
   }
 }