This commit is contained in:
2025-08-02 02:54:21 +08:00
parent 934dce2776
commit 66845d3fe0
74 changed files with 8686 additions and 212 deletions

View File

@@ -0,0 +1,230 @@
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
}