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

如何在WooCommerce结账页面实现多文件上传功能

如何在WooCommerce结账页面实现多文件上传功能

嗨,看起来你已经基于@LoicTheAztec的代码搞定了单文件上传,要改成多文件上传其实只需要对现有代码做几处关键调整就行,我一步步给你说怎么改:

1. 调整结账页面的文件上传字段

首先要让前端的文件输入框支持多文件选择,给字段加上multiple属性就行:

add_action( 'woocommerce_after_order_notes', 'add_custom_checkout_field' );
function add_custom_checkout_field($checkout) {
    echo '<div class="woocommerce-additional-fields__field-wrapper">';
    woocommerce_form_field('certificate', array(
        'type'          => 'file',
        'class'         => array('form-row-wide'),
        'label'         => __('文件', 'woocommerce'),
        'required'      => false,
        'max_size'      => '2048', // 单文件最大2MB
        'accept'        => '.pdf,.doc,.docx,.rtf,.txt',
        'custom_attributes' => array(
            'multiple' => 'multiple' // 开启多文件选择
        )
    ), '');
    echo '</div>';
}

2. 更新JS文件处理多文件上传逻辑

修改你的checkout_upload.js,让它能批量处理选中的多个文件,通过AJAX上传到服务器:

jQuery(document).ready(function($) {
    // 监听文件选择事件
    $('input[name="certificate"]').on('change', function() {
        const formData = new FormData();
        const files = this.files;

        // 把所有选中的文件加入FormData
        for (let i = 0; i < files.length; i++) {
            formData.append('checkout_upload[]', files[i]);
        }

        formData.append('action', 'upload_checkout_files');
        formData.append('security', wc_checkout_params.security);

        // 发起AJAX上传请求
        $.ajax({
            url: wc_checkout_params.ajax_url,
            type: 'POST',
            data: formData,
            contentType: false,
            processData: false,
            success: function(response) {
                if (response.success) {
                    // 把多文件信息存入WooCommerce会话
                    wc_session.set('checkout_upload', response.data);
                } else {
                    alert('文件上传失败:' + response.data);
                }
            },
            error: function() {
                alert('网络错误,请重试文件上传');
            }
        });
    });
});

3. 新增AJAX后端处理函数(接收多文件)

在子主题的functions.php里添加处理多文件上传的AJAX函数,把每个文件保存到服务器并记录信息:

// 注册AJAX处理函数(登录/未登录用户都支持)
add_action('wp_ajax_upload_checkout_files', 'handle_multiple_checkout_file_upload');
add_action('wp_ajax_nopriv_upload_checkout_files', 'handle_multiple_checkout_file_upload');

function handle_multiple_checkout_file_upload() {
    // 验证请求安全性
    check_ajax_referer('wc_checkout', 'security');
    
    $uploaded_files = [];
    $upload_dir = wp_upload_dir();

    if (!empty($_FILES['checkout_upload']['name'])) {
        // 遍历所有上传的文件
        foreach ($_FILES['checkout_upload']['name'] as $key => $file_name) {
            $file_tmp = $_FILES['checkout_upload']['tmp_name'][$key];
            $file_size = $_FILES['checkout_upload']['size'][$key];
            $file_error = $_FILES['checkout_upload']['error'][$key];

            // 检查文件是否上传成功
            if ($file_error === UPLOAD_ERR_OK) {
                // 生成唯一文件名避免覆盖
                $unique_name = wp_unique_filename($upload_dir['path'], $file_name);
                $upload_path = $upload_dir['path'] . '/' . $unique_name;

                // 移动文件到WordPress上传目录
                if (move_uploaded_file($file_tmp, $upload_path)) {
                    $file_url = $upload_dir['url'] . '/' . $unique_name;
                    // 记录文件原始名称和访问URL
                    $uploaded_files[] = [
                        'file_name' => $file_name,
                        'file_url'  => $file_url
                    ];
                }
            }
        }
    }

    if (!empty($uploaded_files)) {
        WC()->session->set('checkout_upload', $uploaded_files);
        wp_send_json_success($uploaded_files);
    } else {
        wp_send_json_error('未检测到有效上传文件');
    }
}

