Files
junhong_cmp_fiber/internal/model/package_traffic_semantics.go
huang fe4c545308
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m55s
修正数据
2026-04-27 18:10:08 +08:00

97 lines
2.7 KiB
Go

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
}