import { useState, useEffect } from "react"; import { useNavigate, useParams } from "react-router-dom"; import { adminFetch } from "./adminApi"; type Music = { id: string; title: string; subtitle: string | null; audioFile: string; sortOrder: number; enabled: boolean; }; export default function MusicForm() { const { id } = useParams(); const navigate = useNavigate(); const isEdit = !!id; const [title, setTitle] = useState(""); const [subtitle, setSubtitle] = useState(""); const [audioFile, setAudioFile] = useState(""); const [sortOrder, setSortOrder] = useState(0); const [enabled, setEnabled] = useState(true); const [uploading, setUploading] = useState(false); const [saving, setSaving] = useState(false); const [error, setError] = useState(""); useEffect(() => { if (!id) return; adminFetch("/music").then((list) => { const item = list.find((m) => m.id === id); if (item) { setTitle(item.title); setSubtitle(item.subtitle || ""); setAudioFile(item.audioFile); setSortOrder(item.sortOrder); setEnabled(item.enabled); } }); }, [id]); const handleUpload = async (file: File) => { if (!id) { setError("请先保存后再上传音频"); return; } setError(""); setUploading(true); try { const formData = new FormData(); formData.append("audio", file); const data = await adminFetch<{ path: string }>(`/music/${id}/upload`, { method: "POST", body: formData, }); setAudioFile(data.path); } catch (e) { setError(e instanceof Error ? e.message : "上传失败"); } finally { setUploading(false); } }; const handleSave = async () => { setError(""); if (!title.trim()) { setError("请输入标题"); return; } setSaving(true); try { const payload = { title: title.trim(), subtitle: subtitle.trim() || undefined, sortOrder, enabled, }; if (isEdit) { await adminFetch(`/music/${id}`, { method: "PUT", body: JSON.stringify(payload), }); } else { const music = await adminFetch("/music", { method: "POST", body: JSON.stringify(payload), }); navigate(`/admin/music/${music.id}/edit`, { replace: true }); return; } navigate("/admin/music"); } catch (e) { setError(e instanceof Error ? e.message : "保存失败"); } finally { setSaving(false); } }; return (

{isEdit ? "编辑音乐" : "添加音乐"}

setTitle(e.target.value)} placeholder="如:朝天宫之歌" className="w-full px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-1 focus:ring-blue-500" />
setSubtitle(e.target.value)} placeholder="选填,如:金陵千年韵" className="w-full px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-1 focus:ring-blue-500" />
setSortOrder(Number(e.target.value))} className="w-24 px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-1 focus:ring-blue-500" />
{isEdit && (
{audioFile && (
)} {!isEdit && (

保存后可上传音频文件

)} {error &&

{error}

}
); }