Implement background optimization composable for data refresh and SSE

Co-authored-by: jxxghp <jxxghp@163.com>
This commit is contained in:
Cursor Agent
2025-07-06 15:01:17 +00:00
parent bea6c1e326
commit 5e62bac245
10 changed files with 423 additions and 173 deletions

View File

@@ -11,12 +11,14 @@ import { cloneDeep } from 'lodash-es'
import { useI18n } from 'vue-i18n'
import { downloaderDict } from '@/api/constants'
import { useDisplay } from 'vuetify'
import { useBackgroundOptimization } from '@/composables/useBackgroundOptimization'
// 显示器宽度
const display = useDisplay()
// 获取i18n实例
const { t } = useI18n()
const { useDataRefresh } = useBackgroundOptimization()
// 定义输入
const props = defineProps({
@@ -43,9 +45,6 @@ const emit = defineEmits(['close', 'done', 'change'])
// 提示框
const $toast = useToast()
// timeout定时器
let timeoutTimer: NodeJS.Timeout | undefined = undefined
// 上传速率
const upload_rate = ref(0)
@@ -79,11 +78,6 @@ async function loadDownloaderInfo() {
if (res) {
upload_rate.value = res.upload_speed
download_rate.value = res.download_speed
// 定时查询
clearTimeout(timeoutTimer)
if (props.downloader.enabled) {
timeoutTimer = setTimeout(loadDownloaderInfo, 3000)
}
}
} catch (e) {
console.log(e)
@@ -141,14 +135,16 @@ function onClose() {
emit('close')
}
onMounted(async () => {
if (props.downloader.enabled) {
await loadDownloaderInfo()
}
})
// 使用优化的数据刷新定时器(只在下载器启用时激活)
const { stop: stopRefresh } = useDataRefresh(
`downloader-${props.downloader.name}`,
loadDownloaderInfo,
3000, // 3秒间隔
props.downloader.enabled // 只在启用时执行
)
onUnmounted(() => {
if (timeoutTimer) clearTimeout(timeoutTimer)
stopRefresh()
})
</script>
<template>

View File

@@ -9,9 +9,11 @@ import ProgressDialog from './ProgressDialog.vue'
import { FileItem, StorageConf, TransferDirectoryConf, TransferForm } from '@/api/types'
import { useI18n } from 'vue-i18n'
import { useGlobalSettingsStore } from '@/stores'
import { useBackgroundOptimization } from '@/composables/useBackgroundOptimization'
// 国际化
const { t } = useI18n()
const { useProgressSSE } = useBackgroundOptimization()
// 显示器宽度
const display = useDisplay()
@@ -49,8 +51,8 @@ const $toast = useToast()
// TMDB选择对话框
const mediaSelectorDialog = ref(false)
// 加载进度SSE
const progressEventSource = ref<EventSource>()
// 进度是否激活
const progressActive = ref(false)
// 整理进度条
const progressDialog = ref(false)
@@ -189,34 +191,34 @@ async function handleTransferLog(logid: number, background: boolean = false) {
}
}
// 进度SSE消息处理函数
function handleProgressMessage(event: MessageEvent) {
const progress = JSON.parse(event.data)
if (progress) {
progressText.value = progress.text
progressValue.value = progress.value
}
}
// 使用优化的进度SSE连接
const progressSSE = useProgressSSE(
`${import.meta.env.VITE_API_BASE_URL}system/progress/filetransfer`,
handleProgressMessage,
'reorganize-progress',
progressActive
)
// 使用SSE监听加载进度
function startLoadingProgress() {
// 在创建新连接之前,先确保任何可能存在的旧连接都被关闭了,防止因快速重复点击而产生孤儿连接。
if (progressEventSource.value) {
progressEventSource.value.close()
}
progressText.value = t('dialog.reorganize.processing')
progressEventSource.value = new EventSource(`${import.meta.env.VITE_API_BASE_URL}system/progress/filetransfer`)
progressEventSource.value.onmessage = event => {
const progress = JSON.parse(event.data)
if (progress) {
progressText.value = progress.text
progressValue.value = progress.value
}
}
// 发生错误时,也确保连接被关闭,避免重试等意外行为
progressEventSource.value.onerror = () => {
if (progressEventSource.value) {
progressEventSource.value.close()
}
}
progressActive.value = true
progressSSE.start()
}
// 停止监听加载进度
function stopLoadingProgress() {
progressEventSource.value?.close()
progressActive.value = false
progressSSE.stop()
}
// 整理文件

View File

@@ -4,9 +4,11 @@ import api from '@/api'
import { FileItem, TransferQueue } from '@/api/types'
import { useDisplay } from 'vuetify'
import { useI18n } from 'vue-i18n'
import { useBackgroundOptimization } from '@/composables/useBackgroundOptimization'
// 多语言支持
const { t } = useI18n()
const { useProgressSSE } = useBackgroundOptimization()
// 显示器宽度
const display = useDisplay()
@@ -16,9 +18,6 @@ const emit = defineEmits(['close'])
// 数据列表
const dataList = ref<TransferQueue[]>([])
// 加载进度SSE
const progressEventSource = ref<EventSource>()
// 整理进度文本
const progressText = ref(t('dialog.transferQueue.processing'))
@@ -28,6 +27,9 @@ const progressValue = ref(0)
// 数据可刷新标志
const refreshFlag = ref(false)
// 进度是否激活
const progressActive = ref(false)
// 活动标签
const activeTab = ref('')
@@ -91,42 +93,54 @@ async function remove_queue_task(fileitem: FileItem) {
}
}
// 使用SSE监听加载进度
function startLoadingProgress() {
progressText.value = t('dialog.transferQueue.processing')
progressEventSource.value = new EventSource(`${import.meta.env.VITE_API_BASE_URL}system/progress/filetransfer`)
progressEventSource.value.onmessage = event => {
const progress = JSON.parse(event.data)
if (progress) {
if (!progress.enable) {
progressText.value = t('dialog.transferQueue.processing')
progressValue.value = 0
if (refreshFlag.value) {
refreshFlag.value = false
get_transfer_queue()
}
return
// 进度SSE消息处理函数
function handleProgressMessage(event: MessageEvent) {
const progress = JSON.parse(event.data)
if (progress) {
if (!progress.enable) {
progressText.value = t('dialog.transferQueue.processing')
progressValue.value = 0
if (refreshFlag.value) {
refreshFlag.value = false
get_transfer_queue()
}
progressText.value = progress.text
progressValue.value = progress.value
if (progress.value >= 100 && refreshFlag.value) {
return
}
progressText.value = progress.text
progressValue.value = progress.value
if (progress.value >= 100 && refreshFlag.value) {
refreshFlag.value = false
get_transfer_queue()
} else {
if (progress.value > 0 && refreshFlag.value && progress.text?.includes('整理完成')) {
refreshFlag.value = false
get_transfer_queue()
} else {
if (progress.value > 0 && refreshFlag.value && progress.text?.includes('整理完成')) {
refreshFlag.value = false
get_transfer_queue()
} else {
refreshFlag.value = true
}
refreshFlag.value = true
}
}
}
}
// 使用优化的进度SSE连接
const progressSSE = useProgressSSE(
`${import.meta.env.VITE_API_BASE_URL}system/progress/filetransfer`,
handleProgressMessage,
'transfer-queue-progress',
progressActive
)
// 使用SSE监听加载进度
function startLoadingProgress() {
progressText.value = t('dialog.transferQueue.processing')
progressActive.value = true
progressSSE.start()
}
// 停止监听加载进度
function stopLoadingProgress() {
progressEventSource.value?.close()
progressActive.value = false
progressSSE.stop()
}
onMounted(() => {

View File

@@ -11,9 +11,11 @@ import ProgressDialog from '../dialog/ProgressDialog.vue'
import { useDisplay } from 'vuetify'
import MediaInfoDialog from '../dialog/MediaInfoDialog.vue'
import { useI18n } from 'vue-i18n'
import { useBackgroundOptimization } from '@/composables/useBackgroundOptimization'
// 国际化
const { t } = useI18n()
const { useProgressSSE } = useBackgroundOptimization()
// 显示器宽度
const display = useDisplay()
@@ -105,8 +107,8 @@ const nameTestDialog = ref(false)
// 弹出菜单
const dropdownItems = ref<{ [key: string]: any }[]>([])
// 加载进度SSE
const progressEventSource = ref<EventSource>()
// 进度是否激活
const progressActive = ref(false)
// 目录过滤
const dirs = computed(() => items.value.filter(item => item.type === 'dir' && item.name.includes(filter.value)))
@@ -530,22 +532,34 @@ async function batchScrape() {
})
}
// 进度SSE消息处理函数
function handleProgressMessage(event: MessageEvent) {
const progress = JSON.parse(event.data)
if (progress) {
progressText.value = progress.text
progressValue.value = progress.value
}
}
// 使用优化的进度SSE连接
const progressSSE = useProgressSSE(
`${import.meta.env.VITE_API_BASE_URL}system/progress/batchrename`,
handleProgressMessage,
'file-batch-rename-progress',
progressActive
)
// 使用SSE监听加载进度
function startLoadingProgress() {
progressText.value = t('common.pleaseWait')
progressEventSource.value = new EventSource(`${import.meta.env.VITE_API_BASE_URL}system/progress/batchrename`)
progressEventSource.value.onmessage = event => {
const progress = JSON.parse(event.data)
if (progress) {
progressText.value = progress.text
progressValue.value = progress.value
}
}
progressActive.value = true
progressSSE.start()
}
// 停止监听加载进度
function stopLoadingProgress() {
progressEventSource.value?.close()
progressActive.value = false
progressSSE.stop()
}
onMounted(() => {