From df6b48d27d08f347a17e0e06519bb7ee7142efbf Mon Sep 17 00:00:00 2001 From: wood chen Date: Wed, 15 Jan 2025 00:43:22 +0800 Subject: [PATCH] Refactor tracking information handling and improve AJAX responses in CZL Express for WooCommerce - Updated AJAX function to validate order ID instead of tracking number for better error handling. - Enhanced success and error responses to include detailed messages for improved user feedback. - Refactored API request methods for better structure and error handling. - Added functionality to automatically update order status and add notes based on tracking information. - Improved logging for API requests and responses to aid in debugging. These changes enhance the reliability and user experience of the CZL Express plugin. --- admin/views/orders.php | 15 +- czlexpress-for-woocommerce.php | 32 +++- includes/class-czl-api.php | 267 +++++++++++++++++++++----------- includes/class-czl-tracking.php | 54 ++++++- 4 files changed, 263 insertions(+), 105 deletions(-) diff --git a/admin/views/orders.php b/admin/views/orders.php index f783448..5c11874 100644 --- a/admin/views/orders.php +++ b/admin/views/orders.php @@ -249,11 +249,11 @@ jQuery(document).ready(function($) { }, success: function(response) { if (response.success) { - alert(wp.escapeHtml(response.data.message || '跟踪单号更新成功')); + alert(response.data.message || '跟踪单号更新成功'); self.parent.tb_remove(); window.location.reload(); } else { - alert(wp.escapeHtml(response.data || '更新失败')); + alert(response.data.message || '更新失败'); } }, error: function() { @@ -279,15 +279,16 @@ jQuery(document).ready(function($) { }, success: function(response) { if (response.success) { - alert('轨迹更新成功'); + alert(response.data.message || '轨迹更新成功'); window.location.reload(); } else { - alert(response.data || '更新失败'); - $button.prop('disabled', false).text('更新轨迹'); + alert(typeof response.data === 'string' ? response.data : (response.data.message || '更新失败')); } }, - error: function() { - alert('请求失败,请重试'); + error: function(xhr, status, error) { + alert('请求失败,请重试: ' + error); + }, + complete: function() { $button.prop('disabled', false).text('更新轨迹'); } }); diff --git a/czlexpress-for-woocommerce.php b/czlexpress-for-woocommerce.php index f0bc249..f8adc90 100644 --- a/czlexpress-for-woocommerce.php +++ b/czlexpress-for-woocommerce.php @@ -300,24 +300,40 @@ function czl_ajax_update_tracking_number() { function czl_ajax_update_tracking_info() { try { // 验证nonce - if (!check_ajax_referer('czl_update_tracking_info', 'nonce', false)) { - throw new Exception('无效的请求'); - } + check_ajax_referer('czl_ajax_nonce', 'nonce'); // 验证权限 if (!current_user_can('edit_shop_orders')) { throw new Exception('权限不足'); } - $tracking_number = isset($_POST['tracking_number']) ? sanitize_text_field($_POST['tracking_number']) : ''; - if (empty($tracking_number)) { - throw new Exception('运单号不能为空'); + $order_id = isset($_POST['order_id']) ? intval($_POST['order_id']) : 0; + if (!$order_id) { + throw new Exception('订单ID不能为空'); + } + + // 获取运单信息 + global $wpdb; + $shipment = $wpdb->get_row($wpdb->prepare( + "SELECT tracking_number FROM {$wpdb->prefix}czl_shipments WHERE order_id = %d", + $order_id + )); + + if (!$shipment || empty($shipment->tracking_number)) { + throw new Exception('未找到运单信息'); } $tracking = new CZL_Tracking(); - $result = $tracking->update_tracking_info($tracking_number); + $result = $tracking->update_tracking_info($shipment->tracking_number); - wp_send_json_success($result); + if ($result['success']) { + wp_send_json_success(array( + 'message' => '轨迹更新成功', + 'data' => $result['data'] + )); + } else { + throw new Exception($result['message'] ?: '更新失败'); + } } catch (Exception $e) { CZL_Logger::error('Error updating tracking info', array('error' => $e->getMessage())); diff --git a/includes/class-czl-api.php b/includes/class-czl-api.php index bc58445..0b0eff9 100644 --- a/includes/class-czl-api.php +++ b/includes/class-czl-api.php @@ -118,55 +118,33 @@ class CZL_API { /** * 发送API请求 */ - private function send_request($endpoint, $params = array(), $method = 'GET') { - try { - $url = $this->get_api_url($endpoint); - $headers = $this->get_headers(); - - $args = array( - 'method' => $method, - 'headers' => $headers, - 'timeout' => 30, - 'sslverify' => false - ); - - if ($method === 'POST') { - $args['body'] = json_encode($params); - CZL_Logger::debug('API request', array( - 'url' => $url, - 'method' => $method, - 'params' => $params - )); - } - - $response = wp_remote_request($url, $args); - - if (is_wp_error($response)) { - throw new Exception($response->get_error_message()); - } - - $body = wp_remote_retrieve_body($response); - $data = json_decode($body, true); - - CZL_Logger::debug('API response', array( - 'url' => $url, - 'response' => $data - )); - - if (!$data) { - throw new Exception('Invalid JSON response'); - } - - return $data; - - } catch (Exception $e) { - CZL_Logger::error('API request failed', array( - 'url' => $url, - 'error' => $e->getMessage(), - 'params' => $params - )); - throw $e; + private function request($endpoint, $method = 'GET', $data = null) { + $args = array( + 'method' => $method, + 'headers' => array( + 'Authorization' => $this->get_token(), + 'Content-Type' => 'application/json' + ), + 'timeout' => 30 + ); + + if ($data !== null) { + $args['body'] = wp_json_encode($data); } + + $response = wp_remote_request($this->api_url . $endpoint, $args); + + if (is_wp_error($response)) { + throw new Exception($response->get_error_message()); + } + + $body = json_decode(wp_remote_retrieve_body($response), true); + + if (empty($body['success'])) { + throw new Exception(!empty($body['message']) ? esc_html($body['message']) : esc_html__('请求失败', 'woocommerce-czlexpress')); + } + + return $body['data']; } /** @@ -570,48 +548,70 @@ class CZL_API { } } - /** - * 获取运单轨迹 - */ - public function get_tracking_info($tracking_number) { + public function create_shipment($params) { try { - $response = $this->send_request('/tracking/query', array( - 'tracking_number' => $tracking_number - ), 'POST'); - - CZL_Logger::debug('Tracking info retrieved', array( - 'tracking_number' => $tracking_number, - 'response' => $response + if (defined('WP_DEBUG_LOG') && WP_DEBUG_LOG) { + error_log('CZL Express: Starting create shipment'); + } + + // 先进行认证 + $auth_result = $this->authenticate(); + if (!$auth_result['ack']) { + throw new Exception('认证失败: ' . $auth_result['message']); + } + + // 添加认证信息到参数 + $params['customer_id'] = $auth_result['customer_id']; + $params['customer_userid'] = $auth_result['customer_userid']; + + // 准备请求数据 + $request_data = array( + 'param' => wp_json_encode($params) + ); + + if (defined('WP_DEBUG_LOG') && WP_DEBUG_LOG) { + error_log('CZL Express: Create shipment request data - ' . print_r($request_data, true)); + } + + // 发送请求 + $response = wp_remote_post('https://tms.czl.net/createOrderApi.htm', array( + 'body' => $request_data, + 'timeout' => 30, + 'headers' => array( + 'Accept' => '*/*', + 'Accept-Language' => 'zh-cn', + 'Cache-Control' => 'no-cache', + 'Content-Type' => 'application/x-www-form-urlencoded;charset=UTF-8' + ) )); - - return $response; - - } catch (Exception $e) { - CZL_Logger::error('Failed to get tracking info', array( - 'tracking_number' => $tracking_number, - 'error' => $e->getMessage() - )); - throw $e; - } - } - - /** - * 创建运单 - */ - public function create_shipment($order_data) { - try { - CZL_Logger::debug('Creating shipment', array( - 'order_data' => $order_data - )); - - $response = $this->send_request('/shipment/create', $order_data, 'POST'); - - CZL_Logger::debug('Shipment created', array( - 'response' => $response - )); - - return $response; - + + if (is_wp_error($response)) { + throw new Exception('CURL错误: ' . $response->get_error_message()); + } + + $body = wp_remote_retrieve_body($response); + if (defined('WP_DEBUG_LOG') && WP_DEBUG_LOG) { + error_log('CZL Express: Raw response - ' . $body); + } + + $result = json_decode($body, true); + if (json_last_error() !== JSON_ERROR_NONE) { + throw new Exception('JSON解析错误: ' . json_last_error_msg()); + } + + if (defined('WP_DEBUG_LOG') && WP_DEBUG_LOG) { + error_log('CZL Express: Create shipment response - ' . print_r($result, true)); + } + + // 检查API错误信息 + if (isset($result['message']) && !empty($result['message'])) { + if (defined('WP_DEBUG_LOG') && WP_DEBUG_LOG) { + error_log('CZL Express: API error message - ' . $result['message']); + } + } + + return $result; + } catch (Exception $e) { CZL_Logger::error('Failed to create shipment', array( 'order_data' => $order_data, @@ -651,4 +651,95 @@ class CZL_API { throw new Exception('获取跟踪单号失败: ' . esc_html($e->getMessage())); } } + + /** + * 获取运单跟踪信息 + */ + public function get_tracking_info($tracking_number) { + try { + $response = wp_remote_post('https://tms.czl.net/selectTrack.htm', array( + 'body' => array( + 'documentCode' => $tracking_number + ), + 'timeout' => 30, + 'headers' => array( + 'Accept-Encoding' => '', + 'Accept-Language' => 'zh-CN,zh;q=0.9' + ) + )); + + if (is_wp_error($response)) { + throw new Exception($response->get_error_message()); + } + + $body = wp_remote_retrieve_body($response); + error_log('CZL Express: Track raw response - ' . $body); + + // 处理中文编码问题 + $body = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $body); + $result = json_decode($body, true); + + if (json_last_error() !== JSON_ERROR_NONE) { + error_log('CZL Express: JSON decode error - ' . json_last_error_msg()); + throw new Exception('JSON解析失败: ' . json_last_error_msg()); + } + + error_log('CZL Express: Track decoded response - ' . print_r($result, true)); + + if (empty($result) || !isset($result[0])) { + throw new Exception('无效的API响应'); + } + + if (empty($result[0]['ack']) || $result[0]['ack'] !== 'true') { + throw new Exception('获取跟踪信息失败: ' . ($result[0]['message'] ?? '未知错误')); + } + + if (empty($result[0]['data']) || !is_array($result[0]['data'])) { + return array( + 'success' => true, + 'data' => array( + 'status' => 'pending', + 'track_content' => '暂无轨迹信息', + 'track_time' => current_time('mysql'), + 'track_location' => '' + ), + 'message' => '' + ); + } + + // 获取最新的轨迹状态 + $latest_track = $result[0]['data'][0]; + $track_details = $latest_track['trackDetails'] ?? array(); + $latest_detail = !empty($track_details) ? $track_details[0] : array(); + + // 根据轨迹内容判断状态 + $status = 'in_transit'; // 默认状态 + $track_content = strtolower($latest_detail['track_content'] ?? ''); + + if (strpos($track_content, 'delivered') !== false || strpos($track_content, 'signed') !== false) { + $status = 'delivered'; + } elseif (strpos($track_content, 'pickup') !== false || strpos($track_content, 'picked up') !== false) { + $status = 'picked_up'; + } + + return array( + 'success' => true, + 'data' => array( + 'status' => $status, + 'track_content' => $latest_detail['track_content'] ?? '', + 'track_time' => $latest_detail['track_date'] ?? current_time('mysql'), + 'track_location' => $latest_detail['track_location'] ?? '' + ), + 'message' => '' + ); + + } catch (Exception $e) { + error_log('CZL Express API Error: ' . esc_html($e->getMessage())); + return array( + 'success' => false, + 'data' => null, + 'message' => esc_html($e->getMessage()) + ); + } + } } \ No newline at end of file diff --git a/includes/class-czl-tracking.php b/includes/class-czl-tracking.php index a41bede..d72aec6 100644 --- a/includes/class-czl-tracking.php +++ b/includes/class-czl-tracking.php @@ -43,8 +43,58 @@ class CZL_Tracking { throw new Exception($tracking_info['message']); } - // 更新跟踪记录 - $this->update_tracking_record($tracking_number, $tracking_info['data']); + // 更新订单状态 + global $wpdb; + $shipment = $wpdb->get_row($wpdb->prepare( + "SELECT order_id FROM {$wpdb->prefix}czl_shipments WHERE tracking_number = %s", + $tracking_number + )); + + if ($shipment && $shipment->order_id) { + $order = wc_get_order($shipment->order_id); + if ($order) { + // 获取最新的轨迹信息 + $latest_track_content = $tracking_info['data']['track_content']; + $latest_track_location = $tracking_info['data']['track_location']; + $latest_track_time = $tracking_info['data']['track_time']; + + // 获取订单的备注 + $notes = wc_get_order_notes(['order_id' => $shipment->order_id, 'limit' => 1]); + + // 检查是否需要添加新备注 + $should_add_note = true; + if (!empty($notes)) { + $last_note = $notes[0]; + // 检查最后一条备注是否包含相同的轨迹信息 + if (strpos($last_note->content, $latest_track_content) !== false && + strpos($last_note->content, $latest_track_location) !== false && + strpos($last_note->content, $latest_track_time) !== false) { + $should_add_note = false; + } + } + + if ($should_add_note) { + // 添加轨迹信息作为订单备注(设置为公开可见) + $note = sprintf( + "📦 Package Update\n\n" . + "Status: %s\n" . + "Location: %s\n" . + "Time: %s\n\n" . + "Track your package: https://exp.czl.net/track/?query=%s", + $latest_track_content, + $latest_track_location, + $latest_track_time, + $tracking_number + ); + $order->add_order_note($note, 1); // 1表示对客户可见 + } + + // 如果是已签收状态,更新订单状态 + if ($tracking_info['data']['status'] === 'delivered') { + $order->update_status('completed', '📦 Package delivered, order completed automatically'); + } + } + } return $tracking_info;