This commit is contained in:
96
internal/model/package_traffic_semantics.go
Normal file
96
internal/model/package_traffic_semantics.go
Normal file
@@ -0,0 +1,96 @@
|
||||
package model
|
||||
|
||||
import "math"
|
||||
|
||||
const unlimitedRemainingQuotaMB = int64(^uint64(0) >> 1)
|
||||
|
||||
// PackageTrafficMetrics 套餐流量统一展示值
|
||||
// 统一封装对外使用的真值、虚值和展示比例,避免各层重复实现公式。
|
||||
type PackageTrafficMetrics struct {
|
||||
RealTotalMB int64
|
||||
RealUsedMB int64
|
||||
VirtualTotalMB int64
|
||||
VirtualUsedMB float64
|
||||
ReductionPct float64
|
||||
}
|
||||
|
||||
// CalculateDisplayGainRatio 计算展示倍率
|
||||
// 启用虚流量且虚总量大于 0 时,倍率 = 真总量 / 虚总量;否则退化为 1。
|
||||
func CalculateDisplayGainRatio(enableVirtualData bool, realTotalMB, virtualTotalMB int64) float64 {
|
||||
if enableVirtualData && virtualTotalMB > 0 {
|
||||
return float64(realTotalMB) / float64(virtualTotalMB)
|
||||
}
|
||||
return 1.0
|
||||
}
|
||||
|
||||
// BuildPackageUsageSnapshotValues 计算套餐使用记录应写入的快照值。
|
||||
func BuildPackageUsageSnapshotValues(pkg *Package) (virtualTotalMB int64, displayGainRatio float64, enableVirtualData bool) {
|
||||
if pkg == nil {
|
||||
return 0, 1.0, false
|
||||
}
|
||||
|
||||
if pkg.EnableVirtualData && pkg.VirtualDataMB > 0 {
|
||||
return pkg.VirtualDataMB, CalculateDisplayGainRatio(true, pkg.RealDataMB, pkg.VirtualDataMB), true
|
||||
}
|
||||
|
||||
return pkg.RealDataMB, 1.0, false
|
||||
}
|
||||
|
||||
// EffectiveThresholdMB 返回套餐业务耗尽阈值。
|
||||
// 启用虚流量时按虚总量快照判断;否则按真总量判断。
|
||||
func (u *PackageUsage) EffectiveThresholdMB() int64 {
|
||||
if u == nil {
|
||||
return 0
|
||||
}
|
||||
if u.EnableVirtualDataSnapshot && u.VirtualTotalMBSnapshot > 0 {
|
||||
return u.VirtualTotalMBSnapshot
|
||||
}
|
||||
return u.DataLimitMB
|
||||
}
|
||||
|
||||
// RemainingQuotaMB 返回套餐剩余业务额度。
|
||||
func (u *PackageUsage) RemainingQuotaMB() int64 {
|
||||
if u == nil {
|
||||
return 0
|
||||
}
|
||||
threshold := u.EffectiveThresholdMB()
|
||||
if threshold <= 0 {
|
||||
return unlimitedRemainingQuotaMB
|
||||
}
|
||||
return threshold - u.DataUsageMB
|
||||
}
|
||||
|
||||
// IsTrafficDepleted 判断套餐是否达到业务耗尽阈值。
|
||||
func (u *PackageUsage) IsTrafficDepleted() bool {
|
||||
if u == nil {
|
||||
return false
|
||||
}
|
||||
threshold := u.EffectiveThresholdMB()
|
||||
if threshold <= 0 {
|
||||
return false
|
||||
}
|
||||
return u.DataUsageMB >= threshold
|
||||
}
|
||||
|
||||
// BuildTrafficMetrics 组装统一五字段和 reduction_pct。
|
||||
func (u *PackageUsage) BuildTrafficMetrics() PackageTrafficMetrics {
|
||||
metrics := PackageTrafficMetrics{}
|
||||
if u == nil {
|
||||
return metrics
|
||||
}
|
||||
|
||||
metrics.RealTotalMB = u.DataLimitMB
|
||||
metrics.RealUsedMB = u.DataUsageMB
|
||||
|
||||
if u.EnableVirtualDataSnapshot && u.VirtualTotalMBSnapshot > 0 {
|
||||
metrics.VirtualTotalMB = u.VirtualTotalMBSnapshot
|
||||
metrics.VirtualUsedMB = math.Min(float64(u.DataUsageMB)*u.DisplayGainRatioSnapshot, float64(u.DataLimitMB))
|
||||
metrics.ReductionPct = u.DisplayGainRatioSnapshot - 1
|
||||
return metrics
|
||||
}
|
||||
|
||||
metrics.VirtualTotalMB = u.DataLimitMB
|
||||
metrics.VirtualUsedMB = float64(u.DataUsageMB)
|
||||
metrics.ReductionPct = 0
|
||||
return metrics
|
||||
}
|
||||
Reference in New Issue
Block a user