/** * RTK 实时遥测:各页面共享最新轨迹点,随假数据/真数据推送刷新 */ import type { MockRtkPoint } from '@/mock/rtkTrack' import { computed, onUnmounted, ref } from 'vue' import { createMockRtkStream } from '@/mock/rtkTrack' const latestPoint = ref(null) let stream: ReturnType | null = null let subscribers = 0 function startBackgroundStream() { if (stream) return stream = createMockRtkStream({ intervalMs: 80, loop: true, rows: 80, pointsPerRow: 40, }) stream.start((point) => { latestPoint.value = point }) } function stopBackgroundStream() { stream?.stop() stream = null } /** 轨迹画布 / 热力图推送最新点(可与后台流并存,以后者为准) */ export function publishRtkPoint(point: MockRtkPoint) { latestPoint.value = point } export function useRtkLive() { subscribers += 1 startBackgroundStream() onUnmounted(() => { subscribers -= 1 if (subscribers <= 0) stopBackgroundStream() }) const speed = computed(() => latestPoint.value?.speed ?? null) const steelWheelTemp = computed(() => latestPoint.value?.steel_wheel_temp ?? null) const compactionValue = computed(() => latestPoint.value?.compaction_value ?? null) const passCount = computed(() => latestPoint.value?.pass_count ?? null) const qualifiedRate = computed(() => latestPoint.value?.qualified_rate ?? null) const heading = computed(() => latestPoint.value?.heading ?? null) const latitude = computed(() => latestPoint.value?.latitude ?? null) const longitude = computed(() => latestPoint.value?.longitude ?? null) /** UI 仍展示的振动频率:由速度衍生的演示值 */ const vibrationHz = computed(() => { const s = speed.value if (s == null) return null return Number((26 + s * 0.6).toFixed(1)) }) /** UI 仍展示的振幅:由压实度衍生的演示值 */ const amplitudeMm = computed(() => { const c = compactionValue.value if (c == null) return null return Number((1.5 + (c - 85) * 0.04).toFixed(2)) }) const speedText = computed(() => (speed.value == null ? '--' : `${speed.value}km/h`)) const speedTextSpaced = computed(() => (speed.value == null ? '--' : `${speed.value} km/h`)) const tempText = computed(() => (steelWheelTemp.value == null ? '--' : `${steelWheelTemp.value}°C`)) const compactionText = computed(() => (compactionValue.value == null ? '--' : `${Math.round(compactionValue.value)}%`)) const passCountText = computed(() => (passCount.value == null ? '--' : `${passCount.value}遍`)) const frequencyText = computed(() => (vibrationHz.value == null ? '--' : `${vibrationHz.value}HZ`)) const amplitudeText = computed(() => (amplitudeMm.value == null ? '--' : `${amplitudeMm.value} mm`)) return { latestPoint, speed, steelWheelTemp, compactionValue, passCount, qualifiedRate, heading, latitude, longitude, vibrationHz, amplitudeMm, speedText, speedTextSpaced, tempText, compactionText, passCountText, frequencyText, amplitudeText, publishRtkPoint, } }