// Epic Games 免费游戏 页面脚本 (function () { 'use strict'; const API = { endpoints: [], currentIndex: 0, // 初始化API接口列表 async init() { try { const res = await fetch('./接口集合.json'); const endpoints = await res.json(); this.endpoints = endpoints.map(endpoint => `${endpoint}/v2/epic`); } catch (e) { // 如果无法加载接口集合,使用默认接口 this.endpoints = ['https://60s.api.shumengya.top/v2/epic']; } }, // 获取当前接口URL getCurrentUrl(encoding) { if (this.endpoints.length === 0) return null; const url = new URL(this.endpoints[this.currentIndex]); if (encoding) url.searchParams.set('encoding', encoding); return url.toString(); }, // 切换到下一个接口 switchToNext() { this.currentIndex = (this.currentIndex + 1) % this.endpoints.length; return this.currentIndex < this.endpoints.length; }, // 重置到第一个接口 reset() { this.currentIndex = 0; } }; // DOM 元素引用 const els = { loading: null, error: null, container: null, gamesGrid: null, totalGames: null, freeNow: null, upcoming: null, refreshBtn: null, }; function initDom() { els.loading = document.getElementById('loading'); els.error = document.getElementById('error'); els.container = document.getElementById('content'); els.gamesGrid = document.getElementById('games-grid'); els.totalGames = document.getElementById('total-games'); els.freeNow = document.getElementById('free-now'); els.upcoming = document.getElementById('upcoming'); els.refreshBtn = document.getElementById('refresh-btn'); } function showLoading() { els.loading.style.display = 'block'; els.error.style.display = 'none'; els.container.style.display = 'none'; } function showError(msg) { els.loading.style.display = 'none'; els.error.style.display = 'block'; els.container.style.display = 'none'; els.error.querySelector('p').textContent = msg || '获取数据失败,请稍后重试'; } function showContent() { els.loading.style.display = 'none'; els.error.style.display = 'none'; els.container.style.display = 'block'; } function safeText(text) { const div = document.createElement('div'); div.textContent = text == null ? '' : String(text); return div.innerHTML; } function formatDate(dateStr) { if (!dateStr) return ''; try { const date = new Date(dateStr); return date.toLocaleDateString('zh-CN', { month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' }); } catch (e) { return dateStr; } } async function fetchData(preferLocal = false) { if (preferLocal) { try { const res = await fetch('./返回接口.json', { cache: 'no-store' }); const json = await res.json(); return json; } catch (e) { throw new Error('本地数据加载失败'); } } // 重置API索引到第一个接口 API.reset(); // 尝试所有API接口 for (let i = 0; i < API.endpoints.length; i++) { try { const url = API.getCurrentUrl(); console.log(`尝试接口 ${i + 1}/${API.endpoints.length}: ${url}`); const res = await fetch(url, { cache: 'no-store', timeout: 10000 // 10秒超时 }); if (!res.ok) { throw new Error(`HTTP ${res.status}: ${res.statusText}`); } const json = await res.json(); if (json && json.code === 200) { console.log(`接口 ${i + 1} 请求成功`); return json; } throw new Error(json && json.message ? json.message : '接口返回异常'); } catch (e) { console.warn(`接口 ${i + 1} 失败:`, e.message); // 如果不是最后一个接口,切换到下一个 if (i < API.endpoints.length - 1) { API.switchToNext(); continue; } // 所有接口都失败了,尝试本地数据 console.warn('所有远程接口都失败,尝试本地数据'); try { const res = await fetch('./返回接口.json', { cache: 'no-store' }); const json = await res.json(); return json; } catch (e2) { throw new Error('所有接口和本地数据都无法访问'); } } } } function createGameCard(game) { const isFree = game.is_free_now; const statusClass = isFree ? 'status-free' : 'status-upcoming'; const statusText = isFree ? '限时免费' : '即将免费'; return `
${safeText(game.description)}