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

按表格行合并对象数组以适配API POST请求

问题:WooCommerce结账表格数据关联错误,每个商品绑定了所有修饰项

我需要从WooCommerce结账表格中提取数据,用于发送API POST请求。目前构建了两个独立数组,但合并时出现问题:当前代码会把所有修饰项(modifiers)数组赋值给每个商品对象,导致API返回的每个商品都包含全部修饰项。我希望每个商品对象仅关联其所在表格行对应的修饰项数组。

当前不符合需求的API响应

{"2022-12-21":[{"api_id":2753,"count":1,"price":10.5,"modifiers":[{"2971":1},{"2972":1.5},{"2972":1.5},{"2971":1},{"2972":1.5},{"2990":0}]},{"api_id":2753,"count":1,"price":9.5,"modifiers":[{"2971":1},{"2972":1.5},{"2972":1.5},{"2971":1},{"2972":1.5},{"2990":0}]},{"api_id":2748,"count":1,"price":14.5,"modifiers":[{"2971":1},{"2972":1.5},{"2972":1.5},{"2971":1},{"2972":1.5},{"2990":0}]}]}

期望的API响应

{"2022-12-21":[{"api_id":2753,"count":1,"price":10.5,"modifiers":[{"2971":1},{"2972":1.5}]},{"api_id":2753,"count":1,"price":9.5,"modifiers":[{"2972":1.5}]},{"api_id":2748,"count":1,"price":14.5,"modifiers":[{"2971":1},{"2972":1.5},{"2990":0}]}]}

当前使用的代码

JavaScript代码

let orderItems = "";
let orderArray = [];
let prodsArray = [];
let datesObj = {};
let modifiersArray = [];
let comboMealsArray = [];
let modifiersObj = {};
let modifierID;
let modifierPrice;

for(var i = 0; i < jQuery(".woocommerce-table__line-item.order_item .wc-item-meta li").length; i++){//get modifier id and price from table

  modifierID = jQuery(".hidden-modifier-id").eq(i).text();//modifier id is hidden from frontend but obtainable
  modifierPrice = jQuery(".wc-item-meta .amount").eq(i).text();//each modifier price

  let removePriceSymbols = modifierPrice.replace("€","");
  let formatPrice = removePriceSymbols.replace(",", ".");
  if(formatPrice === ""){
    formatPrice = 0;
  }
  let actualModifierPrice = parseFloat(formatPrice);

  modifiersObj = {[modifierID]: actualModifierPrice}; //outputs: {2971: 1}
  modifiersArray.push(modifiersObj);
}

console.log(modifiersArray); // outputs: [{2971: 1}, {2972: 1.5}, {2972: 1.5}, {2971: 1}, {2972: 1.5}, 2990: 0}]

for(var i = 0; i < jQuery(".woocommerce-table__line-item.order_item").length; i++){//get order values from checkout table per row
  let prodsObj = {};
  let prodName = jQuery(".woocommerce-table__line-item.order_item > .product-name > a").eq(i).text();//get prodName from table cell
  let prodQuant = jQuery(".woocommerce-table__line-item.order_item > .product-name > .product-quantity").eq(i).text();//get prodQuant from table cell
  let prodDelivetyId = jQuery(".woocommerce-table__line-item.order_item > .product-name > #delivety_api_id_field").eq(i).text();//get delivety prod api id from table cell
  let prodTotal = jQuery(".woocommerce-table__line-item.order_item > .product-total > .amount").eq(i).text();//get prodTotal from table cell
  let removeQuantSymbols = prodQuant.replace(/[^0-9\.]+/g,"");
  let removePriceSymbols = prodTotal.replace("€","");
  let formatPrice = removePriceSymbols.replace(",", ".");

  orderItems += prodName + "  " + prodQuant + "  " + prodTotal + "\r\n";

  let actualID = parseInt(orderNumber);
  let actualQuant = parseInt(removeQuantSymbols);
  let actualApiID = parseInt(prodDelivetyId);
  let actualPrice = parseFloat(formatPrice);    
  let prodTotalUni = actualPrice / actualQuant;

  //prodsObj.name = prodName;
  //prodsObj.id = actualID;
  prodsObj.api_id = actualApiID;
  prodsObj.count = actualQuant;
  prodsObj.price = prodTotalUni;
  prodsObj.modifiers = modifiersArray;

  prodsArray.push(prodsObj);
}
orderArray.push(prodsArray);
console.log(orderArray);

表格HTML结构

<table class="woocommerce-table woocommerce-table--order-details shop_table order_details">

        <thead>
            <tr>
                <th class="woocommerce-table__product-name product-name">Product</th>
                <th class="woocommerce-table__product-table product-total">Total</th>
            </tr>
        </thead>

        <tbody>
            <tr class="woocommerce-table__line-item order_item">

    <td class="woocommerce-table__product-name product-name">
        <a>Fried Chicken</a><span id="delivety_api_id_field">2753</span> <strong class="product-quantity">×&nbsp;1</strong><ul class="wc-item-meta"><li><strong class="wc-item-meta-label">Side Dishes Options:</strong> <p>Rice<span class="hidden-modifier-id">2971</span> (+<span class="woocommerce-Price-amount amount">1,00&nbsp;<span class="woocommerce-Price-currencySymbol">€</span></span>)</p></li><li><strong class="wc-item-meta-label">Side Dishes Options:</strong> <p>French Fries<span class="hidden-modifier-id">2972</span> (+<span class="woocommerce-Price-amount amount">1,50&nbsp;<span class="woocommerce-Price-currencySymbol">€</span></span>)</p></li></ul> </td>

    <td class="woocommerce-table__product-total product-total">
        <span class="woocommerce-Price-amount amount"><bdi>10,50&nbsp;<span class="woocommerce-Price-currencySymbol">€</span></bdi></span>  </td>

