2025-07-11 21:05:58 +08:00
|
|
|
|
package events
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
|
"context"
|
|
|
|
|
|
"encoding/json"
|
|
|
|
|
|
"fmt"
|
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
|
|
"go.uber.org/zap"
|
|
|
|
|
|
|
2025-07-13 16:36:20 +08:00
|
|
|
|
"tyapi-server/internal/infrastructure/external/notification"
|
2025-07-11 21:05:58 +08:00
|
|
|
|
"tyapi-server/internal/shared/interfaces"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// CertificationEventHandler 认证事件处理器
|
|
|
|
|
|
type CertificationEventHandler struct {
|
|
|
|
|
|
logger *zap.Logger
|
|
|
|
|
|
notification notification.WeChatWorkService
|
|
|
|
|
|
name string
|
|
|
|
|
|
eventTypes []string
|
|
|
|
|
|
isAsync bool
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// NewCertificationEventHandler 创建认证事件处理器
|
|
|
|
|
|
func NewCertificationEventHandler(logger *zap.Logger, notification notification.WeChatWorkService) *CertificationEventHandler {
|
|
|
|
|
|
return &CertificationEventHandler{
|
|
|
|
|
|
logger: logger,
|
|
|
|
|
|
notification: notification,
|
|
|
|
|
|
name: "certification-event-handler",
|
|
|
|
|
|
eventTypes: []string{
|
|
|
|
|
|
EventTypeCertificationCreated,
|
2025-07-20 20:53:26 +08:00
|
|
|
|
EventTypeEnterpriseInfoSubmitted,
|
|
|
|
|
|
EventTypeEnterpriseVerified,
|
|
|
|
|
|
EventTypeContractApplied,
|
2025-07-11 21:05:58 +08:00
|
|
|
|
EventTypeContractSigned,
|
|
|
|
|
|
EventTypeCertificationCompleted,
|
|
|
|
|
|
},
|
|
|
|
|
|
isAsync: true,
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GetName 获取处理器名称
|
|
|
|
|
|
func (h *CertificationEventHandler) GetName() string {
|
|
|
|
|
|
return h.name
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GetEventTypes 获取支持的事件类型
|
|
|
|
|
|
func (h *CertificationEventHandler) GetEventTypes() []string {
|
|
|
|
|
|
return h.eventTypes
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// IsAsync 是否为异步处理器
|
|
|
|
|
|
func (h *CertificationEventHandler) IsAsync() bool {
|
|
|
|
|
|
return h.isAsync
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GetRetryConfig 获取重试配置
|
|
|
|
|
|
func (h *CertificationEventHandler) GetRetryConfig() interfaces.RetryConfig {
|
|
|
|
|
|
return interfaces.RetryConfig{
|
|
|
|
|
|
MaxRetries: 3,
|
|
|
|
|
|
RetryDelay: 5 * time.Second,
|
|
|
|
|
|
BackoffFactor: 2.0,
|
|
|
|
|
|
MaxDelay: 30 * time.Second,
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Handle 处理事件
|
|
|
|
|
|
func (h *CertificationEventHandler) 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()),
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
switch event.GetType() {
|
|
|
|
|
|
case EventTypeCertificationCreated:
|
|
|
|
|
|
return h.handleCertificationCreated(ctx, event)
|
2025-07-20 20:53:26 +08:00
|
|
|
|
case EventTypeEnterpriseInfoSubmitted:
|
|
|
|
|
|
return h.handleEnterpriseInfoSubmitted(ctx, event)
|
|
|
|
|
|
case EventTypeEnterpriseVerified:
|
|
|
|
|
|
return h.handleEnterpriseVerified(ctx, event)
|
|
|
|
|
|
case EventTypeContractApplied:
|
|
|
|
|
|
return h.handleContractApplied(ctx, event)
|
2025-07-11 21:05:58 +08:00
|
|
|
|
case EventTypeContractSigned:
|
|
|
|
|
|
return h.handleContractSigned(ctx, event)
|
|
|
|
|
|
case EventTypeCertificationCompleted:
|
|
|
|
|
|
return h.handleCertificationCompleted(ctx, event)
|
|
|
|
|
|
default:
|
|
|
|
|
|
h.logger.Warn("未知的事件类型", zap.String("event_type", event.GetType()))
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// handleCertificationCreated 处理认证创建事件
|
|
|
|
|
|
func (h *CertificationEventHandler) handleCertificationCreated(ctx context.Context, event interfaces.Event) error {
|
|
|
|
|
|
h.logger.Info("认证申请已创建",
|
|
|
|
|
|
zap.String("certification_id", event.GetAggregateID()),
|
|
|
|
|
|
zap.String("user_id", h.extractUserID(event)),
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// 发送通知给用户
|
|
|
|
|
|
message := fmt.Sprintf("🎉 您的企业认证申请已创建成功!\n\n认证ID: %s\n创建时间: %s\n\n请按照指引完成后续认证步骤。",
|
|
|
|
|
|
event.GetAggregateID(),
|
|
|
|
|
|
event.GetTimestamp().Format("2006-01-02 15:04:05"))
|
|
|
|
|
|
|
|
|
|
|
|
return h.sendUserNotification(ctx, event, "认证申请创建成功", message)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// handleEnterpriseInfoSubmitted 处理企业信息提交事件
|
|
|
|
|
|
func (h *CertificationEventHandler) handleEnterpriseInfoSubmitted(ctx context.Context, event interfaces.Event) error {
|
|
|
|
|
|
h.logger.Info("企业信息已提交",
|
2025-07-11 21:05:58 +08:00
|
|
|
|
zap.String("certification_id", event.GetAggregateID()),
|
|
|
|
|
|
zap.String("user_id", h.extractUserID(event)),
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// 发送通知给用户
|
2025-07-28 01:46:39 +08:00
|
|
|
|
message := fmt.Sprintf("✅ 企业信息提交成功!\n\n认证ID: %s\n提交时间: %s\n\n请完成企业认证...",
|
2025-07-11 21:05:58 +08:00
|
|
|
|
event.GetAggregateID(),
|
|
|
|
|
|
event.GetTimestamp().Format("2006-01-02 15:04:05"))
|
|
|
|
|
|
|
2025-07-20 20:53:26 +08:00
|
|
|
|
return h.sendUserNotification(ctx, event, "企业信息提交成功", message)
|
2025-07-11 21:05:58 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// handleEnterpriseVerified 处理企业认证完成事件
|
|
|
|
|
|
func (h *CertificationEventHandler) handleEnterpriseVerified(ctx context.Context, event interfaces.Event) error {
|
|
|
|
|
|
h.logger.Info("企业认证已完成",
|
2025-07-11 21:05:58 +08:00
|
|
|
|
zap.String("certification_id", event.GetAggregateID()),
|
|
|
|
|
|
zap.String("user_id", h.extractUserID(event)),
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// 发送通知给用户
|
2025-07-20 20:53:26 +08:00
|
|
|
|
message := fmt.Sprintf("✅ 企业认证完成!\n\n认证ID: %s\n完成时间: %s\n\n下一步:请申请电子合同。",
|
2025-07-11 21:05:58 +08:00
|
|
|
|
event.GetAggregateID(),
|
|
|
|
|
|
event.GetTimestamp().Format("2006-01-02 15:04:05"))
|
|
|
|
|
|
|
2025-07-20 20:53:26 +08:00
|
|
|
|
return h.sendUserNotification(ctx, event, "企业认证完成", message)
|
2025-07-11 21:05:58 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// handleContractApplied 处理合同申请事件
|
|
|
|
|
|
func (h *CertificationEventHandler) handleContractApplied(ctx context.Context, event interfaces.Event) error {
|
2025-07-11 21:05:58 +08:00
|
|
|
|
h.logger.Info("电子合同申请已提交",
|
|
|
|
|
|
zap.String("certification_id", event.GetAggregateID()),
|
|
|
|
|
|
zap.String("user_id", h.extractUserID(event)),
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// 发送通知给用户
|
2025-07-20 20:53:26 +08:00
|
|
|
|
message := fmt.Sprintf("📋 电子合同申请已提交!\n\n认证ID: %s\n申请时间: %s\n\n系统正在生成电子合同,请稍候...",
|
2025-07-11 21:05:58 +08:00
|
|
|
|
event.GetAggregateID(),
|
|
|
|
|
|
event.GetTimestamp().Format("2006-01-02 15:04:05"))
|
|
|
|
|
|
|
2025-07-20 20:53:26 +08:00
|
|
|
|
return h.sendUserNotification(ctx, event, "合同申请已提交", message)
|
2025-07-11 21:05:58 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// handleContractSigned 处理合同签署事件
|
|
|
|
|
|
func (h *CertificationEventHandler) handleContractSigned(ctx context.Context, event interfaces.Event) error {
|
|
|
|
|
|
h.logger.Info("电子合同已签署",
|
|
|
|
|
|
zap.String("certification_id", event.GetAggregateID()),
|
|
|
|
|
|
zap.String("user_id", h.extractUserID(event)),
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// 发送通知给用户
|
2025-07-20 20:53:26 +08:00
|
|
|
|
message := fmt.Sprintf("✅ 电子合同签署完成!\n\n认证ID: %s\n签署时间: %s\n\n恭喜!您的企业认证已完成。",
|
2025-07-11 21:05:58 +08:00
|
|
|
|
event.GetAggregateID(),
|
|
|
|
|
|
event.GetTimestamp().Format("2006-01-02 15:04:05"))
|
|
|
|
|
|
|
2025-07-20 20:53:26 +08:00
|
|
|
|
return h.sendUserNotification(ctx, event, "合同签署完成", message)
|
2025-07-11 21:05:58 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// handleCertificationCompleted 处理认证完成事件
|
|
|
|
|
|
func (h *CertificationEventHandler) handleCertificationCompleted(ctx context.Context, event interfaces.Event) error {
|
|
|
|
|
|
h.logger.Info("企业认证已完成",
|
|
|
|
|
|
zap.String("certification_id", event.GetAggregateID()),
|
|
|
|
|
|
zap.String("user_id", h.extractUserID(event)),
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// 发送通知给用户
|
2025-07-20 20:53:26 +08:00
|
|
|
|
message := fmt.Sprintf("🎉 恭喜!您的企业认证已完成!\n\n认证ID: %s\n完成时间: %s\n\n您现在可以享受企业用户的所有权益。",
|
2025-07-11 21:05:58 +08:00
|
|
|
|
event.GetAggregateID(),
|
|
|
|
|
|
event.GetTimestamp().Format("2006-01-02 15:04:05"))
|
|
|
|
|
|
|
|
|
|
|
|
return h.sendUserNotification(ctx, event, "企业认证完成", message)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// sendUserNotification 发送用户通知
|
|
|
|
|
|
func (h *CertificationEventHandler) sendUserNotification(ctx context.Context, event interfaces.Event, title, message string) error {
|
2025-07-20 20:53:26 +08:00
|
|
|
|
userID := h.extractUserID(event)
|
|
|
|
|
|
if userID == "" {
|
|
|
|
|
|
h.logger.Warn("无法提取用户ID,跳过通知发送")
|
|
|
|
|
|
return nil
|
2025-07-11 21:05:58 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// 这里可以调用通知服务发送消息
|
|
|
|
|
|
h.logger.Info("发送用户通知",
|
|
|
|
|
|
zap.String("user_id", userID),
|
|
|
|
|
|
zap.String("title", title),
|
|
|
|
|
|
zap.String("message", message),
|
2025-07-11 21:05:58 +08:00
|
|
|
|
)
|
2025-07-28 01:46:39 +08:00
|
|
|
|
h.logger.Info("发送用户通知", zap.String("user_id", userID), zap.String("title", title), zap.String("message", message))
|
2025-07-11 21:05:58 +08:00
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// sendAdminNotification 发送管理员通知
|
|
|
|
|
|
func (h *CertificationEventHandler) sendAdminNotification(ctx context.Context, event interfaces.Event, title, message string) error {
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// 这里可以调用通知服务发送管理员消息
|
|
|
|
|
|
h.logger.Info("发送管理员通知",
|
|
|
|
|
|
zap.String("title", title),
|
|
|
|
|
|
zap.String("message", message),
|
2025-07-11 21:05:58 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// extractUserID 从事件中提取用户ID
|
|
|
|
|
|
func (h *CertificationEventHandler) extractUserID(event interfaces.Event) string {
|
2025-07-20 20:53:26 +08:00
|
|
|
|
payload := event.GetPayload()
|
|
|
|
|
|
if payload == nil {
|
|
|
|
|
|
return ""
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 尝试从payload中提取user_id
|
|
|
|
|
|
if data, ok := payload.(map[string]interface{}); ok {
|
|
|
|
|
|
if userID, exists := data["user_id"]; exists {
|
|
|
|
|
|
if str, ok := userID.(string); ok {
|
|
|
|
|
|
return str
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 尝试从JSON中解析
|
|
|
|
|
|
if data, ok := payload.(map[string]interface{}); ok {
|
|
|
|
|
|
if dataField, exists := data["data"]; exists {
|
|
|
|
|
|
if dataMap, ok := dataField.(map[string]interface{}); ok {
|
|
|
|
|
|
if userID, exists := dataMap["user_id"]; exists {
|
|
|
|
|
|
if str, ok := userID.(string); ok {
|
|
|
|
|
|
return str
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-07-11 21:05:58 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// 尝试从JSON字符串解析
|
|
|
|
|
|
if jsonData, err := json.Marshal(payload); err == nil {
|
|
|
|
|
|
var data map[string]interface{}
|
|
|
|
|
|
if err := json.Unmarshal(jsonData, &data); err == nil {
|
2025-07-11 21:05:58 +08:00
|
|
|
|
if userID, exists := data["user_id"]; exists {
|
2025-07-20 20:53:26 +08:00
|
|
|
|
if str, ok := userID.(string); ok {
|
|
|
|
|
|
return str
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if dataField, exists := data["data"]; exists {
|
|
|
|
|
|
if dataMap, ok := dataField.(map[string]interface{}); ok {
|
|
|
|
|
|
if userID, exists := dataMap["user_id"]; exists {
|
|
|
|
|
|
if str, ok := userID.(string); ok {
|
|
|
|
|
|
return str
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-07-11 21:05:58 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-20 20:53:26 +08:00
|
|
|
|
return ""
|
2025-07-11 21:05:58 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// LoggingEventHandler 日志事件处理器
|
2025-07-11 21:05:58 +08:00
|
|
|
|
type LoggingEventHandler struct {
|
|
|
|
|
|
logger *zap.Logger
|
|
|
|
|
|
name string
|
|
|
|
|
|
eventTypes []string
|
|
|
|
|
|
isAsync bool
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-20 20:53:26 +08:00
|
|
|
|
// NewLoggingEventHandler 创建日志事件处理器
|
2025-07-11 21:05:58 +08:00
|
|
|
|
func NewLoggingEventHandler(logger *zap.Logger) *LoggingEventHandler {
|
|
|
|
|
|
return &LoggingEventHandler{
|
|
|
|
|
|
logger: logger,
|
|
|
|
|
|
name: "logging-event-handler",
|
|
|
|
|
|
eventTypes: []string{
|
|
|
|
|
|
EventTypeCertificationCreated,
|
2025-07-20 20:53:26 +08:00
|
|
|
|
EventTypeEnterpriseInfoSubmitted,
|
|
|
|
|
|
EventTypeEnterpriseVerified,
|
|
|
|
|
|
EventTypeContractApplied,
|
2025-07-11 21:05:58 +08:00
|
|
|
|
EventTypeContractSigned,
|
|
|
|
|
|
EventTypeCertificationCompleted,
|
|
|
|
|
|
},
|
2025-07-20 20:53:26 +08:00
|
|
|
|
isAsync: false,
|
2025-07-11 21:05:58 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GetName 获取处理器名称
|
|
|
|
|
|
func (l *LoggingEventHandler) GetName() string {
|
|
|
|
|
|
return l.name
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GetEventTypes 获取支持的事件类型
|
|
|
|
|
|
func (l *LoggingEventHandler) GetEventTypes() []string {
|
|
|
|
|
|
return l.eventTypes
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// IsAsync 是否为异步处理器
|
|
|
|
|
|
func (l *LoggingEventHandler) IsAsync() bool {
|
|
|
|
|
|
return l.isAsync
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GetRetryConfig 获取重试配置
|
|
|
|
|
|
func (l *LoggingEventHandler) GetRetryConfig() interfaces.RetryConfig {
|
|
|
|
|
|
return interfaces.RetryConfig{
|
2025-07-20 20:53:26 +08:00
|
|
|
|
MaxRetries: 0,
|
|
|
|
|
|
RetryDelay: 0,
|
2025-07-11 21:05:58 +08:00
|
|
|
|
BackoffFactor: 1.0,
|
2025-07-20 20:53:26 +08:00
|
|
|
|
MaxDelay: 0,
|
2025-07-11 21:05:58 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Handle 处理事件
|
|
|
|
|
|
func (l *LoggingEventHandler) Handle(ctx context.Context, event interfaces.Event) error {
|
2025-07-20 20:53:26 +08:00
|
|
|
|
l.logger.Info("认证事件日志",
|
2025-07-11 21:05:58 +08:00
|
|
|
|
zap.String("event_type", event.GetType()),
|
2025-07-20 20:53:26 +08:00
|
|
|
|
zap.String("event_id", event.GetID()),
|
2025-07-11 21:05:58 +08:00
|
|
|
|
zap.String("aggregate_id", event.GetAggregateID()),
|
|
|
|
|
|
zap.Time("timestamp", event.GetTimestamp()),
|
2025-07-20 20:53:26 +08:00
|
|
|
|
zap.Any("payload", event.GetPayload()),
|
2025-07-11 21:05:58 +08:00
|
|
|
|
)
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|