refactor(copy): 术语统一——收录版本、模型服务、智能体等(DEAI-2)
- 版本目标 → 收录版本(前后端用户可见字符串、能力描述、给模型的提示) - Agent 上游 / 上游 → 模型服务;界面上的 Agent / Agent 会话 → 智能体 / 智能体会话 - 身份歧义 / 识别有歧义 / 无法确定作品 → 没识别出作品;待识别(池) → 未识别 - 建档 → 加入媒体库;资产 → 文件;库根 → 媒体库目录;纳管 → 本工具 / 外部任务; 哨兵 → 标记文件 / 检查目录;站点快照 → 抓取;Feed / RSS 订阅 / 来源健康 → RSS - 代码标识符、API 字段名、迁移文件不改;glossary.md 同步;smoke 选择器跟随 Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
d282212a6b
commit
4480fc346d
212 files changed
+741
-715
No files matched your search
@@ -216,7 +216,7 @@ export function DeleteSubscriptionsDialog({
|
||||
open={open}
|
||||
onOpenChange={onOpenChange}
|
||||
title={ids.length > 1 ? `删除 ${ids.length} 个订阅?` : "删除这个订阅?"}
|
||||
description="不再搜索和追更。已入库文件、版本目标和下载记录保留,可在订阅历史里重新订阅。"
|
||||
description="不再搜索和追更。已入库文件、收录版本和下载记录保留,可在订阅历史里重新订阅。"
|
||||
confirmLabel="删除"
|
||||
destructive
|
||||
onConfirm={() =>
|
||||
|
||||
@@ -22,7 +22,7 @@ import {
|
||||
seasonTitle,
|
||||
} from "./model.ts";
|
||||
|
||||
// 覆盖矩阵(设计 §2.1):列 = 集(电影 = 内容版本),行 = 版本目标,首行"库内任一版本"。
|
||||
// 覆盖矩阵(设计 §2.1):列 = 集(电影 = 内容版本),行 = 收录版本,首行"库内任一版本"。
|
||||
// 底色无彩,只有状态用状态色:已入库 success、缺失 destructive、可升级/延后 warning;在途用斜纹。
|
||||
|
||||
type Row = SubscriptionCoverage["rows"][number];
|
||||
@@ -120,7 +120,7 @@ export function CoverageMatrix({
|
||||
scope="col"
|
||||
className="sticky left-0 z-10 bg-surface-raised pr-2 text-left font-normal text-muted-foreground"
|
||||
>
|
||||
版本目标
|
||||
收录版本
|
||||
</th>
|
||||
{cols.map((c) => (
|
||||
<th
|
||||
@@ -238,7 +238,7 @@ export function CellSheet({
|
||||
}
|
||||
}}
|
||||
title={sel ? `${sel.season} · ${columnLabel(sel.col)}` : ""}
|
||||
description={sel ? `${sel.row.name}${sel.row.slotId === null ? "(作品全部资产)" : ""}` : null}
|
||||
description={sel ? `${sel.row.name}${sel.row.slotId === null ? "(作品全部文件)" : ""}` : null}
|
||||
footer={
|
||||
sel && c ? (
|
||||
<>
|
||||
@@ -284,7 +284,7 @@ export function CellSheet({
|
||||
{ label: "pri", value: c.pri !== null ? String(c.pri) : null },
|
||||
{ label: "可升级", value: c.state === "have" ? (c.upgradable ? "是,低于目标档位" : "否") : null },
|
||||
{
|
||||
label: "资产",
|
||||
label: "文件",
|
||||
value: c.assetId ? (
|
||||
mediaEntityId ? (
|
||||
<Link
|
||||
@@ -316,7 +316,7 @@ export function CellSheet({
|
||||
</p>
|
||||
) : null}
|
||||
{sel.row.slotId === null && c.state === "missing" ? (
|
||||
<p className="text-meta text-muted-foreground">这一行汇总全部版本。要补全,点具体版本目标那一行的格。</p>
|
||||
<p className="text-meta text-muted-foreground">这一行汇总全部版本。要补全,点具体收录版本那一行的格。</p>
|
||||
) : null}
|
||||
</>
|
||||
) : null}
|
||||
|
||||
@@ -86,7 +86,7 @@ describe("覆盖矩阵格", () => {
|
||||
expect(moveItem(["a", "b", "c"], 2, 0)).toEqual(["c", "a", "b"]);
|
||||
expect(moveItem(["a", "b"], 0, 5)).toEqual(["a", "b"]);
|
||||
});
|
||||
it("升级策略取自版本目标", () => {
|
||||
it("升级策略取自收录版本", () => {
|
||||
expect(upgradeOf([{ upgradeThreshold: {} }], "series")).toBe("off");
|
||||
expect(upgradeOf([{ upgradeThreshold: { enabled: true, mode: "full_pack" } }], "series")).toBe("full_pack");
|
||||
expect(upgradeOf([{ upgradeThreshold: { enabled: true } }], "movie")).toBe("movie");
|
||||
|
||||
@@ -55,7 +55,7 @@ export function seasonLabel(
|
||||
return x.seasonScope === "following_seasons" && x.seasonNumber > 0 ? `${base} 起` : base;
|
||||
}
|
||||
|
||||
/** 版本目标徽标:洗版中 → 在途 → 缺 N → 已齐;都没有 → 已入库 N */
|
||||
/** 收录版本徽标:洗版中 → 在途 → 缺 N → 已齐;都没有 → 已入库 N */
|
||||
export function slotBadge(s: SubscriptionSlotSummary): ToneLabel {
|
||||
if (s.upgrading)
|
||||
return {
|
||||
@@ -136,7 +136,7 @@ export const PLAN_STAGE: Record<string, string> = { reserved: "已预留", downl
|
||||
export const SKIP_REASON: Record<string, string> = {
|
||||
out_of_range: "集范围外",
|
||||
not_aired: "未播出",
|
||||
not_required: "该版本目标不要求这个内容版本",
|
||||
not_required: "该收录版本不要求这个内容版本",
|
||||
suspected: "总集数未知,按已见最高集推断",
|
||||
deferred: "有延后的资源",
|
||||
};
|
||||
@@ -155,7 +155,7 @@ export function seasonTitle(s: SubscriptionCoverage["seasons"][number], kind: Su
|
||||
return s.seasonNumber === 0 ? "特别篇" : `第 ${s.seasonNumber} 季`;
|
||||
}
|
||||
|
||||
// ── 版本目标 ──
|
||||
// ── 收录版本 ──
|
||||
|
||||
export type UpgradeStrategy = "off" | "per_unit" | "full_pack" | "movie";
|
||||
export const UPGRADE_LABEL: Record<UpgradeStrategy, string> = {
|
||||
@@ -165,7 +165,7 @@ export const UPGRADE_LABEL: Record<UpgradeStrategy, string> = {
|
||||
movie: "洗版",
|
||||
};
|
||||
|
||||
/** 订阅版本目标当前的升级策略:任一开启取其 mode */
|
||||
/** 订阅收录版本当前的升级策略:任一开启取其 mode */
|
||||
export function upgradeOf(
|
||||
slots: Pick<AcquisitionSlot, "upgradeThreshold">[],
|
||||
kind: SubscriptionMediaKind,
|
||||
@@ -231,7 +231,7 @@ export type SubscriptionDraft = {
|
||||
include: string;
|
||||
exclude: string;
|
||||
keywords: string;
|
||||
/** MP 分辨率 / 资源质量 / 特效预设(写到该订阅自己的版本目标) */
|
||||
/** MP 分辨率 / 资源质量 / 特效预设(写到该订阅自己的收录版本) */
|
||||
resolution: SubscriptionResolution | "";
|
||||
source: SubscriptionSourcePreset | "";
|
||||
effect: SubscriptionEffect | "";
|
||||
@@ -334,7 +334,7 @@ const isInt = (s: string) => /^\d+$/.test(s.trim());
|
||||
|
||||
/**
|
||||
* 草稿 → params(PATCH 整体替换,所以以现有 params 为底保留未知键)。
|
||||
* upgradeChanged:只有升级策略改了才带 best_version(否则每次保存都会 bump 版本目标 revision)。
|
||||
* upgradeChanged:只有升级策略改了才带 best_version(否则每次保存都会 bump 收录版本 revision)。
|
||||
*/
|
||||
export function draftToParams(
|
||||
d: SubscriptionDraft,
|
||||
|
||||
@@ -26,7 +26,9 @@ function Flags({ x }: { x: Item }) {
|
||||
return (
|
||||
<>
|
||||
{x.group === "paused" ? <StatusBadge tone="neutral">暂停</StatusBadge> : null}
|
||||
{x.group === "pending" ? <StatusBadge tone="warning">{x.mediaEntityId ? "待定" : "尚未建档"}</StatusBadge> : null}
|
||||
{x.group === "pending" ? (
|
||||
<StatusBadge tone="warning">{x.mediaEntityId ? "待定" : "不在媒体库"}</StatusBadge>
|
||||
) : null}
|
||||
{x.upgrading ? <StatusBadge tone="warning">洗版中</StatusBadge> : null}
|
||||
{x.awaitingNewSeason ? <StatusBadge tone="success">等待新季</StatusBadge> : null}
|
||||
</>
|
||||
@@ -72,7 +74,7 @@ export function ProgressBlock({ x, className }: { x: Pick<Item, "progress" | "mo
|
||||
}
|
||||
|
||||
export function SlotBadges({ slots, max = 4 }: { slots: Item["slots"]; max?: number }) {
|
||||
if (slots.length === 0) return <span className="text-meta text-muted-foreground">没有版本目标</span>;
|
||||
if (slots.length === 0) return <span className="text-meta text-muted-foreground">没有收录版本</span>;
|
||||
return (
|
||||
<div className="flex min-w-0 flex-wrap gap-1">
|
||||
{slots.slice(0, max).map((s) => {
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Button } from "~/components/ui/button.tsx";
|
||||
import { cn } from "~/lib/utils.ts";
|
||||
import { moveItem } from "./model.ts";
|
||||
|
||||
// 版本目标排序:拖动(桌面)或上移/下移(键盘、手机)。第一个是主版本。
|
||||
// 收录版本排序:拖动(桌面)或上移/下移(键盘、手机)。第一个是主版本。
|
||||
|
||||
export function SlotOrderList<T extends { id: string; name: string }>({
|
||||
items,
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
import { SlotOrderList } from "./slot-order.tsx";
|
||||
import { AutoFillFields } from "./subscription-form.tsx";
|
||||
|
||||
// 对比视图的"版本目标"区(设计 §2.2):拖动排序(PUT slot-order)、行尾计数、补全此版本、自动补全开关与预算。
|
||||
// 对比视图的"收录版本"区(设计 §2.2):拖动排序(PUT slot-order)、行尾计数、补全此版本、自动补全开关与预算。
|
||||
|
||||
type SlotRow = SubscriptionCoverage["rows"][number] & { id: string };
|
||||
|
||||
@@ -83,7 +83,7 @@ export function SlotPanel({
|
||||
|
||||
return (
|
||||
<Panel
|
||||
title="版本目标"
|
||||
title="收录版本"
|
||||
description="拖动调整顺序,第一个是主版本。主版本缺的照常追更;其他版本按下面的自动补全设置补齐。"
|
||||
actions={
|
||||
dirty ? (
|
||||
@@ -101,7 +101,7 @@ export function SlotPanel({
|
||||
>
|
||||
{rows.length === 0 ? (
|
||||
<p className="text-caption text-muted-foreground">
|
||||
{sub.mediaEntityId ? "还没有版本目标。在下方规则区新建。" : "作品建档后才有版本目标。"}
|
||||
{sub.mediaEntityId ? "还没有收录版本。在下方规则区新建。" : "作品加入媒体库后才有收录版本。"}
|
||||
</p>
|
||||
) : (
|
||||
<SlotOrderList
|
||||
|
||||
@@ -173,7 +173,7 @@ function WorkPicker({ onPick, error }: { onPick: (t: Target) => void; error?: st
|
||||
kind: "title",
|
||||
titleQuery: c.year ? `${c.title} ${c.year}` : c.title,
|
||||
mediaKind: c.entityType === "movie" ? "movie" : "series",
|
||||
note: `TMDB ${c.externalId},建档失败,按标题追踪`,
|
||||
note: `TMDB ${c.externalId},加入媒体库失败,按标题追踪`,
|
||||
});
|
||||
};
|
||||
const row = (key: string, main: ReactNode, sub: string, onClick: () => void) => (
|
||||
@@ -321,7 +321,7 @@ export function SubscriptionFormDialog({
|
||||
const [totalTouched, setTotalTouched] = useState(false);
|
||||
const [errors, setErrors] = useState<DraftErrors & { target?: string }>({});
|
||||
const [dup, setDup] = useState<string | null>(null);
|
||||
// 编辑:版本目标到了再回填升级策略
|
||||
// 编辑:收录版本到了再回填升级策略
|
||||
useEffect(() => {
|
||||
if (sub && slotsQ.isSuccess && !upgradeTouched) setD((x) => ({ ...x, upgrade: initialUpgrade }));
|
||||
}, [sub, slotsQ.isSuccess, initialUpgrade, upgradeTouched]);
|
||||
@@ -454,7 +454,7 @@ export function SubscriptionFormDialog({
|
||||
<DialogHeader>
|
||||
<DialogTitle>{editing ? "编辑订阅" : "新建订阅"}</DialogTitle>
|
||||
<DialogDescription>
|
||||
{editing ? titleText : initialTarget ? titleText : "从媒体库或 TMDB 选作品;选 TMDB 条目会先建档。"}
|
||||
{editing ? titleText : initialTarget ? titleText : "从媒体库或 TMDB 选作品;选 TMDB 条目会先加入媒体库。"}
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
{dup ? (
|
||||
@@ -497,8 +497,8 @@ export function SubscriptionFormDialog({
|
||||
{target.kind === "entity"
|
||||
? "媒体库作品"
|
||||
: target.kind === "tmdb"
|
||||
? "TMDB 条目,保存时建档"
|
||||
: (target.note ?? "按标题追踪,尚未建档")}
|
||||
? "TMDB 条目,保存时加入媒体库"
|
||||
: (target.note ?? "按标题追踪,不在媒体库")}
|
||||
</p>
|
||||
</div>
|
||||
{initialTarget ? null : (
|
||||
@@ -541,7 +541,9 @@ export function SubscriptionFormDialog({
|
||||
<FormField
|
||||
label="季"
|
||||
htmlFor={f("season")}
|
||||
hint={editing ? "季建好后不能改;要换季就新建订阅" : entityId ? undefined : "作品建档后可选季"}
|
||||
hint={
|
||||
editing ? "季建好后不能改;要换季就新建订阅" : entityId ? undefined : "作品加入媒体库后可选季"
|
||||
}
|
||||
>
|
||||
<Pick
|
||||
id={f("season")}
|
||||
@@ -648,7 +650,7 @@ export function SubscriptionFormDialog({
|
||||
options={(dls.data?.items ?? []).map((x) => ({ value: x.id, label: x.name }))}
|
||||
/>
|
||||
</FormField>
|
||||
<FormField label="库根" htmlFor={f("root")}>
|
||||
<FormField label="媒体库目录" htmlFor={f("root")}>
|
||||
<Pick
|
||||
id={f("root")}
|
||||
value={d.libraryRootId}
|
||||
@@ -668,12 +670,12 @@ export function SubscriptionFormDialog({
|
||||
</FormField>
|
||||
</Section>
|
||||
|
||||
<Section title="版本目标">
|
||||
<Section title="收录版本">
|
||||
{editing ? (
|
||||
slotsQ.isPending ? (
|
||||
<p className="text-caption text-muted-foreground">读取版本目标…</p>
|
||||
<p className="text-caption text-muted-foreground">读取收录版本…</p>
|
||||
) : subSlots.length === 0 ? (
|
||||
<p className="text-caption text-muted-foreground">还没有版本目标。在对比视图里新建。</p>
|
||||
<p className="text-caption text-muted-foreground">还没有收录版本。在对比视图里新建。</p>
|
||||
) : (
|
||||
<FormField label="顺序" htmlFor={f("order")} hint="第一个是主版本;其他版本按自动补全设置补齐">
|
||||
<SlotOrderList
|
||||
@@ -689,8 +691,8 @@ export function SubscriptionFormDialog({
|
||||
htmlFor={f("tpl")}
|
||||
hint={
|
||||
target?.kind === "entity"
|
||||
? "作品还没有版本目标时按模板顺序创建,第一个是主版本"
|
||||
: "作品建档后按模板创建版本目标"
|
||||
? "作品还没有收录版本时按模板顺序创建,第一个是主版本"
|
||||
: "作品加入媒体库后按模板创建收录版本"
|
||||
}
|
||||
>
|
||||
<Pick
|
||||
@@ -708,7 +710,7 @@ export function SubscriptionFormDialog({
|
||||
<FormField
|
||||
label="升级策略"
|
||||
htmlFor={f("upgrade")}
|
||||
hint="作用于这个订阅的全部版本目标;已入库低于目标档位时继续找更好的"
|
||||
hint="作用于这个订阅的全部收录版本;已入库低于目标档位时继续找更好的"
|
||||
>
|
||||
<Pick
|
||||
id={f("upgrade")}
|
||||
@@ -730,7 +732,7 @@ export function SubscriptionFormDialog({
|
||||
<FormField
|
||||
label="规则组"
|
||||
htmlFor={f("groups")}
|
||||
hint="按选择顺序串联;不选 = 订阅默认规则组。版本目标自己的规则组另算"
|
||||
hint="按选择顺序串联;不选 = 订阅默认规则组。收录版本自己的规则组另算"
|
||||
>
|
||||
{groups.isPending ? (
|
||||
<p className="text-caption text-muted-foreground">读取规则组…</p>
|
||||
@@ -810,7 +812,7 @@ export function SubscriptionFormDialog({
|
||||
</FormField>
|
||||
</div>
|
||||
<p className="text-meta text-muted-foreground">
|
||||
分辨率、资源质量、特效写进这个订阅自己的版本目标;UHD 和杜比全景声按标题匹配,与「包含」同时生效。
|
||||
分辨率、资源质量、特效写进这个订阅自己的收录版本;UHD 和杜比全景声按标题匹配,与「包含」同时生效。
|
||||
</p>
|
||||
<FormField
|
||||
label="搜索关键词"
|
||||
|
||||
Reference in new issue
Block a user