This commit is contained in:
@@ -267,16 +267,40 @@
|
|||||||
|
|
||||||
<!-- 信号信息 -->
|
<!-- 信号信息 -->
|
||||||
<ElDescriptionsItem label="信号强度(RSSI)">
|
<ElDescriptionsItem label="信号强度(RSSI)">
|
||||||
{{ deviceRealtime.rssi || '-' }}
|
{{
|
||||||
|
deviceRealtime.rssi !== undefined &&
|
||||||
|
deviceRealtime.rssi !== null &&
|
||||||
|
deviceRealtime.rssi !== ''
|
||||||
|
? deviceRealtime.rssi
|
||||||
|
: '-'
|
||||||
|
}}
|
||||||
</ElDescriptionsItem>
|
</ElDescriptionsItem>
|
||||||
<ElDescriptionsItem label="接收功率(RSRP)">
|
<ElDescriptionsItem label="接收功率(RSRP)">
|
||||||
{{ deviceRealtime.rsrp ? `${deviceRealtime.rsrp} dBm` : '-' }}
|
{{
|
||||||
|
deviceRealtime.rsrp !== undefined &&
|
||||||
|
deviceRealtime.rsrp !== null &&
|
||||||
|
deviceRealtime.rsrp !== ''
|
||||||
|
? `${deviceRealtime.rsrp} dBm`
|
||||||
|
: '-'
|
||||||
|
}}
|
||||||
</ElDescriptionsItem>
|
</ElDescriptionsItem>
|
||||||
<ElDescriptionsItem label="接收质量(RSRQ)">
|
<ElDescriptionsItem label="接收质量(RSRQ)">
|
||||||
{{ deviceRealtime.rsrq ? `${deviceRealtime.rsrq} dB` : '-' }}
|
{{
|
||||||
|
deviceRealtime.rsrq !== undefined &&
|
||||||
|
deviceRealtime.rsrq !== null &&
|
||||||
|
deviceRealtime.rsrq !== ''
|
||||||
|
? `${deviceRealtime.rsrq} dB`
|
||||||
|
: '-'
|
||||||
|
}}
|
||||||
</ElDescriptionsItem>
|
</ElDescriptionsItem>
|
||||||
<ElDescriptionsItem label="信噪比(SINR)">
|
<ElDescriptionsItem label="信噪比(SINR)">
|
||||||
{{ deviceRealtime.sinr ? `${deviceRealtime.sinr} dB` : '-' }}
|
{{
|
||||||
|
deviceRealtime.sinr !== undefined &&
|
||||||
|
deviceRealtime.sinr !== null &&
|
||||||
|
deviceRealtime.sinr !== ''
|
||||||
|
? `${deviceRealtime.sinr} dB`
|
||||||
|
: '-'
|
||||||
|
}}
|
||||||
</ElDescriptionsItem>
|
</ElDescriptionsItem>
|
||||||
<ElDescriptionsItem label="已连接设备数">
|
<ElDescriptionsItem label="已连接设备数">
|
||||||
{{ deviceRealtime.client_number }} / {{ deviceRealtime.max_clients }}
|
{{ deviceRealtime.client_number }} / {{ deviceRealtime.max_clients }}
|
||||||
|
|||||||
@@ -4,8 +4,10 @@
|
|||||||
|
|
||||||
import type { Ref } from 'vue'
|
import type { Ref } from 'vue'
|
||||||
|
|
||||||
|
type TagType = 'primary' | 'success' | 'warning' | 'info' | 'danger'
|
||||||
|
|
||||||
export function useAssetFormatters(deviceRealtime?: Ref<any>) {
|
export function useAssetFormatters(deviceRealtime?: Ref<any>) {
|
||||||
// 格式化数据大小(MB转GB/MB)
|
// 格式化数据大小(MB 转 GB/MB)
|
||||||
const formatDataSize = (mb: number) => {
|
const formatDataSize = (mb: number) => {
|
||||||
if (mb >= 1024) {
|
if (mb >= 1024) {
|
||||||
return `${(mb / 1024).toFixed(2)}GB`
|
return `${(mb / 1024).toFixed(2)}GB`
|
||||||
@@ -20,11 +22,11 @@ export function useAssetFormatters(deviceRealtime?: Ref<any>) {
|
|||||||
return `¥${yuan.toFixed(2)}`
|
return `¥${yuan.toFixed(2)}`
|
||||||
}
|
}
|
||||||
|
|
||||||
// 格式化时长(秒转为时分秒)
|
// 格式化时长(秒转时分秒)
|
||||||
const formatDuration = (seconds?: string) => {
|
const formatDuration = (seconds?: string) => {
|
||||||
if (!seconds) return '-'
|
if (!seconds) return '-'
|
||||||
const sec = Number(seconds)
|
const sec = Number(seconds)
|
||||||
if (isNaN(sec)) return '-'
|
if (Number.isNaN(sec)) return '-'
|
||||||
|
|
||||||
const hours = Math.floor(sec / 3600)
|
const hours = Math.floor(sec / 3600)
|
||||||
const minutes = Math.floor((sec % 3600) / 60)
|
const minutes = Math.floor((sec % 3600) / 60)
|
||||||
@@ -32,14 +34,14 @@ export function useAssetFormatters(deviceRealtime?: Ref<any>) {
|
|||||||
|
|
||||||
if (hours > 0) {
|
if (hours > 0) {
|
||||||
return `${hours}小时${minutes}分${secs}秒`
|
return `${hours}小时${minutes}分${secs}秒`
|
||||||
} else if (minutes > 0) {
|
|
||||||
return `${minutes}分${secs}秒`
|
|
||||||
} else {
|
|
||||||
return `${secs}秒`
|
|
||||||
}
|
}
|
||||||
|
if (minutes > 0) {
|
||||||
|
return `${minutes}分${secs}秒`
|
||||||
|
}
|
||||||
|
return `${secs}秒`
|
||||||
}
|
}
|
||||||
|
|
||||||
// 格式化ICCID为4位一组,用横杠分隔
|
// 格式化 ICCID,每 4 位一组,用横杠分隔
|
||||||
const formatIccidWithDashes = (iccid: string) => {
|
const formatIccidWithDashes = (iccid: string) => {
|
||||||
if (!iccid) return ''
|
if (!iccid) return ''
|
||||||
return iccid.replace(/(\d{4})(?=\d)/g, '$1-')
|
return iccid.replace(/(\d{4})(?=\d)/g, '$1-')
|
||||||
@@ -89,15 +91,13 @@ export function useAssetFormatters(deviceRealtime?: Ref<any>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取资产状态标签类型
|
// 获取资产状态标签类型
|
||||||
const getAssetStatusType = (
|
const getAssetStatusType = (status?: number): TagType => {
|
||||||
status?: number
|
|
||||||
): 'primary' | 'success' | 'warning' | 'info' | 'danger' => {
|
|
||||||
if (status === undefined || status === null) return 'info'
|
if (status === undefined || status === null) return 'info'
|
||||||
const map: Record<number, 'primary' | 'success' | 'warning' | 'info' | 'danger'> = {
|
const map: Record<number, TagType> = {
|
||||||
1: 'info', // 在库
|
1: 'info',
|
||||||
2: 'success', // 已分销
|
2: 'success',
|
||||||
3: 'success', // 已激活
|
3: 'success',
|
||||||
4: 'danger' // 已停用
|
4: 'danger'
|
||||||
}
|
}
|
||||||
return map[status] || 'info'
|
return map[status] || 'info'
|
||||||
}
|
}
|
||||||
@@ -113,81 +113,87 @@ export function useAssetFormatters(deviceRealtime?: Ref<any>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取在线状态标签类型
|
// 获取在线状态标签类型
|
||||||
const getOnlineStatusType = (
|
const getOnlineStatusType = (status?: number): TagType => {
|
||||||
status?: number
|
const map: Record<number, TagType> = {
|
||||||
): 'primary' | 'success' | 'warning' | 'info' | 'danger' => {
|
0: 'info',
|
||||||
const map: Record<number, 'primary' | 'success' | 'warning' | 'info' | 'danger'> = {
|
1: 'success',
|
||||||
0: 'info', // 未知
|
2: 'danger'
|
||||||
1: 'success', // 在线
|
|
||||||
2: 'danger' // 离线
|
|
||||||
}
|
}
|
||||||
return map[status ?? 0] || 'info'
|
return map[status ?? 0] || 'info'
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取钱包状态标签类型
|
// 获取钱包状态标签类型
|
||||||
const getWalletStatusType = (status?: number) => {
|
const getWalletStatusType = (status?: number) => {
|
||||||
const map: Record<number, any> = {
|
const map: Record<number, string> = {
|
||||||
1: 'success', // 正常
|
1: 'success',
|
||||||
2: 'warning', // 冻结
|
2: 'warning',
|
||||||
3: 'danger' // 关闭
|
3: 'danger'
|
||||||
}
|
}
|
||||||
return map[status || 1] || 'info'
|
return map[status || 1] || 'info'
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取套餐状态标签类型
|
// 获取套餐状态标签类型
|
||||||
const getPackageStatusTagType = (
|
const getPackageStatusTagType = (status?: number): TagType => {
|
||||||
status?: number
|
|
||||||
): 'primary' | 'success' | 'warning' | 'info' | 'danger' => {
|
|
||||||
if (status === undefined || status === null) return 'info'
|
if (status === undefined || status === null) return 'info'
|
||||||
const map: Record<number, 'primary' | 'success' | 'warning' | 'info' | 'danger'> = {
|
const map: Record<number, TagType> = {
|
||||||
0: 'info', // 待生效
|
0: 'info',
|
||||||
1: 'success', // 生效中
|
1: 'success',
|
||||||
2: 'warning', // 已用完
|
2: 'warning',
|
||||||
3: 'danger', // 已过期
|
3: 'danger',
|
||||||
4: 'info' // 已失效
|
4: 'info'
|
||||||
}
|
}
|
||||||
return map[status] || 'info'
|
return map[status] || 'info'
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算信号强度等级(基于RSSI、RSRP、RSRQ)
|
const parseSignalValue = (value: unknown) => {
|
||||||
|
if (value === null || value === undefined || value === '') return null
|
||||||
|
const parsed = Number(value)
|
||||||
|
return Number.isNaN(parsed) ? null : parsed
|
||||||
|
}
|
||||||
|
|
||||||
|
const clamp = (value: number, min: number, max: number) => {
|
||||||
|
return Math.min(Math.max(value, min), max)
|
||||||
|
}
|
||||||
|
|
||||||
|
const calculateSignalScore = () => {
|
||||||
|
if (!deviceRealtime?.value) return null
|
||||||
|
|
||||||
|
const rsrp = parseSignalValue(deviceRealtime.value.rsrp)
|
||||||
|
const rsrq = parseSignalValue(deviceRealtime.value.rsrq)
|
||||||
|
const sinr = parseSignalValue(deviceRealtime.value.sinr)
|
||||||
|
|
||||||
|
// RSRP、RSRQ 必须是负数;SINR 允许 0 或负值
|
||||||
|
if (rsrp === null || rsrq === null || sinr === null) return null
|
||||||
|
if (rsrp >= 0 || rsrq >= 0) return null
|
||||||
|
|
||||||
|
const rsrpScore = clamp((rsrp + 120) * 2, 0, 100)
|
||||||
|
const rsrqScore = clamp((rsrq + 20) * 5, 0, 100)
|
||||||
|
const sinrScore = clamp(sinr * 5, 0, 100)
|
||||||
|
|
||||||
|
return rsrpScore * 0.5 + sinrScore * 0.3 + rsrqScore * 0.2
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算信号强度等级:基于 RSRP、RSRQ、SINR 的综合评分,RSSI 不参与
|
||||||
const calculateSignalStrength = () => {
|
const calculateSignalStrength = () => {
|
||||||
if (!deviceRealtime?.value) return '-'
|
const score = calculateSignalScore()
|
||||||
|
if (score === null) return '-'
|
||||||
|
|
||||||
const rssi = deviceRealtime.value.rssi ? Number(deviceRealtime.value.rssi) : null
|
if (score >= 85) return '极好'
|
||||||
const rsrp = deviceRealtime.value.rsrp ? Number(deviceRealtime.value.rsrp) : null
|
if (score >= 70) return '良好'
|
||||||
|
if (score >= 50) return '一般'
|
||||||
// 优先使用RSRP判断(更准确)
|
if (score >= 30) return '较差'
|
||||||
// RSRP范围通常在-140到-44 dBm之间,0或正值表示无效数据
|
return '很差'
|
||||||
if (rsrp !== null && !isNaN(rsrp) && rsrp < 0) {
|
|
||||||
if (rsrp >= -80) return '优秀'
|
|
||||||
if (rsrp >= -90) return '良好'
|
|
||||||
if (rsrp >= -100) return '一般'
|
|
||||||
if (rsrp >= -110) return '较差'
|
|
||||||
return '极差'
|
|
||||||
}
|
|
||||||
|
|
||||||
// 其次使用RSSI
|
|
||||||
// RSSI范围通常在-113到-51 dBm之间,0或正值表示无效数据
|
|
||||||
if (rssi !== null && !isNaN(rssi) && rssi < 0) {
|
|
||||||
if (rssi >= -70) return '优秀'
|
|
||||||
if (rssi >= -85) return '良好'
|
|
||||||
if (rssi >= -100) return '一般'
|
|
||||||
if (rssi >= -110) return '较差'
|
|
||||||
return '极差'
|
|
||||||
}
|
|
||||||
|
|
||||||
return '-'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取信号强度标签类型
|
// 获取信号强度标签类型
|
||||||
const getSignalStrengthType = (): 'primary' | 'success' | 'warning' | 'info' | 'danger' => {
|
const getSignalStrengthType = (): TagType => {
|
||||||
const strength = calculateSignalStrength()
|
const strength = calculateSignalStrength()
|
||||||
const map: Record<string, 'primary' | 'success' | 'warning' | 'info' | 'danger'> = {
|
const map: Record<string, TagType> = {
|
||||||
优秀: 'success',
|
极好: 'success',
|
||||||
良好: 'success',
|
良好: 'success',
|
||||||
一般: 'warning',
|
一般: 'warning',
|
||||||
较差: 'danger',
|
较差: 'danger',
|
||||||
极差: 'danger'
|
很差: 'danger'
|
||||||
}
|
}
|
||||||
return map[strength] || 'info'
|
return map[strength] || 'info'
|
||||||
}
|
}
|
||||||
@@ -203,10 +209,10 @@ export function useAssetFormatters(deviceRealtime?: Ref<any>) {
|
|||||||
|
|
||||||
// 获取交易类型标签颜色
|
// 获取交易类型标签颜色
|
||||||
const getTransactionTypeTag = (type: string | undefined) => {
|
const getTransactionTypeTag = (type: string | undefined) => {
|
||||||
const map: Record<string, any> = {
|
const map: Record<string, string> = {
|
||||||
recharge: 'success', // 充值
|
recharge: 'success',
|
||||||
deduct: 'danger', // 扣款
|
deduct: 'danger',
|
||||||
refund: 'warning' // 退款
|
refund: 'warning'
|
||||||
}
|
}
|
||||||
return map[type || ''] || 'info'
|
return map[type || ''] || 'info'
|
||||||
}
|
}
|
||||||
@@ -214,10 +220,10 @@ export function useAssetFormatters(deviceRealtime?: Ref<any>) {
|
|||||||
// 获取支付状态标签类型
|
// 获取支付状态标签类型
|
||||||
const getPaymentStatusType = (status: number): 'success' | 'warning' | 'danger' | 'info' => {
|
const getPaymentStatusType = (status: number): 'success' | 'warning' | 'danger' | 'info' => {
|
||||||
const statusMap: Record<number, 'success' | 'warning' | 'danger' | 'info'> = {
|
const statusMap: Record<number, 'success' | 'warning' | 'danger' | 'info'> = {
|
||||||
1: 'warning', // 待支付
|
1: 'warning',
|
||||||
2: 'success', // 已支付
|
2: 'success',
|
||||||
3: 'danger', // 已取消
|
3: 'danger',
|
||||||
4: 'info' // 已关闭
|
4: 'info'
|
||||||
}
|
}
|
||||||
return statusMap[status] || 'info'
|
return statusMap[status] || 'info'
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user