All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m55s
97 lines
2.7 KiB
Go
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
|
|
}
|