首页 / 应用软件 / WordPress集成教程,连接公共交通API实现实时到站信息查询与展示

WordPress集成教程,连接公共交通API实现实时到站信息查询与展示

WordPress集成教程:连接公共交通API实现实时到站信息查询与展示

引言:为什么要在WordPress中集成公共交通信息?

在当今快节奏的城市生活中,实时公共交通信息已成为人们日常出行的重要参考。对于地方新闻网站、旅游博客、社区门户或企业网站而言,提供实时公交/地铁到站信息可以显著提升用户体验和网站实用性。WordPress作为全球最流行的内容管理系统,通过代码二次开发可以轻松集成这类实用功能。

本教程将详细指导您如何通过WordPress程序代码二次开发,连接公共交通API实现实时到站信息查询与展示功能。我们将从API选择、开发环境搭建、功能实现到前端展示,一步步构建一个完整的解决方案。

第一部分:准备工作与环境搭建

1.1 选择合适的公共交通API

在选择API前,需要考虑以下因素:

  • 覆盖区域:确保API覆盖您需要的城市或地区
  • 数据准确性:实时更新的频率和数据可靠性
  • 成本:免费还是付费,调用限制如何
  • 文档完整性:是否有完善的开发文档和示例

常用公共交通API推荐:

  1. TransitLand:覆盖全球多个城市的公共交通数据,提供丰富的API接口
  2. Google Maps Transit API:集成在Google Maps平台中,数据全面但可能有使用限制
  3. 本地交通部门API:许多城市的交通部门提供官方API,数据最权威
  4. Moovit API:提供全球范围内的公共交通数据

本教程将以一个模拟的公共交通API为例进行演示,实际应用中您需要替换为真实的API接口。

1.2 开发环境配置

在开始开发前,请确保您的WordPress环境满足以下条件:

  1. WordPress版本:5.0或更高版本
  2. PHP版本:7.4或更高版本
  3. 必要的插件

    • Advanced Custom Fields(可选,用于创建管理界面)
    • 缓存插件(如WP Rocket或W3 Total Cache)
  4. 代码编辑器:VS Code、PHPStorm或Sublime Text
  5. 本地开发环境:XAMPP、MAMP或Local by Flywheel

1.3 创建自定义插件

为了避免主题更新导致功能丢失,我们将创建一个独立插件来实现功能:

<?php
/**
 * Plugin Name: 公共交通实时信息查询
 * Plugin URI: https://yourwebsite.com/
 * Description: 在WordPress中集成公共交通API,显示实时到站信息
 * Version: 1.0.0
 * Author: 您的名称
 * License: GPL v2 or later
 */

// 防止直接访问
if (!defined('ABSPATH')) {
    exit;
}

// 定义插件常量
define('PT_API_PLUGIN_PATH', plugin_dir_path(__FILE__));
define('PT_API_PLUGIN_URL', plugin_dir_url(__FILE__));
define('PT_API_CACHE_TIME', 300); // 缓存时间5分钟

// 初始化插件
require_once PT_API_PLUGIN_PATH . 'includes/class-public-transport-api.php';
require_once PT_API_PLUGIN_PATH . 'includes/class-api-handler.php';
require_once PT_API_PLUGIN_PATH . 'includes/class-shortcode-handler.php';
require_once PT_API_PLUGIN_PATH . 'includes/class-admin-settings.php';

// 初始化主类
function pt_api_init() {
    $plugin = new Public_Transport_API();
    $plugin->run();
}
add_action('plugins_loaded', 'pt_api_init');

第二部分:API连接与数据处理

2.1 创建API处理类

<?php
// includes/class-api-handler.php

class PT_API_Handler {
    
    private $api_key;
    private $api_endpoint;
    private $cache_enabled;
    
    public function __construct() {
        // 从设置中获取API配置
        $options = get_option('pt_api_settings');
        $this->api_key = isset($options['api_key']) ? $options['api_key'] : '';
        $this->api_endpoint = isset($options['api_endpoint']) ? $options['api_endpoint'] : 'https://api.example.com/transit';
        $this->cache_enabled = isset($options['enable_cache']) ? $options['enable_cache'] : true;
    }
    
