首页 / 应用软件 / WordPress集成教程,连接快递物流接口实现订单跟踪地图展示

WordPress集成教程,连接快递物流接口实现订单跟踪地图展示

WordPress集成教程:连接快递物流接口实现订单跟踪地图展示 引言:WordPress的无限扩展可能 在当今数字化商业环境中,一个功能完善的网站已不仅仅是信息展示的平台,更是企业与客户互动、提供服务的关键枢纽。WordPress作为全球最受欢迎的内容管理系统,其真正…

文章目录
  • border-radius: 8px; overflow: hidden; box-shadow: 0
  • 在当今数字化商业环境中,一个功能完善的网站已不仅仅是信息展示的平台,更是企业与客户互动、提供服务的关键枢纽。WordPress作为全球最受欢迎的内容管理系统,其真正的强大之处在于可扩展性——通过代码二次开发,我们可以将各种互联网小工具集成到网站中,创造出独特而实用的功能。本教程将深入探讨如何在WordPress中集成快递物流接口,实现订单跟踪地图展示功能,同时展示WordPress代码二次开发实现常用互联网小工具的方法论。

    对于电商网站而言,订单跟踪功能是提升客户体验的重要环节。传统的物流跟踪通常只提供文字状态的更新,而将物流信息与地图可视化结合,能够直观展示包裹的运输路径和当前位置,显著增强用户的信任感和参与度。这种功能的实现,正是WordPress扩展能力的绝佳例证。

    在开始集成开发之前,我们需要确保拥有合适的开发环境。建议使用本地开发环境如XAMPP、MAMP或Local by Flywheel,这些工具能够快速搭建PHP、MySQL和Apache/Nginx环境。对于WordPress开发,确保你的环境满足以下要求:PHP 7.4或更高版本、MySQL 5.6或更高版本、以及适当的内存限制(建议256MB以上)。

    除了基础环境,我们还需要一些开发工具:代码编辑器(如VS Code、PHPStorm)、Git版本控制系统、浏览器开发者工具,以及用于API测试的工具(如Postman或Insomnia)。这些工具将在开发过程中发挥重要作用。

    理解WordPress的开发模式是成功集成的关键。WordPress采用主题和插件两种扩展方式:主题控制网站的外观和展示,而插件则添加特定功能。对于物流跟踪功能,我们通常选择创建专用插件,这样可以保持功能的独立性,便于维护和迁移。

    WordPress插件的基本结构包括主插件文件、资产文件(CSS、JavaScript)、模板文件以及可能的语言文件。所有插件文件应放置在wp-content/plugins目录下的独立文件夹中。插件的主文件必须包含标准的插件头信息,这样WordPress才能识别并激活它。

    市场上有多种快递物流API可供选择,如快递鸟、快递100、阿里云物流跟踪等。选择API时需要考虑以下因素:支持的快递公司数量、查询稳定性、更新频率、费用结构以及文档完整性。本教程将以快递鸟API为例,但方法和原理适用于大多数物流API。

    注册选定的API服务后,我们将获得关键的访问凭证:通常是API Key和Secret Key。这些凭证需要安全地存储在WordPress中,建议使用WordPress的选项API或自定义数据库表进行存储,避免硬编码在插件文件中。

    首先创建插件目录和主文件。在wp-content/plugins目录下创建新文件夹“shipment-tracker”,然后在该文件夹中创建主文件“shipment-tracker.php”:

    <?php
    /**
     * Plugin Name: Shipment Tracker
     * Plugin URI: https://yourwebsite.com/shipment-tracker
     * Description: 集成快递物流接口,实现订单跟踪地图展示功能
     * Version: 1.0.0
     * Author: Your Name
     * License: GPL v2 or later
     * Text Domain: shipment-tracker
     */
    
    // 防止直接访问
    if (!defined('ABSPATH')) {
        exit;
    }
    
    // 定义插件常量
    define('ST_VERSION', '1.0.0');
    define('ST_PLUGIN_DIR', plugin_dir_path(__FILE__));
    define('ST_PLUGIN_URL', plugin_dir_url(__FILE__));
    define('ST_PLUGIN_BASENAME', plugin_basename(__FILE__));
    
    // 初始化插件
    require_once ST_PLUGIN_DIR . 'includes/class-shipment-tracker.php';
    
    function run_shipment_tracker() {
        $plugin = new Shipment_Tracker();
        $plugin->run();
    }
    run_shipment_tracker();

    在includes目录下创建核心类文件class-shipment-tracker.php:

    <?php
    class Shipment_Tracker {
        
        private $loader;
        
        public function __construct() {
            $this->load_dependencies();
            $this->define_admin_hooks();
            $this->define_public_hooks();
        }
        
        private function load_dependencies() {
            require_once ST_PLUGIN_DIR . 'includes/class-api-handler.php';
            require_once ST_PLUGIN_DIR . 'includes/class-database-handler.php';
            require_once ST_PLUGIN_DIR . 'includes/class-shortcode-handler.php';
            require_once ST_PLUGIN_DIR . 'includes/class-admin-settings.php';
        }
        
        private function define_admin_hooks() {
            // 管理员相关钩子
            $admin_settings = new Admin_Settings();
            add_action('admin_menu', array($admin_settings, 'add_admin_menu'));
            add_action('admin_init', array($admin_settings, 'register_settings'));
        }
        
        private function define_public_hooks() {
            // 前端相关钩子
            $shortcode_handler = new Shortcode_Handler();
            add_shortcode('track_shipment', array($shortcode_handler, 'render_tracking_form'));
            add_shortcode('shipment_map', array($shortcode_handler, 'render_tracking_map'));
            
            // 添加前端脚本和样式
            add_action('wp_enqueue_scripts', array($this, 'enqueue_public_scripts'));
        }
        
        public function enqueue_public_scripts() {
            wp_enqueue_style('shipment-tracker-style', ST_PLUGIN_URL . 'assets/css/public.css', array(), ST_VERSION);
            wp_enqueue_script('shipment-tracker-script', ST_PLUGIN_URL . 'assets/js/public.js', array('jquery'), ST_VERSION, true);
            
            // 本地化脚本,传递数据到JavaScript
            wp_localize_script('shipment-tracker-script', 'st_ajax', array(
                'ajax_url' => admin_url('admin-ajax.php'),
                'nonce' => wp_create_nonce('st_nonce')
            ));
        }
        
        public function run() {
            // 插件运行入口
        }
    }

    物流跟踪数据需要适当的数据库结构来存储。我们将创建自定义数据库表来存储物流查询结果,减少对API的重复调用:

    // 在class-database-handler.php中
    class Database_Handler {
        
        public function create_tables() {
            global $wpdb;
            
            $table_name = $wpdb->prefix . 'shipment_tracking';
            $charset_collate = $wpdb->get_charset_collate();
            
            $sql = "CREATE TABLE IF NOT EXISTS $table_name (
                id mediumint(9) NOT NULL AUTO_INCREMENT,
                order_id varchar(50) NOT NULL,
                tracking_number varchar(100) NOT NULL,
                carrier_code varchar(50) NOT NULL,
                status varchar(50) DEFAULT '',
                last_update datetime DEFAULT CURRENT_TIMESTAMP,
                raw_data longtext,
                PRIMARY KEY (id),
                INDEX tracking_idx (tracking_number, carrier_code)
            ) $charset_collate;";
            
            require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
            dbDelta($sql);
        }
        
        public function get_tracking_data($tracking_number, $carrier_code) {
            global $wpdb;
            $table_name = $wpdb->prefix . 'shipment_tracking';
            
            return $wpdb->get_row($wpdb->prepare(
                "SELECT * FROM $table_name WHERE tracking_number = %s AND carrier_code = %s",
                $tracking_number,
                $carrier_code
            ));
        }
        
        public function update_tracking_data($data) {
            global $wpdb;
            $table_name = $wpdb->prefix . 'shipment_tracking';
            
            // 检查记录是否存在
            $existing = $this->get_tracking_data($data['tracking_number'], $data['carrier_code']);
            
            if ($existing) {
                // 更新现有记录
                return $wpdb->update(
                    $table_name,
                    array(
                        'status' => $data['status'],
                        'last_update' => current_time('mysql'),
                        'raw_data' => maybe_serialize($data['raw_data'])
                    ),
                    array('id' => $existing->id)
                );
            } else {
                // 插入新记录
                return $wpdb->insert(
                    $table_name,
                    array(
                        'order_id' => $data['order_id'],
                        'tracking_number' => $data['tracking_number'],
                        'carrier_code' => $data['carrier_code'],
                        'status' => $data['status'],
                        'last_update' => current_time('mysql'),
                        'raw_data' => maybe_serialize($data['raw_data'])
                    )
                );
            }
        }
    }

    API处理类负责与物流API进行通信,处理请求和响应。我们创建一个独立的类来处理这些逻辑:

    <?php
    class API_Handler {
        
        private $api_key;
        private $api_secret;
        private $api_url = 'https://api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspx';
        
        public function __construct() {
            $options = get_option('st_settings');
            $this->api_key = isset($options['api_key']) ? $options['api_key'] : '';
            $this->api_secret = isset($options['api_secret']) ? $options['api_secret'] : '';
        }
        
        public function track_shipment($tracking_number, $carrier_code) {
            // 首先检查本地数据库是否有缓存数据
            $db_handler = new Database_Handler();
            $cached_data = $db_handler->get_tracking_data($tracking_number, $carrier_code);
            
            // 如果缓存数据在1小时内更新过,直接返回
            if ($cached_data && strtotime($cached_data->last_update) > time() - 3600) {
                return maybe_unserialize($cached_data->raw_data);
            }
            
            // 否则调用API
            $request_data = array(
                'OrderCode' => '',
                'ShipperCode' => $carrier_code,
                'LogisticCode' => $tracking_number
            );
            
            $data_json = json_encode($request_data);
            $datasign = $this->encrypt($data_json, $this->api_secret);
            
            $post_data = array(
                'RequestData' => urlencode($data_json),
                'EBusinessID' => $this->api_key,
                'RequestType' => '1002',
                'DataSign' => urlencode($datasign),
                'DataType' => '2'
            );
            
            $response = $this->send_request($this->api_url, $post_data);
            
            if ($response && isset($response['Success']) && $response['Success']) {
                // 保存到数据库
                $db_handler->update_tracking_data(array(
                    'tracking_number' => $tracking_number,
                    'carrier_code' => $carrier_code,
                    'status' => $response['State'] ?? '',
                    'raw_data' => $response
                ));
                
                return $response;
            }
            
            return false;
        }
        
        private function send_request($url, $data) {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($ch, CURLOPT_TIMEOUT, 30);
            
            $response = curl_exec($ch);
            curl_close($ch);
            
            return json_decode($response, true);
        }
        
        private function encrypt($data, $app_key) {
            return urlencode(base64_encode(md5($data . $app_key)));
        }
        
        public function get_carriers() {
            // 获取支持的快递公司列表
            $carriers = array(
                'SF' => '顺丰速运',
                'HTKY' => '百世快递',
                'ZTO' => '中通快递',
                'STO' => '申通快递',
                'YTO' => '圆通速递',
                'YD' => '韵达速递',
                'YZPY' => '邮政快递包裹',
                'EMS' => 'EMS',
                'HHTT' => '天天快递',
                'JD' => '京东物流'
            );
            
            return apply_filters('st_available_carriers', $carriers);
        }
    }

    健壮的API集成需要完善的错误处理机制。我们添加错误处理和日志记录功能:

    class Logger {
        
        public static function log($message, $level = 'info') {
            if (!defined('WP_DEBUG') || !WP_DEBUG) {
                return;
            }
            
            $log_dir = ST_PLUGIN_DIR . 'logs/';
            
            // 确保日志目录存在
            if (!file_exists($log_dir)) {
                wp_mkdir_p($log_dir);
            }
            
            $log_file = $log_dir . 'shipment-tracker-' . date('Y-m-d') . '.log';
            $timestamp = current_time('mysql');
            $log_message = "[$timestamp] [$level] $message" . PHP_EOL;
            
            file_put_contents($log_file, $log_message, FILE_APPEND);
        }
        
        public static function log_api_error($tracking_number, $carrier_code, $error) {
            $message = sprintf(
                'API查询失败 - 运单号: %s, 快递公司: %s, 错误: %s',
                $tracking_number,
                $carrier_code,
                $error
            );
            self::log($message, 'error');
        }
    }
    
    // 在API_Handler类中添加错误处理
    public function track_shipment($tracking_number, $carrier_code) {
        try {
            // ... 原有代码 ...
        } catch (Exception $e) {
            Logger::log_api_error($tracking_number, $carrier_code, $e->getMessage());
            return false;
        }
    }

    短代码是WordPress中在前端嵌入功能的便捷方式。我们创建跟踪表单短代码:

    class Shortcode_Handler {
        
        public function render_tracking_form($atts) {
            $atts = shortcode_atts(array(
                'title' => '物流跟踪查询',
                'button_text' => '查询'
            ), $atts, 'track_shipment');
            
            ob_start();
            ?>
            <div class="shipment-tracker-form">
                <h3><?php echo esc_html($atts['title']); ?></h3>
                <form id="st-tracking-form" method="post">
                    <?php wp_nonce_field('st_tracking_action', 'st_tracking_nonce'); ?>
                    <div class="form-group">
                        <label for="tracking_number">运单号:</label>
                        <input type="text" id="tracking_number" name="tracking_number" required>
                    </div>
                    <div class="form-group">
                        <label for="carrier_code">快递公司:</label>
                        <select id="carrier_code" name="carrier_code" required>
                            <option value="">请选择快递公司</option>
                            <?php
                            $api_handler = new API_Handler();
                            $carriers = $api_handler->get_carriers();
                            foreach ($carriers as $code => $name) {
                                echo '<option value="' . esc_attr($code) . '">' . esc_html($name) . '</option>';
                            }
                            ?>
                        </select>
                    </div>
                    <div class="form-group">
                        <button type="submit"><?php echo esc_html($atts['button_text']); ?></button>
                    </div>
                </form>
                <div id="st-tracking-result"></div>
            </div>
            <?php
            return ob_get_clean();
        }
    }

    地图展示是物流跟踪的亮点功能。我们使用Leaflet.js,这是一个开源的移动友好交互地图库:

    public function render_tracking_map($atts) {
        $atts = shortcode_atts(array(
            'height' => '400px',
            'width' => '100%'
        ), $atts, 'shipment_map');
        
        wp_enqueue_script('leaflet', 'https://unpkg.com/leaflet@1.7.1/dist/leaflet.js', array(), '1.7.1');
        wp_enqueue_style('leaflet-css', 'https://unpkg.com/leaflet@1.7.1/dist/leaflet.css', array(), '1.7.1');
        
        ob_start();
        ?>
        <div id="shipment-map" style="height: <?php echo esc_attr($atts['height']); ?>; width: <?php echo esc_attr($atts['width']); ?>;"></div>
        <script>
        jQuery(document).ready(function($) {
            // 初始化地图
            var map = L.map('shipment-map').setView([39.9042, 116.4074], 5); // 默认北京中心
            
            // 添加地图图层
            L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
                attribution: '© OpenStreetMap contributors'
            }).addTo(map);
            
            // 如果有跟踪数据,显示路径
            <?php if (isset($_GET['tracking_data'])) : ?>
            var trackingData = <?php echo json_encode($_GET['tracking_data']); ?>;
            displayTrackingPath(map, trackingData);
            <?php endif; ?>
            
            function displayTrackingPath(map, data) {
            var path = [];
            var markers = [];
            
            // 处理轨迹点
            if (data.Traces && data.Traces.length > 0) {
                data.Traces.forEach(function(trace, index) {
                    // 这里需要根据实际API返回的地址信息转换为坐标
                    // 实际应用中可能需要地理编码服务
                    var coords = geocodeAddress(trace.AcceptStation);
                    
                    if (coords) {
                        path.push(coords);
                        
                        // 添加标记点
                        var marker = L.marker(coords)
                            .bindPopup('<b>' + trace.AcceptTime + '</b><br>' + trace.AcceptStation)
                            .addTo(map);
                        
                        markers.push(marker);
                        
                        // 如果是第一个或最后一个点,特别标记
                        if (index === 0) {
                            marker.setIcon(L.icon({
                                iconUrl: '<?php echo ST_PLUGIN_URL; ?>assets/images/start-marker.png',
                                iconSize: [32, 32]
                            }));
                        } else if (index === data.Traces.length - 1) {
                            marker.setIcon(L.icon({
                                iconUrl: '<?php echo ST_PLUGIN_URL; ?>assets/images/end-marker.png',
                                iconSize: [32, 32]
                            }));
                        }
                    }
                });
                
                // 绘制路径线
                if (path.length > 1) {
                    var polyline = L.polyline(path, {
                        color: '#3498db',
                        weight: 3,
                        opacity: 0.7
                    }).addTo(map);
                    
                    // 调整地图视野以显示完整路径
                    map.fitBounds(polyline.getBounds());
                }
            }
        }
        
        // 简化的地理编码函数(实际应用中应使用专业地理编码服务)
        function geocodeAddress(address) {
            // 这里应调用地理编码API
            // 为示例目的,返回随机坐标
            return [
                39.9042 + (Math.random() - 0.5) * 10,
                116.4074 + (Math.random() - 0.5) * 10
            ];
        }
    });
    </script>
    <?php
    return ob_get_clean();

    }

    
    #### 4.3 AJAX交互实现
    
    为了实现无需页面刷新的查询体验,我们添加AJAX处理功能:
    

    // 在Shortcode_Handler类中添加AJAX处理方法
    public function register_ajax_handlers() {

    add_action('wp_ajax_st_track_shipment', array($this, 'handle_tracking_request'));
    add_action('wp_ajax_nopriv_st_track_shipment', array($this, 'handle_tracking_request'));

    }

    public function handle_tracking_request() {

    // 验证nonce
    if (!wp_verify_nonce($_POST['nonce'], 'st_nonce')) {
        wp_die('安全验证失败');
    }
    
    $tracking_number = sanitize_text_field($_POST['tracking_number']);
    $carrier_code = sanitize_text_field($_POST['carrier_code']);
    
    $api_handler = new API_Handler();
    $result = $api_handler->track_shipment($tracking_number, $carrier_code);
    
    if ($result) {
        wp_send_json_success(array(
            'data' => $result,
            'html' => $this->generate_tracking_html($result)
        ));
    } else {
        wp_send_json_error('查询失败,请检查运单号和快递公司是否正确');
    }

    }

    private function generate_tracking_html($data) {

    ob_start();
    ?>
    <div class="tracking-result">
        <div class="tracking-header">
            <h4>物流跟踪信息</h4>
            <div class="tracking-status">
                状态:<span class="status-badge status-<?php echo esc_attr(strtolower($data['State'] ?? '')); ?>">
                    <?php echo $this->get_status_text($data['State'] ?? ''); ?>
                </span>
            </div>
        </div>
        
        <div class="tracking-timeline">
            <?php if (!empty($data['Traces'])) : ?>
                <?php foreach (array_reverse($data['Traces']) as $trace) : ?>
                <div class="timeline-item">
                    <div class="timeline-dot"></div>
                    <div class="timeline-content">
                        <div class="timeline-time"><?php echo esc_html($trace['AcceptTime']); ?></div>
                        <div class="timeline-desc"><?php echo esc_html($trace['AcceptStation']); ?></div>
                    </div>
                </div>
                <?php endforeach; ?>
            <?php else : ?>
                <p>暂无物流信息</p>
            <?php endif; ?>
        </div>
        
        <div class="tracking-actions">
            <button class="view-map-btn" data-tracking='<?php echo json_encode($data); ?>'>
                查看运输路径地图
            </button>
        </div>
    </div>
    <?php
    return ob_get_clean();

    }

    
    ### 第五章:后台管理与设置
    
    #### 5.1 创建设置页面
    
    为插件创建专业的设置页面,让管理员可以配置API密钥和其他选项:
    

    class Admin_Settings {

    
    public function add_admin_menu() {
        add_menu_page(
            '物流跟踪设置',
            '物流跟踪',
            'manage_options',
            'shipment-tracker',
            array($this, 'render_settings_page'),
            'dashicons-location-alt',
            30
        );
        
        add_submenu_page(
            'shipment-tracker',
            'API设置',
            'API设置',
            'manage_options',
            'shipment-tracker-api',
            array($this, 'render_api_settings_page')
        );
        
        add_submenu_page(
            'shipment-tracker',
            '查询记录',
            '查询记录',
            'manage_options',
            'shipment-tracker-logs',
            array($this, 'render_logs_page')
        );
    }
    
    public function register_settings() {
        register_setting('st_settings_group', 'st_settings');
        
        add_settings_section(
            'st_api_section',
            'API配置',
            array($this, 'render_api_section'),
            'shipment-tracker-api'
        );
        
        add_settings_field(
            'api_key',
            'API Key',
            array($this, 'render_api_key_field'),
            'shipment-tracker-api',
            'st_api_section'
        );
        
        add_settings_field(
            'api_secret',
            'API Secret',
            array($this, 'render_api_secret_field'),
            'shipment-tracker-api',
            'st_api_section'
        );
    }
    
    public function render_settings_page() {
        ?>
        <div class="wrap">
            <h1>物流跟踪设置</h1>
            <div class="st-admin-container">
                <div class="st-admin-card">
                    <h2>插件使用说明</h2>
                    <p>1. 在<a href="<?php echo admin_url('admin.php?page=shipment-tracker-api'); ?>">API设置</a>页面配置您的物流API密钥</p>
                    <p>2. 使用短代码在页面中插入跟踪表单:<code>[track_shipment]</code></p>
                    <p>3. 使用短代码插入地图展示:<code>[shipment_map]</code></p>
                    <p>4. 可选参数:<code>[track_shipment title="我的标题" button_text="查询物流"]</code></p>
                </div>
                
                <div class="st-admin-card">
                    <h2>统计信息</h2>
                    <?php
                    global $wpdb;
                    $table_name = $wpdb->prefix . 'shipment_tracking';
                    $total_queries = $wpdb->get_var("SELECT COUNT(*) FROM $table_name");
                    $today_queries = $wpdb->get_var($wpdb->prepare(
                        "SELECT COUNT(*) FROM $table_name WHERE DATE(last_update) = %s",
                        current_time('Y-m-d')
                    ));
                    ?>
                    <p>总查询次数:<?php echo $total_queries; ?></p>
                    <p>今日查询:<?php echo $today_queries; ?></p>
                </div>
            </div>
        </div>
        <?php
    }
    
    public function render_api_settings_page() {
        ?>
        <div class="wrap">
            <h1>API设置</h1>
            <form method="post" action="options.php">
                <?php
                settings_fields('st_settings_group');
                do_settings_sections('shipment-tracker-api');
                submit_button();
                ?>
            </form>
            
            <div class="st-api-test">
                <h3>API连接测试</h3>
                <input type="text" id="test-tracking-number" placeholder="测试运单号">
                <select id="test-carrier-code">
                    <option value="">选择快递公司</option>
                    <?php
                    $api_handler = new API_Handler();
                    $carriers = $api_handler->get_carriers();
                    foreach ($carriers as $code => $name) {
                        echo '<option value="' . esc_attr($code) . '">' . esc_html($name) . '</option>';
                    }
                    ?>
                </select>
                <button id="test-api-btn" class="button">测试连接</button>
                <div id="test-result"></div>
            </div>
        </div>
        <?php
    }
    
    public function render_logs_page() {
        ?>
        <div class="wrap">
            <h1>查询记录</h1>
            <?php
            $this->render_logs_table();
            ?>
        </div>
        <?php
    }
    
    private function render_logs_table() {
        global $wpdb;
        $table_name = $wpdb->prefix . 'shipment_tracking';
        
        // 分页逻辑
        $per_page = 20;
        $current_page = isset($_GET['paged']) ? max(1, intval($_GET['paged'])) : 1;
        $offset = ($current_page - 1) * $per_page;
        
        $total_items = $wpdb->get_var("SELECT COUNT(*) FROM $table_name");
        $logs = $wpdb->get_results(
            $wpdb->prepare(
                "SELECT * FROM $table_name ORDER BY last_update DESC LIMIT %d OFFSET %d",
                $per_page,
                $offset
            )
        );
        ?>
        <table class="wp-list-table widefat fixed striped">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>运单号</th>
                    <th>快递公司</th>
                    <th>状态</th>
                    <th>最后更新</th>
                    <th>操作</th>
                </tr>
            </thead>
            <tbody>
                <?php if (empty($logs)) : ?>
                <tr>
                    <td colspan="6">暂无查询记录</td>
                </tr>
                <?php else : ?>
                <?php foreach ($logs as $log) : ?>
                <tr>
                    <td><?php echo $log->id; ?></td>
                    <td><?php echo esc_html($log->tracking_number); ?></td>
                    <td><?php echo esc_html($log->carrier_code); ?></td>
                    <td>
                        <span class="status-badge status-<?php echo strtolower($log->status); ?>">
                            <?php echo $this->get_status_text($log->status); ?>
                        </span>
                    </td>
                    <td><?php echo $log->last_update; ?></td>
                    <td>
                        <button class="button view-log-details" data-log-id="<?php echo $log->id; ?>">
                            查看详情
                        </button>
                    </td>
                </tr>
                <?php endforeach; ?>
                <?php endif; ?>
            </tbody>
        </table>
        
        <div class="tablenav bottom">
            <div class="tablenav-pages">
                <?php
                $total_pages = ceil($total_items / $per_page);
                echo paginate_links(array(
                    'base' => add_query_arg('paged', '%#%'),
                    'format' => '',
                    'prev_text' => '&laquo;',
                    'next_text' => '&raquo;',
                    'total' => $total_pages,
                    'current' => $current_page
                ));
                ?>
            </div>
        </div>
        <?php
    }

    }

    
    #### 5.2 添加管理员通知和帮助标签
    

    public function add_admin_notices() {

    $options = get_option('st_settings');
    
    if (empty($options['api_key']) || empty($options['api_secret'])) {
        ?>
        <div class="notice notice-warning">
            <p>物流跟踪插件需要配置API密钥才能正常工作。请前往<a href="<?php echo admin_url('admin.php?page=shipment-tracker-api'); ?>">设置页面</a>进行配置。</p>
        </div>
        <?php
    }

    }

    public function add_help_tab() {

    $screen = get_current_screen();
    
    if ($screen->id === 'toplevel_page_shipment-tracker') {
        $screen->add_help_tab(array(
            'id' => 'st_help_tab',
            'title' => '使用帮助',
            'content' => '
                <h3>物流跟踪插件使用指南</h3>
                <p><strong>1. 配置API</strong><br>
                首先需要在API设置页面填写从快递鸟或其他物流API服务商获取的API密钥。</p>
                
                <p><strong>2. 插入短代码</strong><br>
                在文章或页面中使用以下短代码:<br>
                - 跟踪表单:<code>[track_shipment]</code><br>
                - 地图展示:<code>[shipment_map]</code></p>
                
                <p><strong>3. 自定义样式</strong><br>
                可以通过CSS自定义插件外观,样式文件位于:<code>/wp-content/plugins/shipment-tracker/assets/css/</code></p>
            '
        ));
    }

    }

    
    ### 第六章:样式优化与响应式设计
    
    #### 6.1 创建CSS样式文件
    
    在assets/css目录下创建public.css文件:
    

    / 物流跟踪插件样式 /
    .shipment-tracker-form {

    max-width: 600px;
    margin: 20px auto;
    padding: 30px;
    background: #f8f9fa;
    border-radius: 8px;
    box-shadow: 0 2px 10px rgba(0,0,0,0.1);

    }

    .shipment-tracker-form h3 {

    margin-top: 0;
    color: #333;
    border-bottom: 2px solid #3498db;
    padding-bottom: 10px;

    }

    .form-group {

    margin-bottom: 20px;

    }

    .form-group label {

    display: block;
    margin-bottom: 5px;
    font-weight: 600;
    color: #555;

    }

    .form-group input[type="text"],
    .form-group select {

    width: 100%;
    padding: 10px;
    border: 1px solid #ddd;
    border-radius: 4px;
    font-size: 14px;
    transition: border-color 0.3s;

    }

    .form-group input[type="text"]:focus,
    .form-group select:focus {

    outline: none;
    border-color: #3498db;
    box-shadow: 0 0 0 2px rgba(52,152,219,0.2);

    }

    .form-group button {

    background: #3498db;
    color: white;
    border: none;
    padding: 12px 30px;
    border-radius: 4px;
    cursor: pointer;
    font-size: 16px;
    transition: background 0.3s;

    }

    .form-group button:hover {

    background: #2980b9;

    }

    / 跟踪结果样式 /
    .tracking-result {

    margin-top: 30px;
    padding: 20px;
    background: white;
    border-radius: 6px;
    box-shadow: 0 1px 3px rgba(0,0,0,0.1);

    }

    .tracking-header {

    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;
    padding-bottom: 15px;
    border-bottom: 1px solid #eee;

    }

    .status-badge {

    display: inline-block;
    padding: 4px 12px;
    border-radius: 20px;
    font-size: 12px;
    font-weight: 600;

    }

    .status-2 { background: #2ecc71; color: white; } / 已签收 /
    .status-3 { background: #e74c3c; color: white; } / 问题件 /
    .status-1 { background: #3498db; color: white; } / 运输中 /
    .status-0 { background: #95a5a6; color: white; } / 无信息 /

    / 时间线样式 /
    .tracking-timeline {

    position: relative;
    padding-left: 30px;

    }

    .tracking-timeline::before {

    content: '';
    position: absolute;
    left: 10px;
    top: 0;
    bottom: 0;
    width: 2px;
    background: #3498db;

    }

    .timeline-item {

    position: relative;
    margin-bottom: 20px;

    }

    .timeline-dot {

    position: absolute;
    left: -25px;
    top: 5px;
    width: 12px;
    height: 12px;
    background: white;
    border: 2px solid #3498db;
    border-radius: 50%;

    }

    .timeline-content {

    padding: 10px;
    background: #f8f9fa;
    border-radius: 4px;

    }

    .timeline-time {

    font-weight: 600;
    color: #2c3e50;
    margin-bottom: 5px;

    }

    .timeline-desc {

    color: #555;
    line-height: 1.5;

    }

    / 地图容器 /

    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0

    本文来自网络投稿,不代表本站点的立场,转载请注明出处:https://01.vip.exchanges.center/5206.html

    溯源库®作者

    漳州柔性供应链服务有限公司 小批量订单定制化服务商( 投稿邮箱:vip@jiaochengku.com)
    上一篇
    下一篇

    为您推荐

    联系我们

    联系我们

    18559313275

    在线咨询: QQ交谈

    邮箱: vip@jiaochengku.com

    工作时间:周一至周五,9:00-17:30,节假日休息
    关注微信
    微信扫一扫关注我们

    微信扫一扫关注我们

    返回顶部