如何在My Account的order-detail端点启用仿后台商品价格编辑表单?
在WooCommerce我的账户订单详情页添加商品价格编辑功能
核心思路
要实现和后台管理员一致的价格编辑表单,不能直接硬改模板文件,得通过WooCommerce的钩子整合后台编辑逻辑,避免模板更新导致修改失效。
实现步骤
1. 加载后台价格编辑所需的脚本和样式
在主题的functions.php中添加以下代码,确保前台订单详情页加载后台相关资源:
add_action( 'woocommerce_account_order_details_after_order_table', 'load_admin_price_edit_assets' ); function load_admin_price_edit_assets() { if ( is_wc_endpoint_url( 'view-order' ) ) { wp_enqueue_style( 'woocommerce_admin_styles', WC()->plugin_url() . '/assets/css/admin.css' ); wp_enqueue_script( 'woocommerce_admin_scripts', WC()->plugin_url() . '/assets/js/admin/meta-boxes-order.js', array( 'jquery', 'jquery-ui-sortable' ), WC_VERSION, true ); wp_localize_script( 'woocommerce_admin_scripts', 'woocommerce_admin_meta_boxes', array( 'ajax_url' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( 'woocommerce-admin' ), ) ); } }
2. 替换订单详情页的商品价格为可编辑表单
通过钩子替换订单表格中的价格列内容,渲染后台同款输入框:
add_filter( 'woocommerce_order_item_display_meta_value', 'replace_price_with_edit_field', 10, 3 ); function replace_price_with_edit_field( $value, $meta, $item ) { if ( is_wc_endpoint_url( 'view-order' ) && $item->is_type( 'line_item' ) ) { $order = $item->get_order(); if ( get_current_user_id() === $order->get_user_id() ) { $product_price = wc_get_price_to_display( $item->get_product() ); $item_id = $item->get_id(); ob_start(); ?> <div class="view"> <input type="text" name="order_item_price[<?php echo esc_attr( $item_id ); ?>]" value="<?php echo esc_attr( $product_price ); ?>" class="text wc_input_price" /> <button type="button" class="button save-order-item-price" data-item-id="<?php echo esc_attr( $item_id ); ?>" data-order-id="<?php echo esc_attr( $order->get_id() ); ?>">保存</button> </div> <?php return ob_get_clean(); } } return $value; }
3. 添加AJAX保存价格的处理逻辑
在functions.php中添加AJAX处理函数,接收前台修改请求并更新订单数据:
add_action( 'wp_ajax_save_order_item_price', 'save_order_item_price' ); function save_order_item_price() { check_ajax_referer( 'woocommerce-admin', 'nonce' ); $item_id = isset( $_POST['item_id'] ) ? absint( $_POST['item_id'] ) : 0; $order_id = isset( $_POST['order_id'] ) ? absint( $_POST['order_id'] ) : 0; $new_price = isset( $_POST['price'] ) ? wc_format_decimal( $_POST['price'] ) : 0; $order = wc_get_order( $order_id ); $item = $order->get_item( $item_id ); if ( $order && $item && get_current_user_id() === $order->get_user_id() && $new_price > 0 ) { $item->set_subtotal( $new_price * $item->get_quantity() ); $item->set_total( $new_price * $item->get_quantity() ); $item->save(); $order->calculate_totals(); wp_send_json_success( array( 'message' => '价格已更新' ) ); } else { wp_send_json_error( array( 'message' => '无法更新价格' ) ); } }
4. 添加上传保存按钮的JS交互
在主题自定义JS文件或通过wp_enqueue_script添加以下脚本,处理保存按钮点击事件:
jQuery(document).ready(function($) { $('.save-order-item-price').on('click', function() { var $button = $(this); var itemId = $button.data('item-id'); var orderId = $button.data('order-id'); var newPrice = $('input[name="order_item_price[' + itemId + ']"]').val(); $.ajax({ url: woocommerce_admin_meta_boxes.ajax_url, type: 'POST', data: { action: 'save_order_item_price', nonce: woocommerce_admin_meta_boxes.nonce, item_id: itemId, order_id: orderId, price: newPrice }, beforeSend: function() { $button.text('保存中...'); }, success: function(response) { if (response.success) { alert(response.data.message); location.reload(); } else { alert(response.data.message); } $button.text('保存'); }, error: function() { alert('请求失败,请重试'); $button.text('保存'); } }); }); });
注意事项
- 权限控制:代码仅允许订单所有者编辑价格,可按需添加管理员权限判断逻辑
- 价格验证:建议补充更多格式和合理性验证,防止非法值提交
- 兼容性:测试不同WooCommerce版本,确保钩子和函数未被废弃
- 模板维护:优先使用钩子,避免直接修改
order-details.php导致主题更新丢失修改
内容的提问来源于stack exchange,提问作者Francisco Agüero
相关产品推荐
相关产品推荐

