| 261 | |
| 262 | // 获取所有文章(分页获取) |
| 263 | static async getAllArticles(): Promise<Article[]> { |
| 264 | const cacheKey = 'all_articles'; |
| 265 | const cached = cache.get<Article[]>(cacheKey); |
| 266 | if (cached) { |
| 267 | return cached; |
| 268 | } |
| 269 | |
| 270 | const allArticles: Article[] = []; |
| 271 | let page = 1; |
| 272 | const perPage = 100; // GitHub API 最大支持 100 |
| 273 | |
| 274 | try { |
| 275 | while (true) { |
| 276 | const articles = await this.getIssues(page, perPage); |
| 277 | |
| 278 | if (!Array.isArray(articles) || articles.length === 0) { |
| 279 | break; // 没有更多数据 |
| 280 | } |
| 281 | |
| 282 | allArticles.push(...articles); |
| 283 | |
| 284 | if (articles.length < perPage) { |
| 285 | break; // 最后一页 |
| 286 | } |
| 287 | |
| 288 | page++; |
| 289 | |
| 290 | // 限制最大页数,避免无限循环 |
| 291 | if (page > 20) { |
| 292 | break; |
| 293 | } |
| 294 | } |
| 295 | |
| 296 | // 缓存结果(120分钟) |
| 297 | cache.set(cacheKey, allArticles, 120 * 60 * 1000); |
| 298 | |
| 299 | return allArticles; |
| 300 | } catch (error) { |
| 301 | console.error('Error fetching all articles:', error); |
| 302 | // 返回空数组而不是抛出错误 |
| 303 | return []; |
| 304 | } |
| 305 | } |
| 306 | |
| 307 | // 带重试的 fetch 函数 |
| 308 | private static async fetchWithRetry(url: string, options: RequestInit, retries: number = 3): Promise<Response> { |