fix: 账号页闪烁/浏览类型/截图复制/时区统一

This commit is contained in:
2025-12-14 11:30:49 +08:00
parent 2ec88eac3b
commit a9c8aac48f
59 changed files with 685 additions and 339 deletions

View File

@@ -59,7 +59,6 @@ const editForm = reactive({
const browseTypeOptions = [
{ label: '应读', value: '应读' },
{ label: '未读', value: '未读' },
{ label: '注册前未读', value: '注册前未读' },
]
@@ -80,8 +79,13 @@ function normalizeAccountPayload(acc) {
}
function replaceAccounts(list) {
for (const key of Object.keys(accountsById)) delete accountsById[key]
for (const acc of list || []) normalizeAccountPayload(acc)
const nextList = Array.isArray(list) ? list : []
const nextIds = new Set(nextList.map((acc) => String(acc?.id || '')))
for (const existingId of Object.keys(accountsById)) {
if (!nextIds.has(existingId)) delete accountsById[existingId]
}
for (const acc of nextList) normalizeAccountPayload(acc)
}
function ensureBrowseTypeDefaults() {
@@ -138,8 +142,9 @@ function showRuntimeProgress(acc) {
return true
}
async function refreshStats() {
statsLoading.value = true
async function refreshStats(options = {}) {
const silent = Boolean(options?.silent)
if (!silent) statsLoading.value = true
try {
const data = await fetchRunStats()
stats.today_completed = Number(data?.today_completed || 0)
@@ -150,7 +155,7 @@ async function refreshStats() {
} catch (e) {
if (e?.response?.status === 401) window.location.href = '/login'
} finally {
statsLoading.value = false
if (!silent) statsLoading.value = false
}
}
@@ -456,6 +461,41 @@ function bindSocket() {
let unbindSocket = null
let statsTimer = null
const shouldPollStats = computed(() => {
// 仅在“真正执行中”才轮询(排队中不轮询,避免空转导致页面闪烁)
return accounts.value.some((acc) => {
if (!acc?.is_running) return false
const statusText = String(acc.status || '')
if (statusText.includes('排队')) return false
return true
})
})
function stopStatsPolling() {
if (!statsTimer) return
window.clearInterval(statsTimer)
statsTimer = null
}
function startStatsPolling() {
if (statsTimer) return
statsTimer = window.setInterval(() => refreshStats({ silent: true }), 10_000)
}
function syncStatsPolling(prevRunning = null) {
const running = shouldPollStats.value
// 任务从“运行中 -> 空闲”时,补拉一次统计以确保最终数据正确,再停止轮询
if (prevRunning === true && running === false) refreshStats({ silent: true }).catch(() => {})
if (running) startStatsPolling()
else stopStatsPolling()
}
watch(shouldPollStats, (running, prevRunning) => {
syncStatsPolling(prevRunning)
})
onMounted(async () => {
if (!userStore.vipInfo) {
userStore.refreshVipInfo().catch(() => {
@@ -467,12 +507,12 @@ onMounted(async () => {
await refreshAccounts()
await refreshStats()
statsTimer = window.setInterval(refreshStats, 10_000)
syncStatsPolling()
})
onBeforeUnmount(() => {
if (unbindSocket) unbindSocket()
if (statsTimer) window.clearInterval(statsTimer)
stopStatsPolling()
})
</script>
@@ -565,7 +605,7 @@ onBeforeUnmount(() => {
</div>
</div>
<el-skeleton v-if="loading || statsLoading" :rows="5" animated />
<el-skeleton v-if="loading" :rows="5" animated />
<template v-else>
<el-empty v-if="accounts.length === 0" description="暂无账号,点击右上角添加" />
<div v-else class="grid">