数据库里能找到 SKU,后台也能打开商品,但 GraphQL products 返回 items: []。这不一定是 Resolver 出错;GraphQL 会按当前 Store、网站分配、商品状态、可见性以及搜索索引过滤结果。第一步是让 API 请求和你在后台查看的店铺范围一致。
用同一查询对比不同 Store Header
curl -sk https://shop.example.com/graphql -H 'Content-Type: application/json' -H 'Store: default' --data '{"query":"{products(filter:{sku:{eq:"ABC-001"}}){total_count items{sku name url_key}}}"}'
curl -sk https://shop.example.com/graphql -H 'Content-Type: application/json' -H 'Store: zh_cn' --data '{"query":"{products(filter:{sku:{eq:"ABC-001"}}){total_count items{sku name url_key}}}"}'
一个 Store 有结果、另一个为空,优先检查商品网站分配与店铺视图属性,不要立即改 Resolver。Header 值使用 store code,不是网站名称。
数据库里确认网站关系与范围值
SELECT entity_id, sku FROM catalog_product_entity WHERE sku='ABC-001';
SELECT product_id, website_id
FROM catalog_product_website
WHERE product_id=123;
SELECT store_id, code, website_id
FROM store
ORDER BY website_id, store_id;
商品必须分配到 Store 所属 website。状态和可见性是 EAV 属性,还可能被 Store View 覆盖;后台默认范围显示“启用”,并不能证明目标 Store 的值相同。
用命令确认索引没有积压
bin/magento indexer:status catalogsearch_fulltext catalog_product_attribute
bin/magento indexer:show-mode catalogsearch_fulltext
bin/magento indexer:reindex catalogsearch_fulltext catalog_product_attribute
bin/magento cache:clean graphql
只重建全文索引后有结果,说明之前的更新链路存在问题,还要继续查 Cron 与 MView,而不是把每天手工 reindex 当成修复方案。
可见性和库存要按查询场景理解
简单商品如果只允许在 Catalog 中不可单独搜索,按搜索语义调用可能被过滤;可配置商品的子 SKU 也未必作为独立产品返回。启用了库存相关过滤或前端只展示可售商品时,还要对照 source、stock 和 salable quantity。
bin/magento inventory:reservation:list-inconsistencies -r | grep 'ABC-001'
bin/magento inventory:reservation:list-inconsistencies | grep 'ABC-001'
不同版本的库存命令参数可能有差异,先用 bin/magento list inventory 确认可用命令。最终验证应记录请求 Header、GraphQL 原始响应、商品 website 和目标 Store 属性;不要只凭前端页面“看不到”判断 GraphQL 返回空。

