如何以最优方式在WooCommerce订单列表中获取客户类型
在WooCommerce订单列表添加无SQL的客户类型列
核心思路
抛弃手写SQL的方式,完全利用WooCommerce原生API和内置函数来获取客户订单数据,借助框架自带的缓存优化机制,避免低效查询拖慢页面加载。
实现步骤
1. 注册自定义列到订单列表
先在订单列表中插入新的「客户类型」列:
add_filter( 'manage_edit-shop_order_columns', 'add_customer_type_column' ); function add_customer_type_column( $columns ) { // 选择在「订单状态」列后插入新列 $new_columns = []; foreach ( $columns as $key => $label ) { $new_columns[ $key ] = $label; if ( $key === 'order_status' ) { $new_columns['customer_type'] = '客户类型'; } } return $new_columns; }
2. 填充列内容(无SQL实现)
通过订单对象关联的用户ID或账单邮箱,调用WooCommerce内置函数判断客户类型:
add_action( 'manage_shop_order_posts_custom_column', 'display_customer_type_column_content' ); function display_customer_type_column_content( $column ) { global $post; if ( $column !== 'customer_type' ) return; $order = wc_get_order( $post->ID ); $user_id = $order->get_user_id(); // 处理注册客户 if ( $user_id > 0 ) { $order_count = wc_get_customer_order_count( $user_id ); echo $order_count > 1 ? '<span style="color: #27ae60;">回头客</span>' : '<span style="color: #3498db;">新客户</span>'; } // 处理访客客户(基于账单邮箱) else { $billing_email = $order->get_billing_email(); if ( empty( $billing_email ) ) { echo '<span style="color: #95a5a6;">未知</span>'; return; } // 仅查询是否存在历史订单,用limit=1减少数据库负载 $past_orders = wc_get_orders([ 'customer' => $billing_email, 'return' => 'ids', 'exclude' => [ $post->ID ], 'limit' => 1 ]); echo ! empty( $past_orders ) ? '<span style="color: #27ae60;">回头客</span>' : '<span style="color: #3498db;">新客户</span>'; } }
3. 性能优化细节
- 访客查询时设置
limit=1:只要查到1条历史订单就停止查询,避免拉取全部订单数据 - 注册客户用
wc_get_customer_order_count():该函数内部会缓存结果,同一客户的订单数不会重复计算 - 依赖WooCommerce原生查询:
wc_get_orders()已经做了缓存和查询优化,比手写SQL更稳定高效
4. 可选:开启列排序功能
如果需要让「客户类型」列支持排序,添加以下代码:
add_filter( 'manage_edit-shop_order_sortable_columns', 'make_customer_type_column_sortable' ); function make_customer_type_column_sortable( $columns ) { $columns['customer_type'] = 'customer_type'; return $columns; } add_action( 'pre_get_posts', 'sort_customer_type_column' ); function sort_customer_type_column( $query ) { if ( ! is_admin() || ! $query->is_main_query() || $query->get( 'post_type' ) !== 'shop_order' ) { return; } if ( $query->get( 'orderby' ) === 'customer_type' ) { $query->set( 'meta_key', '_customer_user' ); $query->set( 'orderby', 'meta_value_num' ); } }
方案优势
- 完全基于WooCommerce原生能力,避免自定义SQL的兼容性和性能风险
- 内置缓存机制减少重复数据库查询
- 访客查询的精简逻辑大幅降低页面加载时的数据库压力
内容的提问来源于stack exchange,提问作者Saurabh Bisht
相关产品推荐
相关产品推荐

