fix: Local->Many 传输等待后端任务真正完成

- 改用 uploadFile + subscribeUploadProgress 替代 uploadFileWithProgress
- 只有后端任务状态为 success 才标记成功
- 修复显示成功但远端无文件的问题
This commit is contained in:
liumangmang
2026-03-18 23:02:31 +08:00
parent 80fc5c8a0f
commit c387cc2487

View File

@@ -1,7 +1,7 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { ref, computed } from 'vue' import { ref, computed } from 'vue'
import { createRemoteTransferTask, subscribeRemoteTransferProgress, uploadFileWithProgress } from '../api/sftp' import { createRemoteTransferTask, subscribeRemoteTransferProgress, uploadFile, subscribeUploadProgress } from '../api/sftp'
export type TransferMode = 'LOCAL_TO_MANY' | 'REMOTE_TO_MANY' export type TransferMode = 'LOCAL_TO_MANY' | 'REMOTE_TO_MANY'
export type TransferItemStatus = 'queued' | 'running' | 'success' | 'error' | 'cancelled' export type TransferItemStatus = 'queued' | 'running' | 'success' | 'error' | 'cancelled'
@@ -188,17 +188,11 @@ export const useTransfersStore = defineStore('transfers', () => {
runs.value = [run, ...runs.value] runs.value = [run, ...runs.value]
const activeXhrs: XMLHttpRequest[] = [] let cancelled = false
const unsubscribers: (() => void)[] = [] const unsubscribers: (() => void)[] = []
controllers.set(runId, { controllers.set(runId, {
abortAll: () => { abortAll: () => {
for (const xhr of activeXhrs) { cancelled = true
try {
xhr.abort()
} catch {
// ignore
}
}
}, },
unsubscribers, unsubscribers,
}) })
@@ -211,7 +205,7 @@ export const useTransfersStore = defineStore('transfers', () => {
if (itemIndex === -1) continue if (itemIndex === -1) continue
const item = runItems[itemIndex]! const item = runItems[itemIndex]!
tasks.push(async () => { tasks.push(async () => {
if (item.status === 'cancelled') return if (item.status === 'cancelled' || cancelled) return
item.status = 'running' item.status = 'running'
item.progress = 0 item.progress = 0
item.startedAt = now() item.startedAt = now()
@@ -219,28 +213,24 @@ export const useTransfersStore = defineStore('transfers', () => {
const stopPseudoProgress = startPseudoProgress(item) const stopPseudoProgress = startPseudoProgress(item)
try { try {
const xhr = uploadFileWithProgress(connectionId, targetDir || '', file) // 发起上传并获取 taskId
activeXhrs.push(xhr) const uploadRes = await uploadFile(connectionId, targetDir || '', file)
const taskId = uploadRes.data.taskId
// 订阅上传任务进度,等待真正完成
await new Promise<void>((resolve, reject) => { await new Promise<void>((resolve, reject) => {
let lastTick = 0 const unsubscribe = subscribeUploadProgress(taskId, (task) => {
xhr.onProgress = (percent) => { const progress = Math.max(0, Math.min(100, task.progress || 0))
console.log('[Transfers] onProgress callback fired:', percent, 'item:', item.label) item.progress = progress
const t = now()
if (t - lastTick < 100 && percent !== 100) return
lastTick = t
const newProgress = Math.max(item.progress || 0, Math.max(0, Math.min(100, percent)))
console.log('[Transfers] Updating item.progress from', item.progress, 'to', newProgress)
item.progress = newProgress
runs.value = [...runs.value] runs.value = [...runs.value]
}
console.log('[Transfers] Set onProgress callback for:', item.label) if (task.status === 'success') {
xhr.onload = () => { resolve()
if (xhr.status >= 200 && xhr.status < 300) resolve() } else if (task.status === 'error') {
else reject(new Error(xhr.responseText || `HTTP ${xhr.status}`)) reject(new Error(task.error || 'Upload failed'))
} }
xhr.onerror = () => reject(new Error('Network error')) })
xhr.onabort = () => reject(new Error('Cancelled')) unsubscribers.push(unsubscribe)
}) })
item.status = 'success' item.status = 'success'