收口审计治理与套餐任务进展

Constraint: 在线热修前必须保存当前迭代分支全部有效代码进展
Confidence: medium
Scope-risk: broad
Directive: 后续修改需保持审计事件与业务事务边界一致
Tested: git diff --cached --check
Not-tested: 未运行全量测试,提交用于切换分支前保存既有工作
This commit is contained in:
2026-08-05 14:30:54 +08:00
parent b3499adfca
commit 5e552d99bc
178 changed files with 16797 additions and 5674 deletions

View File

@@ -12,21 +12,27 @@ import (
"gorm.io/gorm/clause"
)
func (s *Service) executeMigrationWithTx(ctx context.Context, tx *gorm.DB, order *model.ExchangeOrder, oldAsset, newAsset *resolvedExchangeAsset) (int64, error) {
type exchangeMigrationResult struct {
Balance int64
PackageUsageIDs []uint
}
func (s *Service) executeMigrationWithTx(ctx context.Context, tx *gorm.DB, order *model.ExchangeOrder, oldAsset, newAsset *resolvedExchangeAsset) (*exchangeMigrationResult, error) {
migrationBalance, err := s.transferWalletBalanceWithTx(ctx, tx, order, oldAsset, newAsset)
if err != nil {
return 0, errors.Wrap(errors.CodeExchangeMigrationFailed, err, "执行钱包迁移失败")
return nil, errors.Wrap(errors.CodeExchangeMigrationFailed, err, "执行钱包迁移失败")
}
if err = s.migratePackageUsageWithTx(ctx, tx, oldAsset, newAsset); err != nil {
return 0, errors.Wrap(errors.CodeExchangeMigrationFailed, err, "迁移套餐使用记录失败")
usageIDs, err := s.migratePackageUsageWithTx(ctx, tx, oldAsset, newAsset)
if err != nil {
return nil, errors.Wrap(errors.CodeExchangeMigrationFailed, err, "迁移套餐使用记录失败")
}
if err = s.copyAccumulatedFieldsWithTx(tx, oldAsset, newAsset); err != nil {
return 0, errors.Wrap(errors.CodeExchangeMigrationFailed, err, "复制累计充值字段失败")
return nil, errors.Wrap(errors.CodeExchangeMigrationFailed, err, "复制累计充值字段失败")
}
if err = s.copyResourceTagsWithTx(ctx, tx, oldAsset, newAsset); err != nil {
return 0, errors.Wrap(errors.CodeExchangeMigrationFailed, err, "复制资产标签失败")
return nil, errors.Wrap(errors.CodeExchangeMigrationFailed, err, "复制资产标签失败")
}
return migrationBalance, nil
return &exchangeMigrationResult{Balance: migrationBalance, PackageUsageIDs: usageIDs}, nil
}
func (s *Service) transferWalletBalanceWithTx(ctx context.Context, tx *gorm.DB, order *model.ExchangeOrder, oldAsset, newAsset *resolvedExchangeAsset) (int64, error) {
@@ -95,7 +101,7 @@ func (s *Service) transferWalletBalanceWithTx(ctx context.Context, tx *gorm.DB,
return migrationBalance, nil
}
func (s *Service) migratePackageUsageWithTx(ctx context.Context, tx *gorm.DB, oldAsset, newAsset *resolvedExchangeAsset) error {
func (s *Service) migratePackageUsageWithTx(ctx context.Context, tx *gorm.DB, oldAsset, newAsset *resolvedExchangeAsset) ([]uint, error) {
query := tx.WithContext(ctx).Model(&model.PackageUsage{}).Where("status IN ?", []int{constants.PackageUsageStatusPending, constants.PackageUsageStatusActive, constants.PackageUsageStatusDepleted})
if oldAsset.AssetType == constants.ExchangeAssetTypeIotCard {
query = query.Where("iot_card_id = ?", oldAsset.AssetID)
@@ -105,11 +111,11 @@ func (s *Service) migratePackageUsageWithTx(ctx context.Context, tx *gorm.DB, ol
var usageIDs []uint
if err := query.Pluck("id", &usageIDs).Error; err != nil {
return errors.Wrap(errors.CodeDatabaseError, err, "查询套餐使用记录失败")
return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询套餐使用记录失败")
}
if len(usageIDs) == 0 {
return nil
return nil, nil
}
updates := map[string]any{"updated_at": time.Now()}
@@ -120,14 +126,14 @@ func (s *Service) migratePackageUsageWithTx(ctx context.Context, tx *gorm.DB, ol
}
if err := tx.WithContext(ctx).Model(&model.PackageUsage{}).Where("id IN ?", usageIDs).Updates(updates).Error; err != nil {
return errors.Wrap(errors.CodeDatabaseError, err, "迁移套餐使用记录失败")
return nil, errors.Wrap(errors.CodeDatabaseError, err, "迁移套餐使用记录失败")
}
if err := tx.WithContext(ctx).Model(&model.PackageUsageDailyRecord{}).Where("package_usage_id IN ?", usageIDs).Update("updated_at", gorm.Expr("updated_at")).Error; err != nil {
return errors.Wrap(errors.CodeDatabaseError, err, "迁移套餐日记录失败")
return nil, errors.Wrap(errors.CodeDatabaseError, err, "迁移套餐日记录失败")
}
return nil
return usageIDs, nil
}
func (s *Service) copyAccumulatedFieldsWithTx(tx *gorm.DB, oldAsset, newAsset *resolvedExchangeAsset) error {