This commit is contained in:
2026-04-30 15:49:40 +08:00
parent 5425e2ce19
commit 948243b13d
11 changed files with 703 additions and 178 deletions

View File

@@ -481,6 +481,9 @@ func mapSyncRespToDeviceGatewayInfo(r *gateway.SyncDeviceInfoResp) *dto.DeviceGa
IMSI: flexStrPtr(r.IMSI),
Status: flexIntPtr(r.Status),
}
signalQuality, signalBadReason := buildSignalSummary(info.Rsrp, info.Rsrq, info.Rssi, info.Sinr)
info.SignalQuality = strPtr(signalQuality)
info.SignalBadReason = strPtr(signalBadReason)
if r.BatteryLevel != nil {
n := int(*r.BatteryLevel)
info.BatteryLevel = &n
@@ -713,28 +716,28 @@ func (s *Service) GetPackages(ctx context.Context, assetType string, id uint, pa
pkgType = pkg.PackageType
}
item := &dto.AssetPackageResponse{
PackageUsageID: u.ID,
PackageID: u.PackageID,
PackageName: pkgName,
PackageType: pkgType,
OrderID: u.OrderID,
OrderNo: u.OrderNo,
RefundID: u.RefundID,
RefundNo: u.RefundNo,
UsageType: u.UsageType,
Status: u.Status,
StatusName: packageStatusName(u.Status),
RealTotalMB: metrics.RealTotalMB,
RealUsedMB: metrics.RealUsedMB,
VirtualTotalMB: metrics.VirtualTotalMB,
VirtualUsedMB: metrics.VirtualUsedMB,
ReductionPct: metrics.ReductionPct,
ActivatedAt: u.ActivatedAt,
ExpiresAt: u.ExpiresAt,
MasterUsageID: u.MasterUsageID,
Priority: u.Priority,
PaidAmount: u.PaidAmount,
CreatedAt: u.CreatedAt,
PackageUsageID: u.ID,
PackageID: u.PackageID,
PackageName: pkgName,
PackageType: pkgType,
OrderID: u.OrderID,
OrderNo: u.OrderNo,
RefundID: u.RefundID,
RefundNo: u.RefundNo,
UsageType: u.UsageType,
Status: u.Status,
StatusName: packageStatusName(u.Status),
RealTotalMB: metrics.RealTotalMB,
RealUsedMB: metrics.RealUsedMB,
VirtualTotalMB: metrics.VirtualTotalMB,
VirtualUsedMB: metrics.VirtualUsedMB,
ReductionPct: metrics.ReductionPct,
ActivatedAt: u.ActivatedAt,
ExpiresAt: u.ExpiresAt,
MasterUsageID: u.MasterUsageID,
Priority: u.Priority,
PaidAmount: u.PaidAmount,
CreatedAt: u.CreatedAt,
}
all = append(all, item)
}
@@ -791,28 +794,28 @@ func (s *Service) GetCurrentPackage(ctx context.Context, assetType string, id ui
pkgType = pkg.PackageType
}
return &dto.AssetPackageResponse{
PackageUsageID: usage.ID,
PackageID: usage.PackageID,
PackageName: pkgName,
PackageType: pkgType,
OrderID: usage.OrderID,
OrderNo: usage.OrderNo,
RefundID: usage.RefundID,
RefundNo: usage.RefundNo,
UsageType: usage.UsageType,
Status: usage.Status,
StatusName: packageStatusName(usage.Status),
RealTotalMB: metrics.RealTotalMB,
RealUsedMB: metrics.RealUsedMB,
VirtualTotalMB: metrics.VirtualTotalMB,
VirtualUsedMB: metrics.VirtualUsedMB,
ReductionPct: metrics.ReductionPct,
ActivatedAt: usage.ActivatedAt,
ExpiresAt: usage.ExpiresAt,
MasterUsageID: usage.MasterUsageID,
Priority: usage.Priority,
PaidAmount: usage.PaidAmount,
CreatedAt: usage.CreatedAt,
PackageUsageID: usage.ID,
PackageID: usage.PackageID,
PackageName: pkgName,
PackageType: pkgType,
OrderID: usage.OrderID,
OrderNo: usage.OrderNo,
RefundID: usage.RefundID,
RefundNo: usage.RefundNo,
UsageType: usage.UsageType,
Status: usage.Status,
StatusName: packageStatusName(usage.Status),
RealTotalMB: metrics.RealTotalMB,
RealUsedMB: metrics.RealUsedMB,
VirtualTotalMB: metrics.VirtualTotalMB,
VirtualUsedMB: metrics.VirtualUsedMB,
ReductionPct: metrics.ReductionPct,
ActivatedAt: usage.ActivatedAt,
ExpiresAt: usage.ExpiresAt,
MasterUsageID: usage.MasterUsageID,
Priority: usage.Priority,
PaidAmount: usage.PaidAmount,
CreatedAt: usage.CreatedAt,
}, nil
}