</tr>

<tr class="woocommerce-table__line-item order_item">

    <td class="woocommerce-table__product-name product-name">
        <a>Fried Chicken</a><span id="delivety_api_id_field">2753</span> <strong class="product-quantity">×&nbsp;1</strong><ul class="wc-item-meta"><li><strong class="wc-item-meta-label">Side Dishes Options:</strong> <p>French Fries<span class="hidden-modifier-id">2972</span> (+<span class="woocommerce-Price-amount amount">1,50&nbsp;<span class="woocommerce-Price-currencySymbol">€</span></span>)</p></li></ul>    </td>

    <td class="woocommerce-table__product-total product-total">
        <span class="woocommerce-Price-amount amount"><bdi>9,50&nbsp;<span class="woocommerce-Price-currencySymbol">€</span></bdi></span>   </td>

</tr>

<tr class="woocommerce-table__line-item order_item">

    <td class="woocommerce-table__product-name product-name">
        <a>Steak</a><span id="delivety_api_id_field">2748</span> <strong class="product-quantity">×&nbsp;1</strong><ul class="wc-item-meta"><li><strong class="wc-item-meta-label">Side Dishes Options:</strong> <p>Rice<span class="hidden-modifier-id">2971</span> (+<span class="woocommerce-Price-amount amount">1,00&nbsp;<span class="woocommerce-Price-currencySymbol">€</span></span>)</p></li><li><strong class="wc-item-meta-label">Side Dishes Options:</strong> <p>French Fries<span class="hidden-modifier-id">2972</span> (+<span class="woocommerce-Price-amount amount">1,50&nbsp;<span class="woocommerce-Price-currencySymbol">€</span></span>)</p></li><li><strong class="wc-item-meta-label">Preparation:</strong> <p>Rare<span class="hidden-modifier-id">2990</span></p></li></ul>    </td>

    <td class="woocommerce-table__product-total product-total">
        <span class="woocommerce-Price-amount amount"><bdi>14,50&nbsp;<span class="woocommerce-Price-currencySymbol">€</span></bdi></span>  </td>

</tr>

        </tbody>

        <tfoot>
                                <tr>
                        <th scope="row">Subtotal:</th>
                        <td><span class="woocommerce-Price-amount amount">34,50&nbsp;<span class="woocommerce-Price-currencySymbol">€</span></span></td>
                    </tr>
                                        <tr>
                        <th scope="row">Shipping:</th>
                        <td>Local pickup</td>
                    </tr>
                                        <tr>
                        <th scope="row">Payment method:</th>
                        <td>Multibanco</td>
                    </tr>
                                        <tr>
                        <th scope="row">Total:</th>
                        <td><span class="woocommerce-Price-amount amount">34,50&nbsp;<span class="woocommerce-Price-currencySymbol">€</span></span></td>
                    </tr>
                                        </tfoot>
    </table>

解决方案

问题出在你先把所有修饰项收集到一个全局的modifiersArray,然后直接把这个数组赋值给每个商品的modifiers属性——这会导致所有商品共享同一组修饰项。正确的做法是遍历每个商品行时,只提取当前行内的修饰项,而不是提前一次性收集所有修饰项。

修改后的代码如下:

let orderItems = "";
let orderArray = [];
let prodsArray = [];
let datesObj = {};
let comboMealsArray = [];

// 遍历每个商品行
jQuery(".woocommerce-table__line-item.order_item").each(function() {
  let $row = jQuery(this);
  let prodsObj = {};

  // 提取当前商品的基础信息
  let prodName = $row.find(".product-name > a").text();
  let prodQuant = $row.find(".product-name > .product-quantity").text();
  let prodDelivetyId = $row.find(".product-name > #delivety_api_id_field").text();
  let prodTotal = $row.find(".product-total > .amount").text();

  let removeQuantSymbols = prodQuant.replace(/[^0-9\.]+/g,"");
  let removePriceSymbols = prodTotal.replace("€","");
  let formatPrice = removePriceSymbols.replace(",", ".");

  orderItems += prodName + "  " + prodQuant + "  " + prodTotal + "\r\n";

  let actualQuant = parseInt(removeQuantSymbols);
  let actualApiID = parseInt(prodDelivetyId);
  let actualPrice = parseFloat(formatPrice);    
  let prodTotalUni = actualPrice / actualQuant;

  // 填充商品基础字段
  prodsObj.api_id = actualApiID;
  prodsObj.count = actualQuant;
  prodsObj.price = prodTotalUni;

  // 提取当前行的修饰项
  let modifiersArray = [];
  $row.find(".wc-item-meta li").each(function() {
    let $li = jQuery(this);
    let modifierID = $li.find(".hidden-modifier-id").text();
    let modifierPrice = $li.find(".amount").text() || "0";

    let removePriceSymbols = modifierPrice.replace("€","");
    let formatPrice = removePriceSymbols.replace(",", ".");
    if(formatPrice === ""){
      formatPrice = 0;
    }
    let actualModifierPrice = parseFloat(formatPrice);

    modifiersArray.push({[modifierID]: actualModifierPrice});
  });

  // 绑定当前行的修饰项到商品
  prodsObj.modifiers = modifiersArray;
  prodsArray.push(prodsObj);
});

orderArray.push(prodsArray);
console.log(orderArray);

代码说明

  1. 去掉了全局的修饰项数组,改为在遍历每个商品行时,单独收集当前行内的修饰项
  2. 使用jQuery.each()遍历商品行和修饰项,代码更简洁且上下文明确
  3. 每个商品的modifiers属性只包含当前行对应的修饰项,不会再共享全局数组

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 21:15:11