    /**
     * 获取公交线路信息
     */
    public function get_bus_routes($city = '') {
        $cache_key = 'pt_bus_routes_' . md5($city);
        
        // 检查缓存
        if ($this->cache_enabled) {
            $cached_data = get_transient($cache_key);
            if ($cached_data !== false) {
                return $cached_data;
            }
        }
        
        // 构建API请求URL
        $url = $this->api_endpoint . '/routes';
        if (!empty($city)) {
            $url .= '?city=' . urlencode($city);
        }
        
        // 发送API请求
        $response = $this->make_api_request($url);
        
        if ($response && isset($response['routes'])) {
            // 缓存结果
            if ($this->cache_enabled) {
                set_transient($cache_key, $response['routes'], PT_API_CACHE_TIME);
            }
            return $response['routes'];
        }
        
        return false;
    }
    
    /**
     * 获取实时到站信息
     */
    public function get_realtime_arrivals($route_id, $stop_id) {
        $cache_key = 'pt_arrivals_' . md5($route_id . $stop_id);
        
        // 实时数据缓存时间较短
        if ($this->cache_enabled) {
            $cached_data = get_transient($cache_key);
            if ($cached_data !== false) {
                return $cached_data;
            }
        }
        
        // 构建API请求URL
        $url = $this->api_endpoint . '/realtime/arrivals';
        $url .= '?route=' . urlencode($route_id);
        $url .= '&stop=' . urlencode($stop_id);
        
        // 发送API请求
        $response = $this->make_api_request($url);
        
        if ($response && isset($response['arrivals'])) {
            // 实时数据只缓存1分钟
            if ($this->cache_enabled) {
                set_transient($cache_key, $response['arrivals'], 60);
            }
            return $response['arrivals'];
        }
        
        return false;
    }
    
    /**
     * 搜索公交站点
     */
    public function search_stops($query, $city = '') {
        $cache_key = 'pt_stops_search_' . md5($query . $city);
        
        if ($this->cache_enabled) {
            $cached_data = get_transient($cache_key);
            if ($cached_data !== false) {
                return $cached_data;
            }
        }
        
        // 构建API请求URL
        $url = $this->api_endpoint . '/stops/search';
        $url .= '?q=' . urlencode($query);
        if (!empty($city)) {
            $url .= '&city=' . urlencode($city);
        }
        
        // 发送API请求
        $response = $this->make_api_request($url);
        
        if ($response && isset($response['stops'])) {
            if ($this->cache_enabled) {
                set_transient($cache_key, $response['stops'], PT_API_CACHE_TIME);
            }
            return $response['stops'];
        }
        
        return false;
    }
    
    /**
     * 发送API请求
     */
    private function make_api_request($url) {
        // 添加API密钥
        $url .= (strpos($url, '?') === false ? '?' : '&') . 'api_key=' . $this->api_key;
        
        // 设置请求参数
        $args = array(
            'timeout'     => 15,
            'redirection' => 5,
            'httpversion' => '1.1',
            'user-agent'  => 'WordPress Public Transport Plugin/1.0',
            'headers'     => array(
                'Accept' => 'application/json',
            ),
        );
        
        // 发送请求
        $response = wp_remote_get($url, $args);
        
        // 检查响应
        if (is_wp_error($response)) {
            error_log('公共交通API请求错误: ' . $response->get_error_message());
            return false;
        }
        
        $body = wp_remote_retrieve_body($response);
        $data = json_decode($body, true);
        
        // 检查JSON解析
        if (json_last_error() !== JSON_ERROR_NONE) {
            error_log('公共交通API JSON解析错误: ' . json_last_error_msg());
            return false;
        }
        
        // 检查API返回的错误
        if (isset($data['error'])) {
            error_log('公共交通API错误: ' . $data['error']['message']);
            return false;
        }
        
        return $data;
    }
    
    /**
     * 获取支持的城市列表
     */
    public function get_supported_cities() {
        $cache_key = 'pt_supported_cities';
        
        if ($this->cache_enabled) {
            $cached_data = get_transient($cache_key);
            if ($cached_data !== false) {
                return $cached_data;
            }
        }
        
        $url = $this->api_endpoint . '/cities';
        $response = $this->make_api_request($url);
        
        if ($response && isset($response['cities'])) {
            if ($this->cache_enabled) {
                set_transient($cache_key, $response['cities'], 24 * HOUR_IN_SECONDS);
            }
            return $response['cities'];
        }
        
        // 返回默认城市列表
        return array(
            array('id' => 'beijing', 'name' => '北京'),
            array('id' => 'shanghai', 'name' => '上海'),
            array('id' => 'guangzhou', 'name' => '广州'),
            array('id' => 'shenzhen', 'name' => '深圳'),
        );
    }
}

