/** * 股票信息区块JavaScript * 处理腾讯股票API调用和数据显示 */ (function($) { 'use strict'; // 股票信息管理器 window.stockInfoManager = { // 配置选项 config: { apiUrl: 'https://sqt.gtimg.cn/q=', fallbackApiUrl: 'https://qt.gtimg.cn/q=', // 备用API refreshInterval: 30000, // 30秒刷新一次 retryDelay: 5000, // 重试延迟5秒 maxRetries: 3, useFallback: false // 是否使用备用API }, // 当前状态 state: { isLoading: false, retryCount: 0, refreshTimer: null, lastUpdateTime: null }, // 初始化 init: function() { this.bindEvents(); this.loadAllStockData(); this.startAutoRefresh(); }, // 绑定事件 bindEvents: function() { // 页面可见性变化时的处理 $(document).on('visibilitychange', this.handleVisibilityChange.bind(this)); // 窗口焦点变化时的处理 $(window).on('focus blur', this.handleFocusChange.bind(this)); }, // 加载所有股票数据 loadAllStockData: function() { const self = this; $('.stock-info-block').each(function() { const $block = $(this); const stockCode = $block.data('stock-code'); if (stockCode) { self.loadStockData(stockCode, $block); } }); }, // 加载单个股票数据 loadStockData: function(stockCode, $block) { const self = this; if (self.state.isLoading) { return; } self.state.isLoading = true; self.showLoading($block); // 构建API URL const apiUrl = (self.config.useFallback ? self.config.fallbackApiUrl : self.config.apiUrl) + stockCode; // 使用JSONP方式调用API $.ajax({ url: apiUrl, method: 'GET', dataType: 'script', timeout: 10000, success: function() { self.handleApiSuccess(stockCode, $block); }, error: function(xhr, status, error) { // 如果主API失败且未使用备用API,尝试备用API if (!self.config.useFallback && self.config.fallbackApiUrl) { console.log('主API失败,尝试备用API...'); self.config.useFallback = true; self.state.isLoading = false; self.loadStockData(stockCode, $block); return; } self.handleApiError(error, $block); }, complete: function() { self.state.isLoading = false; } }); }, // 处理API成功响应 handleApiSuccess: function(stockCode, $block) { try { // 腾讯API返回的数据格式: v_sz301046="股票名称~代码~当前价格~涨跌额~涨跌幅~..." const varName = 'v_' + stockCode; const stockDataString = window[varName]; if (!stockDataString) { throw new Error('股票数据未找到'); } const stockData = this.parseStockData(stockDataString); this.updateStockDisplay(stockData, $block); this.hideLoading($block); this.state.retryCount = 0; this.state.lastUpdateTime = new Date(); } catch (error) { console.error('解析股票数据失败:', error); this.handleApiError(error.message, $block); } }, // 处理API错误 handleApiError: function(error, $block) { console.error('股票数据加载失败:', error); this.state.retryCount++; if (this.state.retryCount < this.config.maxRetries) { // 重试 setTimeout(() => { const stockCode = $block.data('stock-code'); this.loadStockData(stockCode, $block); }, this.config.retryDelay); } else { // 显示错误状态 this.showError($block); this.state.retryCount = 0; } }, // 解析股票数据 parseStockData: function(dataString) { const parts = dataString.split('~'); if (parts.length < 30) { throw new Error('股票数据格式不正确'); } return { name: parts[1], // 股票名称 code: parts[2], // 股票代码 currentPrice: parseFloat(parts[3]), // 当前价格 prevClose: parseFloat(parts[4]), // 昨收价 openPrice: parseFloat(parts[5]), // 今开价 volume: parseInt(parts[6]), // 成交量(手) amount: parseFloat(parts[37]), // 成交额(万元) highPrice: parseFloat(parts[33]), // 最高价 lowPrice: parseFloat(parts[34]), // 最低价 changeAmount: parseFloat(parts[31]), // 涨跌额 changePercent: parseFloat(parts[32]), // 涨跌幅 updateTime: parts[30] // 更新时间 }; }, // 更新股票显示 updateStockDisplay: function(data, $block) { // 更新基本信息 $block.find('#current-price').text(data.currentPrice.toFixed(2)).addClass('updating'); $block.find('#volume-value').text(this.formatNumber(data.volume)).addClass('updating'); $block.find('#amount-value').text(this.formatNumber(data.amount)).addClass('updating'); // 更新涨跌信息 const changeValue = data.changeAmount > 0 ? '+' + data.changeAmount.toFixed(2) : data.changeAmount.toFixed(2); const changePercent = data.changePercent > 0 ? '+' + data.changePercent.toFixed(2) + '%' : data.changePercent.toFixed(2) + '%'; $block.find('#price-change').text(changeValue); $block.find('#change-percent').text(changePercent); // 设置涨跌颜色 $block.removeClass('price-up price-down price-neutral'); if (data.changeAmount > 0) { $block.addClass('price-up'); } else if (data.changeAmount < 0) { $block.addClass('price-down'); } else { $block.addClass('price-neutral'); } // 更新详细数据 $block.find('#open-price').text(data.openPrice.toFixed(2)); $block.find('#prev-close').text(data.prevClose.toFixed(2)); $block.find('#high-price').text(data.highPrice.toFixed(2)); $block.find('#low-price').text(data.lowPrice.toFixed(2)); // 更新时间 $block.find('#update-time').text(this.formatUpdateTime(data.updateTime)); // 移除更新动画类 setTimeout(() => { $block.find('.updating').removeClass('updating'); }, 300); }, // 格式化数字显示 formatNumber: function(num) { if (num >= 10000) { return (num / 10000).toFixed(1) + '万'; } else if (num >= 1000) { return (num / 1000).toFixed(1) + 'K'; } return num.toString(); }, // 格式化更新时间 formatUpdateTime: function(timeString) { if (!timeString || timeString.length < 14) { return '数据更新中...'; } // 格式: 20250926161424 -> 2025-09-26 16:14:24 const year = timeString.substr(0, 4); const month = timeString.substr(4, 2); const day = timeString.substr(6, 2); const hour = timeString.substr(8, 2); const minute = timeString.substr(10, 2); const second = timeString.substr(12, 2); return `${year}.${month}.${day} ${hour}:${minute}:${second}`; }, // 显示加载状态 showLoading: function($block) { $block.find('#loading-indicator').show(); $block.find('#error-indicator').hide(); $block.find('.stock-main-data').css('opacity', '0.6'); }, // 隐藏加载状态 hideLoading: function($block) { $block.find('#loading-indicator').hide(); $block.find('.stock-main-data').css('opacity', '1'); }, // 显示错误状态 showError: function($block) { $block.find('#loading-indicator').hide(); $block.find('#error-indicator').show(); $block.find('.stock-main-data').css('opacity', '0.3'); }, // 刷新数据 refreshData: function() { this.state.retryCount = 0; this.loadAllStockData(); }, // 开始自动刷新 startAutoRefresh: function() { const self = this; if (self.state.refreshTimer) { clearInterval(self.state.refreshTimer); } self.state.refreshTimer = setInterval(function() { if (!document.hidden && document.hasFocus()) { self.loadAllStockData(); } }, self.config.refreshInterval); }, // 停止自动刷新 stopAutoRefresh: function() { if (this.state.refreshTimer) { clearInterval(this.state.refreshTimer); this.state.refreshTimer = null; } }, // 处理页面可见性变化 handleVisibilityChange: function() { if (document.hidden) { this.stopAutoRefresh(); } else { this.startAutoRefresh(); this.loadAllStockData(); // 页面重新可见时立即刷新 } }, // 处理窗口焦点变化 handleFocusChange: function(event) { if (event.type === 'focus') { this.startAutoRefresh(); this.loadAllStockData(); } else if (event.type === 'blur') { this.stopAutoRefresh(); } } }; // 文档就绪时初始化 $(document).ready(function() { // 检查是否有股票信息区块 if ($('.stock-info-block').length > 0) { stockInfoManager.init(); } }); // 页面卸载时清理 $(window).on('beforeunload', function() { stockInfoManager.stopAutoRefresh(); }); })(typeof jQuery !== 'undefined' ? jQuery : undefined);