X Tutup
/** * GitHub API 集成模块 * 用于获取 GitHub 仓库统计信息和动态数据 */ class GitHubAPI { constructor(username = 'jacksoncode', repository = 'jacksoncode.github.io') { this.username = username; this.repository = repository; this.baseURL = 'https://api.github.com'; this.cacheKey = 'github-data-cache'; this.cacheExpiry = 15 * 60 * 1000; // 15分钟缓存 } /** * 获取缓存的 GitHub 数据 */ getCachedData() { try { const cached = localStorage.getItem(this.cacheKey); if (!cached) return null; const data = JSON.parse(cached); const now = Date.now(); // 检查缓存是否过期 if (now - data.timestamp > this.cacheExpiry) { localStorage.removeItem(this.cacheKey); return null; } return data.content; } catch (error) { console.warn('读取缓存失败:', error); return null; } } /** * 缓存 GitHub 数据 */ cacheData(data) { try { const cacheEntry = { timestamp: Date.now(), content: data }; localStorage.setItem(this.cacheKey, JSON.stringify(cacheEntry)); } catch (error) { console.warn('缓存数据失败:', error); } } /** * 获取仓库基本信息 */ async getRepositoryInfo() { try { const response = await fetch( `${this.baseURL}/repos/${this.username}/${this.repository}` ); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return await response.json(); } catch (error) { console.error('获取仓库信息失败:', error); return null; } } /** * 获取仓库 star 数 */ async getStarCount() { try { const response = await fetch( `${this.baseURL}/repos/${this.username}/${this.repository}` ); const data = await response.json(); return data.stargazers_count || 0; } catch (error) { console.error('获取 star 数失败:', error); return 0; } } /** * 获取最新提交记录 */ async getRecentCommits(limit = 5) { try { const response = await fetch( `${this.baseURL}/repos/${this.username}/${this.repository}/commits?per_page=${limit}` ); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return await response.json(); } catch (error) { console.error('获取提交记录失败:', error); return []; } } /** * 获取 issues 数量 */ async getIssuesCount() { try { const response = await fetch( `${this.baseURL}/repos/${this.username}/${this.repository}` ); const data = await response.json(); return data.open_issues_count || 0; } catch (error) { console.error('获取 issues 数失败:', error); return 0; } } /** * 获取贡献者统计 */ async getContributors() { try { const response = await fetch( `${this.baseURL}/repos/${this.username}/${this.repository}/contributors` ); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return await response.json(); } catch (error) { console.error('获取贡献者失败:', error); return []; } } /** * 获取语言分布 */ async getLanguages() { try { const response = await fetch( `${this.baseURL}/repos/${this.username}/${this.repository}/languages` ); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return await response.json(); } catch (error) { console.error('获取语言分布失败:', error); return {}; } } /** * 获取所有统计数据(带缓存) */ async getAllStats() { // 尝试从缓存获取 const cached = this.getCachedData(); if (cached) { console.log('使用缓存的 GitHub 数据'); return cached; } // 缓存未命中,获取新数据 console.log('从 GitHub API 获取新数据'); try { const [repoInfo, commits, contributors, languages] = await Promise.all([ this.getRepositoryInfo(), this.getRecentCommits(), this.getContributors(), this.getLanguages() ]); const stats = { repository: { name: repoInfo?.full_name || '', description: repoInfo?.description || '', stars: repoInfo?.stargazers_count || 0, forks: repoInfo?.forks_count || 0, issues: repoInfo?.open_issues_count || 0, watchers: repoInfo?.subscribers_count || 0, createdAt: repoInfo?.created_at || '', updatedAt: repoInfo?.updated_at || '', url: repoInfo?.html_url || '' }, recentCommits: commits.map(commit => ({ sha: commit.sha.substring(0, 7), message: commit.commit.message.split('\n')[0], author: commit.commit.author.name, date: commit.commit.author.date, url: commit.html_url })), contributors: contributors.map(contributor => ({ login: contributor.login, contributions: contributor.contributions, avatar: contributor.avatar_url, url: contributor.html_url })), languages: languages, lastUpdate: new Date().toISOString() }; // 缓存数据 this.cacheData(stats); return stats; } catch (error) { console.error('获取 GitHub 统计数据失败:', error); return null; } } /** * 格式化日期 */ formatDate(dateString) { const date = new Date(dateString); const now = new Date(); const diffTime = Math.abs(now - date); const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)); if (diffDays === 0) return '今天'; if (diffDays === 1) return '昨天'; if (diffDays < 7) return `${diffDays}天前`; if (diffDays < 30) return `${Math.floor(diffDays / 7)}周前`; if (diffDays < 365) return `${Math.floor(diffDays / 30)}月前`; return `${Math.floor(diffDays / 365)}年前`; } /** * 格式化数字(添加千位分隔符) */ formatNumber(num) { if (num >= 1000000) { return (num / 1000000).toFixed(1) + 'M'; } if (num >= 1000) { return (num / 1000).toFixed(1) + 'K'; } return num.toString(); } } // 创建全局实例 const githubAPI = new GitHubAPI(); // 导出供其他模块使用 if (typeof module !== 'undefined' && module.exports) { module.exports = GitHubAPI; }
X Tutup