2.2 创建短代码处理器

<?php
// includes/class-shortcode-handler.php

class PT_Shortcode_Handler {
    
    private $api_handler;
    
    public function __construct() {
        $this->api_handler = new PT_API_Handler();
        
        // 注册短代码
        add_shortcode('bus_arrivals', array($this, 'render_arrivals_shortcode'));
        add_shortcode('bus_route_search', array($this, 'render_search_shortcode'));
        add_shortcode('bus_stop_info', array($this, 'render_stop_info_shortcode'));
        
        // 注册AJAX处理
        add_action('wp_ajax_pt_search_stops', array($this, 'ajax_search_stops'));
        add_action('wp_ajax_nopriv_pt_search_stops', array($this, 'ajax_search_stops'));
        
        add_action('wp_ajax_pt_get_arrivals', array($this, 'ajax_get_arrivals'));
        add_action('wp_ajax_nopriv_pt_get_arrivals', array($this, 'ajax_get_arrivals'));
    }
    
    /**
     * 渲染实时到站信息短代码
     */
    public function render_arrivals_shortcode($atts) {
        // 解析短代码属性
        $atts = shortcode_atts(array(
            'route' => '',
            'stop' => '',
            'title' => '实时到站信息',
            'max_results' => 5,
            'show_refresh' => true,
            'city' => '',
        ), $atts, 'bus_arrivals');
        
        // 生成唯一ID
        $container_id = 'pt-arrivals-' . uniqid();
        
        // 如果提供了route和stop,直接加载数据
        $initial_data = '';
        if (!empty($atts['route']) && !empty($atts['stop'])) {
            $arrivals = $this->api_handler->get_realtime_arrivals($atts['route'], $atts['stop']);
            if ($arrivals) {
                $initial_data = json_encode($arrivals);
            }
        }
        
        // 输出HTML
        ob_start();
        ?>
        <div id="<?php echo esc_attr($container_id); ?>" class="pt-arrivals-container" data-route="<?php echo esc_attr($atts['route']); ?>" data-stop="<?php echo esc_attr($atts['stop']); ?>" data-city="<?php echo esc_attr($atts['city']); ?>" data-max-results="<?php echo esc_attr($atts['max_results']); ?>">
            <div class="pt-arrivals-header">
                <h3><?php echo esc_html($atts['title']); ?></h3>
                <?php if ($atts['show_refresh']) : ?>
                <button class="pt-refresh-btn" onclick="ptRefreshArrivals('<?php echo esc_js($container_id); ?>')">
                    <span class="dashicons dashicons-update"></span> 刷新
                </button>
                <?php endif; ?>
            </div>
            
            <div class="pt-arrivals-body">
                <?php if (empty($atts['route']) || empty($atts['stop'])) : ?>
                <div class="pt-no-selection">
                    <p>请选择线路和站点查看实时到站信息</p>
                    <div class="pt-search-form">
                        <input type="text" class="pt-stop-search" placeholder="搜索站点..." data-target="<?php echo esc_attr($container_id); ?>">
                        <div class="pt-search-results"></div>
                    </div>
                </div>
                <?php else : ?>
                <div class="pt-arrivals-list">
                    <!-- 动态加载内容 -->
                </div>
                <?php endif; ?>
            </div>
            
            <div class="pt-arrivals-footer">
                <small>数据更新时间: <span class="pt-update-time">--:--:--</span></small>
            </div>
        </div>
        
        <?php if (!empty($initial_data)) : ?>
        <script>
        jQuery(document).ready(function($) {
            ptRenderArrivals('<?php echo esc_js($container_id); ?>', <?php echo $initial_data; ?>);
        });
        </script>
        <?php endif; ?>
        
        <?php
        return ob_get_clean();
    }
    
