"use client"; import { useState, useEffect } from "react"; import { useParams, useRouter } from "next/navigation"; import Link from "next/link"; import { TopNav } from "@/components/layout/top-nav"; import { AmbientParticles } from "@/components/ui/ambient-particles"; import { useApp } from "@/lib/app-context"; import type { StylePack, StyleRefImage } from "@/lib/types"; export default function StyleDetailPage() { const params = useParams<{ id: string }>(); const router = useRouter(); const isNew = params.id === "new"; const { stylePacks, upsertStylePack, deleteStylePack, setSessionStyleId, assets, } = useApp(); const [pack, setPack] = useState(null); useEffect(() => { if (isNew) { const now = Date.now(); setPack({ id: `style-${now.toString(36)}`, name: "", description: "", keywords: [], source: "custom", refImages: [], positivePrompt: "", negativePrompt: "", usageCount: 0, createdAt: now, updatedAt: now, }); } else { const found = stylePacks.find((s) => s.id === params.id); if (found) setPack(found); } }, [params.id, stylePacks, isNew]); if (!pack) { return (

加载中...

); } const handleSave = () => { if (!pack.name.trim()) { alert("请填写风格名称"); return; } upsertStylePack(pack); alert("已保存(占位)"); if (isNew) router.push(`/styles/${pack.id}`); }; const handleApplyToSession = () => { setSessionStyleId(pack.id); alert(`已将风格 "${pack.name}" 应用到当前会话(占位)`); router.push("/"); }; const handleFork = () => { const now = Date.now(); const forked: StylePack = { ...pack, id: `style-${now.toString(36)}`, name: `${pack.name} (副本)`, source: "custom", forkFromId: pack.id, usageCount: 0, createdAt: now, updatedAt: now, }; upsertStylePack(forked); alert("已创建副本(占位)"); router.push(`/styles/${forked.id}`); }; const handleDelete = () => { if (!confirm(`确认删除风格 "${pack.name}"?(占位操作)`)) return; deleteStylePack(pack.id); router.push("/styles"); }; const addRef = () => { const id = `ref-${Date.now()}`; setPack({ ...pack, refImages: [...pack.refImages, { id, url: "", caption: "占位参考图" }], }); }; const removeRef = (id: string) => { setPack({ ...pack, refImages: pack.refImages.filter((r) => r.id !== id) }); }; const addKeyword = (kw: string) => { if (!kw || pack.keywords.includes(kw)) return; setPack({ ...pack, keywords: [...pack.keywords, kw] }); }; const removeKeyword = (kw: string) => { setPack({ ...pack, keywords: pack.keywords.filter((k) => k !== kw) }); }; // 历史预览(按 prompt 关键词简单匹配) const relatedAssets = assets .filter((a) => pack.keywords.some((k) => a.prompt.toLowerCase().includes(k.toLowerCase())) ) .slice(0, 6); return (
{/* 面包屑 */}
风格库 / {isNew ? "新建风格" : pack.name || "未命名"}
{/* 标题 + 操作 */}
setPack({ ...pack, name: e.target.value })} placeholder="风格名称" className="text-2xl font-bold bg-transparent border-none text-[var(--text-primary)] placeholder:text-[var(--text-secondary)]/60 focus:outline-none min-w-0 flex-1" /> Phase 1
{pack.forkFromId && (
Fork 自: {stylePacks.find((s) => s.id === pack.forkFromId)?.name || pack.forkFromId}
)}
{!isNew && ( <> 训练风格 LoRA P2 )}
{/* 左侧:基本信息 + Prompt */}
{/* 描述 */}

风格描述