Files
device-voice-h5/components/DeviceStatusCard.vue
sexygoat 5f0c215bdc
All checks were successful
构建并部署前端到生产环境 / build-and-deploy (push) Successful in 52s
fix: status
2026-04-29 16:26:37 +08:00

99 lines
3.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="card device-status-card">
<view class="card-header mb-md flex-row-sb">
<view class="title">设备信息</view>
<view class="tag-apple tag-success">{{ deviceInfo.carrier_name || '-' }}</view>
</view>
<view class="device-info flex-col-g16">
<view class="info-row flex-row-sb">
<view class="info-label">
<view class="subtitle">当前卡: {{ deviceInfo.currentIccid }}</view>
</view>
<view class="info-values flex-row-g20" @tap="$emit('authentication')">
<view class="tag-apple" :class="isRealName ? 'tag-success' : 'tag-warning'">
{{ isRealName ? "已实名" : "未实名" }}
</view>
</view>
</view>
<view class="info-row flex-row-sb">
<view class="info-label">
<view class="subtitle" v-if="isDevice">IMEI{{ deviceInfo.imei || '-' }}</view>
<view class="subtitle" v-else>手机号{{ deviceInfo.bound_phone || '-' }}</view>
</view>
</view>
</view>
<view class="device-metrics flex-row-sb mt-md">
<view class="metric-item flex-col-center">
<view class="caption mb-xs">信号强度</view>
<view class="metric-value">{{ getSignalText(deviceInfo) }}</view>
</view>
<view class="metric-item flex-col-center">
<view class="caption mb-xs">设备电量</view>
<view class="metric-value">{{ deviceInfo.battery }} %</view>
</view>
<view class="metric-item flex-col-center">
<view class="caption mb-xs">连接数量</view>
<view class="metric-value">{{ deviceInfo.connCnt }}/{{ deviceInfo.max_clients }}</view>
</view>
</view>
</view>
</template>
<script setup>
const props = defineProps({
deviceInfo: { type: Object, default: () => ({}) },
isRealName: { type: Boolean, default: false },
isDevice: { type: Boolean, default: true },
opratorList: { type: Array, default: () => [] }
});
defineEmits(['authentication']);
const normalizeSignalScore = (value, min, max) => {
if (value === null || value === undefined || value === '' || value === '-') return null;
const numericValue = Number(value);
if (!Number.isFinite(numericValue)) return null;
if (numericValue <= min) return 0;
if (numericValue >= max) return 100;
return ((numericValue - min) / (max - min)) * 100;
};
const getSignalText = (deviceInfo) => {
const signalScores = [
{ score: normalizeSignalScore(deviceInfo?.rsrp, -120, -80), weight: 0.5 },
{ score: normalizeSignalScore(deviceInfo?.rsrq, -20, -10), weight: 0.25 },
{ score: normalizeSignalScore(deviceInfo?.rssi, -100, -65), weight: 0.25 }
].filter(item => item.score !== null);
if (!signalScores.length) return '-';
const totalWeight = signalScores.reduce((sum, item) => sum + item.weight, 0);
const weightedScore =
signalScores.reduce((sum, item) => sum + item.score * item.weight, 0) / totalWeight;
if (weightedScore >= 67) return '强';
if (weightedScore >= 34) return '中';
return '弱';
};
</script>
<style scoped lang="scss">
.device-status-card {
.info-row {
padding: var(--space-sm) 0;
border-bottom: 1rpx solid var(--gray-200);
&:last-child { border-bottom: none; }
.info-label { min-width: 200rpx; }
.info-values { flex: 1; justify-content: flex-end; }
}
.device-metrics {
background: var(--gray-100);
border-radius: var(--radius-small);
padding: 20rpx;
.metric-item { flex: 1; }
}
}
</style>