    /**
     * 渲染搜索短代码
     */
    public function render_search_shortcode($atts) {
        $atts = shortcode_atts(array(
            'city' => '',
            'placeholder' => '输入公交线路或站点名称...',
        ), $atts, 'bus_route_search');
        
        $container_id = 'pt-search-' . uniqid();
        
        ob_start();
        ?>
        <div id="<?php echo esc_attr($container_id); ?>" class="pt-search-container">
            <div class="pt-search-box">
                <input type="text" class="pt-global-search" placeholder="<?php echo esc_attr($atts['placeholder']); ?>" data-city="<?php echo esc_attr($atts['city']); ?>">
                <button class="pt-search-btn">
                    <span class="dashicons dashicons-search"></span>
                </button>
            </div>
            <div class="pt-search-results-container">
                <div class="pt-search-results"></div>
            </div>
        </div>
        <?php
        return ob_get_clean();
    }
    
    /**
     * AJAX搜索站点
     */
    public function ajax_search_stops() {
        // 验证nonce
        if (!check_ajax_referer('pt_ajax_nonce', 'nonce', false)) {
            wp_die('安全验证失败', 403);
        }
        
        $query = isset($_POST['query']) ? sanitize_text_field($_POST['query']) : '';
        $city = isset($_POST['city']) ? sanitize_text_field($_POST['city']) : '';
        
        if (empty($query)) {
            wp_send_json_error('请输入搜索关键词');
        }
        
        $stops = $this->api_handler->search_stops($query, $city);
        
        if ($stops) {
            wp_send_json_success($stops);
        } else {
            wp_send_json_error('未找到相关站点');
        }
    }
    
    /**
     * AJAX获取到站信息
     */
    public function ajax_get_arrivals() {
        // 验证nonce
        if (!check_ajax_referer('pt_ajax_nonce', 'nonce', false)) {
            wp_die('安全验证失败', 403);
        }
        
        $route_id = isset($_POST['route']) ? sanitize_text_field($_POST['route']) : '';
        $stop_id = isset($_POST['stop']) ? sanitize_text_field($_POST['stop']) : '';
        
        if (empty($route_id) || empty($stop_id)) {
            wp_send_json_error('缺少必要参数');
        }
        
        $arrivals = $this->api_handler->get_realtime_arrivals($route_id, $stop_id);
        
        if ($arrivals) {
            wp_send_json_success($arrivals);
        } else {
            wp_send_json_error('获取到站信息失败');
        }
    }
}

第三部分:前端展示与用户交互

3.1 添加前端样式

/* assets/css/public-transport.css */

/* 主容器样式 */
.pt-arrivals-container {
    background-color: #f8f9fa;
    border-radius: 8px;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
    padding: 20px;
    margin: 20px 0;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

/* 头部样式 */
.pt-arrivals-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;
    border-bottom: 2px solid #007cba;
    padding-bottom: 10px;
}

.pt-arrivals-header h3 {
    margin: 0;
    color: #1d2327;
    font-size: 1.5em;
}

.pt-refresh-btn {
    background-color: #007cba;

color: white;

border: none;
border-radius: 4px;
padding: 8px 16px;
cursor: pointer;
font-size: 14px;
display: flex;
align-items: center;
gap: 5px;
transition: background-color 0.3s;

}

.pt-refresh-btn:hover {

background-color: #005a87;

}

.pt-refresh-btn .dashicons {

font-size: 16px;
width: 16px;
height: 16px;

}

/ 到站信息列表 /
.pt-arrivals-list {

min-height: 200px;

}

.pt-arrival-item {

background: white;
border-radius: 6px;
padding: 15px;
margin-bottom: 10px;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
transition: transform 0.2s;

}

.pt-arrival-item:hover {

transform: translateY(-2px);
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);

}

.pt-arrival-info {

flex: 1;

}

.pt-route-number {

display: inline-block;
background-color: #007cba;
color: white;
padding: 4px 12px;
border-radius: 20px;
font-weight: bold;
font-size: 14px;
margin-right: 10px;

}

.pt-destination {

font-weight: 600;
color: #1d2327;
font-size: 16px;

}

.pt-stop-name {

color: #646970;
font-size: 14px;
margin-top: 5px;

}

/ 时间信息 /
.pt-time-info {

text-align: right;
min-width: 120px;

}

.pt-arrival-time {

font-size: 24px;
font-weight: bold;
color: #007cba;
line-height: 1;

}

.pt-arrival-time.imminent {

color: #d63638;

}

.pt-arrival-time.soon {

color: #dba617;

}

