WooCommerce自定义时段统计用户已完成订单总消费额
问题分析
原代码存在3个核心逻辑错误,导致实际只统计当月数据而非指定天数范围:
- 硬编码
date_query规则仅查询当前月+错误计算的上月数据,完全没有使用提前计算的时间边界做范围过滤 - 跨年月计算逻辑存在bug,非1月场景下错误将查询年份设为当前年份减1,和30天的时间跨度完全不匹配
- 总金额计算处误用
preg_replace函数,存在计算精度风险,且统计天数、提示文案、短代码标识均为硬编码,修改成本高
修改后完整代码
/** * 统计指定周期内用户已完成订单总消费额 * @param int|null $user_id 待查询用户ID,为空默认取当前登录用户 * @param int $stat_days 统计覆盖的天数范围,默认180天(6个月) * @return float|string 格式化后的总消费金额/无订单提示 */ function total_spent_by_user_days( $user_id = null, $stat_days = 180 ) { if ( empty($user_id) ){ $user_id = get_current_user_id(); } // 未登录用户直接返回提示 if ( !$user_id ) { return __('指定周期内无已完成订单', 'mytheme'); } // 按站点时区计算时间边界,避免服务器时区偏差 $now = current_time('timestamp'); $gap_time = $now - DAY_IN_SECONDS * $stat_days; // 订单查询参数 $args = array( 'post_type' => 'shop_order', 'post_status' => array( 'wc-completed' ), // 仅统计已完成状态订单 'numberposts' => -1, 'meta_key' => '_customer_user', 'meta_value' => $user_id, 'date_query' => array( array( 'after' => date('Y-m-d H:i:s', $gap_time), 'inclusive' => true, // 包含临界时间点的订单 ), ), ); $customer_orders = get_posts( $args ); $total = 0; $no_orders_message = __('指定周期内无已完成订单', 'mytheme'); if ( !empty($customer_orders) ) { foreach ( $customer_orders as $customer_order ){ $order = wc_get_order( $customer_order->ID ); if ( !$order ) continue; $total += (float)$order->get_total(); } // 金额保留2位小数返回 return round($total, 2); } return $no_orders_message; } // 注册短代码,支持自定义参数 add_shortcode( 'spent-last-days', function( $atts ) { $atts = shortcode_atts( array( 'days' => 180, 'user_id' => null ), $atts ); return total_spent_by_user_days( $atts['user_id'], intval($atts['days']) ); } );
使用说明
- 调整默认统计周期:直接修改函数定义处
$stat_days = 180的数值即可,比如要默认统计30天就将值改为30 - 短代码调用方式:
- 输出默认180天消费额:直接在页面/小工具中插入
[spent-last-days] - 输出自定义天数消费额:比如统计30天消费插入
[spent-last-days days="30"],统计90天插入[spent-last-days days="90"] - 查询指定用户消费:比如查询ID为123的用户180天消费,插入
[spent-last-days user_id="123" days="180"]
- 输出默认180天消费额:直接在页面/小工具中插入
- 代码层调用:可在主题模板、自定义插件中直接调用
total_spent_by_user_days( $user_id, $days )获取对应消费数据,无需重复写查询逻辑
注意:代码默认仅统计状态为
wc-completed的已完成订单,待支付、已取消、已退款的订单不会计入总金额。
内容的提问来源于stack exchange,提问作者netnet
相关产品推荐
相关产品推荐

