| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- import { computed, onBeforeUnmount, ref } from 'vue'
- import { useRoute } from 'vue-router'
- import {
- cancelFaultRecordOperation,
- createFaultRecordOperation,
- getFaultRecordOperation,
- } from '@/service/faultRecord'
- import type {
- FaultRecordCreateReq,
- FaultRecordEnv,
- FaultRecordOpDetail,
- } from '@/service/faultRecord/interface'
- import { ENV_LABEL, errText, isTerminal } from './constants'
- /** 当前页面所属环境(来自路由 meta.env) */
- export function useFaultRecordEnv() {
- const route = useRoute()
- const env = computed<FaultRecordEnv>(() => (route.meta.env === 'test' ? 'test' : 'prod'))
- const envLabel = computed(() => ENV_LABEL[env.value])
- return { env, envLabel }
- }
- // 轮询间隔:开始后 10 秒内每 2 秒(及时看到设备应答),之后每 5 秒(等待 379/上传/下载,状态变化慢)
- const POLL_FAST_INTERVAL = 2000
- const POLL_FAST_PERIOD = 10_000
- const POLL_SLOW_INTERVAL = 5000
- /** 创建操作并轮询状态,直到结束 */
- export function useOperation(onFinished?: (d: FaultRecordOpDetail) => void) {
- const detail = ref<FaultRecordOpDetail>()
- const running = ref(false)
- const error = ref('')
- let timer: ReturnType<typeof setTimeout> | undefined
- let watchingId = ''
- // 每次开始轮询递增;只有最新一轮可以继续排下一次,避免请求在途时重复开始导致多条轮询并行
- let generation = 0
- let startedAt = 0
- function stop() {
- generation++
- if (timer) clearTimeout(timer)
- timer = undefined
- running.value = false
- }
- async function poll(gen: number) {
- const id = watchingId
- try {
- const d = await getFaultRecordOperation(id)
- if (gen !== generation) return
- detail.value = d
- if (isTerminal(d.status)) {
- stop()
- onFinished?.(d)
- return
- }
- } catch (e) {
- if (gen !== generation) return
- error.value = errText(e)
- }
- const interval = Date.now() - startedAt < POLL_FAST_PERIOD ? POLL_FAST_INTERVAL : POLL_SLOW_INTERVAL
- timer = setTimeout(poll, interval, gen)
- }
- /** 查看某个已有操作(如从历史中选择),未结束时继续轮询;对正在轮询的同一操作重复调用不会重新开始 */
- function watch(id: string) {
- if (id === watchingId && running.value) return
- stop()
- watchingId = id
- error.value = ''
- running.value = true
- startedAt = Date.now()
- poll(generation)
- }
- async function start(req: FaultRecordCreateReq) {
- error.value = ''
- detail.value = undefined
- const { id } = await createFaultRecordOperation(req)
- watch(id)
- return id
- }
- async function cancel() {
- if (!detail.value) return
- await cancelFaultRecordOperation(detail.value.id)
- }
- onBeforeUnmount(stop)
- return { detail, running, error, start, watch, cancel, stop }
- }
|