"use client"; import { useState } from "react"; import { useRouter } from "next/navigation"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Textarea } from "@/components/ui/textarea"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { toast } from "sonner"; import { Upload } from "lucide-react"; export function SoftwareVersionForm({ softwareId }: { softwareId: string }) { const router = useRouter(); const [loading, setLoading] = useState(false); const [downloadType, setDownloadType] = useState("local"); const [wowVersion, setWowVersion] = useState<"1.18" | "1.17">("1.18"); const [uploadedFilePath, setUploadedFilePath] = useState(""); const [fileSize, setFileSize] = useState(0); const [uploading, setUploading] = useState(false); async function handleFileUpload(e: React.ChangeEvent) { const file = e.target.files?.[0]; if (!file) return; setUploading(true); const formData = new FormData(); formData.append("file", file); const res = await fetch("/api/upload", { method: "POST", body: formData }); if (res.ok) { const data = await res.json(); setUploadedFilePath(data.filePath); setFileSize(data.size); toast.success(`文件 ${data.originalName} 上传成功`); } else { toast.error("文件上传失败"); } setUploading(false); } async function handleSubmit(e: React.FormEvent) { e.preventDefault(); setLoading(true); const fd = new FormData(e.currentTarget); if (downloadType === "local" && !uploadedFilePath) { toast.error("请先上传文件"); setLoading(false); return; } const res = await fetch(`/api/software/${softwareId}/versions`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ version: fd.get("version"), versionCode: Number(fd.get("versionCode")), changelog: fd.get("changelog"), changelogEn: fd.get("changelogEn"), downloadType, filePath: downloadType === "local" ? uploadedFilePath : null, externalUrl: downloadType === "url" ? fd.get("externalUrl") : null, fileSize, forceUpdate: fd.get("forceUpdate") === "on", minVersion: fd.get("minVersion") || null, wowVersion, }), }); if (res.ok) { toast.success("版本发布成功"); router.push("/admin/software"); router.refresh(); } else { const err = await res.json(); toast.error(err.error || "发布失败"); } setLoading(false); } return ( 版本信息
{(["1.18", "1.17"] as const).map((v) => ( ))}

同一启动器的两个 WoW 客户端发行渠道独立维护