Files
junhong_cmp_fiber/internal/model/card_traffic_collection.go
邹进 9c3c258f16
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 9m27s
feat: 卡流量读数先过采集队列再入账,扣减按采集时刻确定套餐
- 每卡 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>
2026-10-29 12:18:47 +09:00

55 lines
3.3 KiB
Go

package model
import (
"time"
"gorm.io/datatypes"
)
// CardTrafficCollection 卡流量采集记录:采集时刻有套餐的卡每次采集一条,按月分区保留 90 天。
type CardTrafficCollection struct {
ID uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
IotCardID uint `gorm:"column:iot_card_id;not null" json:"iot_card_id"`
ObservedAt time.Time `gorm:"column:observed_at;primaryKey;not null" json:"observed_at"`
ObservationID string `gorm:"column:observation_id;type:varchar(128);not null;default:''" json:"observation_id"`
Source string `gorm:"column:source;type:varchar(32);not null;default:''" json:"source"`
Scene string `gorm:"column:scene;type:varchar(64);not null;default:''" json:"scene"`
Result string `gorm:"column:result;type:varchar(32);not null" json:"result"`
VendorUsedMB *float64 `gorm:"column:vendor_used_mb;type:numeric(14,3)" json:"vendor_used_mb"`
QueuePoints datatypes.JSON `gorm:"column:queue_points;type:jsonb" json:"queue_points"`
Decision string `gorm:"column:decision;type:varchar(32);not null;default:''" json:"decision"`
MonthUsedMB *float64 `gorm:"column:month_used_mb;type:numeric(14,3)" json:"month_used_mb"`
StaleGuarded *bool `gorm:"column:stale_guarded" json:"stale_guarded"`
DeltaMB *float64 `gorm:"column:delta_mb;type:numeric(14,3)" json:"delta_mb"`
EventID string `gorm:"column:event_id;type:varchar(128);not null;default:''" json:"event_id"`
CreatedAt time.Time `gorm:"column:created_at;not null;default:now()" json:"created_at"`
}
// TableName 指定表名。
func (CardTrafficCollection) TableName() string {
return "tb_card_traffic_collection"
}
// PackageUsageAdjustment 套餐流量人工冲正流水:只新增,不修改、不删除。
type PackageUsageAdjustment struct {
ID uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
PackageUsageID uint `gorm:"column:package_usage_id;not null" json:"package_usage_id"`
IotCardID uint `gorm:"column:iot_card_id;not null;default:0" json:"iot_card_id"`
DeviceID uint `gorm:"column:device_id;not null;default:0" json:"device_id"`
DeltaMB int64 `gorm:"column:delta_mb;not null" json:"delta_mb"`
BeforeUsageMB int64 `gorm:"column:before_usage_mb;not null" json:"before_usage_mb"`
AfterUsageMB int64 `gorm:"column:after_usage_mb;not null" json:"after_usage_mb"`
BeforeStatus int `gorm:"column:before_status;not null" json:"before_status"`
AfterStatus int `gorm:"column:after_status;not null" json:"after_status"`
Reason string `gorm:"column:reason;type:varchar(500);not null" json:"reason"`
RefObservationID string `gorm:"column:ref_observation_id;type:varchar(128);not null;default:''" json:"ref_observation_id"`
RefEventID string `gorm:"column:ref_event_id;type:varchar(128);not null;default:''" json:"ref_event_id"`
OperatorID uint `gorm:"column:operator_id;not null" json:"operator_id"`
CreatedAt time.Time `gorm:"column:created_at;not null;default:now()" json:"created_at"`
}
// TableName 指定表名。
func (PackageUsageAdjustment) TableName() string {
return "tb_package_usage_adjustment"
}