Browse Source

feat: poll open device detail every 5s

main
xiaosi 2 weeks ago
parent
commit
1c6cf6a2cc
  1. 83
      src/views/DeviceDetailView/DeviceDetailView.vue

83
src/views/DeviceDetailView/DeviceDetailView.vue

@ -295,7 +295,7 @@
</template> </template>
<script setup> <script setup>
import { computed, onMounted, ref } from 'vue'
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router' import { useRoute, useRouter } from 'vue-router'
import { useDeviceStore } from '@/stores/modules/devicesStore' import { useDeviceStore } from '@/stores/modules/devicesStore'
import { useUiStore } from '@/stores/modules/uiStore' import { useUiStore } from '@/stores/modules/uiStore'
@ -345,6 +345,69 @@ const logColumns = [
const record = computed(() => devices.record(route.params.id)) const record = computed(() => devices.record(route.params.id))
const asset = computed(() => devices.asset(route.params.id)) const asset = computed(() => devices.asset(route.params.id))
const isDrone = computed(() => record.value?.kind === 'drone') const isDrone = computed(() => record.value?.kind === 'drone')
const DETAIL_POLL_MS = 5000
let detailPollTimer = null
let detailPollInflight = null
let detailPollGen = 0
let detailDisposed = false
function clearDetailPollTimer() {
window.clearInterval(detailPollTimer)
detailPollTimer = null
}
async function pollCurrentDetail() {
if (detailDisposed) return
if (detailPollInflight) return
const id = String(route.params.id || '')
const rec = devices.record(id)
if (!id || !rec) return
const gen = detailPollGen
const url = rec.kind === 'drone' ? urls.DRONE(id) : urls.DOCK(id)
detailPollInflight = request.get(url)
try {
const detail = await detailPollInflight
if (detailDisposed || gen !== detailPollGen) return
if (String(route.params.id) !== id) return
if (rec.kind === 'drone') devices.applyDroneDetail(id, detail || {})
else devices.applyDockDetail(id, detail || {})
} catch (e) {
if (detailDisposed || gen !== detailPollGen) return
console.warn('[device-detail] poll failed', e)
} finally {
detailPollInflight = null
}
}
function startDetailPolling() {
clearDetailPollTimer()
if (detailDisposed || document.visibilityState === 'hidden') return
detailPollTimer = window.setInterval(() => {
void pollCurrentDetail()
}, DETAIL_POLL_MS)
}
function stopDetailPolling() {
clearDetailPollTimer()
}
function restartDetailPolling() {
detailPollGen += 1
stopDetailPolling()
void pollCurrentDetail()
startDetailPolling()
}
function onDetailVisibility() {
if (detailDisposed) return
if (document.visibilityState === 'hidden') {
stopDetailPolling()
return
}
void pollCurrentDetail()
startDetailPolling()
}
const boundDrone = computed(() => (record.value?.kind === 'dock' ? devices.drones.find((d) => d.dockId === record.value.dockId) : null)) const boundDrone = computed(() => (record.value?.kind === 'dock' ? devices.drones.find((d) => d.dockId === record.value.dockId) : null))
const boundDock = computed(() => (record.value?.kind === 'drone' ? devices.docks.find((d) => d.dockId === record.value.dockId) : null)) const boundDock = computed(() => (record.value?.kind === 'drone' ? devices.docks.find((d) => d.dockId === record.value.dockId) : null))
const latestLog = computed(() => logs.value[0] || null) const latestLog = computed(() => logs.value[0] || null)
@ -486,6 +549,8 @@ function chargeText(value) {
} }
onMounted(async () => { onMounted(async () => {
detailDisposed = false
document.addEventListener('visibilitychange', onDetailVisibility)
try { try {
await devices.load() await devices.load()
if (!isAdmin.value) { if (!isAdmin.value) {
@ -494,8 +559,24 @@ onMounted(async () => {
} catch (e) { } catch (e) {
ui.toast(e.message || '加载设备失败') ui.toast(e.message || '加载设备失败')
} }
startDetailPolling()
}) })
onUnmounted(() => {
detailDisposed = true
detailPollGen += 1
stopDetailPolling()
document.removeEventListener('visibilitychange', onDetailVisibility)
})
watch(
() => String(route.params.id || ''),
(next, prev) => {
if (!next || next === prev) return
restartDetailPolling()
}
)
const COMMAND_NAMES = { const COMMAND_NAMES = {
'dock.open': '打开舱门', 'dock.open': '打开舱门',

Loading…
Cancel
Save