fix(dandan): 优化详情请求数,原名搜索添加低门槛预过滤避免出现完全无关结果 (#419)

* fix(dandan): 优化详情请求数,搜索返回前用低阈值titleMatches预过滤

search()返回前用titleMatches(t, keyword, season, false, 0.5)对原始搜索
结果做初筛,剔除明显无关条目避免浪费getEpisodes详情请求。0.5阈值仅挡
明显无关项,翻译差异结果放行交由handleAnimes含别名0.8最终过滤。

TMDB abort从原始搜索返回时推迟到预过滤后:保留结果则abort,初筛清空则
不abort以触发内部日语原名兜底。执行顺序由Promise.all改为先await原始再
决定是否await TMDB,确保abort在TMDB完成前生效。

* feat(dandan): 关联作品恢复预过滤误剔除的原始搜索结果条目

search()预过滤后在结果数组上记录原始animeIds,handleAnimes处理
关联作品时检查其animeId是否在原始搜索结果中被误过滤(如翻译差异
导致低阈值titleMatches未命中),自动补回至sourceAnimes与处理队列。

仅在未指定目标季时触发,避免干扰明确指定季度的场景。

* fix: 修复titleMatches相似度策略无法返回true的回归bug

commit 3345ed19添加年份兜底时将末尾return simMatch改为return false,
导致simMatch为true时跳过年份检查块后直接返回false。相似度匹配自7月14日
起在所有调用路径中静默失效,影响dandan预过滤及含别名0.8最终过滤。

预过滤titleMatches调用传入forceNonStrict=true,确保严格匹配模式下
仍使用包含+相似度双策略判断。

* perf(dandan): 日语原名搜索添加预过滤,常规预过滤阀门调整为0.4

常规搜索预过滤threshold由0.5调至0.4,更宽松以减少翻译差异导致的
误过滤。TMDB日语原名搜索结果新增threshold 0.19的低门阀预过滤,
剔除明显无关条目(如「正能量企鹅」等仅包含个别匹配字的噪声)。
This commit is contained in:
Elegy233 authored and GitHub committed 2026-08-08 21:32:43 +08:00
1 parent 463c14708a
commit 5e984a60a5
2 files changed
+56 -14

No files matched your search

+55 -13
View File
@@ -85,9 +85,6 @@ export default class DandanSource extends BaseSource {
log("info", "[dandan] 原始搜索成功,但未返回任何结果 (source: original)");
return { success: false, source: 'original' };
}
// 原始搜索有结果,中断 TMDB 流程
tmdbAbortController.abort();
const animes = resp.data.animes;
log("info", `[dandan] dandanSearchresp (original): ${JSON.stringify(animes)}`);
log("info", `[dandan] 返回 ${animes.length} 条结果 (source: original)`);
@@ -165,20 +162,35 @@ export default class DandanSource extends BaseSource {
}
})();
// 等待两个搜索任务同时完成,优先采用原始搜索结果
const [originalResult, tmdbResult] = await Promise.all([
originalSearchPromise,
tmdbSearchPromise
]);
// 优先返回原始搜索结果
// 搜索结果预过滤:先拿到原始结果再决定是否等待TMDB兜底
const originalResult = await originalSearchPromise;
if (originalResult.success) {
return originalResult.data;
const resolvedSeason = getExplicitSeasonNumber(keyword);
const preFiltered = originalResult.data.filter(anime => {
if (anime.isTmdbSource) return true;
const t = anime.animeTitle || anime.title || '';
return titleMatches(t, keyword, resolvedSeason, true, 0.8);
});
if (preFiltered.length > 0) {
tmdbAbortController.abort();
// 记录原始搜索结果的全部animeId,供handleAnimes关联作品恢复误过滤条目使用
preFiltered._originalAnimeIds = originalResult.data.map(a => a.animeId);
return preFiltered;
}
// 初筛清空原始结果时不abort,等待TMDB兜底
}
// 原始搜索无结果,返回 TMDB 搜索结果
// 原始搜索无结果或被初筛清空,等待并返回TMDB搜索结果
const tmdbResult = await tmdbSearchPromise;
// 原始搜索无结果,对TMDB日语原名结果做最终预过滤
if (tmdbResult.success) {
return tmdbResult.data;
const resolvedSeason = getExplicitSeasonNumber(keyword);
const tmdbFiltered = tmdbResult.data.filter(anime => {
const t = anime.animeTitle || anime.title || '';
return titleMatches(t, keyword, resolvedSeason, true, 0.19);
});
if (tmdbFiltered.length > 0) return tmdbFiltered;
}
log("info", `[dandan] 原始搜索和基于TMDB的搜索均未返回任何结果 (当前搜索词: ${keyword})`);
@@ -394,6 +406,36 @@ export default class DandanSource extends BaseSource {
}
}
}
// 关联作品补回预过滤误剔除的原始搜索结果条目(如翻译差异导致误过滤)
if (!isTargetFoundInInitial && Array.isArray(details.relateds)) {
const originalIds = sourceAnimes._originalAnimeIds;
if (Array.isArray(originalIds) && originalIds.length > 0) {
const recoveredIds = new Set(originalIds);
for (const rel of details.relateds) {
if (recoveredIds.has(rel.animeId) && !existingIds.has(rel.animeId)) {
existingIds.add(rel.animeId);
if (!sourceAnimes.some(a => a.animeId === rel.animeId)) {
sourceAnimes.push({
animeId: rel.animeId,
animeTitle: rel.animeTitle,
title: rel.animeTitle,
imageUrl: rel.imageUrl,
rating: rel.rating || 0,
isRelated: true
});
}
queue.push({
animeId: rel.animeId,
animeTitle: rel.animeTitle,
imageUrl: rel.imageUrl,
rating: rel.rating || 0,
isRelated: true // 标记动态挖掘出的条目为相关作品
});
}
}
}
}
}
// 区分初始搜索结果与动态相关作品的结果过滤逻辑
+1 -1
View File
@@ -368,7 +368,7 @@ export function titleMatches(title, query, parsedSeason = null, forceNonStrict =
}
}
return false;
return simMatch;
}
/**