.pt-time-unit {

font-size: 12px;
color: #646970;
display: block;
margin-top: 2px;

}

.pt-scheduled-time {

font-size: 12px;
color: #8c8f94;
margin-top: 5px;

}

/ 搜索框样式 /
.pt-search-form {

position: relative;
margin: 20px 0;

}

.pt-stop-search {

width: 100%;
padding: 12px 15px;
border: 2px solid #c3c4c7;
border-radius: 6px;
font-size: 16px;
transition: border-color 0.3s;

}

.pt-stop-search:focus {

outline: none;
border-color: #007cba;

}

.pt-search-results {

position: absolute;
top: 100%;
left: 0;
right: 0;
background: white;
border: 1px solid #c3c4c7;
border-radius: 0 0 6px 6px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
max-height: 300px;
overflow-y: auto;
z-index: 1000;
display: none;

}

.pt-search-result-item {

padding: 12px 15px;
border-bottom: 1px solid #f0f0f1;
cursor: pointer;
transition: background-color 0.2s;

}

.pt-search-result-item:hover {

background-color: #f6f7f7;

}

.pt-search-result-item:last-child {

border-bottom: none;

}

.pt-result-stop-name {

font-weight: 600;
color: #1d2327;
display: block;

}

.pt-result-route-list {

font-size: 12px;
color: #646970;
margin-top: 4px;

}

/ 全局搜索样式 /
.pt-search-container {

max-width: 600px;
margin: 30px auto;

}

.pt-search-box {

display: flex;
gap: 10px;

}

.pt-global-search {

flex: 1;
padding: 15px;
border: 2px solid #007cba;
border-radius: 8px;
font-size: 16px;

}

.pt-search-btn {

background-color: #007cba;
color: white;
border: none;
border-radius: 8px;
padding: 0 25px;
cursor: pointer;
font-size: 16px;
display: flex;
align-items: center;
justify-content: center;

}

.pt-search-btn:hover {

background-color: #005a87;

}

/ 加载状态 /
.pt-loading {

text-align: center;
padding: 40px;
color: #646970;

}

.pt-loading-spinner {

border: 3px solid #f3f3f3;
border-top: 3px solid #007cba;
border-radius: 50%;
width: 40px;
height: 40px;
animation: pt-spin 1s linear infinite;
margin: 0 auto 15px;

}

@keyframes pt-spin {

0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }

}

/ 空状态 /
.pt-no-selection {

text-align: center;
padding: 40px 20px;
color: #646970;

}

.pt-no-selection p {

margin-bottom: 20px;
font-size: 16px;

}

/ 响应式设计 /
@media (max-width: 768px) {

.pt-arrival-item {
    flex-direction: column;
    align-items: flex-start;
    gap: 15px;
}

.pt-time-info {
    text-align: left;
    width: 100%;
    border-top: 1px solid #f0f0f1;
    padding-top: 10px;
}

.pt-search-box {
    flex-direction: column;
}

.pt-search-btn {
    padding: 15px;
}

}

/ 夜间模式支持 /
@media (prefers-color-scheme: dark) {

.pt-arrivals-container {
    background-color: #1d2327;
    color: #f0f0f1;
}

.pt-arrival-item {
    background-color: #2c3338;
}

.pt-arrivals-header h3,
.pt-destination {
    color: #f0f0f1;
}

.pt-stop-search,
.pt-global-search {
    background-color: #2c3338;
    border-color: #4f555c;
    color: #f0f0f1;
}

.pt-search-results {
    background-color: #2c3338;
    border-color: #4f555c;
}

}


### 3.2 添加JavaScript交互

// assets/js/public-transport.js

