fix: 支持追加队列批量上传PSD字体
This commit is contained in:
parent
3ee9701a50
commit
9362b25593
@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import Link from "next/link";
|
||||
import { useEffect, useMemo, useState, type ChangeEvent } from "react";
|
||||
import { useEffect, useMemo, useRef, useState, type ChangeEvent } from "react";
|
||||
import useSWR from "swr";
|
||||
import { toast } from "sonner";
|
||||
import {
|
||||
@ -104,6 +104,26 @@ function normalizeManagedBrandName(value?: string | null) {
|
||||
return normalized;
|
||||
}
|
||||
|
||||
function getQueuedFontFileKey(file: File) {
|
||||
return [file.name, file.size, file.lastModified].join("__");
|
||||
}
|
||||
|
||||
function mergeQueuedFontFiles(current: File[], incoming: File[]) {
|
||||
const merged = [...current];
|
||||
const seen = new Set(current.map((file) => getQueuedFontFileKey(file)));
|
||||
|
||||
for (const file of incoming) {
|
||||
const key = getQueuedFontFileKey(file);
|
||||
if (seen.has(key)) {
|
||||
continue;
|
||||
}
|
||||
seen.add(key);
|
||||
merged.push(file);
|
||||
}
|
||||
|
||||
return merged;
|
||||
}
|
||||
|
||||
function hasTemplateCategoryTag(tags: string[] | undefined, target: string) {
|
||||
const normalizedTarget = String(target || "").trim().toLowerCase();
|
||||
if (!normalizedTarget) {
|
||||
@ -258,6 +278,7 @@ export function PsdTemplatesSettingsClient({
|
||||
const [fontFamily, setFontFamily] = useState("");
|
||||
const [fontUploadBrandName, setFontUploadBrandName] = useState("");
|
||||
const [fontUploadFiles, setFontUploadFiles] = useState<File[]>([]);
|
||||
const fontFileInputRef = useRef<HTMLInputElement | null>(null);
|
||||
const [isCreating, setIsCreating] = useState(false);
|
||||
const [isCreatingAndParsing, setIsCreatingAndParsing] = useState(false);
|
||||
const [templateUploadPercent, setTemplateUploadPercent] = useState(0);
|
||||
@ -487,9 +508,13 @@ export function PsdTemplatesSettingsClient({
|
||||
|
||||
function handleFontFileChange(event: ChangeEvent<HTMLInputElement>) {
|
||||
const nextFiles = Array.from(event.target.files || []);
|
||||
setFontUploadFiles(nextFiles);
|
||||
if (nextFiles.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (nextFiles.length === 1) {
|
||||
setFontUploadFiles((current) => mergeQueuedFontFiles(current, nextFiles));
|
||||
|
||||
if (fontUploadFiles.length === 0 && nextFiles.length === 1) {
|
||||
const normalizedName = nextFiles[0]?.name.replace(/\.[^.]+$/, "") || "";
|
||||
if (normalizedName && !fontUploadName.trim()) {
|
||||
setFontUploadName(normalizedName);
|
||||
@ -498,6 +523,23 @@ export function PsdTemplatesSettingsClient({
|
||||
setFontFamily(normalizedName);
|
||||
}
|
||||
}
|
||||
|
||||
event.currentTarget.value = "";
|
||||
}
|
||||
|
||||
function handleRemoveQueuedFontFile(file: File) {
|
||||
setFontUploadFiles((current) =>
|
||||
current.filter(
|
||||
(item) => getQueuedFontFileKey(item) !== getQueuedFontFileKey(file)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function handleClearQueuedFontFiles() {
|
||||
setFontUploadFiles([]);
|
||||
if (fontFileInputRef.current) {
|
||||
fontFileInputRef.current.value = "";
|
||||
}
|
||||
}
|
||||
|
||||
async function saveCategoryTagConfig(nextTags: string[]) {
|
||||
@ -734,6 +776,9 @@ export function PsdTemplatesSettingsClient({
|
||||
setFontFamily("");
|
||||
setFontUploadBrandName("");
|
||||
setFontUploadFiles([]);
|
||||
if (fontFileInputRef.current) {
|
||||
fontFileInputRef.current.value = "";
|
||||
}
|
||||
await mutateFonts();
|
||||
} catch (error) {
|
||||
toast.error(error instanceof Error ? error.message : "字体上传失败");
|
||||
@ -1435,11 +1480,15 @@ export function PsdTemplatesSettingsClient({
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="psdFontFile">字体文件</Label>
|
||||
<Input
|
||||
ref={fontFileInputRef}
|
||||
id="psdFontFile"
|
||||
type="file"
|
||||
accept=".ttf,.otf,.woff,.woff2"
|
||||
multiple
|
||||
onChange={handleFontFileChange}
|
||||
onClick={(event) => {
|
||||
event.currentTarget.value = "";
|
||||
}}
|
||||
/>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{fontUploadFiles.length > 0
|
||||
@ -1448,13 +1497,55 @@ export function PsdTemplatesSettingsClient({
|
||||
: `已选择 ${fontUploadFiles.length} 个字体文件:${fontUploadFiles
|
||||
.map((file) => file.name)
|
||||
.join("、")}`
|
||||
: "支持一次选择多个字体文件批量上传,建议按实际字重分别整理后再导入"}
|
||||
: "支持一次多选,也支持多次继续添加字体文件后再批量上传"}
|
||||
</p>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{fontUploadFiles.length > 1
|
||||
? "批量上传时会使用每个文件名作为字体名称;如果填写了 CSS 字体族,会批量应用到这一批字体。"
|
||||
: "单个上传时可自定义字体名称和 CSS 字体族。"}
|
||||
</p>
|
||||
{fontUploadFiles.length > 0 ? (
|
||||
<div className="space-y-2 rounded-xl border border-dashed p-3">
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
<div className="text-xs font-medium text-muted-foreground">
|
||||
待上传文件队列
|
||||
</div>
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="h-7 px-2 text-xs"
|
||||
onClick={handleClearQueuedFontFiles}
|
||||
>
|
||||
清空已选
|
||||
</Button>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
{fontUploadFiles.map((file) => (
|
||||
<div
|
||||
key={getQueuedFontFileKey(file)}
|
||||
className="flex items-center justify-between gap-3 rounded-lg border bg-background/60 px-3 py-2"
|
||||
>
|
||||
<div className="min-w-0">
|
||||
<div className="truncate text-sm">{file.name}</div>
|
||||
<div className="text-[11px] text-muted-foreground">
|
||||
{(file.size / 1024 / 1024).toFixed(2)} MB
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="h-8 w-8 shrink-0"
|
||||
onClick={() => handleRemoveQueuedFontFile(file)}
|
||||
>
|
||||
<Trash2 className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
<Button onClick={handleUploadFont} disabled={isUploadingFont} className="w-full" variant="outline">
|
||||
{isUploadingFont ? (
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user