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

Magento2后台如何实现自定义SKU、价格字段及动态更新按钮功能

Magento2 后台自定义商品价格更新功能实现方案

需求说明

  • 在后台配置页添加SKU输入框(支持逗号分隔批量输入)、价格、促销价字段
  • 管理员输入SKU后,填写新价格/促销价,点击「更新价格」按钮完成商品价格批量更新
  • 实现动态交互:点击按钮后异步提交,实时显示操作结果

当前问题

已通过etc/adminhtml/system.xml创建了基础静态字段,但未绑定点击事件、数据提交逻辑,无法完成实际的价格更新操作。

现有代码(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>
        <tab id="irshad_custom" translate="label" sortOrder="10">
            <label>自定义标签</label>
        </tab>
        <section id="test_section" translate="label" sortOrder="130" showInDefault="1" showInWebsite="1" showInStore="1">
            <class>separator-top</class>
            <label>价格配置</label>
            <tab>irshad_custom</tab>
            <resource>Irshad_Ahmad::config_ahmad</resource>
            <group id="custom_settings" translate="label" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
                <label>价格管理</label>
                <field id="enable" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>启用功能</label>
                    <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
                </field>
                <field id="product_sku" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>商品SKU</label>
                    <comment>支持多个SKU,用逗号分隔</comment>
                    <depends>
                        <field id="enable">1</field>
                    </depends>
                </field>
                <field id="price" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>价格</label>
                    <validate>required-entry validate-number validate-greater-than-zero</validate>
                    <comment>输入新的商品价格</comment>
                    <depends>
                        <field id="enable">1</field>
                    </depends>
                </field>
                <field id="sell_price" translate="label" type="text" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>促销价</label>
                    <validate>validate-number validate-greater-than-zero</validate>
                    <comment>输入新的商品促销价(可选)</comment>
                    <depends>
                        <field id="enable">1</field>
                    </depends>
                </field>
                <field id="update_button" translate="label" type="button" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>更新价格</label>
                    <frontend_model>Irshad\Ahmad\Block\Adminhtml\System\Config\UpdateButton</frontend_model>
                    <depends>
                        <field id="enable">1</field>
                    </depends>
                </field>
            </group>
        </section>
    </system>
</config>

完整实现步骤

1. 给按钮绑定前端交互模型

创建按钮前端模型文件 Irshad/Ahmad/Block/Adminhtml/System/Config/UpdateButton.php:

<?php
namespace Irshad\Ahmad\Block\Adminhtml\System\Config;

use Magento\Config\Block\System\Config\Form\Field;
use Magento\Framework\Data\Form\Element\AbstractElement;

class UpdateButton extends Field
{
    protected $_template = 'Irshad_Ahmad::system/config/update_button.phtml';

    protected function _getElementHtml(AbstractElement $element)
    {
        return $this->_toHtml();
    }

    public function getAjaxUrl()
    {
        return $this->getUrl('irshad_ahmad/price/update');
    }

    public function getButtonHtml()
    {
        $button = $this->getLayout()->createBlock(
            \Magento\Backend\Block\Widget\Button::class
        )->setData([
            'id' => 'update_price_button',
            'label' => __('更新价格'),
            'class' => 'primary'
        ]);
        return $button->toHtml();
    }
}

创建按钮模板文件 Irshad/Ahmad/view/adminhtml/templates/system/config/update_button.phtml:

<div class="actions">
    <?= $block->getButtonHtml() ?>
</div>
<script type="text/x-magento-init">
{
    "#update_price_button": {
        "Irshad_Ahmad/js/update-price": {
            "ajaxUrl": "<?= $block->getAjaxUrl() ?>",
            "skuField": "#test_section_custom_settings_product_sku",
            "priceField": "#test_section_custom_settings_price",
            "salePriceField": "#test_section_custom_settings_sell_price"
        }
    }
}
</script>

2. 编写前端交互JS逻辑

创建JS文件 Irshad/Ahmad/view/adminhtml/web/js/update-price.js:

define([
    'jquery',
    'Magento_Ui/js/modal/alert',
    'mage/translate'
], function ($, alert, $t) {
    'use strict';

    return function (config) {
        $('#update_price_button').on('click', function () {
            let sku = $(config.skuField).val().trim(),
                price = $(config.priceField).val().trim(),
                salePrice = $(config.salePriceField).val().trim();

            if (!sku || !price) {
                alert({
                    title: $t('错误'),
                    content: $t('请填写SKU和价格')
                });
                return;
            }

            $.ajax({
                url: config.ajaxUrl,
                type: 'POST',
                data: {
                    form_key: window.FORM_KEY,
                    sku: sku,
                    price: price,
                    sale_price: salePrice
                },
                showLoader: true,
                success: function (response) {
                    if (response.success) {
                        alert({
                            title: $t('成功'),
                            content: response.message
                        });
                        // 清空输入框
                        $(config.skuField).val('');
                        $(config.priceField).val('');
                        $(config.salePriceField).val('');
                    } else {
                        alert({
                            title: $t('失败'),
                            content: response.message
                        });
                    }
                },
                error: function () {
                    alert({
                        title: $t('错误'),
                        content: $t('请求失败,请稍后重试')
                    });
                }
            });
        });
    };
});

3. 配置后端路由

创建 Irshad/Ahmad/etc/adminhtml/routes.xml:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="admin">
        <route id="irshad_ahmad" frontName="irshad_ahmad">
            <module name="Irshad_Ahmad" before="Magento_Backend"/>
        </route>
    </router>
</config>

4. 编写后端价格更新控制器

创建控制器文件 Irshad/Ahmad/Controller/Adminhtml/Price/Update.php:

<?php
namespace Irshad\Ahmad\Controller\Adminhtml\Price;

use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Catalog\Model\ProductRepository;
use Magento\Framework\Controller\Result\JsonFactory;
use Magento\Framework\Exception\NoSuchEntityException;

class Update extends Action
{
    protected $productRepository;
    protected $resultJsonFactory;

    public function __construct(
        Context $context,
        ProductRepository $productRepository,
        JsonFactory $resultJsonFactory
    ) {
        parent::__construct($context);
        $this->productRepository = $productRepository;
        $this->resultJsonFactory = $resultJsonFactory;
    }

    protected function _isAllowed()
    {
        return $this->_authorization->isAllowed('Irshad_Ahmad::config_ahmad');
    }

    public function execute()
    {
        $result = $this->resultJsonFactory->create();
        $postData = $this->getRequest()->getPostValue();

        if (!$postData || !isset($postData['sku']) || !isset($postData['price'])) {
            return $result->setData([
                'success' => false,
                'message' => __('缺少必要参数')
            ]);
        }

        $skuList = explode(',', trim($postData['sku']));
        $price = (float)$postData['price'];
        $salePrice = isset($postData['sale_price']) ? (float)$postData['sale_price'] : null;
        $successCount = 0;
        $errorSkus = [];

        foreach ($skuList as $sku) {
            $sku = trim($sku);
            if (!$sku) continue;

            try {
                $product = $this->productRepository->get($sku);
                $product->setPrice($price);
                if ($salePrice !== null) {
                    $product->setSpecialPrice($salePrice);
                }
                $this->productRepository->save($product);
                $successCount++;
            } catch (NoSuchEntityException $e) {
                $errorSkus[] = $sku . '(商品不存在)';
            } catch (\Exception $e) {
                $errorSkus[] = $sku . '(更新失败:' . $e->getMessage() . ')';
            }
        }

        $message = __('成功更新 %1 个商品', $successCount);
        if (!empty($errorSkus)) {
            $message .= '<br>' . __('以下SKU更新失败:') . '<br>' . implode('<br>', $errorSkus);
        }

        return $result->setData([
            'success' => $successCount > 0 || empty($errorSkus),
            'message' => $message
        ]);
    }
}

注意事项

  • 确保模块的registration.php和module.xml配置正确,模块已启用
  • 执行命令清理缓存:bin/magento cache:clean、bin/magento cache:flush
  • 给管理员角色分配Irshad_Ahmad::config_ahmad权限

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 14:29:54