4. 修改订单元数据保存逻辑

把多文件信息保存到订单的元数据里,这里我们把元数据键名改成复数更贴合场景:

add_action( 'woocommerce_checkout_create_order', 'save_checkout_uploaded_files', 10, 2 );
function save_checkout_uploaded_files( $order, $data ){
    if( $checkout_uploads = WC()->session->get('checkout_upload') ) {
        $order->update_meta_data( '_checkout_uploads', $checkout_uploads );
    }
    // 上传完成后清空会话中的临时数据
    WC()->session->__unset('checkout_upload');
}

5. 调整各场景的文件显示逻辑

后台订单页面显示多文件

add_action('woocommerce_admin_order_data_after_billing_address', 'display_uploaded_files_in_admin_orders');
function display_uploaded_files_in_admin_orders( $order ){
    if( $checkout_uploads = $order->get_meta( '_checkout_uploads' ) ) {
        echo '<p><strong>客户上传的文件:</strong><br>';
        foreach( $checkout_uploads as $file ) {
            echo '<a href="' . esc_url($file['file_url']) . '" target="_blank">' . esc_html($file['file_name']) . '</a><br>';
        }
        echo '</p>';
    }
}

订单感谢页面显示多文件

add_action('woocommerce_order_details_after_order_table', 'display_uploaded_files_in_thankyou');
function display_uploaded_files_in_thankyou ( $order ){
    if( $checkout_uploads = $order->get_meta( '_checkout_uploads' ) ) {
        echo '<p><strong>你上传的文件:</strong><br>';
        foreach( $checkout_uploads as $file ) {
            echo '<a href="' . esc_url($file['file_url']) . '" target="_blank">' . esc_html($file['file_name']) . '</a><br>';
        }
        echo '</p>';
    }
}

订单邮件中显示多文件

add_action('woocommerce_email_customer_details', 'display_uploaded_files_in_email');
function display_uploaded_files_in_email ( $order ){
    if( $checkout_uploads = $order->get_meta( '_checkout_uploads' ) ) {
        echo '<p><strong>上传的文件:</strong><br>';
        foreach( $checkout_uploads as $file ) {
            echo '<a href="' . esc_url($file['file_url']) . '" target="_blank">' . esc_html($file['file_name']) . '</a><br>';
        }
        echo '</p>';
    }
}

最后:确保JS文件正确加载

在functions.php里添加JS文件的注册逻辑,确保只在结账页面加载:

add_action('wp_enqueue_scripts', 'enqueue_checkout_upload_script');
function enqueue_checkout_upload_script() {
    // 仅在结账页面(非订单完成等端点)加载脚本
    if (is_checkout() && !is_wc_endpoint_url()) {
        wp_enqueue_script(
            'checkout-upload',
            get_stylesheet_directory_uri() . '/checkout_upload.js',
            array('jquery'),
            '1.0',
            true
        );
        // 传递必要的全局参数给JS
        wp_localize_script('checkout-upload', 'wc_checkout_params', array(
            'ajax_url' => admin_url('admin-ajax.php'),
            'security' => wp_create_nonce('wc_checkout')
        ));
    }
}

额外注意事项

  • 请确保服务器的PHP配置支持多文件上传:调整php.ini中的upload_max_filesize、post_max_size、max_file_uploads参数,避免因限制导致上传失败;
  • 每个文件的大小仍受你设置的max_size(2MB)限制,若需要调整可修改字段参数;
  • 所有输出的链接都用了esc_url和esc_html进行安全转义,避免XSS风险。

这样改完之后,你的WooCommerce结账页面就能完美支持多文件上传啦~

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 08:59:33