feat: 卡流量读数先过采集队列再入账,扣减按采集时刻确定套餐
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 9m27s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 9m27s
- 每卡 Redis 采集队列(默认 N=3、跨天清空、回退容差 1 MB),攒满且不下降才写最后一个点 - 测试环境全量切换日快照计量,下线灰度名单、切换水位与卡表基线扣费;全部卡置待建起点 - 读数区分没给值与 0;有套餐的卡读数 0 也写快照与日用量 0 行;重置日比较基准为 0 照常防旧值 - 新增采集记录(按月分区保留 90 天)、人工冲正流水与后台接口、采集告警 - 扣减按采集时刻有效套餐查找,只对生效中套餐做状态迁移,查不到套餐按成功跳过 - 换货新卡(新设备下的卡)打待建起点;采集间隔上限只校验启用中的轮询配置 Change: add-card-traffic-queue-and-observed-deduction Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -32,28 +32,6 @@ type Config struct {
|
||||
Worker WorkerConfig `mapstructure:"worker"`
|
||||
WeCom WeComConfig `mapstructure:"wecom"`
|
||||
Approval ApprovalConfig `mapstructure:"approval"`
|
||||
TrafficCalc TrafficCalcConfig `mapstructure:"traffic_calc"`
|
||||
}
|
||||
|
||||
// 卡流量计量模式取值。
|
||||
const (
|
||||
TrafficCalcModeOff = "off"
|
||||
TrafficCalcModeGray = "gray"
|
||||
TrafficCalcModeFull = "full"
|
||||
)
|
||||
|
||||
// TrafficCalcConfig 卡流量计量(日快照算法)切换配置。
|
||||
// API 与全部 Worker 进程必须使用一致的取值,改动后先停掉全部进程再一起启动。
|
||||
type TrafficCalcConfig struct {
|
||||
// Mode 计量模式:off 全部走卡表基线算法;gray 只有名单内的卡走日快照算法;full 全部卡走日快照算法。
|
||||
// 环境变量:JUNHONG_TRAFFIC_CALC_MODE
|
||||
Mode string `mapstructure:"mode"`
|
||||
// Cards 灰度名单,逗号分隔的扣减载体:device:<设备ID> 或 iot_card:<卡ID>。
|
||||
// 环境变量:JUNHONG_TRAFFIC_CALC_CARDS
|
||||
Cards string `mapstructure:"cards"`
|
||||
// FlowSnapshotEnabled 未切换卡的日快照写入总开关,关闭后未切换卡停止写快照。
|
||||
// 环境变量:JUNHONG_TRAFFIC_FLOW_SNAPSHOT_ENABLED
|
||||
FlowSnapshotEnabled bool `mapstructure:"flow_snapshot_enabled"`
|
||||
}
|
||||
|
||||
// ServerConfig HTTP 服务器配置
|
||||
@@ -304,11 +282,6 @@ func (c *Config) ValidateRequired() error {
|
||||
}
|
||||
|
||||
func (c *Config) Validate() error {
|
||||
switch c.TrafficCalc.Mode {
|
||||
case TrafficCalcModeOff, TrafficCalcModeGray, TrafficCalcModeFull:
|
||||
default:
|
||||
return fmt.Errorf("invalid configuration: traffic_calc.mode: invalid mode (current value: %s, expected: off, gray, full)", c.TrafficCalc.Mode)
|
||||
}
|
||||
// 服务器验证
|
||||
if c.Server.Address == "" {
|
||||
return fmt.Errorf("invalid configuration: server.address: must be non-empty (current value: empty)")
|
||||
|
||||
@@ -168,12 +168,6 @@ approval:
|
||||
legacy_offline_recharge_pay_enabled: true
|
||||
|
||||
|
||||
# 卡流量计量(日快照算法)切换配置;API 与全部 Worker 必须一致,改动后先停全部进程再一起启动
|
||||
traffic_calc:
|
||||
mode: "off" # off / gray / full(环境变量:JUNHONG_TRAFFIC_CALC_MODE)
|
||||
cards: "" # 灰度名单,如 device:15276,iot_card:103154(环境变量:JUNHONG_TRAFFIC_CALC_CARDS)
|
||||
flow_snapshot_enabled: true # 未切换卡写日快照(环境变量:JUNHONG_TRAFFIC_FLOW_SNAPSHOT_ENABLED)
|
||||
|
||||
# 企业微信 Adapter 配置
|
||||
wecom:
|
||||
base_url: "https://qyapi.weixin.qq.com"
|
||||
|
||||
@@ -160,13 +160,9 @@ func bindEnvVariables(v *viper.Viper) {
|
||||
"wechat.payment.notify_url",
|
||||
"wechat.payment.http_debug",
|
||||
"wechat.payment.timeout",
|
||||
"traffic_calc.mode",
|
||||
"traffic_calc.cards",
|
||||
}
|
||||
|
||||
for _, key := range bindings {
|
||||
_ = v.BindEnv(key)
|
||||
}
|
||||
// 快照写入开关沿用方案约定的环境变量名,与配置键的默认映射不同,需要显式绑定。
|
||||
_ = v.BindEnv("traffic_calc.flow_snapshot_enabled", "JUNHONG_TRAFFIC_FLOW_SNAPSHOT_ENABLED")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user