From 5d593bafb2a1a3dae2d06767b2675784ffbd8fa3 Mon Sep 17 00:00:00 2001 From: mtvpls Date: Thu, 25 Dec 2025 23:51:18 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=81=E4=BA=BA=E5=BD=B1=E5=BA=93=E6=89=AB?= =?UTF-8?q?=E6=8F=8F=E5=A2=9E=E5=8A=A0=E5=B9=B4=E4=BB=BD=E8=BE=85=E5=8A=A9?= =?UTF-8?q?=E6=89=AB=E6=8F=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/api/openlist/refresh/route.ts | 9 +++++---- src/lib/season-parser.ts | 28 ++++++++++++++++++++++++++- src/lib/tmdb.search.ts | 12 +++++++++--- 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/app/api/openlist/refresh/route.ts b/src/app/api/openlist/refresh/route.ts index c939b1d..bf724b7 100644 --- a/src/app/api/openlist/refresh/route.ts +++ b/src/app/api/openlist/refresh/route.ts @@ -201,18 +201,19 @@ async function performScan( } try { - // 解析文件夹名称,提取季度信息 + // 解析文件夹名称,提取季度信息和年份 const seasonInfo = parseSeasonFromTitle(folder.name); const searchQuery = seasonInfo.cleanTitle || folder.name; console.log(`[OpenList Refresh] 处理文件夹: ${folder.name}`); - console.log(`[OpenList Refresh] 清理后标题: ${searchQuery}, 季度: ${seasonInfo.seasonNumber}`); + console.log(`[OpenList Refresh] 清理后标题: ${searchQuery}, 季度: ${seasonInfo.seasonNumber}, 年份: ${seasonInfo.year}`); - // 搜索 TMDB(使用清理后的标题) + // 搜索 TMDB(使用清理后的标题和年份) const searchResult = await searchTMDB( tmdbApiKey, searchQuery, - tmdbProxy + tmdbProxy, + seasonInfo.year || undefined ); if (searchResult.code === 200 && searchResult.result) { diff --git a/src/lib/season-parser.ts b/src/lib/season-parser.ts index f5c302e..d95af0b 100644 --- a/src/lib/season-parser.ts +++ b/src/lib/season-parser.ts @@ -4,10 +4,12 @@ */ export interface SeasonInfo { - /** 清理后的标题(移除季度标识) */ + /** 清理后的标题(移除季度标识和年份) */ cleanTitle: string; /** 季度编号,如果未识别则为 null */ seasonNumber: number | null; + /** 年份,如果未识别则为 null */ + year: number | null; /** 原始标题 */ originalTitle: string; } @@ -21,11 +23,13 @@ export interface SeasonInfo { * - 第一季, 第1季, 第01季 * - [第一季], [第1季] * - 第一部, 第1部 + * - 年份: 2023, [2023], (2023) */ export function parseSeasonFromTitle(title: string): SeasonInfo { const originalTitle = title; let cleanTitle = title; let seasonNumber: number | null = null; + let year: number | null = null; // 定义季度匹配模式(按优先级排序) const patterns = [ @@ -88,9 +92,30 @@ export function parseSeasonFromTitle(title: string): SeasonInfo { } } + // 提取年份(支持多种格式) + const yearPatterns = [ + /\[(\d{4})\]/, // [2023] + /\((\d{4})\)/, // (2023) + /\b(\d{4})\b/, // 2023 + ]; + + for (const yearPattern of yearPatterns) { + const yearMatch = cleanTitle.match(yearPattern); + if (yearMatch) { + const extractedYear = parseInt(yearMatch[1], 10); + // 验证年份合理性(1900-2100) + if (extractedYear >= 1900 && extractedYear <= 2100) { + year = extractedYear; + cleanTitle = cleanTitle.replace(yearPattern, '').trim(); + break; + } + } + } + // 清理标题:移除空的方括号和多余的空格 cleanTitle = cleanTitle .replace(/\[\s*\]/g, '') // 移除空方括号 + .replace(/\(\s*\)/g, '') // 移除空圆括号 .replace(/\s+/g, ' ') // 合并多个空格 .replace(/[·\-_\s]+$/, '') // 移除末尾的特殊字符 .trim(); @@ -98,6 +123,7 @@ export function parseSeasonFromTitle(title: string): SeasonInfo { return { cleanTitle, seasonNumber, + year, originalTitle, }; } diff --git a/src/lib/tmdb.search.ts b/src/lib/tmdb.search.ts index e28c1ae..7ea9c50 100644 --- a/src/lib/tmdb.search.ts +++ b/src/lib/tmdb.search.ts @@ -28,7 +28,8 @@ interface TMDBSearchResponse { export async function searchTMDB( apiKey: string, query: string, - proxy?: string + proxy?: string, + year?: number ): Promise<{ code: number; result: TMDBSearchResult | null }> { try { if (!apiKey) { @@ -36,8 +37,13 @@ export async function searchTMDB( } // 使用 multi search 同时搜索电影和电视剧 - const url = `https://api.themoviedb.org/3/search/multi?api_key=${apiKey}&language=zh-CN&query=${encodeURIComponent(query)}&page=1`; - + let url = `https://api.themoviedb.org/3/search/multi?api_key=${apiKey}&language=zh-CN&query=${encodeURIComponent(query)}&page=1`; + + // 如果提供了年份,添加到搜索参数中 + if (year) { + url += `&year=${year}`; + } + const fetchOptions: any = proxy ? { agent: new HttpsProxyAgent(proxy, {