收口审计治理与套餐任务进展
Constraint: 在线热修前必须保存当前迭代分支全部有效代码进展 Confidence: medium Scope-risk: broad Directive: 后续修改需保持审计事件与业务事务边界一致 Tested: git diff --cached --check Not-tested: 未运行全量测试,提交用于切换分支前保存既有工作
This commit is contained in:
@@ -2,8 +2,10 @@ package recharge_order
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/infrastructure/audit"
|
||||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||||
"github.com/break/junhong_cmp_fiber/internal/store/postgres"
|
||||
"github.com/break/junhong_cmp_fiber/internal/task"
|
||||
@@ -28,6 +30,12 @@ type Service struct {
|
||||
commissionRecordStore *postgres.CommissionRecordStore
|
||||
queueClient *queue.Client
|
||||
logger *zap.Logger
|
||||
auditWriter *audit.Writer
|
||||
}
|
||||
|
||||
// SetPaymentAudit 注入充值支付统一审计 Writer。
|
||||
func (s *Service) SetPaymentAudit(writer *audit.Writer) {
|
||||
s.auditWriter = writer
|
||||
}
|
||||
|
||||
func New(
|
||||
@@ -157,8 +165,60 @@ func (s *Service) HandlePaymentCallback(ctx context.Context, paymentNo string, p
|
||||
if err := s.triggerOneTimeCommissionIfNeededInTx(ctx, tx, rechargeOrder, rechargeOrder.Amount); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
if s.auditWriter == nil {
|
||||
return errors.New(errors.CodeInvalidStatus, "充值支付统一审计接缝未配置")
|
||||
}
|
||||
afterPayment := *payment
|
||||
afterPayment.Status = model.PaymentRecordStatusPaid
|
||||
afterPayment.ThirdPartyTradeNo = transactionID
|
||||
afterPayment.PaidAt = &now
|
||||
paymentResource := audit.PaymentResource(&afterPayment, constants.AuditResourceRelationPrimary, constants.AuditResourceRolePaymentTarget,
|
||||
map[string]any{"status": payment.Status, "third_party_trade_no": payment.ThirdPartyTradeNo, "paid_at": payment.PaidAt},
|
||||
map[string]any{"status": afterPayment.Status, "third_party_trade_no": afterPayment.ThirdPartyTradeNo, "paid_at": afterPayment.PaidAt})
|
||||
rechargeID := strconv.FormatUint(uint64(rechargeOrder.ID), 10)
|
||||
rechargeResource := audit.ResourceInput{
|
||||
Type: constants.AuditResourceRechargeOrder, ID: &rechargeID, Key: rechargeOrder.RechargeOrderNo, DisplayName: rechargeOrder.RechargeOrderNo,
|
||||
Relation: constants.AuditResourceRelationAffected, Role: constants.AuditResourceRolePaymentBusinessOrder,
|
||||
IdentitySnapshot: map[string]any{
|
||||
"id": rechargeOrder.ID, "recharge_order_no": rechargeOrder.RechargeOrderNo, "user_id": rechargeOrder.UserID,
|
||||
"asset_wallet_id": rechargeOrder.AssetWalletID, "resource_type": rechargeOrder.ResourceType,
|
||||
"resource_id": rechargeOrder.ResourceID, "amount": rechargeOrder.Amount, "status": model.RechargeOrderStatusPaid,
|
||||
},
|
||||
BeforeData: map[string]any{"status": rechargeOrder.Status}, AfterData: map[string]any{"status": model.RechargeOrderStatusPaid},
|
||||
SubjectVisibility: constants.AuditSubjectResult, SubjectSummary: "充值支付已到账",
|
||||
}
|
||||
transactionIDValue := strconv.FormatUint(uint64(transaction.ID), 10)
|
||||
transactionResource := audit.ResourceInput{
|
||||
Type: constants.AuditResourceAssetWalletTransaction, ID: &transactionIDValue, Key: transactionIDValue, DisplayName: "资产钱包流水 " + transactionIDValue,
|
||||
Relation: constants.AuditResourceRelationAffected, Role: constants.AuditResourceRolePaymentWalletTransaction,
|
||||
IdentitySnapshot: map[string]any{
|
||||
"id": transaction.ID, "asset_wallet_id": transaction.AssetWalletID, "resource_type": transaction.ResourceType,
|
||||
"resource_id": transaction.ResourceID, "transaction_type": transaction.TransactionType,
|
||||
"reference_type": transaction.ReferenceType, "reference_no": transaction.ReferenceNo, "status": transaction.Status,
|
||||
},
|
||||
AfterData: map[string]any{"amount": transaction.Amount, "balance_before": transaction.BalanceBefore, "balance_after": transaction.BalanceAfter},
|
||||
}
|
||||
resources := []audit.ResourceInput{paymentResource, rechargeResource, transactionResource}
|
||||
references, err := audit.AssetRechargeReferences(ctx, tx, rechargeOrder)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for i := range references {
|
||||
if references[i].Type != constants.AuditResourceAssetWallet {
|
||||
continue
|
||||
}
|
||||
references[i].Relation = constants.AuditResourceRelationAffected
|
||||
references[i].BeforeData = map[string]any{"balance": balanceBefore}
|
||||
references[i].AfterData = map[string]any{"balance": balanceBefore + rechargeOrder.Amount}
|
||||
references[i].SubjectVisibility = constants.AuditSubjectResult
|
||||
references[i].SubjectSummary = "充值支付已到账"
|
||||
}
|
||||
resources = append(resources, references...)
|
||||
return s.auditWriter.Append(ctx, tx, audit.AppendInput{
|
||||
ActionCode: constants.AuditActionPaymentConfirmed, Summary: "第三方支付确认资产充值已到账",
|
||||
ScopeType: constants.AuditScopePlatform, Result: constants.AuditResultSuccess,
|
||||
CorrelationID: payment.PaymentNo, Resources: resources,
|
||||
})
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user