PrestaShop 1.7如何批量修改同一分类所有产品的组合选择器
实现可行性说明
该功能完全可以实现,以下是具体实现步骤:
一、后端接口改造(修改psajax.php)
新增批量获取产品规格数据的接口逻辑,新增对应action处理分支:
// 新增批量获取分类产品属性数据的处理分支 if (Tools::getValue('action') == 'get-batch-attribute-data') { $result = []; $context = Context::getContext(); $category_id = (int)Tools::getValue('category_id'); $spec_index = (int)Tools::getValue('spec_index'); // 单选按钮传递的索引0-6 $token = Tools::getValue('token'); // 先做token校验,防止非法请求 if ($token !== xyz_token) die(Tools::jsonEncode(['error' => 'invalid token'])); // 1. 查询指定分类下所有在售产品ID列表 $product_ids = Db::getInstance()->executeS('SELECT id_product FROM '._DB_PREFIX_.'category_product WHERE id_category = '.(int)$category_id); $attribute_data = new LeofeatureProduct(); // 2. 规格索引和属性字段的对应关系,和你现有逻辑保持一致 $spec_map = [ 0 => 'variante_1g', 1 => 'variante_3g', 2 => 'variante_5g', 3 => 'variante_10g', 4 => 'variante_25g', 5 => 'variante_50g', 6 => 'variante_100g', ]; $spec_field = $spec_map[$spec_index]; foreach ($product_ids as $item) { $id_product = (int)$item['id_product']; // 这里获取该产品对应规格的属性ID,和你现有逻辑保持一致 $id_product_attribute = $result[$id_product][$spec_field] ?? 0; if (!$id_product_attribute) continue; $res_final = $attribute_data->getTemplateVarProduct2($id_product, $id_product_attribute); $result[$id_product] = [ 'product_cover' => $res_final['cover'], 'price_attribute' => $module->renderPriceAttribute($res_final), 'product_url' => $context->link->getProductLink($id_product, null, null, null, $context->language->id, null, $id_product_attribute, false, false, true), 'selected_attr_id' => $id_product_attribute, // 新增返回选中的属性ID,用于更新下拉状态 ]; } die(Tools::jsonEncode($result)); }
原有单产品更新的逻辑无需修改,不影响原有单个产品切换规格的功能
二、前端JS逻辑改造
编写showPrices函数,实现批量请求和页面更新:
function showPrices(specIndex) { // 1. 收集当前轮播内所有产品ID let productIds = []; $('#carousel-2642346269 .product-miniature').each(function() { productIds.push($(this).data('id-product')); }); if (!productIds.length) return; // 2. 发起批量请求 $.ajax({ type: 'POST', headers: {"cache-control": "no-cache"}, url: prestashop.urls.base_url + 'modules/mymodule/psajax.php?rand=' + new Date().getTime(), async: true, cache: false, data: { "action": "get-batch-attribute-data", "category_id": 21, "spec_index": specIndex, "token": xyz_token }, success: function (result) { if(result == '') { alert(add_cart_error); return; } let res = $.parseJSON(result); // 3. 遍历更新所有产品信息 $.each(res, function(productId, data) { let $product = $('.product-miniature[data-id-product=' + productId + ']'); if (!$product.length) return; // 更新封面、链接、价格 $product.find('.product-thumbnail img').attr('src', data.product_cover.bySize.home_default.url).attr('alt', data.product_cover.legend); $product.find('.product-thumbnail').attr('href', data.product_url); $product.find('.product-price-and-shipping').empty().append(data.price_attribute); // 更新下拉选择器状态,解决属性ID获取问题 let $dropdown = $product.find('.leo-pro-attr-section'); // 移除原有选中状态 $dropdown.find('.leo-select-attr').removeClass('selected'); // 匹配当前选中的属性ID let $selectedAttr = $dropdown.find('.leo-select-attr[data-id-attr=' + data.selected_attr_id + ']'); $selectedAttr.addClass('selected'); // 更新下拉按钮文本 $dropdown.find('.dropdown-toggle').text($selectedAttr.text()); }); }, error: function (XMLHttpRequest, textStatus, errorThrown) { alert("TECHNICAL ERROR: \n\nDetails:\nError thrown: " + XMLHttpRequest + "\n" + 'Text status: ' + textStatus); } }); }
原有单个产品切换规格的JS逻辑无需修改,和新功能互不影响
三、原有逻辑优化说明
你现有写的更新价格的JS存在冗余的双层循环问题,上述新代码已经优化了该问题,直接遍历后端返回的结果即可完成所有产品的更新,无需额外循环产品ID数组。
内容的提问来源于stack exchange,提问作者RfTune
相关产品推荐
相关产品推荐

