188 lines
6.5 KiB
TypeScript
188 lines
6.5 KiB
TypeScript
import { NextRequest, NextResponse } from "next/server";
|
|
import { upsertSystemSetting } from "@/lib/db/queries";
|
|
import { auth } from "@/app/(auth)/auth";
|
|
import { db } from "@/lib/db";
|
|
import { systemSettings } from "@/lib/db/schema";
|
|
import { eq } from "drizzle-orm";
|
|
import {
|
|
AGENT_PSD_TEMPLATES_KEY,
|
|
getEditableAgentPsdTemplateLayers,
|
|
isAgentPsdTextLayerSlot,
|
|
isAgentPsdTemplateReady,
|
|
normalizeAgentPsdTemplateMode,
|
|
type AgentPsdTemplateListResponse,
|
|
} from "@/lib/agents/psd-template-config";
|
|
import {
|
|
AGENT_PSD_TEXT_COLOR_CONFIG_KEY,
|
|
defaultAgentPsdTextColorConfig,
|
|
normalizeAgentPsdTextColorConfig,
|
|
resolveAgentPsdTextColorConfigForBrand,
|
|
} from "@/lib/agents/psd-text-color-config";
|
|
import {
|
|
AGENT_PSD_TEMPLATE_SECONDARY_CATEGORY_CONFIG_KEY,
|
|
defaultAgentPsdTemplateSecondaryCategoryConfig,
|
|
normalizeAgentPsdTemplateSecondaryCategoryConfig,
|
|
} from "@/lib/agents/psd-template-secondary-category-config";
|
|
import {
|
|
AGENT_PSD_TEMPLATE_CATEGORY_TAG_CONFIG_KEY,
|
|
defaultAgentPsdTemplateCategoryTagConfig,
|
|
normalizeAgentPsdTemplateCategoryTagConfig,
|
|
} from "@/lib/agents/psd-template-category-tag-config";
|
|
import { readAgentPsdFonts } from "@/lib/agents/psd-font-settings";
|
|
import { repairAgentPsdTemplateAssetsIfNeeded } from "@/lib/agents/psd-template-repair";
|
|
import { resolveAgentPsdTemplateTextStyles } from "@/lib/agents/psd-template-style-resolver";
|
|
import { readAgentPsdTemplates } from "@/lib/agents/psd-template-settings";
|
|
|
|
export const runtime = "nodejs";
|
|
export const dynamic = "force-dynamic";
|
|
|
|
function jsonError(status: number, error: string) {
|
|
const payload: AgentPsdTemplateListResponse = {
|
|
success: false,
|
|
templates: [],
|
|
error,
|
|
};
|
|
return NextResponse.json(payload, { status });
|
|
}
|
|
|
|
export async function GET(request: NextRequest) {
|
|
const session = await auth().catch(() => null);
|
|
if (!session?.user?.id) {
|
|
return jsonError(401, "未登录");
|
|
}
|
|
|
|
try {
|
|
const requestedBrand = String(request.nextUrl.searchParams.get("brand") || "").trim();
|
|
const requestedModeRaw = String(request.nextUrl.searchParams.get("mode") || "").trim();
|
|
const requestedMode =
|
|
requestedModeRaw === "main" || requestedModeRaw === "sku"
|
|
? normalizeAgentPsdTemplateMode(requestedModeRaw)
|
|
: null;
|
|
const [allTemplates, textColorSetting, secondaryCategorySetting, categoryTagSetting] =
|
|
await Promise.all([
|
|
readAgentPsdTemplates(),
|
|
db
|
|
.select()
|
|
.from(systemSettings)
|
|
.where(eq(systemSettings.key, AGENT_PSD_TEXT_COLOR_CONFIG_KEY))
|
|
.limit(1)
|
|
.then((rows) => rows[0])
|
|
.catch(() => null),
|
|
db
|
|
.select()
|
|
.from(systemSettings)
|
|
.where(eq(systemSettings.key, AGENT_PSD_TEMPLATE_SECONDARY_CATEGORY_CONFIG_KEY))
|
|
.limit(1)
|
|
.then((rows) => rows[0])
|
|
.catch(() => null),
|
|
db
|
|
.select()
|
|
.from(systemSettings)
|
|
.where(eq(systemSettings.key, AGENT_PSD_TEMPLATE_CATEGORY_TAG_CONFIG_KEY))
|
|
.limit(1)
|
|
.then((rows) => rows[0])
|
|
.catch(() => null),
|
|
]);
|
|
const repairedTemplateMap = new Map<
|
|
string,
|
|
Awaited<ReturnType<typeof readAgentPsdTemplates>>[number]
|
|
>();
|
|
|
|
for (const template of allTemplates) {
|
|
if (
|
|
template.status !== "active" ||
|
|
!isAgentPsdTemplateReady(template) ||
|
|
(requestedBrand ? template.brandName !== requestedBrand : false) ||
|
|
(requestedMode ? template.mode !== requestedMode : false) ||
|
|
getEditableAgentPsdTemplateLayers(template).length === 0
|
|
) {
|
|
continue;
|
|
}
|
|
|
|
const repairedTemplate = await repairAgentPsdTemplateAssetsIfNeeded(template);
|
|
if (repairedTemplate !== template) {
|
|
repairedTemplateMap.set(template.id, repairedTemplate);
|
|
}
|
|
}
|
|
|
|
const sourceTemplates =
|
|
repairedTemplateMap.size > 0
|
|
? allTemplates.map((template) => repairedTemplateMap.get(template.id) || template)
|
|
: allTemplates;
|
|
|
|
if (repairedTemplateMap.size > 0) {
|
|
await upsertSystemSetting({
|
|
key: AGENT_PSD_TEMPLATES_KEY,
|
|
value: sourceTemplates,
|
|
updatedBy: session.user.id,
|
|
}).catch((error) => {
|
|
console.warn("[PSD Templates] failed to persist repaired assets:", error);
|
|
});
|
|
}
|
|
|
|
const fonts = (await readAgentPsdFonts().catch(
|
|
() => [] as Awaited<ReturnType<typeof readAgentPsdFonts>>
|
|
)) as Awaited<ReturnType<typeof readAgentPsdFonts>>;
|
|
const fontMap = new Map(fonts.map((font) => [font.id, font]));
|
|
const templates = await Promise.all(
|
|
sourceTemplates
|
|
.filter((template) => template.status === "active")
|
|
.filter(isAgentPsdTemplateReady)
|
|
.filter((template) =>
|
|
requestedBrand ? template.brandName === requestedBrand : true
|
|
)
|
|
.filter((template) => (requestedMode ? template.mode === requestedMode : true))
|
|
.filter((template) => getEditableAgentPsdTemplateLayers(template).length > 0)
|
|
.map(async (template) => {
|
|
const resolvedTemplate = await resolveAgentPsdTemplateTextStyles(template).catch(
|
|
() => template
|
|
);
|
|
|
|
return {
|
|
...resolvedTemplate,
|
|
layers: resolvedTemplate.layers.map((layer) => {
|
|
if (!isAgentPsdTextLayerSlot(layer) || !layer.fontId) {
|
|
return layer;
|
|
}
|
|
|
|
const font = fontMap.get(layer.fontId);
|
|
if (!font) {
|
|
return layer;
|
|
}
|
|
|
|
return {
|
|
...layer,
|
|
fontFileUrl: font.fileUrl,
|
|
fontContentType: font.contentType,
|
|
};
|
|
}),
|
|
};
|
|
})
|
|
);
|
|
|
|
const normalizedTextColorConfig = textColorSetting
|
|
? normalizeAgentPsdTextColorConfig(textColorSetting.value)
|
|
: defaultAgentPsdTextColorConfig;
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
templates,
|
|
textColorConfig: requestedBrand
|
|
? resolveAgentPsdTextColorConfigForBrand(
|
|
normalizedTextColorConfig,
|
|
requestedBrand
|
|
)
|
|
: normalizedTextColorConfig,
|
|
secondaryCategoryConfig: secondaryCategorySetting
|
|
? normalizeAgentPsdTemplateSecondaryCategoryConfig(secondaryCategorySetting.value)
|
|
: defaultAgentPsdTemplateSecondaryCategoryConfig,
|
|
categoryTagConfig: categoryTagSetting
|
|
? normalizeAgentPsdTemplateCategoryTagConfig(categoryTagSetting.value)
|
|
: defaultAgentPsdTemplateCategoryTagConfig,
|
|
} satisfies AgentPsdTemplateListResponse);
|
|
} catch (error) {
|
|
console.error("[PSD Templates] list failed:", error);
|
|
return jsonError(503, "PSD 模板读取失败");
|
|
}
|
|
}
|