fix(web): expose organize recovery and file episode evidence

This commit is contained in:
root committed 2026-10-13 20:26:43 +08:00
1 parent b7883eaf4f
commit 2b3ccb89e4
12 files changed
+390 -72

No files matched your search

@@ -73,6 +73,8 @@ export function EpisodeMappingPanel({ entityId }: { entityId: string }) {
const location = useLocation();
const words = useEntityWords(entityId);
const preview = useEpisodeMappingPreview(entityId, {});
const [editing, setEditing] = useState(false);
const editorRef = useRef<HTMLDetailsElement>(null);
const [draft, setDraft] = useState<string | null>(null);
const ref = useRef<HTMLDivElement>(null);
const saved = words.data?.block.text ?? "";
@@ -80,12 +82,13 @@ export function EpisodeMappingPanel({ entityId }: { entityId: string }) {
/** 把一行追加进草稿(建议、集数待确认的「修改」、从别处跳来带的一行) */
const append = (line: string) => {
setEditing(true);
setDraft((cur) => {
const base = (cur ?? saved).replace(/\n*$/, "");
if (base.split("\n").some((l) => l.trim() === line.trim())) return cur ?? saved;
return `${base ? `${base}\n` : ""}${line}\n`;
});
ref.current?.scrollIntoView({ block: "start", behavior: "smooth" });
editorRef.current?.scrollIntoView({ block: "start", behavior: "smooth" });
};
// 从集数待确认「修改」跳来:把那一行放进草稿并滚到这里
@@ -108,22 +111,33 @@ export function EpisodeMappingPanel({ entityId }: { entityId: string }) {
bodyClassName="space-y-4"
>
{preview.data ? <SeasonSummary p={preview.data.seasons} /> : null}
{words.isPending ? (
<LoadingState rows={3} />
) : words.isError ? (
<ErrorState plain error={words.error} onRetry={() => words.refetch()} />
) : (
<WordsEditor
scope="entity"
entityId={entityId}
block={words.data.block}
knownGroups={words.data.knownGroups}
draft={text}
onDraftChange={setDraft}
/>
)}
{preview.data ? <GroupStats groups={preview.data.groups} onUseSuggestion={append} /> : null}
<EpisodeIssuesList entityId={entityId} onEdit={append} />
<details
ref={editorRef}
open={editing}
onToggle={(event) => setEditing(event.currentTarget.open)}
className="space-y-3"
>
<summary className="cursor-pointer text-caption text-foreground">作品识别词 · 长期规则</summary>
<p className="text-meta text-muted-foreground">
按来源季和发布组换算季集,保存后用于这部作品后续的资源与整理文件。
</p>
{words.isPending ? (
<LoadingState rows={3} />
) : words.isError ? (
<ErrorState plain error={words.error} onRetry={() => words.refetch()} />
) : (
<WordsEditor
scope="entity"
entityId={entityId}
block={words.data.block}
knownGroups={words.data.knownGroups}
draft={text}
onDraftChange={setDraft}
/>
)}
</details>
{preview.data ? <GroupStats groups={preview.data.groups} onUseSuggestion={append} /> : null}
</Panel>
<Panel
className="mt-3"