114 lines
5.8 KiB
TypeScript
114 lines
5.8 KiB
TypeScript
import type { CloneOutputKey } from "./platformRules";
|
|
|
|
export type EcommerceSetCountKey = "selling" | "white" | "scene";
|
|
|
|
export interface EcommercePromptDetailModule {
|
|
id: string;
|
|
title: string;
|
|
desc: string;
|
|
}
|
|
|
|
export interface EcommerceImagePromptOptions {
|
|
gender?: string;
|
|
age?: string;
|
|
ethnicity?: string;
|
|
body?: string;
|
|
appearance?: string;
|
|
scenes?: string[];
|
|
customScene?: string;
|
|
smartScene?: boolean;
|
|
detailModules?: string[];
|
|
}
|
|
|
|
export const setCountLabels: Record<EcommerceSetCountKey, { label: string; promptDesc: string }> = {
|
|
selling: { label: "卖点图", promptDesc: "selling-point infographic image highlighting core product advantages and detail close-ups" },
|
|
white: { label: "白底图", promptDesc: "clean white-background product photo showing the item from its best angle, studio lighting, no props" },
|
|
scene: { label: "场景图", promptDesc: "lifestyle scene image showing the product in a realistic usage environment with natural surroundings" },
|
|
};
|
|
|
|
export const buildDetailModulePrompt = (moduleIds: string[], modules: EcommercePromptDetailModule[]): string => {
|
|
if (!moduleIds.length) {
|
|
return "Generate a complete A+ detail layout with hero, selling points, usage scene, product detail, and specification modules.";
|
|
}
|
|
|
|
const selectedModules = modules.filter((module) => moduleIds.includes(module.id));
|
|
if (!selectedModules.length) return "";
|
|
|
|
const moduleList = selectedModules.map((module) => `${module.title}: ${module.desc}`).join("; ");
|
|
return `Only generate these selected A+ detail modules, no extra modules: ${moduleList}. Keep the output focused even if only one or two modules are selected.`;
|
|
};
|
|
|
|
export const buildSetSubPrompt = (
|
|
countKey: EcommerceSetCountKey,
|
|
index: number,
|
|
totalCount: number,
|
|
platform: string,
|
|
ratio: string,
|
|
language: string,
|
|
market: string,
|
|
): string => {
|
|
const info = setCountLabels[countKey];
|
|
const parts: string[] = [];
|
|
parts.push(`Generate an e-commerce ${info.label.toLowerCase()} for a product listing.`);
|
|
parts.push(info.promptDesc);
|
|
if (countKey === "white") {
|
|
parts.push("The output must be a clean white-background product image. Do not use lifestyle backgrounds, props, text overlays, or people.");
|
|
}
|
|
if (countKey === "scene") {
|
|
parts.push("The output must be a realistic usage scene image. Keep the product clearly visible and preserve its shape, color, and key details.");
|
|
}
|
|
if (countKey === "selling") {
|
|
parts.push("The output must be a selling-point graphic with clear hierarchy, concise copy, and product detail callouts.");
|
|
}
|
|
if (totalCount > 1) {
|
|
parts.push(`This is variant ${index + 1} of ${totalCount} —vary the angle, composition, or emphasis to make each distinct.`);
|
|
}
|
|
parts.push(`Platform: ${platform}. Aspect ratio: ${ratio}. Language/copy: ${language}. Market: ${market}.`);
|
|
parts.push("Must comply with platform image guidelines —proper margins, no watermark, professional quality.");
|
|
return parts.join(" ");
|
|
};
|
|
|
|
export const buildEcommerceImagePrompt = (
|
|
outputKey: CloneOutputKey,
|
|
userText: string,
|
|
platform: string,
|
|
ratio: string,
|
|
language: string,
|
|
market: string,
|
|
options?: EcommerceImagePromptOptions,
|
|
detailModules: EcommercePromptDetailModule[] = [],
|
|
): string => {
|
|
const parts: string[] = [];
|
|
if (outputKey === "detail") {
|
|
parts.push("Generate a professional A+ detail page hero image for an e-commerce product listing.");
|
|
parts.push("Create a high-impact first-screen visual that combines the product photo with key selling points, usage scenes, and detailed specifications in a cohesive layout.");
|
|
parts.push(`Platform: ${platform}. Aspect ratio: ${ratio}. Language/copy: ${language}. Market: ${market}.`);
|
|
if (options?.detailModules) parts.push(buildDetailModulePrompt(options.detailModules, detailModules));
|
|
parts.push("Follow platform A+ page best practices —clear hierarchy, professional typography, high visual impact.");
|
|
} else if (outputKey === "model") {
|
|
parts.push("Generate model/try-on lifestyle images for an e-commerce product listing.");
|
|
parts.push("Show the product being used or worn by a model in attractive lifestyle settings.");
|
|
parts.push(`Platform: ${platform}. Aspect ratio: ${ratio}. Language/copy: ${language}. Market: ${market}.`);
|
|
if (options) {
|
|
if (options.gender) parts.push(`Model gender: ${options.gender}.`);
|
|
if (options.age) parts.push(`Model age: ${options.age}.`);
|
|
if (options.ethnicity) parts.push(`Model ethnicity: ${options.ethnicity}.`);
|
|
if (options.body) parts.push(`Model body type: ${options.body}.`);
|
|
if (options.appearance) parts.push(`Model appearance details: ${options.appearance}.`);
|
|
if (options.scenes?.length) parts.push(`Background scenes: ${options.scenes.join(", ")}.`);
|
|
if (options.customScene) parts.push(`Custom background scene: ${options.customScene}.`);
|
|
if (options.smartScene) parts.push("Use smart scene matching to select the best background context.");
|
|
}
|
|
parts.push("Model should appear natural and appealing. Background should complement the product. Image must meet platform standards.");
|
|
} else if (outputKey === "hot") {
|
|
parts.push("Generate a high-conversion e-commerce product image that closely replicates the style and composition of the reference image while adapting it to the target platform.");
|
|
parts.push(`Replicate the visual style, color palette, and layout feel of the source product image, then adapt it for ${platform} marketplace standards.`);
|
|
parts.push(`Platform: ${platform}. Aspect ratio: ${ratio}. Language/copy: ${language}. Market: ${market}.`);
|
|
parts.push("The result must look professional and optimized for high click-through rate and conversion on the specified platform.");
|
|
}
|
|
if (userText.trim()) {
|
|
parts.push(`Additional user requirements: ${userText.trim()}`);
|
|
}
|
|
return parts.join(" ");
|
|
};
|