Merge branch 'search4'

Co-Authored-By: Claude Fable 5.1 <[email protected]>

# Conflicts:
#	docs/plan/00-first-version-plan.md
This commit is contained in:
root committed 2026-09-30 22:41:26 +08:00
commit 511ad93077
20 files changed
+773 -94

No files matched your search

+16 -38
View File
@@ -56,33 +56,19 @@ const RESOLUTION: { value: ResolutionStatus; label: string }[] = [
{ value: "ambiguous", label: "有歧义" },
{ value: "unidentifiable", label: "无法识别" },
];
const SIZE = [
{ value: "lt5", label: "< 5 GB" },
{ value: "5to20", label: "5–20 GB" },
{ value: "20to60", label: "20–60 GB" },
{ value: "gt60", label: "> 60 GB" },
];
const AGE = [
{ value: "1", label: "24 小时内" },
{ value: "7", label: "7 天内" },
{ value: "30", label: "30 天内" },
];
const GB = 1024 ** 3;
/** 服务端不支持的维度(做种/大小/上传时间)在已加载结果里筛选,界面上写明;H&R 在快速筛选里(POLISH-1) */
type LocalFilters = { seeding: string; size: string; age: string };
/**
* 服务端不支持的维度(上传时间)在已加载结果里筛选,界面上写明。H&R(POLISH-1)、做种与大小(SEARCH-4)
* 在快速筛选里,按全部本地资源计数和筛选。
*/
type LocalFilters = { age: string };
function localMatch(r: WorkbenchRelease, f: LocalFilters, now: number) {
if (f.seeding === "alive" && !(r.seeders && r.seeders > 0)) return false;
if (f.seeding === "hot" && !(r.seeders && r.seeders >= 20)) return false;
if (f.size) {
const s = r.sizeBytes;
if (s === null) return false;
if (f.size === "lt5" && s >= 5 * GB) return false;
if (f.size === "5to20" && (s < 5 * GB || s >= 20 * GB)) return false;
if (f.size === "20to60" && (s < 20 * GB || s >= 60 * GB)) return false;
if (f.size === "gt60" && s < 60 * GB) return false;
}
if (f.age) {
const t = r.sourcePublishedAt ? new Date(r.sourcePublishedAt).getTime() : null;
if (t === null || now - t > Number(f.age) * 86_400_000) return false;
@@ -151,7 +137,7 @@ export default function SiteWorkbenchPage() {
const q = useDebounced(qInput.trim());
const [category, setCategory] = useState("");
const [resolution, setResolution] = useState("");
const [local, setLocal] = useState<LocalFilters>({ seeding: "", size: "", age: "" });
const [local, setLocal] = useState<LocalFilters>({ age: "" });
// 快速筛选(SEARCH-3):服务端按本地资源表数据统计与筛选,不触发站点请求
const [quick, setQuick] = useQuickFilters("site");
const qf = formatQuickFilter(quick);
@@ -202,7 +188,7 @@ export default function SiteWorkbenchPage() {
setCategory("");
setQuick({});
setResolution("");
setLocal({ seeding: "", size: "", age: "" });
setLocal({ age: "" });
};
const anyFilter = !!(qInput || category || resolution || localActive || selectedCount(quick));
@@ -377,21 +363,6 @@ export default function SiteWorkbenchPage() {
>
<FilterSelect label="分类" value={category} onChange={setCategory} options={categories} />
<FilterSelect label="识别" value={resolution} onChange={setResolution} options={RESOLUTION} />
<FilterSelect
label="做种"
value={local.seeding}
onChange={(v) => setLocal((l) => ({ ...l, seeding: v }))}
options={[
{ value: "alive", label: "有人做种" },
{ value: "hot", label: "≥ 20 做种" },
]}
/>
<FilterSelect
label="大小"
value={local.size}
onChange={(v) => setLocal((l) => ({ ...l, size: v }))}
options={SIZE}
/>
<FilterSelect
label="上传"
value={local.age}
@@ -401,7 +372,14 @@ export default function SiteWorkbenchPage() {
</FilterBar>
{/* 「清除筛选」在上方筛选行,一并清掉快速筛选 */}
<QuickFilterBar facets={pages[0]?.facets} value={quick} onChange={setQuick} hide={["site"]} hideClear />
{/* 分类已有上方的站点分类下拉(与 MP 站点资源一致),不再给分面 */}
<QuickFilterBar
facets={pages[0]?.facets}
value={quick}
onChange={setQuick}
hide={["site", "category"]}
hideClear
/>
{coverage || refreshFailed ? (
<CoverageBanner coverage={coverage} refreshError={refreshFailed ? releases.error : null} />
@@ -429,7 +407,7 @@ export default function SiteWorkbenchPage() {
}
description={
all.length
? "做种、大小、上传时间只筛选已加载的结果。加载更多或放宽条件。"
? "上传时间只筛选已加载的结果。加载更多或放宽条件。"
: quickHidden
? "减少快速筛选条件再看。"
: coverage?.liveError