// Package packagetrafficalert 提供套餐真流量达量预警的领域判定规则。 // // 判定口径固定为「真流量」:分子取套餐使用记录的真已用量,分母取套餐使用记录的真总量快照, // 二者按资产汇总后再与主套餐规则阈值比较;全部使用整数万分比比较,不使用浮点判定, // 避免边界(例如恰好等于阈值)因二进制浮点误差产生错误结论。 package packagetrafficalert import "math" // ratioScale 是万分比刻度:1% = 100,0.01% = 1。 const ratioScale = 10000 // MinThresholdPercent 与 MaxThresholdPercent 是可配置阈值百分比的闭区间端点。 const ( MinThresholdPercent = 1.0 MaxThresholdPercent = 100.0 ) // ThresholdBasisPoints 把百分比阈值换算为整数万分比(0.01% = 1)。 // 数据库以 NUMERIC(5,2) 保存两位小数,读取后先四舍五入到两位再换算,保证 1.25% 恒等于 125。 func ThresholdBasisPoints(percent float64) int64 { return int64(math.Round(NormalizeThresholdPercent(percent) * 100)) } // NormalizeThresholdPercent 把百分比四舍五入到两位小数,与 NUMERIC(5,2) 的存储精度一致。 func NormalizeThresholdPercent(percent float64) float64 { return math.Round(percent*100) / 100 } // IsValidThresholdPercent 判断百分比是否落在 1%~100% 闭区间内。 func IsValidThresholdPercent(percent float64) bool { normalized := NormalizeThresholdPercent(percent) return normalized >= MinThresholdPercent && normalized <= MaxThresholdPercent } // Decide 按资产的汇总真流量判定是否达到阈值,并返回向下取整的汇总比例万分比。 // // usedMB 为该资产全部当前有效套餐的真已用量之和,limitMB 为同集合的真总量快照之和。 // 分母不大于零属于不可判定资产,调用方必须先跳过;此处返回未命中以避免除零。 func Decide(usedMB, limitMB, thresholdBasisPoints int64) (bool, int64) { if limitMB <= 0 || thresholdBasisPoints <= 0 { return false, 0 } ratioBasisPoints := usedMB * ratioScale / limitMB hit := usedMB*ratioScale >= thresholdBasisPoints*limitMB return hit, ratioBasisPoints } // PercentFromBasisPoints 把万分比换算为保留两位小数的百分比展示值。 func PercentFromBasisPoints(basisPoints int64) float64 { return float64(basisPoints) / 100 }