import type { EpisodeGroupList, EpisodeStructureSeason } from "@umt/contracts"; // 季集结构(TMDB 默认季 / 剧集组)的界面纯函数:轨道选项、季卡片文案、切换确认文案。学 MoviePilot 的订阅选季对话框: // 横向轨道选「TMDB 默认 / 各剧集组」,下面按所选结构显示季卡片(海报、季名、首播年、集数、已入库)。 export interface StructureOption { /** 剧集组 id;null = TMDB 默认季 */ groupId: string | null; label: string; /** 第二行:类型 · 季数 · 集数 */ meta: string | null; current: boolean; } export const DEFAULT_STRUCTURE_LABEL = "TMDB 默认季"; /** 轨道选项:TMDB 默认季在最前,其后按 TMDB 顺序列剧集组;当前选择打标 */ export function structureOptions(list: EpisodeGroupList | undefined): StructureOption[] { const cur = list?.current?.groupId ?? null; const out: StructureOption[] = [{ groupId: null, label: DEFAULT_STRUCTURE_LABEL, meta: null, current: cur === null }]; for (const g of list?.groups ?? []) { out.push({ groupId: g.id, label: g.name, meta: [g.typeLabel, `${g.groupCount} 季`, `${g.episodeCount} 集`].filter(Boolean).join(" · "), current: cur === g.id, }); } // 当前选的剧集组已从 TMDB 删除:仍列出来,免得界面上看不到当前状态 if (cur && !out.some((o) => o.groupId === cur)) out.push({ groupId: cur, label: list?.current?.name ?? cur, meta: "TMDB 上已不存在", current: true }); return out; } /** 有剧集组可选时才显示轨道 */ export const hasStructureChoice = (list: EpisodeGroupList | undefined) => !!list?.applicable && (list.groups.length > 0 || !!list.current); export function seasonTitle(s: Pick): string { return s.name ?? (s.seasonNumber === 0 ? "特别篇" : `第 ${s.seasonNumber} 季`); } /** 季卡片第二行:首播年 · 集数 */ export function seasonLine(s: Pick): string { return [s.airDate ? s.airDate.slice(0, 4) : null, `${s.episodeCount} 集`].filter(Boolean).join(" · "); } /** 已入库 x/y;一集都没有时返回 null(只列非零项) */ export function inLibraryText(s: Pick): string | null { return s.inLibrary > 0 ? `已入库 ${s.inLibrary}/${s.episodeCount}` : null; } const pad = (n: number) => String(n).padStart(2, "0"); /** 剧集组里的集与 TMDB 默认季集号不同时给「原 S01E14」对照 */ export function originText( seasonNumber: number, e: { episodeNumber: number; tmdbSeason: number; tmdbEpisode: number }, ): string | null { if (e.tmdbSeason === seasonNumber && e.tmdbEpisode === e.episodeNumber) return null; return `原 S${pad(e.tmdbSeason)}E${pad(e.tmdbEpisode)}`; } /** 切换确认的说明:改的是作品设置,影响季表、集数映射、订阅与刮削 */ export function switchDescription(target: string): string { return `作品改按「${target}」分季:季与集按 TMDB 原季集迁到新位置,已入库文件跟着走;集数映射、订阅和刮削都按新季集,已绑定的资源会重新换算。之后可以再切回来。`; }