(function($) {

'use strict';

// 全局变量
var ptAjaxUrl = ptSettings.ajax_url;
var ptNonce = ptSettings.nonce;

/**
 * 初始化插件功能
 */
function initPublicTransport() {
    // 绑定搜索事件
    $('.pt-stop-search').on('input', debounce(handleStopSearch, 300));
    $('.pt-global-search').on('input', debounce(handleGlobalSearch, 300));
    
    // 绑定搜索按钮点击事件
    $('.pt-search-btn').on('click', handleSearchButtonClick);
    
    // 绑定搜索结果点击事件
    $(document).on('click', '.pt-search-result-item', handleResultItemClick);
    
    // 自动刷新到站信息
    initAutoRefresh();
}

/**
 * 处理站点搜索
 */
function handleStopSearch(event) {
    var $input = $(this);
    var query = $input.val().trim();
    var city = $input.data('city') || '';
    var $results = $input.siblings('.pt-search-results');
    var targetContainer = $input.data('target');
    
    if (query.length < 2) {
        $results.hide().empty();
        return;
    }
    
    // 显示加载状态
    $results.html('<div class="pt-loading"><div class="pt-loading-spinner"></div><p>搜索中...</p></div>').show();
    
    $.ajax({
        url: ptAjaxUrl,
        type: 'POST',
        data: {
            action: 'pt_search_stops',
            nonce: ptNonce,
            query: query,
            city: city
        },
        success: function(response) {
            if (response.success && response.data.length > 0) {
                renderSearchResults($results, response.data, targetContainer);
            } else {
                $results.html('<div class="pt-no-results"><p>未找到相关站点</p></div>').show();
            }
        },
        error: function() {
            $results.html('<div class="pt-error"><p>搜索失败,请稍后重试</p></div>').show();
        }
    });
}

/**
 * 渲染搜索结果
 */
function renderSearchResults($container, results, targetContainer) {
    var html = '';
    
    results.forEach(function(stop) {
        var routes = stop.routes ? stop.routes.join('、') : '多条线路';
        html += '<div class="pt-search-result-item" data-stop-id="' + stop.id + '" data-stop-name="' + stop.name + '" data-routes="' + JSON.stringify(stop.routes || []) + '" data-target="' + targetContainer + '">';
        html += '<span class="pt-result-stop-name">' + stop.name + '</span>';
        html += '<span class="pt-result-route-list">途经线路: ' + routes + '</span>';
        html += '</div>';
    });
    
    $container.html(html).show();
}

/**
 * 处理搜索结果点击
 */
function handleResultItemClick() {
    var $item = $(this);
    var stopId = $item.data('stop-id');
    var stopName = $item.data('stop-name');
    var routes = $item.data('routes');
    var targetContainer = $item.data('target');
    
    // 隐藏搜索结果
    $item.closest('.pt-search-results').hide().empty();
    
    // 清空搜索框
    $item.closest('.pt-search-form').find('.pt-stop-search').val('');
    
    // 如果只有一个线路,自动选择
    if (routes && routes.length === 1) {
        loadArrivalsForStop(targetContainer, routes[0], stopId, stopName);
    } else {
        // 显示线路选择
        showRouteSelection(targetContainer, routes, stopId, stopName);
    }
}

/**
 * 显示线路选择
 */
function showRouteSelection(containerId, routes, stopId, stopName) {
    var $container = $('#' + containerId);
    var html = '<div class="pt-route-selection">';
    html += '<h4>选择线路 - ' + stopName + '</h4>';
    html += '<div class="pt-route-list">';
    
    routes.forEach(function(route) {
        html += '<button class="pt-route-option" data-route="' + route + '" data-stop="' + stopId + '">' + route + '路</button>';
    });
    
    html += '</div></div>';
    
    $container.find('.pt-arrivals-body').html(html);
    
    // 绑定线路选择事件
    $container.find('.pt-route-option').on('click', function() {
        var routeId = $(this).data('route');
        loadArrivalsForStop(containerId, routeId, stopId, stopName);
    });
}

/**
 * 加载到站信息
 */
function loadArrivalsForStop(containerId, routeId, stopId, stopName) {
    var $container = $('#' + containerId);
    var maxResults = $container.data('max-results') || 5;
    
    // 显示加载状态
    $container.find('.pt-arrivals-body').html('<div class="pt-loading"><div class="pt-loading-spinner"></div><p>加载到站信息中...</p></div>');
    
    // 更新容器数据属性
    $container.data('route', routeId);
    $container.data('stop', stopId);
    
    // 获取到站信息
    $.ajax({
        url: ptAjaxUrl,
        type: 'POST',
        data: {
            action: 'pt_get_arrivals',
            nonce: ptNonce,
            route: routeId,
            stop: stopId
        },
        success: function(response) {
            if (response.success) {
                ptRenderArrivals(containerId, response.data);
            } else {
                showError($container, response.data || '加载失败');
            }
        },
        error: function() {
            showError($container, '网络错误,请稍后重试');
        }
    });
}

/**
 * 渲染到站信息
 */
window.ptRenderArrivals = function(containerId, arrivals) {
    var $container = $('#' + containerId);
    var maxResults = $container.data('max-results') || 5;
    var routeId = $container.data('route');
    var stopId = $container.data('stop');
    
    if (!arrivals || arrivals.length === 0) {
        $container.find('.pt-arrivals-body').html('<div class="pt-no-arrivals"><p>暂无到站信息</p></div>');
        updateTimeStamp($container);
        return;
    }
    
    // 限制显示数量
    var displayArrivals = arrivals.slice(0, maxResults);
    var html = '';
    
    displayArrivals.forEach(function(arrival) {
        var minutes = arrival.minutes || 0;
        var timeClass = 'pt-arrival-time';
        
        if (minutes <= 2) {
            timeClass += ' imminent';
        } else if (minutes <= 5) {
            timeClass += ' soon';
        }
        
        html += '<div class="pt-arrival-item">';
        html += '<div class="pt-arrival-info">';
        html += '<span class="pt-route-number">' + (arrival.route || routeId) + '路</span>';
        html += '<span class="pt-destination">' + (arrival.destination || '未知方向') + '</span>';
        html += '<div class="pt-stop-name">' + (arrival.stop_name || '') + '</div>';
        html += '</div>';
        html += '<div class="pt-time-info">';
        html += '<div class="' + timeClass + '">' + minutes + '<span class="pt-time-unit">分钟</span></div>';
        
        if (arrival.scheduled_time) {
            html += '<div class="pt-scheduled-time">计划: ' + arrival.scheduled_time + '</div>';
        }
        
        html += '</div>';
        html += '</div>';
    });
    
    $container.find('.pt-arrivals-body').html(html);
    updateTimeStamp($container);
};

/**
 * 刷新到站信息
 */
window.ptRefreshArrivals = function(containerId) {
    var $container = $('#' + containerId);
    var routeId = $container.data('route');
    var stopId = $container.data('stop');
    
    if (!routeId || !stopId) {
        return;
    }
    
    loadArrivalsForStop(containerId, routeId, stopId);
};

/**
 * 更新时间戳
 */
function updateTimeStamp($container) {
    var now = new Date();
    var timeString = now.getHours().toString().padStart(2, '0') + ':' + 
                     now.getMinutes().toString().padStart(2, '0') + ':' + 
                     now.getSeconds().toString().padStart(2, '0');
    
    $container.find('.pt-update-time').text(timeString);
}

/**
 * 显示错误信息
 */
function showError($container, message) {
    $container.find('.pt-arrivals-body').html('<div class="pt-error"><p>' + message + '</p></div>');
}

/**
 * 初始化自动刷新
 */
function initAutoRefresh() {
    // 每30秒刷新一次到站信息
    setInterval(function() {
        $('.pt-arrivals-container').each(function() {
            var $container = $(this);
            var routeId = $container.data('route');
            var stopId = $container.data('stop');
            
            if (routeId && stopId) {
                // 静默刷新,不显示加载状态
                $.ajax({
                    url: ptAjaxUrl,
                    type: 'POST',
                    data: {
                        action: 'pt_get_arrivals',
                        nonce: ptNonce,
                        route: routeId,
                        stop: stopId
                    },
                    success: function(response) {
                        if (response.success) {
                            ptRenderArrivals($container.attr('id'), response.data);
                        }
                    }
                });
            }
        });
    }, 30000); // 30秒
}

/**
 * 防抖函数
 */
function debounce(func, wait) {
    var timeout;
    return function() {
        var context = this, args = arguments;
        clearTimeout(timeout);
        timeout = setTimeout(function() {
            func.apply(context, args);
        }, wait);
    };
}

/**
 * 全局搜索处理
 */
function handleGlobalSearch(event) {
    // 实现逻辑类似handleStopSearch,但用于全局搜索
    console.log('全局搜索:', $(this).val());
}

function handleSearchButtonClick
本文来自网络,不代表柔性供应链服务中心立场,转载请注明出处:https://mall.org.cn/5326.html

EXCHANGES®作者

上一篇
下一篇

为您推荐

发表回复

联系我们

联系我们

18559313275

在线咨询: QQ交谈

邮箱: vip@exchanges.center

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