feat(search): 按作品搜资源时判定每条结果是否属于这部作品

对照 MP TorrentHelper.match_torrent:已识别到同一本地作品(或同一 TMDB 身份)的属于、识别到别的作品的不属于;
未识别的先排除音乐 / 游戏 / 软件 / 书分类,再核对类型、年份(剧集按各季首播年份 ±1)、季集范围(TMDB 季列表,
单季集号可按全部季总集数的绝对集号),最后按解析出的中 / 英文名、标题非英文词、副标题非英文词比对作品名、原名、别名。
不属于的不参与筛选与分面,响应里单独给出(unmatched / unmatchedTotal,只在第一页,最多 200 条),
页面在列表最后折叠为「另有 N 条可能不是这部作品」,展开后仍可下载。关键词搜索不做这一步。
用「药屋少女的呢喃」109 条真实结果做样本:只有《迷宫饭》片尾曲专辑和标题写成 S01-S24 的一条被判为不属于。

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-10-06 15:48:46 +08:00
1 parent f6d976a963
commit 9d7e20067b
9 files changed
+1560 -10

No files matched your search

@@ -1,8 +1,11 @@
import { readFileSync } from "node:fs";
import { fileURLToPath } from "node:url";
import type { MediaServerInventory, WorkInventory } from "@umt/contracts";
import type { MediaServerInventory, SearchRelease, WorkInventory } from "@umt/contracts";
import { createElement } from "react";
import { renderToStaticMarkup } from "react-dom/server";
import { MemoryRouter } from "react-router";
import { describe, expect, it } from "vitest";
import { parseWorkRef, type ReleaseFilterState, toApiFilters } from "./release-results.tsx";
import { parseWorkRef, type ReleaseFilterState, toApiFilters, UnmatchedReleases } from "./release-results.tsx";
import { resolvePick } from "./site-picker-dialog.tsx";
import { inventoryBadge, mediaServerSummary, releaseSearchPath, slotLine, workHref, workRef } from "./work-card.tsx";
@@ -127,3 +130,70 @@ describe("订阅入口位置", () => {
}
});
});
describe("可能不是这部作品的资源", () => {
const rel = (key: string, title: string): SearchRelease => ({
key,
sourceReleaseId: null,
siteId: ID,
siteName: "馒头",
siteReleaseId: key,
title,
subtitle: null,
category: { id: null, name: "音乐" },
sizeBytes: null,
seeders: 3,
leechers: 0,
snatched: null,
promotion: { type: "none", downloadFactor: 1, uploadFactor: 1, expiresAt: null },
free: false,
hr: false,
uploadedAt: null,
detailUrl: "http://x/",
observedAt: "2026-10-06T00:00:00.000Z",
parsed: {
titleCn: null,
titleEn: null,
year: 2023,
season: null,
episodes: null,
resolution: "1080p",
source: "BluRay-Disc",
videoCodec: null,
hdr: [],
releaseGroup: null,
},
mediaEntityId: null,
entityMatch: null,
entity: null,
inventory: null,
ruleVerdict: null,
});
const rows = [rel("a", "Channel U ESCL-6057~9 2023 BDMV 1080p FLAC-@U2")];
const render = (defaultOpen: boolean, total = 1) =>
renderToStaticMarkup(
createElement(
MemoryRouter,
null,
createElement(UnmatchedReleases, { rows, total, onOpen: () => {}, onDownload: () => {}, defaultOpen }),
),
);
it("默认折叠成一行「另有 N 条可能不是这部作品」,不列资源", () => {
const html = render(false);
expect(html).toContain("另有 1 条可能不是这部作品");
expect(html).toContain('aria-expanded="false"');
expect(html).not.toContain("Channel U");
});
it("展开后列出资源,仍有下载按钮", () => {
const html = render(true);
expect(html).toContain('aria-expanded="true"');
expect(html).toContain("Channel U ESCL-6057~9 2023 BDMV 1080p FLAC-@U2");
expect(html).toContain("下载");
});
it("没有时不渲染", () => {
expect(render(false, 0)).toBe("");
});
});