View File

@@ -0,0 +1,159 @@
package asset
import "strings"
const (
signalQualityExcellent = "信号很好"
signalQualityNormal = "信号正常"
signalQualityWeak = "信号较弱"
signalQualityPoor = "信号很差"
signalQualityNoData = "暂无数据"
signalReasonWeakCoverage = "怀疑当前位置信号覆盖较弱"
signalReasonInterference = "怀疑周围干扰较多"
signalReasonBlocked = "怀疑设备所处位置遮挡较强"
signalReasonUnstable = "怀疑网络环境不稳定"
signalReasonUnknown = "暂时无法判断"
)
// buildSignalSummary 根据四个原始信号指标输出统一的信号摘要。
func buildSignalSummary(rsrp, rsrq *int, rssi *string, sinr *int) (string, string) {
score := 0
seen := 0
coverageBad := false
interferenceBad := false
blockedBad := false
unstableBad := false
if rsrp != nil {
seen++
switch {
case *rsrp >= -90:
score += 2
case *rsrp >= -105:
score += 1
case *rsrp >= -115:
score -= 1
coverageBad = true
default:
score -= 2
coverageBad = true
blockedBad = true
}
}
if rsrq != nil {
seen++
switch {
case *rsrq >= -10:
score += 2
case *rsrq >= -15:
score += 1
case *rsrq >= -18:
score -= 1
interferenceBad = true
default:
score -= 2
interferenceBad = true
unstableBad = true
}
}
if sinr != nil {
seen++
switch {
case *sinr >= 20:
score += 2
case *sinr >= 13:
score += 1
case *sinr >= 5:
score -= 1
interferenceBad = true
default:
score -= 2
interferenceBad = true
unstableBad = true
}
}
if rssiValue, ok := parseRSSI(rssi); ok {
seen++
switch {
case rssiValue >= -65:
score += 2
case rssiValue >= -75:
score += 1
case rssiValue >= -85:
score -= 1
coverageBad = true
default:
score -= 2
coverageBad = true
blockedBad = true
}
}
if seen == 0 {
return signalQualityNoData, signalReasonUnknown
}
quality := signalQualityNormal
switch {
case score >= 6:
quality = signalQualityExcellent
case score >= 2:
quality = signalQualityNormal
case score >= -2:
quality = signalQualityWeak
default:
quality = signalQualityPoor
}
if quality == signalQualityExcellent || quality == signalQualityNormal {
return quality, signalReasonUnknown
}
switch {
case blockedBad:
return quality, signalReasonBlocked
case interferenceBad:
return quality, signalReasonInterference
case coverageBad:
return quality, signalReasonWeakCoverage
case unstableBad:
return quality, signalReasonUnstable
default:
return quality, signalReasonUnknown
}
}
func parseRSSI(rssi *string) (int, bool) {
if rssi == nil {
return 0, false
}
value := strings.TrimSpace(*rssi)
if value == "" {
return 0, false
}
sign := 1
number := 0
started := false
for i, ch := range value {
if ch == '-' && i == 0 {
sign = -1
continue
}
if ch >= '0' && ch <= '9' {
started = true
number = number*10 + int(ch-'0')
continue
}
if started {
break
}
}
if !started {
return 0, false
}
return sign * number, true
}