fix 整理进度显示

This commit is contained in:
jxxghp
2025-08-24 17:50:03 +08:00
parent 1af1a06700
commit b6cb341082
+90 -112
View File
@@ -20,22 +20,14 @@ const emit = defineEmits(['close'])
// 数据列表 // 数据列表
const dataList = ref<TransferQueue[]>([]) const dataList = ref<TransferQueue[]>([])
// 整体进度相关 // 整体进度相关 - 根据完成的文件计算
const overallProgress = ref({ const overallProgress = ref({
enable: false,
value: 0, value: 0,
text: t('dialog.transferQueue.processing'), text: t('dialog.transferQueue.processing'),
data: {
current: '',
finished: [] as string[],
},
}) })
// 当前文件进度相关 // 文件进度映射
const currentFileProgress = ref({ const fileProgressMap = ref<Map<string, { enable: boolean; value: number }>>(new Map())
enable: false,
value: 0,
})
// 数据可刷新标志 // 数据可刷新标志
const refreshFlag = ref(false) const refreshFlag = ref(false)
@@ -87,6 +79,22 @@ const activeTasks = computed(() => {
return dataList.value.find(item => item.media.title_year === activeTab.value)?.tasks return dataList.value.find(item => item.media.title_year === activeTab.value)?.tasks
}) })
// 计算整体进度
const overallProgressComputed = computed(() => {
if (dataList.value.length === 0) return 0
const allTasks = dataList.value.flatMap(item => item.tasks)
const totalTasks = allTasks.length
const completedTasks = allTasks.filter(task => task.state === 'completed').length
return totalTasks > 0 ? (completedTasks / totalTasks) * 100 : 0
})
// 获取文件进度
function getFileProgress(filePath: string) {
return fileProgressMap.value.get(filePath) || { enable: false, value: 0 }
}
// 调用API获取队列信息 // 调用API获取队列信息
async function get_transfer_queue() { async function get_transfer_queue() {
try { try {
@@ -119,119 +127,87 @@ async function remove_queue_task(fileitem: FileItem) {
} }
} }
// 整体进度SSE消息处理函数 // 文件进度SSE消息处理函数
function handleOverallProgressMessage(event: MessageEvent) { function createFileProgressHandler(filePath: string) {
try { return function handleFileProgressMessage(event: MessageEvent) {
const progress = JSON.parse(event.data) try {
if (progress) { const progress = JSON.parse(event.data)
overallProgress.value = { if (progress) {
enable: progress.enable || false, fileProgressMap.value.set(filePath, {
value: progress.value || 0, enable: progress.enable || false,
text: progress.text || t('dialog.transferQueue.processing'), value: progress.value || 0,
data: { })
current: progress.data?.current || '',
finished: progress.data?.finished || [],
},
}
// 如果进度完成或禁用,刷新队列数据
if (!progress.enable || progress.value >= 100) {
if (refreshFlag.value) {
refreshFlag.value = false
get_transfer_queue()
}
} else {
refreshFlag.value = true
} }
} catch (error) {
console.error('解析文件进度消息失败:', error)
} }
} catch (error) {
console.error('解析整体进度消息失败:', error)
} }
} }
// 当前文件进度SSE消息处理函数 // 文件进度SSE连接映射
function handleCurrentFileProgressMessage(event: MessageEvent) { const fileProgressSSEMap = ref<Map<string, any>>(new Map())
try {
const progress = JSON.parse(event.data) // 启动文件进度监听
if (progress) { function startFileProgress(filePath: string) {
currentFileProgress.value = { if (fileProgressSSEMap.value.has(filePath)) {
enable: progress.enable || false, return // 已经存在连接
value: progress.value || 0,
}
}
} catch (error) {
console.error('解析当前文件进度消息失败:', error)
} }
// filePath计算md5
const filePathMd5 = CryptoJS.MD5(filePath).toString()
// 使用包含文件路径的唯一监听器ID
const uniqueListenerId = `transfer-queue-file-progress-${filePathMd5}`
const fileProgressUrl = `${import.meta.env.VITE_API_BASE_URL}system/progress/${filePathMd5}`
const fileProgressSSE = useProgressSSE(
fileProgressUrl,
createFileProgressHandler(filePath),
uniqueListenerId,
progressActive,
)
fileProgressSSE.start()
fileProgressSSEMap.value.set(filePath, fileProgressSSE)
} }
// 使用优化的进度SSE连接 - 整体进度 // 停止所有文件进度监听
const overallProgressUrl = `${import.meta.env.VITE_API_BASE_URL}system/progress/filetransfer` function stopAllFileProgress() {
const overallProgressSSE = useProgressSSE( fileProgressSSEMap.value.forEach((sse, filePath) => {
overallProgressUrl, sse.stop()
handleOverallProgressMessage, })
'transfer-queue-overall-progress', fileProgressSSEMap.value.clear()
progressActive, fileProgressMap.value.clear()
)
// 当前文件进度SSE连接
let currentFileProgressSSE: any = null
// 启动当前文件进度监听
function startCurrentFileProgress(filePath: string) {
if (currentFileProgressSSE) {
currentFileProgressSSE.stop()
}
if (filePath) {
// filePath计算md5
const filePathMd5 = CryptoJS.MD5(filePath).toString()
// 使用包含文件路径的唯一监听器ID,避免SSE管理器复用连接导致的消息串流
const uniqueListenerId = `transfer-queue-current-file-progress-${filePathMd5}`
const currentFileProgressUrl = `${import.meta.env.VITE_API_BASE_URL}system/progress/${filePathMd5}`
currentFileProgressSSE = useProgressSSE(
currentFileProgressUrl,
handleCurrentFileProgressMessage,
uniqueListenerId,
progressActive,
)
currentFileProgressSSE.start()
}
} }
// 停止当前文件进度监听 // 监听队列变化,自动管理文件进度SSE
function stopCurrentFileProgress() {
if (currentFileProgressSSE) {
currentFileProgressSSE.stop()
currentFileProgressSSE = null
}
}
// 监听当前文件变化,自动切换进度监听
watch( watch(
() => overallProgress.value.data.current, dataList,
newCurrentFile => { newDataList => {
if (newCurrentFile) { // 停止所有现有的文件进度监听
startCurrentFileProgress(newCurrentFile) stopAllFileProgress()
} else {
stopCurrentFileProgress() // 为所有正在运行的文件启动进度监听
currentFileProgress.value = { enable: false, value: 0 } newDataList.forEach(item => {
} item.tasks.forEach(task => {
if (task.state === 'running') {
startFileProgress(task.fileitem.path)
}
})
})
}, },
{ deep: true },
) )
// 使用SSE监听加载进度 // 使用SSE监听加载进度
function startLoadingProgress() { function startLoadingProgress() {
overallProgress.value.text = t('dialog.transferQueue.processing') overallProgress.value.text = t('dialog.transferQueue.processing')
progressActive.value = true progressActive.value = true
overallProgressSSE.start()
} }
// 停止监听加载进度 // 停止监听加载进度
function stopLoadingProgress() { function stopLoadingProgress() {
progressActive.value = false progressActive.value = false
overallProgressSSE.stop() stopAllFileProgress()
stopCurrentFileProgress()
} }
// 启动定时获取队列 // 启动定时获取队列
@@ -277,10 +253,10 @@ onUnmounted(() => {
<VDialogCloseBtn @click="emit('close')" /> <VDialogCloseBtn @click="emit('close')" />
<!-- 整体进度显示 --> <!-- 整体进度显示 -->
<VProgressLinear v-if="dataList.length > 0" :value="overallProgress.value" color="primary" :height="2" /> <VProgressLinear v-if="dataList.length > 0" :value="overallProgressComputed" color="primary" :height="2" />
<VDivider v-else /> <VDivider v-else />
<div v-if="overallProgress.enable && overallProgress.value > 0" class="pt-2 text-center"> <div v-if="dataList.length > 0 && overallProgressComputed > 0" class="pt-2 text-center">
<div class="text-sm font-medium">{{ overallProgress.value.toFixed(1) }}%{{ overallProgress.text }}</div> <div class="text-sm font-medium">{{ overallProgressComputed.toFixed(1) }}%{{ overallProgress.text }}</div>
</div> </div>
<VCardText v-if="dataList.length === 0" class="text-center"> <VCardText v-if="dataList.length === 0" class="text-center">
@@ -310,14 +286,16 @@ onUnmounted(() => {
</VChip> </VChip>
</VListItemSubtitle> </VListItemSubtitle>
<!-- 当前文件进度显示 --> <!-- 文件进度显示 -->
<div <div v-if="task.state === 'running' && getFileProgress(task.fileitem.path).enable" class="mt-2">
v-if="overallProgress.data.current === task.fileitem.path && currentFileProgress.enable" <VProgressLinear
class="mt-2" :value="getFileProgress(task.fileitem.path).value"
> color="success"
<VProgressLinear :value="currentFileProgress.value" color="success" :height="1" class="mb-1" /> :height="1"
class="mb-1"
/>
<div class="text-xs text-medium-emphasis text-center"> <div class="text-xs text-medium-emphasis text-center">
{{ currentFileProgress.value.toFixed(1) }}% {{ getFileProgress(task.fileitem.path).value.toFixed(1) }}%
</div> </div>
</div> </div>
<template #append> <template #append>
@@ -325,7 +303,7 @@ onUnmounted(() => {
size="small" size="small"
icon="mdi-cancel" icon="mdi-cancel"
@click="remove_queue_task(task.fileitem)" @click="remove_queue_task(task.fileitem)"
:disabled="overallProgress.data.current === task.fileitem.path" :disabled="task.state === 'running'"
/> />
</template> </template>
</VListItem> </VListItem>