export const STORAGE_KEY = "image-prompt-studio:simple-prompt:v1"; export const GENERATION_DEFAULTS = { size: "1024x1024", quality: "high", outputFormat: "png", background: "auto", count: 1, moderation: "auto", outputCompression: 90, }; export const EXAMPLE_PROMPTS = [ "一只白色陶瓷杯放在浅灰色窗边桌面上,晨光柔和,极简产品摄影,干净背景,苹果官网质感。", "未来感电动车停在雾气很轻的海边公路,银色车身,阴天柔光,电影级写实海报。", "一间现代风格客厅,浅木地板,奶油白沙发,大面积自然光,室内设计杂志封面感。", "一款无线耳机悬浮在纯白背景中,蓝色柔和反射光,商业广告风,细节锐利。", ]; export const PROCESSING_STAGES = [ { title: "整理 Prompt", detail: "检查内容并准备发送到服务端。", thresholdMs: 1400, }, { title: "连接 gpt-image-2", detail: "向 OpenAI Images API 发起图片生成请求。", thresholdMs: 5200, }, { title: "等待渲染", detail: "模型正在生成高质量图片,这一步通常最耗时。", thresholdMs: 15000, }, { title: "准备下载", detail: "接收 base64 图片并整理成浏览器可下载文件。", thresholdMs: 24000, }, ]; export function sanitizePrompt(input) { return String(input ?? "") .replace(/\r/g, "") .replace(/[ \t]+\n/g, "\n") .replace(/\n{3,}/g, "\n\n") .split("\n") .map((line) => line.trim()) .join("\n") .trim(); } export function buildPromptStats(prompt) { const cleanPrompt = sanitizePrompt(prompt); if (!cleanPrompt) { return "输入一句清晰的画面描述即可开始。"; } const lineCount = cleanPrompt.split("\n").length; const charCount = cleanPrompt.length; return `${charCount} 个字符 · ${lineCount} 行`; } export function buildDownloadStem(prompt) { const normalized = sanitizePrompt(prompt) .toLowerCase() .replace(/[^a-z0-9\u4e00-\u9fa5\s-]/g, "") .trim() .replace(/\s+/g, "-") .slice(0, 48); return normalized || "generated-image"; } export function createProcessingSnapshot(elapsedMs, isComplete = false) { if (isComplete) { return { progress: 1, activeStageIndex: PROCESSING_STAGES.length - 1, lead: "图片已生成完成,可以预览和下载。", }; } const safeElapsed = Math.max(0, elapsedMs); const finalThreshold = PROCESSING_STAGES[PROCESSING_STAGES.length - 1]?.thresholdMs ?? 24000; const progress = Math.min(0.92, safeElapsed / finalThreshold); const activeStageIndex = resolveActiveStageIndex(safeElapsed); const activeStage = PROCESSING_STAGES[activeStageIndex]; return { progress, activeStageIndex, lead: activeStage ? `${activeStage.title}中... ${activeStage.detail}` : "正在处理,请稍候。", }; } function resolveActiveStageIndex(elapsedMs) { for (let index = PROCESSING_STAGES.length - 1; index >= 0; index -= 1) { if (elapsedMs >= PROCESSING_STAGES[index].thresholdMs) { return index; } } return 0; }