merge
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
import { computed, toValue, type MaybeRefOrGetter } from 'vue'
|
||||
import type { VehicleCardModel } from '@/types/car'
|
||||
|
||||
export interface VehicleCardStateOptions {
|
||||
vehicle: MaybeRefOrGetter<VehicleCardModel>
|
||||
}
|
||||
|
||||
const stateLabels: Record<string, string> = {
|
||||
idle: '空闲',
|
||||
running: '运行',
|
||||
charging: '充电',
|
||||
paused: '暂停',
|
||||
fault: '故障',
|
||||
offline: '离线'
|
||||
}
|
||||
|
||||
function formatMissionIdSuffix(missionId?: string | number | null): string {
|
||||
if (missionId == null) return ''
|
||||
const id = String(missionId).trim()
|
||||
if (!id || id === '0') return ''
|
||||
return `-${id}`
|
||||
}
|
||||
|
||||
function appendMissionId(base: string, missionId?: string | number | null): string {
|
||||
const suffix = formatMissionIdSuffix(missionId)
|
||||
return suffix ? `${base}${suffix}` : base
|
||||
}
|
||||
|
||||
export function useVehicleCardState(opts: VehicleCardStateOptions) {
|
||||
const vehicle = computed(() => toValue(opts.vehicle))
|
||||
|
||||
const stateLabel = computed(() => stateLabels[vehicle.value.state] ?? vehicle.value.state)
|
||||
|
||||
const batteryPct = computed(() => {
|
||||
const raw = vehicle.value.batterySoc ?? 0
|
||||
const pct = raw > 1 ? raw : raw * 100
|
||||
return Math.max(0, Math.min(100, Math.round(pct)))
|
||||
})
|
||||
|
||||
const batteryTone = computed(() => {
|
||||
const p = batteryPct.value
|
||||
if (p < 20) return 'tone-danger'
|
||||
if (p < 50) return 'tone-warning'
|
||||
return 'tone-success'
|
||||
})
|
||||
|
||||
const switchOn = computed(() => vehicle.value.maintenanceMode === 'online')
|
||||
|
||||
const statusPill = computed(() => {
|
||||
const v = vehicle.value
|
||||
if (v.reachable === false) return { label: '不可达', tone: 'tone-danger' }
|
||||
if (v.isAlarmActive) return { label: '报警中', tone: 'tone-danger' }
|
||||
if (v.maintenanceMode === 'offline') return { label: '下线维护', tone: 'tone-warning' }
|
||||
if (v.maintenanceMode === 'repair') return { label: '现场检修', tone: 'tone-warning' }
|
||||
if (v.maintenanceMode === 'blown') return { label: '返厂检修', tone: 'tone-danger' }
|
||||
if (v.state === 'fault') return { label: '故障', tone: 'tone-danger' }
|
||||
if (v.state === 'running') return { label: '运行中', tone: 'tone-success' }
|
||||
if (v.state === 'charging') return { label: '充电中', tone: 'tone-info' }
|
||||
if (v.state === 'offline') return { label: '离线', tone: 'tone-idle' }
|
||||
return { label: stateLabel.value, tone: 'tone-idle' }
|
||||
})
|
||||
|
||||
const missionIdSuffix = computed(() => formatMissionIdSuffix(vehicle.value.missionId))
|
||||
|
||||
const statusDisplayLabel = computed(() =>
|
||||
appendMissionId(statusPill.value.label, vehicle.value.missionId)
|
||||
)
|
||||
|
||||
const runtimeStatusLabel = computed(() =>
|
||||
appendMissionId(vehicle.value.lstatus ?? stateLabel.value, vehicle.value.missionId)
|
||||
)
|
||||
|
||||
const accentTone = computed(() => statusPill.value.tone)
|
||||
|
||||
const latencyLabel = computed(() => {
|
||||
const ms = vehicle.value.latencyMs
|
||||
if (ms == null) return '—'
|
||||
if (vehicle.value.reachable === false) return '超时'
|
||||
return `${ms} ms`
|
||||
})
|
||||
|
||||
const latencyClass = computed(() => {
|
||||
const ms = vehicle.value.latencyMs
|
||||
if (vehicle.value.reachable === false) return 'val-danger'
|
||||
if (ms != null && ms > 80) return 'val-warn'
|
||||
return ''
|
||||
})
|
||||
|
||||
const faultLabel = computed(() => {
|
||||
const v = vehicle.value.faultRatePercent
|
||||
if (v == null) return '—'
|
||||
return `${v.toFixed(2)}%`
|
||||
})
|
||||
|
||||
const faultClass = computed(() => {
|
||||
const v = vehicle.value.faultRatePercent ?? 0
|
||||
if (v >= 5) return 'val-danger'
|
||||
if (v >= 1) return 'val-warn'
|
||||
return ''
|
||||
})
|
||||
|
||||
const cpuLabel = computed(() => {
|
||||
const v = vehicle.value.cpuPercent
|
||||
return v != null ? `${Math.round(v)}%` : '—'
|
||||
})
|
||||
|
||||
const memLabel = computed(() => {
|
||||
const v = vehicle.value.memPercent
|
||||
return v != null ? `${Math.round(v)}%` : '—'
|
||||
})
|
||||
|
||||
const cpuChipClass = computed(() => {
|
||||
const v = vehicle.value.cpuPercent
|
||||
if (v == null) return ''
|
||||
if (v >= 90) return 'val-danger'
|
||||
if (v >= 75) return 'val-warn'
|
||||
return 'val-ok'
|
||||
})
|
||||
|
||||
const memChipClass = computed(() => {
|
||||
const v = vehicle.value.memPercent
|
||||
if (v == null) return ''
|
||||
if (v >= 90) return 'val-danger'
|
||||
if (v >= 75) return 'val-warn'
|
||||
return 'val-ok'
|
||||
})
|
||||
|
||||
return {
|
||||
stateLabel,
|
||||
batteryPct,
|
||||
batteryTone,
|
||||
switchOn,
|
||||
statusPill,
|
||||
missionIdSuffix,
|
||||
statusDisplayLabel,
|
||||
runtimeStatusLabel,
|
||||
accentTone,
|
||||
latencyLabel,
|
||||
latencyClass,
|
||||
faultLabel,
|
||||
faultClass,
|
||||
cpuLabel,
|
||||
memLabel,
|
||||
cpuChipClass,
|
||||
memChipClass
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user