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

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

@@ -10,11 +10,11 @@ import (
"github.com/break/junhong_cmp_fiber/internal/infrastructure/integrationlog"
"github.com/break/junhong_cmp_fiber/internal/model"
"github.com/break/junhong_cmp_fiber/internal/model/dto"
assetAuditSvc "github.com/break/junhong_cmp_fiber/internal/service/asset_audit"
"github.com/break/junhong_cmp_fiber/pkg/constants"
pkgerrors "github.com/break/junhong_cmp_fiber/pkg/errors"
"github.com/break/junhong_cmp_fiber/pkg/middleware"
"go.uber.org/zap"
"gorm.io/gorm"
)
type speedTierIntegrationLog interface {
@@ -30,7 +30,7 @@ func (s *Service) SetSpeedTier(ctx context.Context, iccid string, code *int) (*d
if code == nil || !constants.IsGatewaySpeedTier(*code) {
return nil, pkgerrors.New(pkgerrors.CodeInvalidParam, "固定限速档位不合法")
}
if s == nil || s.iotCardStore == nil || s.gatewayClient == nil || s.speedTierIntegration == nil {
if s == nil || s.iotCardStore == nil || s.gatewayClient == nil || s.speedTierIntegration == nil || s.db == nil || s.auditWriter == nil {
return nil, pkgerrors.New(pkgerrors.CodeServiceUnavailable, "卡限速服务未完整配置")
}
@@ -58,11 +58,10 @@ func (s *Service) SetSpeedTier(ctx context.Context, iccid string, code *int) (*d
"iccid": card.ICCID,
"tier_code": *code,
"tier_name": tierName,
"operator_id": middleware.GetUserIDFromContext(ctx),
},
})
if err != nil {
s.logSpeedTierAudit(ctx, card, *code, "", constants.AssetAuditResultFailed, err)
s.recordSpeedTierAudit(ctx, card, *code, "", false, constants.AuditResultFailed, err)
return nil, err
}
@@ -87,18 +86,22 @@ func (s *Service) SetSpeedTier(ctx context.Context, iccid string, code *int) (*d
zap.Error(completeErr),
)
}
s.logSpeedTierAudit(ctx, card, *code, attempt.IntegrationID, constants.AssetAuditResultFailed, completeErr)
auditErr := gatewayErr
if auditErr == nil {
auditErr = completeErr
}
s.recordSpeedTierAudit(ctx, card, *code, attempt.IntegrationID, false, speedTierAuditResult(gatewayErr), auditErr)
return nil, pkgerrors.Wrap(pkgerrors.CodeDatabaseError, completeErr, "终结卡限速外部交互记录失败")
}
if gatewayErr != nil {
s.logSpeedTierAudit(ctx, card, *code, attempt.IntegrationID, constants.AssetAuditResultFailed, gatewayErr)
s.recordSpeedTierAudit(ctx, card, *code, attempt.IntegrationID, true, speedTierAuditResult(gatewayErr), gatewayErr)
if isGatewayTimeout(gatewayErr) {
return nil, pkgerrors.New(pkgerrors.CodeGatewayTimeout, "Gateway 卡限速请求结果未知,请核对实际档位后再操作")
}
return nil, gatewayErr
}
s.logSpeedTierAudit(ctx, card, *code, attempt.IntegrationID, constants.AssetAuditResultSuccess, nil)
s.recordSpeedTierAudit(ctx, card, *code, attempt.IntegrationID, true, constants.AuditResultSuccess, nil)
return &dto.SetIotCardSpeedTierResponse{
IotCardID: card.ID, ICCID: card.ICCID, Code: *code,
SpeedTierName: tierName, IntegrationID: attempt.IntegrationID,
@@ -118,7 +121,7 @@ func speedTierCompletion(err error, duration time.Duration) integrationlog.Compl
completion := integrationlog.Completion{
Result: constants.IntegrationResultSuccess,
DurationMS: duration.Milliseconds(),
StateChanged: true,
StateChanged: false,
ResponseSummary: map[string]any{
"result": "success",
},
@@ -132,6 +135,7 @@ func speedTierCompletion(err error, duration time.Duration) integrationlog.Compl
completion.ResponseSummary = map[string]any{"result": "failed"}
if isGatewayTimeout(err) {
completion.Result = constants.IntegrationResultUnknown
completion.SafeProviderMessage = "Gateway 卡限速请求结果未知"
completion.ResponseSummary = map[string]any{"result": "unknown"}
completion.RecoveryStrategy = constants.GatewaySpeedTierUnknownRecoveryStrategy
}
@@ -143,24 +147,34 @@ func isGatewayTimeout(err error) bool {
return stderrors.As(err, &appErr) && appErr != nil && appErr.Code == pkgerrors.CodeGatewayTimeout
}
func (s *Service) logSpeedTierAudit(ctx context.Context, card *model.IotCard, code int, integrationID, result string, err error) {
errorCode, errorMsg := assetAuditSvc.BuildErrorInfo(err)
s.logCardAudit(ctx, assetAuditSvc.BuildLogParams{
AssetType: constants.AssetTypeIotCard,
AssetID: card.ID,
AssetIdentifier: card.ICCID,
OperationType: constants.AssetAuditOpCardSpeedTier,
OperationDesc: "设置 IoT 卡固定限速档位",
BeforeData: map[string]any{"card": cardSnapshot(card)},
AfterData: map[string]any{
"tier_code": code,
"tier_name": constants.GetGatewaySpeedTierName(code),
"integration_id": integrationID,
},
ResultStatus: result,
ErrorCode: errorCode,
ErrorMsg: errorMsg,
})
func speedTierAuditResult(err error) string {
if err == nil {
return constants.AuditResultSuccess
}
if isGatewayTimeout(err) {
return constants.AuditResultUnknown
}
return constants.AuditResultFailed
}
func (s *Service) recordSpeedTierAudit(ctx context.Context, card *model.IotCard, code int, integrationID string, integrationLogCompleted bool, result string, businessErr error) {
afterData := map[string]any{
"requested_tier_code": code,
"requested_tier_name": constants.GetGatewaySpeedTierName(code),
"integration_id": integrationID,
"integration_log_completed": integrationLogCompleted,
}
if s.db == nil || s.auditWriter == nil {
recordCardAuditSecondaryFailure(ctx, constants.AuditActionIotCardSpeedTierSet, card.ID, businessErr,
pkgerrors.New(pkgerrors.CodeInvalidStatus, "IoT 卡统一审计接缝未配置"))
return
}
if err := s.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
return s.appendCardLifecycleAudit(ctx, tx, constants.AuditActionIotCardSpeedTierSet,
"设置 IoT 卡固定限速档位为"+constants.GetGatewaySpeedTierName(code), result, card, nil, afterData, businessErr)
}); err != nil {
recordCardAuditSecondaryFailure(ctx, constants.AuditActionIotCardSpeedTierSet, card.ID, businessErr, err)
}
}
var _ speedTierIntegrationLog = (*integrationlog.Repository)(nil)