博客 / WooCommerce/ WooCommerce 开发实战:批量处理自定义订单状态与表单字段定制

WooCommerce 开发实战:批量处理自定义订单状态与表单字段定制

WooCommerce 开发实战:批量处理自定义订单状态与表单字段定制

引言

在运营基于 WooCommerce 的电商网站时,深度定制化是提升管理效率与用户体验的关键。本文将介绍如何通过代码实现两个核心功能:一是为自定义订单状态添加批量操作功能,以便快速管理订单;二是在用户注册及“我的账户”页面添加自定义下拉字段,以收集更丰富的用户信息。

为自定义订单状态添加批量操作

WooCommerce 后台默认支持对核心订单状态(如处理中、已完成)进行批量更改。若要为自定义状态(例如“待发货”)添加批量操作选项,需通过钩子扩展功能。

实现代码

将以下代码添加到主题的 functions.php 文件或自定义功能插件中。

// 1. 注册批量操作选项
add_filter( 'bulk_actions-edit-shop_order', 'custom_register_bulk_action' );
function custom_register_bulk_action( $bulk_actions ) {
    $bulk_actions['mark_awaiting_shipment'] = '标记为待发货';
    return $bulk_actions;
}

// 2. 处理批量操作请求
add_action( 'admin_action_mark_awaiting_shipment', 'custom_bulk_process_status' );
function custom_bulk_process_status() {
    if ( ! isset( $_REQUEST['post'] ) || ! is_array( $_REQUEST['post'] ) ) {
        return;
    }
    foreach ( $_REQUEST['post'] as $order_id ) {
        $order = wc_get_order( $order_id );
        if ( $order ) {
            $order->update_status( 'wc-awaiting-shipment', '批量操作更新状态', true );
        }
    }
    $location = add_query_arg( array(
        'post_type' => 'shop_order',
        'marked_awaiting_shipment' => 1,
        'changed' => count( $_REQUEST['post'] ),
        'ids' => join( ',', $_REQUEST['post'] ),
        'post_status' => 'all'
    ), 'edit.php' );
    wp_redirect( admin_url( $location ) );
    exit;
}

// 3. 显示操作成功通知
add_action( 'admin_notices', 'custom_bulk_action_admin_notice' );
function custom_bulk_action_admin_notice() {
    global $pagenow, $typenow;
    if ( $typenow == 'shop_order' && $pagenow == 'edit.php' && isset( $_REQUEST['marked_awaiting_shipment'] ) ) {
        $count = intval( $_REQUEST['changed'] );
        echo '<div class="updated"><p>已成功更新 ' . $count . ' 个订单的状态。</p></div>';
    }
}

关键点解析

  • 钩子匹配: bulk_actions-edit-shop_order 中的 edit-shop_order 是订单列表页面的屏幕 ID。
  • 动作命名: admin_action_mark_awaiting_shipment 的后半部分必须与注册的数组键值(mark_awaiting_shipment)一致。
  • 状态标识: update_status() 中使用的状态标识符(如 wc-awaiting-shipment)必须是系统中已注册的有效状态。

在注册表单添加自定义下拉字段

为了收集用户属性(如客户类型),我们需要在注册表单中添加下拉选择框,并确保数据能正确保存与回显。

完整实现代码

以下代码演示了如何添加一个“客户类型”字段,涵盖前端显示、数据保存及后台/前端编辑回显。

// 1. 在注册表单添加下拉字段
add_action( 'woocommerce_register_form', 'add_extra_register_select_field' );
function add_extra_register_select_field() {
    ?>
    <p class="form-row form-row-wide">
        <label for="customer_type">客户类型 <span class="required">*</span></label>
        <select id="customer_type" name="customer_type" required>
            <option value="">请选择...</option>
            <option value="individual">个人</option>
            <option value="company">企业</option>
            <option value="reseller">经销商</option>
        </select>
    </p>
    <?php
}

// 2. 注册时保存字段值
add_action( 'woocommerce_created_customer', 'save_extra_register_fields' );
function save_extra_register_fields( $customer_id ) {
    if ( isset( $_POST['customer_type'] ) ) {
        update_user_meta( $customer_id, 'customer_type', sanitize_text_field( $_POST['customer_type'] ) );
    }
}

