From ef003d788268dd67d5452687896c4cab480cfed2 Mon Sep 17 00:00:00 2001 From: Elegy233 <82034747+wan0ge@users.noreply.github.com> Date: Sat, 1 Aug 2026 12:57:26 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E4=BC=98=E9=80=89=20qq=20=E5=B9=B3=E5=8F=B0=E5=8C=B9=E9=85=8D?= =?UTF-8?q?=20(#409)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PLATFORM_ORDER 优选平台匹配自 PR #167 起改为依据番剧身份(标题 from 段或 source)与目标平台评分。当源身份名与配置平台名不一致、但集上挂有目标平台标签时(如 tencent 源、集标题挂 qq),getPlatformMatchScore(identity, "qq") 得 0,与无交集的 dandan 同为 0 分,平局由 SOURCE_ORDER 决定,导致配置 qq 却选中 dandan 而非 tencent。 现于 matchAniAndEp 评分时,将命中集所挂平台标签并入候选平台(与身份标签去重合并),使 tencent 这类源在集上挂有 qq 时能正确加分。同时 getPlatformMatchScore 预处理支持全角&并去重,修正合并标题重复标签(如 dandan&qiyi&qiyi)抬高杂质长度导致评分失真的问题。该加性改动不影响既有的合并源优选评分(已以 40 例用例验证,含合并源、正常单源、全角&、去重及手动优选绝对优先等场景)。 --- danmu_api/apis/dandan-api.js | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/danmu_api/apis/dandan-api.js b/danmu_api/apis/dandan-api.js index 4d261b8..f20fb54 100644 --- a/danmu_api/apis/dandan-api.js +++ b/danmu_api/apis/dandan-api.js @@ -972,9 +972,9 @@ export function filterSameEpisodeTitle(filteredTmpEpisodes) { function getPlatformMatchScore(candidatePlatform, targetPlatform) { if (!candidatePlatform || !targetPlatform) return 0; - // 预处理:按 & 分割,转小写,去空格 - const cParts = candidatePlatform.split('&').map(s => s.trim().toLowerCase()).filter(s => s); - const tParts = targetPlatform.split('&').map(s => s.trim().toLowerCase()).filter(s => s); + // 预处理:按半角/全角 & 分割,转小写去空格并去重,避免合并标题重复标签抬高杂质长度导致评分失真 + const cParts = [...new Set(candidatePlatform.split(/[&&]/).map(s => s.trim().toLowerCase()).filter(s => s))]; + const tParts = [...new Set(targetPlatform.split(/[&&]/).map(s => s.trim().toLowerCase()).filter(s => s))]; let matchCount = 0; @@ -1002,7 +1002,7 @@ function getPlatformMatchScore(candidatePlatform, targetPlatform) { // 辅助函数:从标题中提取来源平台列表 (新增函数 - 适配合并源标题格式) function extractPlatformFromTitle(title) { - const match = title.match(/from\s+([a-zA-Z0-9&]+)/i); + const match = title.match(/from\s+([a-zA-Z0-9&&]+)/i); return match ? match[1] : null; } @@ -1439,12 +1439,16 @@ async function matchAniAndEp(season, episode, year, searchData, title, req, plat // 3. 匹配结果处理与评分比较 if (matchedEpisode) { // 计算当前匹配的得分 - const actualPlatform = extractPlatformFromTitle(anime.animeTitle) || anime.source; + // 候选平台由番剧身份标签(标题 from 段或 source)与命中集所挂平台标签共同决定,使身份名(如 tencent)与优选平台名(如 qq)不一致但集上挂有该标签的源也能正确加分 + const identityPlatform = extractPlatformFromTitle(anime.animeTitle) || anime.source; + const epPlatform = matchedEpisode ? extractEpisodeTitle(matchedEpisode.episodeTitle) : null; + const candidatePlatform = [...new Set([identityPlatform, epPlatform].filter(Boolean) + .flatMap(p => p.split(/[&&]/).map(s => s.trim().toLowerCase())).filter(s => s))].join('&'); let currentScore = 0; - + if (platform) { // 如果指定了平台偏好,计算匹配得分 - currentScore = getPlatformMatchScore(actualPlatform, platform); + currentScore = getPlatformMatchScore(candidatePlatform, platform); } else { // 如果没有指定平台偏好,默认为 1 currentScore = 1;