package event import ( "fmt" "sync" "git.x2erp.com/qdy/go-base/ctx" "git.x2erp.com/qdy/go-base/logger" "git.x2erp.com/qdy/go-db/factory/mongodb" ) // SubscriptionService 订阅服务,负责管理事件订阅并记录相关日志 type SubscriptionService struct { dispatcher *EventDispatcher mongoFactory *mongodb.MongoDBFactory } // NewSubscriptionService 创建新的订阅服务 func NewSubscriptionService(dispatcher *EventDispatcher, mongoFactory *mongodb.MongoDBFactory) *SubscriptionService { return &SubscriptionService{ dispatcher: dispatcher, mongoFactory: mongoFactory, } } // SubscribeWithContext 使用上下文信息订阅会话事件 func (s *SubscriptionService) SubscribeWithContext(sessionID string, reqCtx *ctx.RequestContext) (<-chan string, error) { // 提取用户ID(优先使用reqCtx.UserID,如果为空则使用Username) userID := reqCtx.UserID if userID == "" { userID = reqCtx.Username } if userID == "" { userID = "unknown-user" } // 记录详细的调试日志 logger.Debug(fmt.Sprintf("🔔 订阅服务: 开始订阅 sessionID=%s, userID=%s, tenantID=%s, traceID=%s", sessionID, userID, reqCtx.TenantID, reqCtx.TraceID)) // 调用事件分发器的Subscribe方法 ch, err := s.dispatcher.Subscribe(sessionID, userID) if err != nil { logger.Error(fmt.Sprintf("❌ 订阅服务: 订阅失败 sessionID=%s, error=%v", sessionID, err)) return nil, err } // 记录成功的订阅信息 logger.Info(fmt.Sprintf("✅ 订阅服务: 订阅成功 sessionID=%s, userID=%s, tenantID=%s", sessionID, userID, reqCtx.TenantID)) // 这里可以扩展:将订阅信息保存到MongoDB // 例如:s.saveSubscriptionToDB(sessionID, reqCtx) // 对于调试,记录MongoDB工厂状态 if s.mongoFactory != nil { logger.Debug(fmt.Sprintf("🔍 订阅服务: MongoDB工厂可用 sessionID=%s", sessionID)) // 可以测试连接或执行其他操作 } else { logger.Debug(fmt.Sprintf("⚠️ 订阅服务: MongoDB工厂未配置 sessionID=%s", sessionID)) } return ch, nil } // UnsubscribeWithContext 使用上下文信息取消订阅 func (s *SubscriptionService) UnsubscribeWithContext(sessionID string, ch <-chan string, reqCtx *ctx.RequestContext) { // 记录取消订阅日志 logger.Debug(fmt.Sprintf("🔔 订阅服务: 取消订阅 sessionID=%s, userID=%s, traceID=%s", sessionID, reqCtx.UserID, reqCtx.TraceID)) s.dispatcher.Unsubscribe(sessionID, ch) // 这里可以扩展:更新MongoDB中的订阅状态 // 例如:s.updateSubscriptionStatus(sessionID, "unsubscribed") logger.Info(fmt.Sprintf("✅ 订阅服务: 已取消订阅 sessionID=%s", sessionID)) } // RegisterSessionWithContext 使用上下文信息注册会话 func (s *SubscriptionService) RegisterSessionWithContext(sessionID string, reqCtx *ctx.RequestContext) { userID := reqCtx.UserID if userID == "" { userID = reqCtx.Username } if userID == "" { userID = "unknown-user" } logger.Debug(fmt.Sprintf("🔔 订阅服务: 注册会话 sessionID=%s, userID=%s, tenantID=%s", sessionID, userID, reqCtx.TenantID)) s.dispatcher.RegisterSession(sessionID, userID) // 这里可以扩展:将会话注册信息保存到MongoDB logger.Info(fmt.Sprintf("✅ 订阅服务: 会话已注册 sessionID=%s", sessionID)) } // GetSubscriptionStats 获取订阅统计信息(用于调试和监控) func (s *SubscriptionService) GetSubscriptionStats() map[string]interface{} { // 这里可以扩展:从MongoDB获取订阅统计 // 目前返回基本信息 stats := map[string]interface{}{ "service": "SubscriptionService", "status": "active", "mongoDB": s.mongoFactory != nil, } logger.Debug(fmt.Sprintf("📊 订阅服务: 获取统计信息 stats=%+v", stats)) return stats } // saveSubscriptionToDB 将订阅信息保存到MongoDB(待扩展) func (s *SubscriptionService) saveSubscriptionToDB(sessionID string, reqCtx *ctx.RequestContext) { // 待实现:将订阅信息保存到MongoDB // 可以记录:sessionID, userID, tenantID, subscriptionTime, status等 logger.Debug(fmt.Sprintf("💾 订阅服务: 待实现 - 保存订阅信息到数据库 sessionID=%s", sessionID)) } // updateSubscriptionStatus 更新MongoDB中的订阅状态(待扩展) func (s *SubscriptionService) updateSubscriptionStatus(sessionID string, status string) { // 待实现:更新订阅状态 logger.Debug(fmt.Sprintf("💾 订阅服务: 待实现 - 更新订阅状态 sessionID=%s, status=%s", sessionID, status)) } // 单例模式 var ( subscriptionServiceInstance *SubscriptionService subscriptionServiceOnce sync.Once ) // InitSubscriptionService 初始化订阅服务单例 func InitSubscriptionService(dispatcher *EventDispatcher, mongoFactory *mongodb.MongoDBFactory) { subscriptionServiceOnce.Do(func() { subscriptionServiceInstance = NewSubscriptionService(dispatcher, mongoFactory) logger.Info("✅ 订阅服务单例已初始化") }) } // GetSubscriptionService 获取订阅服务单例 func GetSubscriptionService() *SubscriptionService { if subscriptionServiceInstance == nil { logger.Warn("⚠️ 订阅服务单例未初始化,返回nil") } return subscriptionServiceInstance }