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

修复WooCommerce后台订单页打印按钮仅首条订单生效问题

问题诊断

你遇到的问题核心原因有两个:

  1. 所有打印按钮使用了重复的ID,而DOM中ID必须唯一,导致事件监听器只绑定到了第一个按钮上;
  2. 按钮默认类型为submit,未绑定事件的按钮点击时会触发订单列表表单的提交,最终导致页面刷新。
修复代码

1. 修改后台订单列表添加按钮的PHP代码

替换原添加按钮的逻辑,用类选择器替代ID,添加唯一的订单ID数据属性,并显式设置按钮类型为button:

add_action('manage_shop_order_posts_custom_column', 'add_print_invoice_button', 20, 2);
function add_print_invoice_button($column, $post_id) {
    if ($column === 'order_actions') {
        // 用类代替ID,添加data-order-id存储订单ID,设置type="button"阻止默认提交
        echo '<button class="print-invoice-btn" type="button" data-order-id="' . esc_attr($post_id) . '">打印发票</button>';
    }
}

2. 修改前端点击事件的JS代码

使用事件委托或遍历类选择器绑定所有按钮,确保每个按钮都能触发打印逻辑:

// 推荐用事件委托,兼容动态加载的元素
document.querySelector('.wp-list-table.widefat.fixed').addEventListener('click', function(e) {
    if (e.target.classList.contains('print-invoice-btn')) {
        e.preventDefault(); // 阻止默认表单提交行为
        const orderId = e.target.dataset.orderId;
        // 打开打印窗口,替换为你的发票处理接口
        window.open('/wp-admin/admin-ajax.php?action=print_invoice&order_id=' + orderId, '_blank');
    }
});

3. 确保发票处理的AJAX函数正常工作

如果还没有实现发票生成的AJAX逻辑,添加以下代码:

add_action('wp_ajax_print_invoice', 'handle_print_invoice');
function handle_print_invoice() {
    $order_id = isset($_GET['order_id']) ? absint($_GET['order_id']) : 0;
    if (!$order_id || !($order = wc_get_order($order_id))) {
        wp_die('无效的订单ID');
    }

    // 输出发票HTML,可根据需求自定义样式和内容
    ?>
    <!DOCTYPE html>
    <html>
    <head>
        <title>订单发票 #<?php echo $order->get_id(); ?></title>
        <style>
            @media print {
                body { font-family: Arial, sans-serif; }
                .invoice-header { text-align: center; margin-bottom: 30px; }
                .order-details table { width: 100%; border-collapse: collapse; }
                .order-details th, .order-details td { border: 1px solid #ccc; padding: 8px; text-align: left; }
            }
        </style>
    </head>
    <body>
        <div class="invoice-header">
            <h1>订单发票</h1>
            <p>订单号: #<?php echo $order->get_id(); ?></p>
            <p>下单时间: <?php echo wc_format_datetime($order->get_date_created()); ?></p>
        </div>
        <div class="customer-details">
            <h3>客户信息</h3>
            <p>姓名: <?php echo $order->get_billing_first_name() . ' ' . $order->get_billing_last_name(); ?></p>
            <p>邮箱: <?php echo $order->get_billing_email(); ?></p>
        </div>
        <div class="order-details">
            <h3>订单商品</h3>
            <table>
                <thead>
                    <tr><th>商品名称</th><th>数量</th><th>单价</th><th>小计</th></tr>
                </thead>
                <tbody>
                    <?php foreach ($order->get_items() as $item) : ?>
                        <tr>
                            <td><?php echo $item->get_name(); ?></td>
                            <td><?php echo $item->get_quantity(); ?></td>
                            <td><?php echo wc_price($item->get_subtotal() / $item->get_quantity()); ?></td>
                            <td><?php echo wc_price($item->get_subtotal()); ?></td>
                        </tr>
                    <?php endforeach; ?>
                </tbody>
                <tfoot>
                    <tr><td colspan="3" style="text-align: right;">总计:</td><td><?php echo wc_price($order->get_total()); ?></td></tr>
                </tfoot>
            </table>
        </div>
        <script>
            window.onload = () => { window.print(); window.close(); }
        </script>
    </body>
    </html>
    <?php
    wp_die();
}
修复要点说明
  • 用类选择器替代ID,确保所有按钮都能被事件监听器捕获;
  • 设置type="button"避免按钮默认触发表单提交;
  • 通过data-order-id传递订单ID,保证每个按钮对应正确的订单;
  • 事件委托方式兼容后续动态加载的订单按钮,无需重复绑定事件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 15:17:20