Files
junhong_cmp_fiber/internal/infrastructure/wallet/credit_event.go
break 1e4f998fe7
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m11s
补充通知信息
2026-07-28 16:14:20 +08:00

66 lines
3.0 KiB
Go

package wallet
import (
"context"
"fmt"
"strconv"
notificationapp "github.com/break/junhong_cmp_fiber/internal/application/notification"
walletapp "github.com/break/junhong_cmp_fiber/internal/application/wallet"
"github.com/break/junhong_cmp_fiber/internal/infrastructure/messaging/outbox"
"github.com/break/junhong_cmp_fiber/internal/model"
"github.com/break/junhong_cmp_fiber/pkg/constants"
"github.com/break/junhong_cmp_fiber/pkg/errors"
"gorm.io/gorm"
)
// CreditEventWriter 将代理主钱包正向入账事实写入公共 Outbox。
type CreditEventWriter struct {
outbox *outbox.Repository
}
// NewCreditEventWriter 创建代理主钱包入账 Outbox Writer。
func NewCreditEventWriter(repository *outbox.Repository) *CreditEventWriter {
return &CreditEventWriter{outbox: repository}
}
// Append 在调用方业务事务中追加代理主钱包入账事件。
func (w *CreditEventWriter) Append(ctx context.Context, tx *gorm.DB, event walletapp.CreditedEvent) error {
if w == nil || w.outbox == nil {
return errors.New(errors.CodeInternalError, "代理主钱包入账 Outbox Writer 未配置")
}
_, err := w.outbox.Append(ctx, tx, outbox.Envelope{
EventID: event.EventID, EventType: constants.OutboxEventTypeAgentMainWalletCredited,
PayloadVersion: constants.AgentMainWalletCreditedPayloadVersionV1,
AggregateType: "agent_wallet", AggregateID: strconv.FormatUint(uint64(event.WalletID), 10),
ResourceType: event.ReferenceType, ResourceID: strconv.FormatUint(uint64(event.ReferenceID), 10),
BusinessKey: event.EventID, RequestID: event.RequestID, CorrelationID: event.CorrelationID, Payload: event,
})
if err != nil || event.ReferenceType != constants.ReferenceTypeTopup || event.TransactionType != constants.AgentTransactionTypeRecharge {
return err
}
rechargeID := strconv.FormatUint(uint64(event.ReferenceID), 10)
var shop model.Shop
if err := tx.WithContext(ctx).Select("shop_name").Where("id = ?", event.ShopID).Take(&shop).Error; err != nil {
return errors.Wrap(errors.CodeDatabaseError, err, "查询充值通知店铺失败")
}
notificationEventID := "agent-recharge:" + rechargeID + ":completed"
_, err = w.outbox.AppendIdempotent(ctx, tx, outbox.Envelope{
EventID: notificationEventID, EventType: constants.OutboxEventTypeAdminDynamicNotification,
PayloadVersion: constants.NotificationPayloadVersionV1,
AggregateType: "agent_recharge", AggregateID: rechargeID,
ResourceType: constants.NotificationRefTypeAgentRecharge, ResourceID: rechargeID,
BusinessKey: notificationEventID, RequestID: event.RequestID, CorrelationID: event.CorrelationID,
Payload: notificationapp.AdminDynamicPayload{
TargetKind: constants.NotificationTargetKindShop, TargetID: event.ShopID,
NotificationType: constants.NotificationTypeAgentRechargeCompleted,
TemplateData: map[string]string{
"shop_name": shop.ShopName,
"amount": fmt.Sprintf("%d.%02d 元", event.Amount/100, event.Amount%100),
},
RefType: constants.NotificationRefTypeAgentRecharge, RefID: rechargeID,
},
})
return err
}