package menu import ( "context" "errors" "time" "git.x2erp.com/qdy/go-base/logger" "git.x2erp.com/qdy/go-db/factory/mongodb" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" ) // SessionMenuMapping 会话-菜单映射结构 type SessionMenuMapping struct { ID primitive.ObjectID `bson:"_id,omitempty" json:"id,omitempty"` SessionID string `bson:"session_id" json:"session_id"` // 会话ID MenuItemID string `bson:"menu_item_id" json:"menu_item_id"` // 菜单项ID UserID string `bson:"user_id" json:"user_id"` // 用户ID TenantID string `bson:"tenant_id" json:"tenant_id"` // 租户ID CreatedAt time.Time `bson:"created_at" json:"created_at"` // 创建时间 } // CollectionName 返回MongoDB集合名称 func (SessionMenuMapping) CollectionName() string { return "session_menu_mappings" } // MappingService 会话-菜单映射服务 type MappingService struct { mongoFactory *mongodb.MongoDBFactory } // NewMappingService 创建新的映射服务 func NewMappingService(factory *mongodb.MongoDBFactory) *MappingService { return &MappingService{mongoFactory: factory} } // CreateMapping 创建会话-菜单映射 func (s *MappingService) CreateMapping(ctx context.Context, sessionID, menuItemID, userID, tenantID string) error { mapping := SessionMenuMapping{ SessionID: sessionID, MenuItemID: menuItemID, UserID: userID, TenantID: tenantID, CreatedAt: time.Now(), } _, success := s.mongoFactory.InsertOneWithResult(SessionMenuMapping{}.CollectionName(), mapping) if !success { logger.Error("创建会话-菜单映射失败", "session_id", sessionID, "menu_item_id", menuItemID) return errors.New("failed to create session-menu mapping") } logger.Debug("创建会话-菜单映射成功", "session_id", sessionID, "menu_item_id", menuItemID) return nil } // GetMenuItemBySessionID 根据会话ID获取菜单项ID func (s *MappingService) GetMenuItemBySessionID(ctx context.Context, sessionID string) (string, error) { filter := bson.M{"session_id": sessionID} var mapping SessionMenuMapping err := s.mongoFactory.FindOne(SessionMenuMapping{}.CollectionName(), filter, &mapping) if err != nil { if err.Error() == "mongo: no documents in result" { return "", nil // 未找到映射,返回空字符串 } logger.Error("根据会话ID查询菜单项失败", "session_id", sessionID, "error", err) return "", err } return mapping.MenuItemID, nil } // GetSessionIDsByMenuItemID 根据菜单项ID获取会话ID列表 func (s *MappingService) GetSessionIDsByMenuItemID(ctx context.Context, menuItemID, userID string) ([]string, error) { filter := bson.M{"menu_item_id": menuItemID, "user_id": userID} var mappings []SessionMenuMapping err := s.mongoFactory.Find(SessionMenuMapping{}.CollectionName(), filter, &mappings) if err != nil { logger.Error("根据菜单项ID查询会话ID失败", "menu_item_id", menuItemID, "error", err) return nil, err } sessionIDs := make([]string, 0, len(mappings)) for _, mapping := range mappings { sessionIDs = append(sessionIDs, mapping.SessionID) } return sessionIDs, nil } // GetMappingsByUser 获取用户的所有会话-菜单映射 func (s *MappingService) GetMappingsByUser(ctx context.Context, userID string) (map[string]string, error) { filter := bson.M{"user_id": userID} var mappings []SessionMenuMapping err := s.mongoFactory.Find(SessionMenuMapping{}.CollectionName(), filter, &mappings) if err != nil { logger.Error("查询用户会话-菜单映射失败", "user_id", userID, "error", err) return nil, err } result := make(map[string]string) for _, mapping := range mappings { result[mapping.SessionID] = mapping.MenuItemID } return result, nil } // DeleteMappingBySessionID 根据会话ID删除映射 func (s *MappingService) DeleteMappingBySessionID(ctx context.Context, sessionID string) error { filter := bson.M{"session_id": sessionID} success, deletedCount := s.mongoFactory.DeleteOne(SessionMenuMapping{}.CollectionName(), filter) if !success { logger.Error("根据会话ID删除映射失败", "session_id", sessionID) return errors.New("failed to delete session-menu mapping") } logger.Debug("删除会话-菜单映射成功", "session_id", sessionID, "deleted_count", deletedCount) return nil } // EnsureIndexes 确保集合索引 func (s *MappingService) EnsureIndexes(ctx context.Context) error { // 创建会话ID唯一索引 sessionIDIndexKeys := bson.D{{Key: "session_id", Value: 1}} sessionIDSuccess := s.mongoFactory.CreateIndex(SessionMenuMapping{}.CollectionName(), sessionIDIndexKeys) if !sessionIDSuccess { logger.Error("创建会话ID索引失败") return errors.New("failed to create session_id index") } // 创建复合索引:菜单项ID + 用户ID menuItemUserIndexKeys := bson.D{ {Key: "menu_item_id", Value: 1}, {Key: "user_id", Value: 1}, } menuItemUserSuccess := s.mongoFactory.CreateIndex(SessionMenuMapping{}.CollectionName(), menuItemUserIndexKeys) if !menuItemUserSuccess { logger.Error("创建菜单项用户复合索引失败") return errors.New("failed to create menu_item_id-user_id index") } logger.Debug("会话-菜单映射索引创建成功") return nil }