补充一些通知
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m7s

This commit is contained in:
2026-07-28 15:50:12 +08:00
parent 9303af3d46
commit 1fee19feeb
12 changed files with 151 additions and 27 deletions

View File

@@ -85,7 +85,10 @@ func (s *Service) applyApprovedDecision(ctx context.Context, event approvalapp.T
default:
return errors.New(errors.CodeInvalidStatus, "订单状态不允许完成退款")
}
return s.refundWalletPayment(ctx, tx, &refund, &order, approvedAmount, event.SubmitterAccountID)
if err := s.refundWalletPayment(ctx, tx, &refund, &order, approvedAmount, event.SubmitterAccountID); err != nil {
return err
}
return s.appendCompletedNotification(ctx, tx, &refund)
})
if err != nil {
return err

View File

@@ -14,8 +14,10 @@ import (
"gorm.io/gorm"
"gorm.io/gorm/clause"
notificationapp "github.com/break/junhong_cmp_fiber/internal/application/notification"
refundapprovalapp "github.com/break/junhong_cmp_fiber/internal/application/refundapproval"
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/internal/model/dto"
"github.com/break/junhong_cmp_fiber/internal/store"
@@ -47,6 +49,7 @@ type Service struct {
assetWalletStore *postgres.AssetWalletStore
agentWalletRefundService *walletapp.RefundService
refundApprovalCreation *refundapprovalapp.CreationService
notificationOutbox *outbox.Repository
logger *zap.Logger
}
@@ -93,6 +96,11 @@ func (s *Service) SetRefundApprovalCreationService(service *refundapprovalapp.Cr
s.refundApprovalCreation = service
}
// SetNotificationOutbox 注入退款完成后的可靠店铺通知 Outbox。
func (s *Service) SetNotificationOutbox(repository *outbox.Repository) {
s.notificationOutbox = repository
}
// Create 创建退款申请
// 校验订单存在且已支付,检查是否存在活跃退款申请,生成退款单号并创建记录
func (s *Service) Create(ctx context.Context, req *dto.CreateRefundRequest) (*dto.RefundResponse, error) {
@@ -306,8 +314,7 @@ func (s *Service) Approve(ctx context.Context, id uint, req *dto.ApproveRefundRe
if err := s.refundWalletPayment(ctx, tx, refund, order, approvedAmount, userID); err != nil {
return err
}
return nil
return s.appendCompletedNotification(ctx, tx, refund)
}); err != nil {
return err
}
@@ -326,6 +333,34 @@ func (s *Service) Approve(ctx context.Context, id uint, req *dto.ApproveRefundRe
return nil
}
// appendCompletedNotification 在退款业务事务内幂等写入目标店铺通知。
func (s *Service) appendCompletedNotification(ctx context.Context, tx *gorm.DB, refund *model.RefundRequest) error {
if refund == nil || refund.ShopID == nil {
return nil
}
if s.notificationOutbox == nil {
return errors.New(errors.CodeInternalError, "退款通知 Outbox 未配置")
}
refundID := fmt.Sprintf("%d", refund.ID)
eventID := "refund:" + refundID + ":completed"
_, err := s.notificationOutbox.AppendIdempotent(ctx, tx, outbox.Envelope{
EventID: eventID, EventType: constants.OutboxEventTypeAdminDynamicNotification,
PayloadVersion: constants.NotificationPayloadVersionV1,
AggregateType: "refund", AggregateID: refundID,
ResourceType: constants.NotificationRefTypeRefund, ResourceID: refundID,
BusinessKey: eventID,
Payload: notificationapp.AdminDynamicPayload{
TargetKind: constants.NotificationTargetKindShop, TargetID: *refund.ShopID,
NotificationType: constants.NotificationTypeRefundCompleted, TemplateData: map[string]string{},
RefType: constants.NotificationRefTypeRefund, RefID: refundID, RefKey: refund.RefundNo,
},
})
if err != nil {
return errors.Wrap(errors.CodeDatabaseError, err, "写入退款完成通知事件失败")
}
return nil
}
// refundWalletPayment 处理钱包支付订单的退款回款。
func (s *Service) refundWalletPayment(ctx context.Context, tx *gorm.DB, refund *model.RefundRequest, order *model.Order, amount int64, operatorID uint) error {
if order.PaymentMethod != model.PaymentMethodWallet {