You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Magento 2特定分类库存为0时自定义显示需求求助

解决方案:针对特定分类的缺货商品自定义展示逻辑

一、第三方扩展推荐

如果不想自行开发,可以选择Magento官方市场的成熟扩展,直接通过后台配置实现需求:

  • Custom Stock Status for Magento 2:支持为指定分类/商品设置自定义库存状态文本,可控制加购按钮显示状态,后台配置界面直观,兼容back order模式。
  • Advanced Inventory Manager:除基础库存管理功能外,支持按分类配置缺货商品的展示规则,包括是否强制显示商品、替换提示文本、隐藏加购按钮,配置项集成在后台库存管理模块中。

二、自定义代码实现方案(适合具备开发能力的场景)

以下是完整的自定义模块实现步骤,可实现后台可配置的分类级缺货逻辑:

1. 创建基础模块结构

创建命名为Vendor_CustomStock的模块,包含以下核心文件:

  • registration.php:模块注册文件
  • etc/module.xml:模块配置文件
  • etc/adminhtml/acl.xml:权限控制文件(配置后台访问权限)

2. 添加后台配置项

在etc/adminhtml/system.xml中添加可配置项,让管理员指定目标分类和自定义提示文本:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
    <system>
        <section id="custom_stock" translate="label" type="text" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="1">
            <label>自定义库存设置</label>
            <tab>catalog</tab>
            <resource>Vendor_CustomStock::config</resource>
            <group id="category_rules" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
                <label>分类专属库存规则</label>
                <field id="target_categories" translate="label" type="multiselect" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>目标分类</label>
                    <source_model>Magento\Catalog\Model\Category\Source\Tree</source_model>
                </field>
                <field id="out_of_stock_text" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>缺货自定义提示文本</label>
                    <comment>目标分类下商品缺货时显示的文本</comment>
                </field>
            </group>
        </section>
    </system>
</config>

在etc/config.xml中设置默认配置值:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
    <default>
        <custom_stock>
            <category_rules>
                <out_of_stock_text>该商品已无法购买</out_of_stock_text>
            </category_rules>
        </custom_stock>
    </default>
</config>

3. 拦截产品可见性与加购按钮逻辑

通过插件修改核心逻辑,确保目标分类的缺货商品强制显示、隐藏加购按钮:

插件配置(etc/frontend/di.xml)

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <!-- 拦截产品可见性判断 -->
    <type name="Magento\Catalog\Model\Product">
        <plugin name="customstock_product_visibility" type="Vendor\CustomStock\Plugin\ProductVisibilityPlugin" sortOrder="10"/>
    </type>
    <!-- 拦截加购按钮显示判断 -->
    <type name="Magento\Catalog\Block\Product\View\AddToCart">
        <plugin name="customstock_hide_addtocart" type="Vendor\CustomStock\Plugin\HideAddToCartPlugin" sortOrder="10"/>
    </type>
</config>

产品可见性插件(Vendor/CustomStock/Plugin/ProductVisibilityPlugin.php)

<?php
namespace Vendor\CustomStock\Plugin;

use Magento\Catalog\Model\Product;
use Magento\Framework\App\Config\ScopeConfigInterface;

class ProductVisibilityPlugin
{
    protected $scopeConfig;

    public function __construct(ScopeConfigInterface $scopeConfig)
    {
        $this->scopeConfig = $scopeConfig;
    }

    public function afterIsVisibleInCatalog(Product $subject, $result)
    {
        if ($result) {
            return $result;
        }

        // 获取后台配置的目标分类ID
        $targetCatIds = $this->scopeConfig->getValue(
            'custom_stock/category_rules/target_categories',
            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
        );
        
        if (!$targetCatIds) {
            return $result;
        }

        $targetCatIds = explode(',', $targetCatIds);
        $productCatIds = $subject->getCategoryIds();
        
        // 判断商品是否在目标分类中,且缺货+开启back order
        $isInTargetCat = !empty(array_intersect($targetCatIds, $productCatIds));
        if ($isInTargetCat && !$subject->getIsInStock() && $subject->getBackorders() != 0) {
            return true;
        }

        return $result;
    }
}

隐藏加购按钮插件(Vendor/CustomStock/Plugin/HideAddToCartPlugin.php)

<?php
namespace Vendor\CustomStock\Plugin;

use Magento\Catalog\Block\Product\View\AddToCart;
use Magento\Framework\App\Config\ScopeConfigInterface;

class HideAddToCartPlugin
{
    protected $scopeConfig;

    public function __construct(ScopeConfigInterface $scopeConfig)
    {
        $this->scopeConfig = $scopeConfig;
    }

    public function afterIsPossibleBuyFromThis(AddToCart $subject, $result)
    {
        $product = $subject->getProduct();
        
        $targetCatIds = $this->scopeConfig->getValue(
            'custom_stock/category_rules/target_categories',
            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
        );
        
        if (!$targetCatIds) {
            return $result;
        }

        $targetCatIds = explode(',', $targetCatIds);
        $productCatIds = $product->getCategoryIds();
        $isInTargetCat = !empty(array_intersect($targetCatIds, $productCatIds));
        
        if ($isInTargetCat && !$product->getIsInStock() && $product->getBackorders() != 0) {
            return false;
        }

        return $result;
    }
}

4. 替换缺货提示文本

复制Magento默认库存模板vendor/magento/module-catalog/view/frontend/templates/product/view/stock.phtml到app/code/Vendor/CustomStock/view/frontend/templates/product/view/stock.phtml,修改为以下内容:

<?php
/** @var \Magento\Catalog\Block\Product\View\Stock $block */
/** @var \Magento\Framework\Escaper $escaper */
$product = $block->getProduct();
$stockMessage = $block->getStockStatus();

// 获取自定义配置
$customText = $block->getScopeConfig()->getValue(
    'custom_stock/category_rules/out_of_stock_text',
    \Magento\Store\Model\ScopeInterface::SCOPE_STORE
);
$targetCatIds = $block->getScopeConfig()->getValue(
    'custom_stock/category_rules/target_categories',
    \Magento\Store\Model\ScopeInterface::SCOPE_STORE
);

// 判断是否替换文本
$replaceText = false;
if ($targetCatIds) {
    $targetCatIds = explode(',', $targetCatIds);
    $productCatIds = $product->getCategoryIds();
    $replaceText = !empty(array_intersect($targetCatIds, $productCatIds)) 
        && !$product->getIsInStock() 
        && $product->getBackorders() != 0;
}

if ($replaceText) {
    $stockMessage = $customText ?: '该商品已无法购买';
}
?>
<?php if ($block->displayProductStockStatus()): ?>
    <div class="stock available" title="<?= $escaper->escapeHtmlAttr(__('Availability')) ?>">
        <span><?= $escaper->escapeHtml($stockMessage) ?></span>
    </div>
<?php endif; ?>

在etc/frontend/layout/catalog_product_view.xml中替换模板:

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="product.info.stock">
            <action method="setTemplate">
                <argument name="template" xsi:type="string">Vendor_CustomStock::product/view/stock.phtml</argument>
            </action>
        </referenceBlock>
    </body>
</page>

5. 模块安装与测试

执行以下命令完成模块部署:

bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento setup:static-content:deploy -f
bin/magento cache:flush

之后在后台进入** Stores > Configuration > Catalog > 自定义库存设置**,选择目标分类“overstock sale”,配置自定义提示文本,保存后测试对应分类下的缺货商品即可。


内容的提问来源于stack exchange,提问作者Saif

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 23:55:22