230 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			230 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 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
 | ||
| }
 | ||
| 
 | ||
|   |