Constraint: 在线热修前必须保存当前迭代分支全部有效代码进展 Confidence: medium Scope-risk: broad Directive: 后续修改需保持审计事件与业务事务边界一致 Tested: git diff --cached --check Not-tested: 未运行全量测试,提交用于切换分支前保存既有工作
85 lines
4.3 KiB
Go
85 lines
4.3 KiB
Go
package audit
|
|
|
|
import (
|
|
"context"
|
|
"strconv"
|
|
|
|
"gorm.io/gorm"
|
|
|
|
agentrecharge "github.com/break/junhong_cmp_fiber/internal/application/agentrecharge"
|
|
"github.com/break/junhong_cmp_fiber/internal/model"
|
|
"github.com/break/junhong_cmp_fiber/pkg/constants"
|
|
"github.com/break/junhong_cmp_fiber/pkg/errors"
|
|
)
|
|
|
|
// WriteAgentRechargePayment 将代理充值支付生命周期写入统一 Audit Event。
|
|
func (w *Writer) WriteAgentRechargePayment(ctx context.Context, tx *gorm.DB, change agentrecharge.PaymentAudit) error {
|
|
if change.Payment == nil || change.Payment.ID == 0 || change.Payment.PaymentNo == "" || change.Recharge == nil || change.Recharge.ID == 0 {
|
|
return errors.New(errors.CodeInvalidParam, "代理充值支付审计资源不完整")
|
|
}
|
|
payment := PaymentResource(change.Payment, constants.AuditResourceRelationPrimary, constants.AuditResourceRolePaymentTarget, change.BeforeData, change.AfterData)
|
|
rechargeID := strconv.FormatUint(uint64(change.Recharge.ID), 10)
|
|
rechargeRelation := constants.AuditResourceRelationReference
|
|
if len(change.RechargeBeforeData) > 0 || len(change.RechargeAfterData) > 0 {
|
|
rechargeRelation = constants.AuditResourceRelationAffected
|
|
}
|
|
rechargeStatus := any(change.Recharge.Status)
|
|
if status, ok := change.RechargeAfterData["status"]; ok {
|
|
rechargeStatus = status
|
|
}
|
|
recharge := ResourceInput{
|
|
Type: constants.AuditResourceAgentRecharge, ID: &rechargeID,
|
|
Key: change.Recharge.RechargeNo, DisplayName: change.Recharge.RechargeNo,
|
|
Relation: rechargeRelation, Role: constants.AuditResourceRolePaymentBusinessOrder,
|
|
IdentitySnapshot: map[string]any{
|
|
"id": change.Recharge.ID, "recharge_no": change.Recharge.RechargeNo,
|
|
"user_id": change.Recharge.UserID,
|
|
"shop_id": change.Recharge.ShopID, "agent_wallet_id": change.Recharge.AgentWalletID,
|
|
"amount": change.Recharge.Amount, "payment_method": change.Recharge.PaymentMethod,
|
|
"payment_channel": change.Recharge.PaymentChannel,
|
|
"approval_instance_id": change.Recharge.ApprovalInstanceID, "status": rechargeStatus,
|
|
},
|
|
BeforeData: change.RechargeBeforeData, AfterData: change.RechargeAfterData,
|
|
SubjectVisibility: constants.AuditSubjectResult, SubjectSummary: change.Summary,
|
|
}
|
|
resources := []ResourceInput{payment, recharge}
|
|
if change.Recharge.UserID > 0 {
|
|
var account model.Account
|
|
if err := tx.WithContext(ctx).Unscoped().First(&account, change.Recharge.UserID).Error; err != nil && err != gorm.ErrRecordNotFound {
|
|
return errors.Wrap(errors.CodeDatabaseError, err, "查询代理充值提交人审计快照失败")
|
|
}
|
|
if account.ID > 0 {
|
|
accountID := strconv.FormatUint(uint64(account.ID), 10)
|
|
resources = append(resources, ResourceInput{
|
|
Type: constants.AuditResourceAccount, ID: &accountID, Key: accountID, DisplayName: account.Username,
|
|
Relation: constants.AuditResourceRelationReference, Role: constants.AuditResourceRoleRechargeSubmitter,
|
|
IdentitySnapshot: accountIdentity(&account),
|
|
})
|
|
}
|
|
}
|
|
var shop model.Shop
|
|
if err := tx.WithContext(ctx).Unscoped().First(&shop, change.Recharge.ShopID).Error; err != nil {
|
|
return errors.Wrap(errors.CodeDatabaseError, err, "查询代理充值店铺审计快照失败")
|
|
}
|
|
resources = append(resources, ShopResource(&shop, constants.AuditResourceRelationReference, constants.AuditResourceRoleRechargeShop))
|
|
var wallet model.AgentWallet
|
|
if err := tx.WithContext(ctx).First(&wallet, change.Recharge.AgentWalletID).Error; err != nil {
|
|
return errors.Wrap(errors.CodeDatabaseError, err, "查询代理充值钱包审计快照失败")
|
|
}
|
|
walletID := strconv.FormatUint(uint64(wallet.ID), 10)
|
|
resources = append(resources, ResourceInput{
|
|
Type: constants.AuditResourceAgentWallet, ID: &walletID, Key: walletID, DisplayName: "代理主钱包 " + walletID,
|
|
Relation: constants.AuditResourceRelationReference, Role: constants.AuditResourceRoleRechargeWallet,
|
|
IdentitySnapshot: map[string]any{
|
|
"id": wallet.ID, "shop_id": wallet.ShopID, "wallet_type": wallet.WalletType,
|
|
"currency": wallet.Currency, "status": wallet.Status,
|
|
},
|
|
SubjectVisibility: constants.AuditSubjectResult, SubjectSummary: change.Summary,
|
|
})
|
|
return w.Append(ctx, tx, AppendInput{
|
|
ActionCode: change.ActionCode, Summary: change.Summary,
|
|
ScopeType: constants.AuditScopePlatform, Result: constants.AuditResultSuccess,
|
|
CorrelationID: change.Payment.PaymentNo, Resources: resources,
|
|
})
|
|
}
|