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

如何实现Woocommerce追加销售与交叉销售的手动排序?

解决WooCommerce交叉销售/追加销售手动排序问题

我来帮你搞定这个问题——你遇到的核心痛点是拖拽排序后没有同步更新后端存储的ID顺序,加上默认的查询逻辑会强制按字母排序,所以保存后就恢复原样了。下面是一套完整的解决方案,覆盖编辑页拖拽、保存持久化和前端展示全流程:

1. 前端实现拖拽排序并同步隐藏字段

你之前的sortable代码只做了视觉上的排序,但WooCommerce是通过隐藏的input字段存储选中产品ID的,必须同步更新这个字段的值才能让排序被保存。

把这段代码添加到你的主题functions.php或者自定义插件里(用wp_enqueue_script加载,或者直接放到产品编辑页的自定义脚本中):

jQuery(document).ready(function($) {
    // 定位cross-sell和upsell的Select2选择容器
    const sortableContainers = '.woocommerce-product-data .cross-sells ul.select2-selection__rendered, .woocommerce-product-data .up-sells ul.select2-selection__rendered';
    
    $(sortableContainers).sortable({
        containment: 'parent', // 限制拖拽范围在父容器内
        items: '.select2-selection__choice', // 只允许拖拽已选中的选项
        cursor: 'move',
        stop: function(event, ui) {
            // 收集拖拽后的产品ID顺序
            const sortedIds = [];
            $(this).find('.select2-selection__choice').each(function() {
                // 从Select2元素的data属性里提取产品ID
                const productId = $(this).data('select2-id');
                sortedIds.push(productId);
            });
            // 找到对应的隐藏input,更新它的value为排序后的ID字符串
            const hiddenInput = $(this).closest('.form-field').find('input[type="hidden"]');
            hiddenInput.val(sortedIds.join(','));
        }
    });
});

2. 后端修改查询逻辑,保留手动排序

WooCommerce默认会对upsell/cross-sell产品按字母排序,我们需要修改查询参数,让它按照我们保存的ID顺序返回产品:

// 统一处理upsell和cross-sell的排序规则
add_filter('woocommerce_upsells_orderby', 'custom_woocommerce_sorted_products_orderby', 10, 1);
add_filter('woocommerce_cross_sells_orderby', 'custom_woocommerce_sorted_products_orderby', 10, 1);
add_filter('woocommerce_upsells_order', 'custom_woocommerce_sorted_products_order', 10, 1);
add_filter('woocommerce_cross_sells_order', 'custom_woocommerce_sorted_products_order', 10, 1);

function custom_woocommerce_sorted_products_orderby($orderby) {
    // 使用post__in规则,让WordPress按照我们传入的ID顺序返回产品
    return 'post__in';
}

function custom_woocommerce_sorted_products_order($order) {
    // 保持正序,和我们拖拽的顺序一致
    return 'ASC';
}

3. 优化编辑页Select2下拉框的显示顺序

为了让编辑体验更顺畅,我们可以让Select2下拉框里的已选产品按照保存的顺序显示,而不是默认的字母序:

// 修改编辑页upsell/cross-sell选择框的查询参数
add_filter('woocommerce_product_upsell_ids', 'custom_woocommerce_edit_page_sorted_query', 10, 2);
add_filter('woocommerce_product_crosssell_ids', 'custom_woocommerce_edit_page_sorted_query', 10, 2);

function custom_woocommerce_edit_page_sorted_query($query_args, $product) {
    if (!empty($query_args['post__in'])) {
        // 让下拉框里的已选产品按保存的ID顺序排列
        $query_args['orderby'] = 'post__in';
        $query_args['order'] = 'ASC';
    }
    return $query_args;
}

为什么之前的方法失效?

你之前的sortable代码只改变了DOM元素的视觉位置,但没有更新隐藏字段的ID顺序——WooCommerce保存的还是原来的ID列表,加上默认的orderby是title,所以刷新后就回到了字母排序。这套方案通过同步隐藏字段+修改查询排序规则,完美解决了这个问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 18:20:59