// 3. 在后台用户编辑页显示字段
add_action( 'show_user_profile', 'show_extra_register_fields_admin' );
add_action( 'edit_user_profile', 'show_extra_register_fields_admin' );
function show_extra_register_fields_admin( $user ) {
    $value = get_user_meta( $user->ID, 'customer_type', true );
    ?>
    <h3>额外信息</h3>
    <table class="form-table">
        <tr>
            <th><label for="customer_type">客户类型</label></th>
            <td>
                <select id="customer_type" name="customer_type">
                    <option value="">请选择...</option>
                    <option value="individual" <?php selected( $value, 'individual' ); ?>>个人</option>
                    <option value="company" <?php selected( $value, 'company' ); ?>>企业</option>
                    <option value="reseller" <?php selected( $value, 'reseller' ); ?>>经销商</option>
                </select>
            </td>
        </tr>
    </table>
    <?php
}

// 4. 在前端“我的账户”编辑页面显示字段
add_action( 'woocommerce_edit_account_form', 'show_extra_register_fields_frontend' );
function show_extra_register_fields_frontend() {
    $user_id = get_current_user_id();
    $value = get_user_meta( $user_id, 'customer_type', true );
    ?>
    <p class="form-row form-row-wide">
        <label for="customer_type">客户类型 <span class="required">*</span></label>
        <select id="customer_type" name="customer_type">
            <option value="">请选择...</option>
            <option value="individual" <?php selected( $value, 'individual' ); ?>>个人</option>
            <option value="company" <?php selected( $value, 'company' ); ?>>企业</option>
            <option value="reseller" <?php selected( $value, 'reseller' ); ?>>经销商</option>
        </select>
    </p>
    <?php
}

// 5. 保存后台及前端编辑页面的更新
add_action( 'personal_options_update', 'save_extra_register_fields_admin' );
add_action( 'edit_user_profile_update', 'save_extra_register_fields_admin' );
add_action( 'woocommerce_save_account_details', 'save_extra_register_fields_admin' );
function save_extra_register_fields_admin( $customer_id ) {
    if ( isset( $_POST['customer_type'] ) ) {
        update_user_meta( $customer_id, 'customer_type', sanitize_text_field( $_POST['customer_type'] ) );
    }
}

功能逻辑说明

  1. 前端注册: 利用 woocommerce_register_form 钩子在标准表单下方插入 HTML。
  2. 数据存储: 使用 update_user_meta 将数据存入 wp_usermeta 表,并进行安全清理。
  3. 多端回显: 分别挂载到后台和前端编辑页面的钩子,确保用户在任何地方都能看到和修改该字段。
  4. 数据同步: 保存逻辑挂载到对应的更新动作中,确保修改生效。

修改支付网关标题与描述

有时为了提升转化率或符合品牌调性,需要修改支付网关在前端显示的文字。例如,将“货到付款”改为更具描述性的文案。

// 修改支付网关标题
add_filter( 'woocommerce_gateway_title', 'custom_payment_gateway_title', 25, 2 );
function custom_payment_gateway_title( $title, $gateway_id ) {
    if ( 'cod' === $gateway_id ) { // 'cod' 是货到付款的默认 ID
        $title = '送货时现金或刷卡支付';
    }
    return $title;
}

// 修改支付网关描述
add_filter( 'woocommerce_gateway_description', 'custom_payment_gateway_description', 25, 2 );
function custom_payment_gateway_description( $description, $gateway_id ) {
    if ( 'cod' === $gateway_id ) {
        $description = '送货上门时支付,支持现金与移动支付。';
    }
    return $description;
}

总结与注意事项

  • 代码存放: 建议将代码放入子主题的 functions.php 或使用自定义插件,避免主题更新后代码丢失。
  • 安全性: 所有用户输入(如 $_POST)必须经过清理(如 sanitize_text_field),防止 XSS 攻击。
  • 测试环境: 修改订单状态和支付逻辑涉及核心业务,务必在测试站点充分验证后再部署至生产环境。
  • 扩展性: 上述代码为标准模板,可根据实际业务需求调整字段名称、选项值及逻辑判断。

发表评论

您的邮箱不会公开。必填项已用 * 标注。