Files
tyapi-server/internal/infrastructure/events/invoice_event_handler.go
liangzai 66845d3fe0 v1.0.0
2025-08-02 02:54:21 +08:00

230 lines
7.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package events
import (
"context"
"encoding/json"
"fmt"
"time"
"go.uber.org/zap"
"tyapi-server/internal/domains/finance/events"
"tyapi-server/internal/infrastructure/external/email"
"tyapi-server/internal/shared/interfaces"
)
// InvoiceEventHandler 发票事件处理器
type InvoiceEventHandler struct {
logger *zap.Logger
emailService *email.QQEmailService
name string
eventTypes []string
isAsync bool
}
// NewInvoiceEventHandler 创建发票事件处理器
func NewInvoiceEventHandler(logger *zap.Logger, emailService *email.QQEmailService) *InvoiceEventHandler {
return &InvoiceEventHandler{
logger: logger,
emailService: emailService,
name: "invoice-event-handler",
eventTypes: []string{
"InvoiceApplicationCreated",
"InvoiceApplicationApproved",
"InvoiceApplicationRejected",
"InvoiceFileUploaded",
},
isAsync: true,
}
}
// GetName 获取处理器名称
func (h *InvoiceEventHandler) GetName() string {
return h.name
}
// GetEventTypes 获取支持的事件类型
func (h *InvoiceEventHandler) GetEventTypes() []string {
return h.eventTypes
}
// IsAsync 是否为异步处理器
func (h *InvoiceEventHandler) IsAsync() bool {
return h.isAsync
}
// GetRetryConfig 获取重试配置
func (h *InvoiceEventHandler) GetRetryConfig() interfaces.RetryConfig {
return interfaces.RetryConfig{
MaxRetries: 3,
RetryDelay: 5 * time.Second,
BackoffFactor: 2.0,
MaxDelay: 30 * time.Second,
}
}
// Handle 处理事件
func (h *InvoiceEventHandler) Handle(ctx context.Context, event interfaces.Event) error {
h.logger.Info("🔄 开始处理发票事件",
zap.String("event_type", event.GetType()),
zap.String("event_id", event.GetID()),
zap.String("aggregate_id", event.GetAggregateID()),
zap.String("handler_name", h.GetName()),
zap.Time("event_timestamp", event.GetTimestamp()),
)
switch event.GetType() {
case "InvoiceApplicationCreated":
h.logger.Info("📝 处理发票申请创建事件")
return h.handleInvoiceApplicationCreated(ctx, event)
case "InvoiceApplicationApproved":
h.logger.Info("✅ 处理发票申请通过事件")
return h.handleInvoiceApplicationApproved(ctx, event)
case "InvoiceApplicationRejected":
h.logger.Info("❌ 处理发票申请拒绝事件")
return h.handleInvoiceApplicationRejected(ctx, event)
case "InvoiceFileUploaded":
h.logger.Info("📎 处理发票文件上传事件")
return h.handleInvoiceFileUploaded(ctx, event)
default:
h.logger.Warn("⚠️ 未知的发票事件类型", zap.String("event_type", event.GetType()))
return nil
}
}
// handleInvoiceApplicationCreated 处理发票申请创建事件
func (h *InvoiceEventHandler) handleInvoiceApplicationCreated(ctx context.Context, event interfaces.Event) error {
h.logger.Info("发票申请已创建",
zap.String("application_id", event.GetAggregateID()),
)
// 这里可以发送通知给管理员,告知有新的发票申请
// 暂时只记录日志
return nil
}
// handleInvoiceApplicationApproved 处理发票申请通过事件
func (h *InvoiceEventHandler) handleInvoiceApplicationApproved(ctx context.Context, event interfaces.Event) error {
h.logger.Info("发票申请已通过",
zap.String("application_id", event.GetAggregateID()),
)
// 这里可以发送通知给用户,告知发票申请已通过
// 暂时只记录日志
return nil
}
// handleInvoiceApplicationRejected 处理发票申请拒绝事件
func (h *InvoiceEventHandler) handleInvoiceApplicationRejected(ctx context.Context, event interfaces.Event) error {
h.logger.Info("发票申请被拒绝",
zap.String("application_id", event.GetAggregateID()),
)
// 这里可以发送邮件通知用户,告知发票申请被拒绝
// 暂时只记录日志
return nil
}
// handleInvoiceFileUploaded 处理发票文件上传事件
func (h *InvoiceEventHandler) handleInvoiceFileUploaded(ctx context.Context, event interfaces.Event) error {
h.logger.Info("📎 发票文件已上传事件开始处理",
zap.String("invoice_id", event.GetAggregateID()),
zap.String("event_id", event.GetID()),
)
// 解析事件数据
payload := event.GetPayload()
if payload == nil {
h.logger.Error("❌ 事件数据为空")
return fmt.Errorf("事件数据为空")
}
h.logger.Info("📋 事件数据解析开始",
zap.Any("payload_type", fmt.Sprintf("%T", payload)),
)
// 将payload转换为JSON然后解析为InvoiceFileUploadedEvent
payloadBytes, err := json.Marshal(payload)
if err != nil {
h.logger.Error("❌ 序列化事件数据失败", zap.Error(err))
return fmt.Errorf("序列化事件数据失败: %w", err)
}
h.logger.Info("📄 事件数据序列化成功",
zap.String("payload_json", string(payloadBytes)),
)
var fileUploadedEvent events.InvoiceFileUploadedEvent
err = json.Unmarshal(payloadBytes, &fileUploadedEvent)
if err != nil {
h.logger.Error("❌ 解析发票文件上传事件失败", zap.Error(err))
return fmt.Errorf("解析发票文件上传事件失败: %w", err)
}
h.logger.Info("✅ 事件数据解析成功",
zap.String("invoice_id", fileUploadedEvent.InvoiceID),
zap.String("user_id", fileUploadedEvent.UserID),
zap.String("receiving_email", fileUploadedEvent.ReceivingEmail),
zap.String("file_name", fileUploadedEvent.FileName),
zap.String("file_url", fileUploadedEvent.FileURL),
zap.String("company_name", fileUploadedEvent.CompanyName),
zap.String("amount", fileUploadedEvent.Amount.String()),
zap.String("invoice_type", string(fileUploadedEvent.InvoiceType)),
)
// 发送发票邮件给用户
return h.sendInvoiceEmail(ctx, &fileUploadedEvent)
}
// sendInvoiceEmail 发送发票邮件
func (h *InvoiceEventHandler) sendInvoiceEmail(ctx context.Context, event *events.InvoiceFileUploadedEvent) error {
h.logger.Info("📧 开始发送发票邮件",
zap.String("invoice_id", event.InvoiceID),
zap.String("user_id", event.UserID),
zap.String("receiving_email", event.ReceivingEmail),
zap.String("file_name", event.FileName),
zap.String("file_url", event.FileURL),
)
// 构建邮件数据
emailData := &email.InvoiceEmailData{
CompanyName: event.CompanyName,
Amount: event.Amount.String(),
InvoiceType: event.InvoiceType.GetDisplayName(),
FileURL: event.FileURL,
FileName: event.FileName,
ReceivingEmail: event.ReceivingEmail,
ApprovedAt: event.UploadedAt.Format("2006-01-02 15:04:05"),
}
h.logger.Info("📋 邮件数据构建完成",
zap.String("company_name", emailData.CompanyName),
zap.String("amount", emailData.Amount),
zap.String("invoice_type", emailData.InvoiceType),
zap.String("file_url", emailData.FileURL),
zap.String("file_name", emailData.FileName),
zap.String("receiving_email", emailData.ReceivingEmail),
zap.String("approved_at", emailData.ApprovedAt),
)
// 发送邮件
h.logger.Info("🚀 开始调用邮件服务发送邮件")
err := h.emailService.SendInvoiceEmail(ctx, emailData)
if err != nil {
h.logger.Error("❌ 发送发票邮件失败",
zap.String("invoice_id", event.InvoiceID),
zap.String("receiving_email", event.ReceivingEmail),
zap.Error(err),
)
return fmt.Errorf("发送发票邮件失败: %w", err)
}
h.logger.Info("✅ 发票邮件发送成功",
zap.String("invoice_id", event.InvoiceID),
zap.String("receiving_email", event.ReceivingEmail),
)
return nil
}