mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-07 00:36:41 +08:00
fix 整理进度显示
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user