WordPress中如何基于用户位置显示产品超出配送区域标签
在WordPress产品归档页显示超出配送区域标签的实现方案
嘿,我来帮你搞定这个需求!既然你已经能获取访客位置,剩下的核心就是把这个位置和你的自定义distance rate配送方式做匹配,然后在产品归档页的每个产品上显示对应的标签。下面是具体的实现步骤:
第一步:确认访客位置的存储方式
首先得明确你把获取到的访客位置存在了哪里——是WooCommerce的session里?还是自定义cookie?比如假设你存在了WC()->session->get('visitor_location'),里面包含邮编、纬度、经度这些关键数据,后面的代码会基于这个来写。
第二步:编写函数判断产品是否可配送
我们需要一个自定义函数,接收产品ID和访客位置,来判断这个产品是否在配送范围内。这里分两种情况处理:如果你的distance rate插件有内置判断函数,优先用它;如果没有,就手动结合配送区域和距离计算来判断。
function is_product_shippable_to_location( $product_id, $location ) { $product = wc_get_product($product_id); // 先判断产品本身是否支持配送 if ( !$product->is_shippable() ) { return false; } // --- 情况1:使用distance rate插件的内置函数(推荐)--- // 替换成你所用插件的实际判断函数,比如假设插件提供了dr_shipping_check_availability if ( function_exists('dr_shipping_check_availability') ) { // 按需传入参数,比如邮编、产品ID、经纬度等 return dr_shipping_check_availability( $location['postcode'], $product_id ); } // --- 情况2:手动实现判断(如果插件没有提供API)--- // 先获取所有启用的配送区域 $shipping_zones = WC_Shipping_Zones::get_zones(); foreach ( $shipping_zones as $zone ) { // 检查当前区域是否启用了你的自定义distance配送方式 $has_valid_method = false; foreach ( $zone['shipping_methods'] as $method ) { // 替换成你的自定义配送方式ID(在WooCommerce配送设置里找) if ( $method->id === 'custom_distance_shipping' && $method->is_enabled() ) { $has_valid_method = true; break; } } if ( !$has_valid_method ) continue; // 判断访客位置是否在当前配送区域内(这里以邮编为例) foreach ( $zone['zone_locations'] as $location_obj ) { if ( $location_obj->type === 'postcode' && strpos($location['postcode'], $location_obj->code) === 0 ) { // 计算访客位置到店铺的距离(用Haversine公式) $store_lat = get_option('woocommerce_store_latitude'); $store_lng = get_option('woocommerce_store_longitude'); $distance = calculate_distance( $store_lat, $store_lng, $location['lat'], $location['lng'] ); // 获取产品设置的最大配送距离(假设你加了自定义字段_max_delivery_distance) $max_delivery_distance = $product->get_meta('_max_delivery_distance', true); if ( $distance <= $max_delivery_distance ) { return true; } } } } // 所有条件都不满足,返回false return false; } // 辅助函数:计算两点间的直线距离(单位:公里) function calculate_distance( $lat1, $lng1, $lat2, $lng2 ) { $earth_radius = 6371; $dLat = deg2rad($lat2 - $lat1); $dLng = deg2rad($lng2 - $lng1); $a = sin($dLat/2) * sin($dLat/2) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * sin($dLng/2) * sin($dLng/2); $c = 2 * atan2(sqrt($a), sqrt(1-$a)); return round($earth_radius * $c, 2); }
第三步:在归档页添加“超出配送区域”标签
用WooCommerce的钩子,在产品标题后面插入判断逻辑,显示对应的标签:
add_action('woocommerce_after_shop_loop_item_title', 'display_out_of_delivery_zone_badge', 15); function display_out_of_delivery_zone_badge() { global $product; $product_id = $product->get_id(); // 获取访客位置(替换成你实际的存储方式) $visitor_location = WC()->session->get('visitor_location'); // 如果没获取到位置,不显示标签(也可以改成提示用户确认位置) if ( empty($visitor_location) ) { return; } // 判断是否超出配送范围,是就显示标签 if ( !is_product_shippable_to_location( $product_id, $visitor_location ) ) { echo '<span class="out-of-delivery-badge">*超出配送区域</span>'; } }
第四步:美化标签样式
给标签加一点CSS,让它更显眼,你可以把这段代码加到主题的自定义CSS里:
.out-of-delivery-badge { color: #dc3545; font-size: 0.85em; margin-left: 10px; font-weight: 600; background: #ffebee; padding: 2px 6px; border-radius: 3px; }
关键注意事项
- 一定要替换代码里的
custom_distance_shipping为你实际使用的自定义配送方式ID,可以在WooCommerce后台「配送」→「配送方式」里找到,或者用浏览器开发者工具查看元素。 - 如果你的distance rate插件有官方API,优先用插件提供的判断函数,这样能避免自己写的逻辑和插件冲突,结果也更准确。
- IP定位可能有误差,建议在页面上加个位置确认按钮,让用户手动选择邮编或地址,提升判断的准确性。
- 测试时记得切换不同的访客位置,验证标签是否正确显示。
内容的提问来源于stack exchange,提问作者Karan Rpn




