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

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

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

引言:WordPress的无限扩展可能

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

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

第一章:准备工作与环境配置

1.1 开发环境搭建

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

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

1.2 WordPress开发基础

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

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

1.3 选择快递物流API

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

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

第二章:创建物流跟踪插件框架

2.1 插件基础结构

首先创建插件目录和主文件。在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();

2.2 创建核心类

在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() {
        // 插件运行入口
    }
}

2.3 数据库设计

物流跟踪数据需要适当的数据库结构来存储。我们将创建自定义数据库表来存储物流查询结果,减少对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

3.1 API处理类设计

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);
    }
}

3.2 错误处理与日志记录

健壮的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;
    }
}

第四章:前端展示与地图集成

4.1 创建跟踪表单短代码

短代码是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();
    }
}

4.2 集成地图展示功能

地图展示是物流跟踪的亮点功能。我们使用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;

}

/ 地图容器 /

shipment-map {

border-radius: 8px;
overflow: hidden;
box-shadow: 0
本文来自网络,不代表柔性供应链服务中心立场,转载请注明出处:https://mall.org.cn/5206.html

EXCHANGES®作者

上一篇
下一篇

为您推荐

发表回复

联系我们

联系我们

18559313275

在线咨询: QQ交谈

邮箱: vip@exchanges.center

工作时间:周一至周五,9:00-17:30,节假日休息
返回顶部