如何为WooCommerce访客购物者分配自定义Customer Code
问题描述
我正在开发一个电商项目,需要为所有购买商品的顾客(包括访客)分配基于姓名与序号的Customer Code,供会计软件使用。现有代码仅对注册用户生效,无法为访客生成代码。希望将该信息存储到wp_wc_customer_lookup表(该表记录所有顾客,无论是否注册),同时在WooCommerce客户标签页显示该代码。
现有代码
用户资料字段与注册用户代码生成
add_action( 'show_user_profile', 'ipx_user_profile_fields' ); add_action( 'edit_user_profile', 'ipx_user_profile_fields' ); function ipx_user_profile_fields( $user ) { ?> <h3><?php _e("IPX", "blank"); ?></h3> <table class="form-table"> <tr> <th><label for="ipx_customer_code"><?php _e("Customer Code"); ?></label></th> <td> <input type="text" name="ipx_customer_code" id="ipx_customer_code" value="<?php echo esc_attr( get_the_author_meta( 'ipx_customer_code', $user->ID ) ); ?>" class="regular-text" /><br /> <span class="description"><?php _e("This field should contain only the IPX Customer Code."); ?></span> </td> </tr> </table> <?php } add_action( 'personal_options_update', 'save_ipx_user_profile_fields' ); add_action( 'edit_user_profile_update', 'save_ipx_user_profile_fields' ); function save_ipx_user_profile_fields( $user_id ) { if ( !current_user_can( 'edit_user', $user_id ) ) { return false; } update_user_meta( $user_id, 'ipx_customer_code', $_POST['ipx_customer_code'] ); } /** * Generate customer code based on user's first name, last name and a sequential number */ function generate_customer_code($user_id) { $user = get_userdata($user_id); $first_name = $user->first_name; $last_name = $user->last_name; // Get the current sequential number for the customer code $sequential_number = get_user_meta($user_id, 'sequential_customer_code', true); if (!$sequential_number) { $sequential_number = 0; } // Loop until a unique customer code is generated do { $sequential_number++; // Generate the customer code $customer_code = strtoupper(substr($first_name, 0, 4) . substr($last_name, 0, 4) . sprintf('%02d', $sequential_number)); // Check if the customer code already exists $user_query = new WP_User_Query(array( 'meta_key' => 'ipx_customer_code', 'meta_value' => $customer_code )); } while (!empty($user_query->results)); // Save the customer code and sequential number as separate custom fields update_user_meta($user_id, 'ipx_customer_code', $customer_code); update_user_meta($user_id, 'sequential_customer_code', $sequential_number); } add_action('user_register', 'generate_customer_code');
订单关联客户代码
add_action( 'woocommerce_checkout_update_order_meta', 'include_customer_code_on_order', 10, 2 ); function include_customer_code_on_order( $order_id, $posted_data ) { $order = wc_get_order( $order_id ); $user_id = $order->get_user_id(); if ( $user_id ) { $customer_code = get_user_meta( $user_id, 'ipx_customer_code', true ); if ( $customer_code ) { $order->update_meta_data( 'ipx_customer_code', $customer_code ); $order->save(); } } }
解决方案
1. 为wp_wc_customer_lookup表新增客户代码字段
首先需要在WooCommerce的统一顾客表中添加存储字段:
// 初始化时检查并新增字段 add_action('init', 'ipx_add_customer_code_column'); function ipx_add_customer_code_column() { global $wpdb; $table_name = $wpdb->prefix . 'wc_customer_lookup'; $column_exists = $wpdb->get_var("SHOW COLUMNS FROM $table_name LIKE 'ipx_customer_code'"); if (!$column_exists) { $wpdb->query("ALTER TABLE $table_name ADD COLUMN ipx_customer_code VARCHAR(20) NULL DEFAULT ''"); } }
2. 通用唯一客户代码生成逻辑
重构生成逻辑,同时支持注册用户和访客:
// 注册用户注册时生成代码 add_action('user_register', 'ipx_generate_customer_code_for_user'); function ipx_generate_customer_code_for_user($user_id) { $user = get_userdata($user_id); $first_name = $user->first_name; $last_name = $user->last_name; $customer_code = ipx_generate_unique_customer_code($first_name, $last_name); // 同步更新用户meta和customer_lookup表 update_user_meta($user_id, 'ipx_customer_code', $customer_code); ipx_update_customer_lookup_code($user_id, $customer_code); } // 访客下单时生成代码 add_action('woocommerce_checkout_create_order', 'ipx_generate_customer_code_for_guest', 20, 2); function ipx_generate_customer_code_for_guest($order, $data) { if (!$order->get_user_id()) { // 判断为访客订单 $first_name = $order->get_billing_first_name(); $last_name = $order->get_billing_last_name(); $customer_code = ipx_generate_unique_customer_code($first_name, $last_name); // 更新customer_lookup表(WooCommerce会自动为访客创建该表记录) ipx_update_customer_lookup_code($order->get_customer_id(), $customer_code); // 将代码存入订单元数据 $order->update_meta_data('ipx_customer_code', $customer_code); } } // 生成唯一客户代码的核心函数 function ipx_generate_unique_customer_code($first_name, $last_name) { global $wpdb; $table_name = $wpdb->prefix . 'wc_customer_lookup'; // 提取姓名前缀(最多4位) $first_prefix = strtoupper(substr($first_name ?: '', 0, 4)); $last_prefix = strtoupper(substr($last_name ?: '', 0, 4)); $sequential_number = 0; do { $sequential_number++; $customer_code = $first_prefix . $last_prefix . sprintf('%02d', $sequential_number); // 检查customer_lookup表中是否已存在该代码 $exists = $wpdb->get_var($wpdb->prepare( "SELECT COUNT(*) FROM $table_name WHERE ipx_customer_code = %s", $customer_code )); } while ($exists > 0); return $customer_code; } // 更新customer_lookup表的客户代码 function ipx_update_customer_lookup_code($customer_id, $customer_code) { global $wpdb; $table_name = $wpdb->prefix . 'wc_customer_lookup'; $wpdb->update( $table_name, array('ipx_customer_code' => $customer_code), array('customer_id' => $customer_id), array('%s'), array('%d') ); }
3. 在WooCommerce客户列表显示客户代码
添加自定义列并填充数据:
// 为客户列表添加自定义列 add_filter('manage_edit-shop_customer_columns', 'ipx_add_customer_code_column_to_list'); function ipx_add_customer_code_column_to_list($columns) { $columns['ipx_customer_code'] = __('Customer Code', 'woocommerce'); return $columns; } // 填充客户列表的自定义列数据 add_action('manage_shop_customer_posts_custom_column', 'ipx_populate_customer_code_column', 10, 2); function ipx_populate_customer_code_column($column, $customer_id) { if ($column === 'ipx_customer_code') { global $wpdb; $table_name = $wpdb->prefix . 'wc_customer_lookup'; // 从customer_lookup表获取代码 $customer_code = $wpdb->get_var($wpdb->prepare( "SELECT ipx_customer_code FROM $table_name WHERE customer_id = %d", $customer_id )); // 兼容旧数据:如果注册用户没有在lookup表找到,从用户meta读取 if (!$customer_code && get_userdata($customer_id)) { $customer_code = get_user_meta($customer_id, 'ipx_customer_code', true); } echo esc_html($customer_code ?: '-'); } }
4. 更新订单关联代码逻辑
替换原有函数,同时支持注册用户和访客:
add_action('woocommerce_checkout_update_order_meta', 'ipx_include_customer_code_on_order', 10, 2); function ipx_include_customer_code_on_order($order_id, $posted_data) { $order = wc_get_order($order_id); $user_id = $order->get_user_id(); $customer_id = $order->get_customer_id(); $customer_code = ''; if ($user_id) { // 注册用户优先从customer_lookup表获取 global $wpdb; $table_name = $wpdb->prefix . 'wc_customer_lookup'; $customer_code = $wpdb->get_var($wpdb->prepare( "SELECT ipx_customer_code FROM $table_name WHERE user_id = %d", $user_id )); // 兼容旧数据 if (!$customer_code) { $customer_code = get_user_meta($user_id, 'ipx_customer_code', true); } } else { // 访客直接从订单meta获取(生成时已存入) $customer_code = $order->get_meta('ipx_customer_code'); } if ($customer_code) { $order->update_meta_data('ipx_customer_code', $customer_code); $order->save(); } }
5. 保留注册用户个人资料编辑功能
修改原有资料字段函数,适配新的存储来源:
add_action('show_user_profile', 'ipx_user_profile_fields'); add_action('edit_user_profile', 'ipx_user_profile_fields'); function ipx_user_profile_fields($user) { global $wpdb; $table_name = $wpdb->prefix . 'wc_customer_lookup'; // 优先从customer_lookup表获取代码 $customer_code = $wpdb->get_var($wpdb->prepare( "SELECT ipx_customer_code FROM $table_name WHERE user_id = %d", $user->ID )); // 兼容旧数据 if (!$customer_code) { $customer_code = get_user_meta($user->ID, 'ipx_customer_code', true); } ?> <h3><?php _e("IPX", "blank"); ?></h3> <table class="form-table"> <tr> <th><label for="ipx_customer_code"><?php _e("Customer Code"); ?></label></th> <td> <input type="text" name="ipx_customer_code" id="ipx_customer_code" value="<?php echo esc_attr($customer_code); ?>" class="regular-text" /><br /> <span class="description"><?php _e("This field should contain only the IPX Customer Code."); ?></span> </td> </tr> </table> <?php } add_action('personal_options_update', 'save_ipx_user_profile_fields'); add_action('edit_user_profile_update', 'save_ipx_user_profile_fields'); function save_ipx_user_profile_fields($user_id) { if (!current_user_can('edit_user', $user_id)) { return false; } $customer_code = sanitize_text_field($_POST['ipx_customer_code']); // 同步更新用户meta和customer_lookup表 update_user_meta($user_id, 'ipx_customer_code', $customer_code); ipx_update_customer_lookup_code($user_id, $customer_code); }
内容的提问来源于stack exchange,提问作者AbandonedHope
相关产品推荐
相关产品推荐

