From 9c3b014fde2072e0860475e8da23f92a55140a08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B2=A1=E5=A4=8D=E4=B9=A0?= <2353956224@qq.com> Date: Wed, 22 Apr 2026 10:22:03 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=B8=8A=E4=B8=8B=E9=99=90?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/HostListDialog.vue | 121 ++++++++++++++++++++++++------ 1 file changed, 96 insertions(+), 25 deletions(-) diff --git a/src/components/HostListDialog.vue b/src/components/HostListDialog.vue index fb0ea69..a767262 100644 --- a/src/components/HostListDialog.vue +++ b/src/components/HostListDialog.vue @@ -339,7 +339,7 @@ const maxCount = ref() const checkTaskGateState = ref(null) const selectedLevels = ref(new Set()) const showLevelDropdown = ref(false) -let hostListMonitorTimer = null +const hostListDialogInstanceId = `host-list-dialog-${Math.random().toString(36).slice(2)}` const resolveRestrictedMaxAnchorCount = (fallbackValue = 9999999) => { const permissions = getPermissions() @@ -401,15 +401,24 @@ const parsedIds = computed(() => { watch(() => props.visible, (newVal) => { if (newVal) { document.body.style.overflow = 'hidden' + loadLocalGateConfig() + if (gateEnabled.value) { + claimGateOwnership() + } loadHosts() loadConfig() } else { document.body.style.overflow = '' } + + refreshHostListMonitor() }) onMounted(() => { loadLocalGateConfig() + if (gateEnabled.value) { + claimGateOwnership() + } loadConfig() if (props.visible) { @@ -417,11 +426,11 @@ onMounted(() => { loadHosts() } - startHostListMonitor() + refreshHostListMonitor() }) onUnmounted(() => { - stopHostListMonitor() + releaseGateOwnership() }) // 监听过滤器变化,同步到后端配置 @@ -479,32 +488,87 @@ const loadConfig = async () => { filters.value.ordinary = config.filters.ordinary } // 加载在线人数过滤配置 - if (config?.filters?.minOnlineFans !== undefined && config.filters.minOnlineFans > 0) { - filters.value.minOnlineFans = config.filters.minOnlineFans - } - if (config?.filters?.maxOnlineFans !== undefined && config.filters.maxOnlineFans > 0 && config.filters.maxOnlineFans < 9999999999999) { - filters.value.maxOnlineFans = config.filters.maxOnlineFans - } + filters.value.minOnlineFans = config?.filters?.minOnlineFans !== undefined && config.filters.minOnlineFans > 0 + ? config.filters.minOnlineFans + : '' + filters.value.maxOnlineFans = config?.filters?.maxOnlineFans !== undefined + && config.filters.maxOnlineFans > 0 + && config.filters.maxOnlineFans < 9999999999999 + ? config.filters.maxOnlineFans + : '' } catch (e) { console.error('加载配置失败:', e) } } -const startHostListMonitor = () => { - stopHostListMonitor() +const getGateRuntime = () => { + if (typeof window === 'undefined') { + return { ownerId: null, timer: null } + } - if (!isElectron()) return + if (!window.__hostListGateRuntime) { + window.__hostListGateRuntime = { + ownerId: null, + timer: null, + } + } - hostListMonitorTimer = setInterval(async () => { - if (!gateEnabled.value) return - await loadHosts() - }, HOST_LIST_MONITOR_INTERVAL_MS) + return window.__hostListGateRuntime } -const stopHostListMonitor = () => { - if (!hostListMonitorTimer) return - clearInterval(hostListMonitorTimer) - hostListMonitorTimer = null +const isGateOwner = () => { + return getGateRuntime().ownerId === hostListDialogInstanceId +} + +const claimGateOwnership = () => { + const runtime = getGateRuntime() + if (runtime.ownerId === hostListDialogInstanceId) return + + if (runtime.timer) { + clearInterval(runtime.timer) + runtime.timer = null + } + + runtime.ownerId = hostListDialogInstanceId +} + +const releaseGateOwnership = () => { + const runtime = getGateRuntime() + if (runtime.ownerId !== hostListDialogInstanceId) return + + if (runtime.timer) { + clearInterval(runtime.timer) + runtime.timer = null + } + + runtime.ownerId = null +} + +const refreshHostListMonitor = () => { + if (!isElectron()) return + + const runtime = getGateRuntime() + const shouldRun = gateEnabled.value && isGateOwner() + + if (!shouldRun) { + if (runtime.timer && isGateOwner()) { + clearInterval(runtime.timer) + runtime.timer = null + } + return + } + + if (runtime.timer) return + + runtime.timer = setInterval(async () => { + if (!gateEnabled.value || !isGateOwner()) { + refreshHostListMonitor() + return + } + + await loadHosts() + await syncControlCheckTaskGate() + }, HOST_LIST_MONITOR_INTERVAL_MS) } const loadLocalGateConfig = () => { @@ -570,6 +634,7 @@ const persistGateState = (value) => { const syncControlCheckTaskGate = async (forceSync = false) => { if (!isElectron()) return if (!gateEnabled.value) return + if (!isGateOwner()) return const hostCount = filteredHosts.value.length const upperLimit = Number(maxCount.value) @@ -581,8 +646,10 @@ const syncControlCheckTaskGate = async (forceSync = false) => { nextState = false } else if (Number.isFinite(lowerLimit) && lowerLimit >= 0 && hostCount < lowerLimit) { nextState = true - } else if (forceSync && checkTaskGateState.value !== null) { + } else if (checkTaskGateState.value !== null) { nextState = checkTaskGateState.value + } else if (forceSync) { + nextState = true } if (nextState === null) return @@ -699,12 +766,16 @@ watch(gateEnabled, async (enabled) => { persistGateEnabled() if (enabled) { + claimGateOwnership() + refreshHostListMonitor() void syncControlCheckTaskGate(true) return } checkTaskGateState.value = null persistGateState(null) + releaseGateOwnership() + refreshHostListMonitor() if (!isElectron()) return @@ -762,7 +833,7 @@ const selectNone = () => { const invertSelect = () => { const next = new Set() filteredHosts.value.forEach(h => { - if (!selected.value.has(h.anchorId)) next.add(h.anchorId) + if (!selected.value.has(h.id)) next.add(h.id) }) selected.value = next } @@ -781,16 +852,16 @@ const deleteSelected = async () => { } else { console.error('[HostListDialog] 删除失败:', result.error) // fallback: 前端本地删除 - hosts.value = hosts.value.filter(h => !selected.value.has(h.anchorId)) + hosts.value = hosts.value.filter(h => !selected.value.has(h.id)) selected.value = new Set() } } catch (e) { console.error('[HostListDialog] 删除异常:', e) - hosts.value = hosts.value.filter(h => !selected.value.has(h.anchorId)) + hosts.value = hosts.value.filter(h => !selected.value.has(h.id)) selected.value = new Set() } } else { - hosts.value = hosts.value.filter(h => !selected.value.has(h.anchorId)) + hosts.value = hosts.value.filter(h => !selected.value.has(h.id)) selected.value = new Set() } }