Compare commits
2 Commits
76f657c986
...
fc6af43baa
| Author | SHA1 | Date | |
|---|---|---|---|
| fc6af43baa | |||
| 52bdbbae25 |
@@ -88,13 +88,22 @@ func (s *UsageService) DeductDataUsage(ctx context.Context, carrierType string,
|
||||
return err
|
||||
}
|
||||
|
||||
today := time.Now().Format("2006-01-02")
|
||||
|
||||
if len(packages) == 0 {
|
||||
// 无生效套餐:尝试找 Depleted 套餐记录溢出流量详单,避免详单断档
|
||||
if recordErr := s.recordOverflowToDepletedPackage(ctx, tx, targetCarrierType, targetCarrierID, deductUsageMB, today); recordErr != nil {
|
||||
s.logger.Warn("记录溢出流量到已耗尽套餐失败",
|
||||
zap.String("carrier_type", targetCarrierType),
|
||||
zap.Uint("carrier_id", targetCarrierID),
|
||||
zap.Int64("usage_mb", deductUsageMB),
|
||||
zap.Error(recordErr))
|
||||
}
|
||||
return errors.New(errors.CodeNoAvailablePackage, "没有可用套餐")
|
||||
}
|
||||
|
||||
// 按优先级扣减流量
|
||||
remainingUsage := deductUsageMB
|
||||
today := time.Now().Format("2006-01-02")
|
||||
|
||||
for index, pkg := range packages {
|
||||
if remainingUsage <= 0 {
|
||||
@@ -446,3 +455,45 @@ func (s *UsageService) triggerSuspensionAfterCommit(carrierType string, carrierI
|
||||
}(cardID)
|
||||
}
|
||||
}
|
||||
|
||||
// recordOverflowToDepletedPackage 在所有套餐已耗尽时,将溢出流量写入最近的 Depleted 套餐日记录。
|
||||
// 目的:保持流量详单连续性,即便套餐用完期间上游仍有流量使用,详单不会断档。
|
||||
// 只写日记录和累加 data_usage_mb,不改变套餐 status,不触发停机。
|
||||
func (s *UsageService) recordOverflowToDepletedPackage(ctx context.Context, tx *gorm.DB, carrierType string, carrierID uint, overflowMB int64, today string) error {
|
||||
query := tx.Where("status = ?", constants.PackageUsageStatusDepleted)
|
||||
switch carrierType {
|
||||
case constants.AssetTypeIotCard:
|
||||
query = query.Where("iot_card_id = ?", carrierID)
|
||||
case constants.AssetTypeDevice:
|
||||
query = query.Where("device_id = ?", carrierID)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
// 优先选主套餐(master_usage_id IS NULL),主套餐不存在时再退而求其次取加油包
|
||||
var pkg model.PackageUsage
|
||||
err := query.Where("master_usage_id IS NULL").Order("id DESC").First(&pkg).Error
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
err = query.Order("id DESC").First(&pkg).Error
|
||||
}
|
||||
if err != nil {
|
||||
// 找不到任何 Depleted 套餐,静默忽略
|
||||
return nil
|
||||
}
|
||||
|
||||
newUsage := pkg.DataUsageMB + overflowMB
|
||||
if err := tx.Model(&pkg).Update("data_usage_mb", newUsage).Error; err != nil {
|
||||
return errors.Wrap(errors.CodeDatabaseError, err, "更新溢出流量失败")
|
||||
}
|
||||
|
||||
if err := s.updateDailyRecord(ctx, tx, pkg.ID, today, overflowMB, newUsage); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.logger.Info("记录溢出流量到已耗尽套餐",
|
||||
zap.Uint("package_usage_id", pkg.ID),
|
||||
zap.Int64("overflow_mb", overflowMB),
|
||||
zap.Int64("new_usage_mb", newUsage))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user