import { useCallback, useEffect, useState } from "react"; import { X } from "lucide-react"; import { adminApi } from "../../api"; import { IconKitSvg } from "../../components/IconKitSvg"; import type { AdminQualityWord } from "../../types"; type Notify = (type: "success" | "error" | "info", text: string) => void; // 与后端 QualityWord.Stage 对齐(生成侧已接入这 4 个阶段) const STAGES = [ { key: "person", label: "人物立绘" }, { key: "model_tryon", label: "模特上身图" }, { key: "storyboard", label: "故事板" }, { key: "video", label: "视频" } ]; export function AdminQualityPage({ notify }: { notify: Notify }) { const [words, setWords] = useState([]); const [loading, setLoading] = useState(true); const [editMode, setEditMode] = useState(false); const [adding, setAdding] = useState>({}); const load = useCallback(async () => { setLoading(true); try { setWords(await adminApi.qualityWords()); } catch { notify("error", "加载质量词失败"); } finally { setLoading(false); } // eslint-disable-next-line react-hooks/exhaustive-deps }, []); useEffect(() => { void load(); }, [load]); async function add(stage: string) { const text = (adding[stage] || "").trim(); if (!text) return; try { await adminApi.createQualityWord({ stage, text }); setAdding((a) => ({ ...a, [stage]: "" })); notify("success", "已添加质量词"); await load(); } catch { notify("error", "添加失败"); } } async function saveText(w: AdminQualityWord, text: string) { const t = text.trim(); if (!t || t === w.text) return; try { await adminApi.updateQualityWord(w.id, { text: t }); notify("success", "已更新"); await load(); } catch { notify("error", "更新失败"); } } async function del(w: AdminQualityWord) { try { await adminApi.deleteQualityWord(w.id); notify("success", "已删除"); await load(); } catch { notify("error", "删除失败"); } } return ( <>

质量词

// 平台单层 · 各生成阶段的画质 / 风格词,留空则用默认
{loading ? (

加载中…

// fetching quality words

) : (
{STAGES.map((s) => { const ws = words.filter((w) => w.stage === s.key); return (
{s.label} // {s.key}
{ws.length === 0 && !editMode &&
未配置 · 使用默认质量词
}
{ws.map((w) => editMode ? ( saveText(w, e.target.value)} onKeyDown={(e) => { if (e.key === "Enter") e.currentTarget.blur(); }} /> ) : ( {w.text} ) )} {editMode && ( setAdding((a) => ({ ...a, [s.key]: e.target.value }))} onKeyDown={(e) => { if (e.key === "Enter") { e.preventDefault(); void add(s.key); } }} /> )}
); })}
)} ); }