Merge branch 'search3'
Co-Authored-By: Claude Fable 5.1 <[email protected]> # Conflicts: # docs/plan/00-first-version-plan.md
This commit is contained in:
commit
4c7375b52f
20 files changed
+1273
-81
No files matched your search
@@ -0,0 +1,33 @@
|
||||
import { z } from "zod";
|
||||
import { NonNegInt } from "./common.ts";
|
||||
|
||||
// 资源列表快速筛选(SEARCH-3):GET /search/releases 与 GET /sites/{id}/releases 共用。
|
||||
// 口径实现在 @umt/domain release-facets:同一维度多选为 OR,不同维度为 AND;
|
||||
// 计数按其它维度的已选条件统计(0 = 在其它条件下没有结果)。
|
||||
|
||||
export const FacetCount = z.object({ value: z.string(), label: z.string(), count: NonNegInt });
|
||||
export type FacetCount = z.infer<typeof FacetCount>;
|
||||
|
||||
/**
|
||||
* 快速筛选参数 qf:`维度:值,值;维度:值`,值经 encodeURIComponent。
|
||||
* 维度:resolution(2160p/1080p/720p/other)、videoCodec(H.265/H.264/AV1/other)、
|
||||
* releaseType(disc/remux/encode/webdl/hdtv/other)、site(站点 ID)、promotion(free/2x/50%/other/none)、
|
||||
* hdr(DV/HDR10/HDR10+/other/SDR)、releaseGroup(制作组名,不分大小写)、season(季号)、episode(集号 / pack 整季)。
|
||||
*/
|
||||
export const QuickFilterParam = z.string().max(4000).optional();
|
||||
|
||||
export const ReleaseQuickFacets = z.object({
|
||||
resolution: z.array(FacetCount),
|
||||
videoCodec: z.array(FacetCount),
|
||||
releaseType: z.array(FacetCount),
|
||||
/** 站点列表(单站)里只有一项 */
|
||||
site: z.array(FacetCount),
|
||||
promotion: z.array(FacetCount),
|
||||
hdr: z.array(FacetCount),
|
||||
/** 计数最多的前 20 个 + 已选的 */
|
||||
releaseGroup: z.array(FacetCount),
|
||||
/** 没有剧集资源时为空 */
|
||||
season: z.array(FacetCount),
|
||||
episode: z.array(FacetCount),
|
||||
});
|
||||
export type ReleaseQuickFacets = z.infer<typeof ReleaseQuickFacets>;
|
||||
@@ -3,6 +3,9 @@ import { Id, NonNegInt, Timestamp } from "./common.ts";
|
||||
import { MediaCredit, MediaEntityStatus, MediaKind } from "./content.ts";
|
||||
import { ManualAcquisitionRequest } from "./execution.ts";
|
||||
import { InventoryEntry, MediaServerInventory, SlotStatusCounts } from "./organization.ts";
|
||||
import { FacetCount, QuickFilterParam, ReleaseQuickFacets } from "./release-facets.ts";
|
||||
|
||||
export { FacetCount, QuickFilterParam, ReleaseQuickFacets } from "./release-facets.ts";
|
||||
|
||||
// 全局搜索(W9-G,对标 MP 顶栏搜索 + 资源搜索页):
|
||||
// GET /search 聚合本地作品 / TMDB 候选 / 跨站资源 / 页面与操作;GET /search/releases 是资源结果页(筛选/排序/游标,复用同一缓存)。
|
||||
@@ -68,6 +71,8 @@ export const SearchReleaseParsed = z.object({
|
||||
titleEn: z.string().nullable(),
|
||||
year: z.number().int().nullable(),
|
||||
season: z.number().int().nullable(),
|
||||
/** 多季合集的最后一季(S01-S03 = 3);单季 / 电影为 null */
|
||||
seasonEnd: z.number().int().nullable().optional(),
|
||||
episodes: z.object({ start: z.number().int(), end: z.number().int() }).nullable(),
|
||||
resolution: z.string().nullable(),
|
||||
source: z.string().nullable(),
|
||||
@@ -264,10 +269,12 @@ export const ReleaseSearchQuery = z.object({
|
||||
sites: csv,
|
||||
/** 逗号分隔的站点 ID:只筛选结果(仍查 sites 里的全部站点,分面计数不变) */
|
||||
siteFilter: csv,
|
||||
/** 逗号分隔:2160p,1080p… */
|
||||
/** 逗号分隔的解析原值:2160p,1080p…(旧参数;快速筛选用 qf) */
|
||||
resolution: csv,
|
||||
/** 逗号分隔:REMUX,WEB-DL,BluRay… */
|
||||
/** 逗号分隔的解析原值:REMUX,WEB-DL,BluRay…(旧参数;快速筛选用 qf) */
|
||||
source: csv,
|
||||
/** 快速筛选(SEARCH-3):`维度:值,值;维度:值`,同维度 OR、不同维度 AND,见 ReleaseQuickFacets */
|
||||
qf: QuickFilterParam,
|
||||
/** 字节 */
|
||||
minSize: z.coerce.number().int().nonnegative().optional(),
|
||||
maxSize: z.coerce.number().int().nonnegative().optional(),
|
||||
@@ -285,9 +292,6 @@ export const ReleaseSearchQuery = z.object({
|
||||
});
|
||||
export type ReleaseSearchQuery = z.infer<typeof ReleaseSearchQuery>;
|
||||
|
||||
export const FacetCount = z.object({ value: z.string(), label: z.string(), count: NonNegInt });
|
||||
export type FacetCount = z.infer<typeof FacetCount>;
|
||||
|
||||
export const ReleaseSearchPage = z
|
||||
.object({
|
||||
q: z.string(),
|
||||
@@ -299,8 +303,11 @@ export const ReleaseSearchPage = z
|
||||
total: NonNegInt,
|
||||
/** 未筛选的全部条数 */
|
||||
unfilteredTotal: NonNegInt,
|
||||
/** 筛选项计数(基于未筛选的全部结果) */
|
||||
facets: z.object({
|
||||
/**
|
||||
* sites / resolutions / sources:旧的筛选项计数(基于未筛选的全部结果);
|
||||
* 其余为快速筛选分面(SEARCH-3,在其它筛选条件之后、按其它维度的已选条件计数)
|
||||
*/
|
||||
facets: ReleaseQuickFacets.extend({
|
||||
sites: z.array(FacetCount),
|
||||
resolutions: z.array(FacetCount),
|
||||
sources: z.array(FacetCount),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { z } from "zod";
|
||||
import { CursorQuery, DateOnly, EntityBase, Id, JsonObject, NonNegInt, SERVER_MANAGED, Timestamp } from "./common.ts";
|
||||
import { QuickFilterParam, ReleaseQuickFacets } from "./release-facets.ts";
|
||||
|
||||
// 来源域:站点、站点账号、Feed、站点资源、观察(REQ §4)
|
||||
// 含 passkey 的 Feed URL 只以 urlSecretRef 保存,对外只给脱敏的 urlDisplay。
|
||||
@@ -594,6 +595,8 @@ export const WorkbenchReleaseQuery = z.object({
|
||||
resolution: ResolutionStatus.optional(),
|
||||
/** true = 强制实时补查;false = 只看本地快照;缺省 = 本地无结果或快照过期时补查 */
|
||||
live: z.enum(["true", "false"]).optional(),
|
||||
/** 快速筛选(SEARCH-3,格式同 GET /search/releases 的 qf);只筛本地数据,不触发站点请求 */
|
||||
qf: QuickFilterParam,
|
||||
cursor: z.string().min(1).optional(),
|
||||
limit: z.coerce.number().int().min(1).max(200).default(50),
|
||||
});
|
||||
@@ -633,6 +636,12 @@ export const WorkbenchReleasePage = z.object({
|
||||
items: z.array(WorkbenchRelease),
|
||||
nextCursor: z.string().nullable(),
|
||||
coverage: WorkbenchCoverage,
|
||||
/** 快速筛选后的条数 */
|
||||
total: NonNegInt.optional(),
|
||||
/** 快速筛选前的条数(q / 分类 / 促销 / 识别状态筛选之后) */
|
||||
unfilteredTotal: NonNegInt.optional(),
|
||||
/** 快速筛选分面(SEARCH-3,基于本地资源表数据);site 只有本站一项 */
|
||||
facets: ReleaseQuickFacets.optional(),
|
||||
});
|
||||
export type WorkbenchReleasePage = z.infer<typeof WorkbenchReleasePage>;
|
||||
|
||||
|
||||
Reference in new issue
Block a user