import { preparePerformanceSurveyImagesInBrowser, type PerformanceSurveyBrowserProcessedImage, } from '@/lib/performance-survey-image-browser' export type TaskDetailAssetKind = 'main' | 'sku' | 'detail' export type TaskDetailBrowserPreview = PerformanceSurveyBrowserProcessedImage & { sourceIndex: number } /** * 为选图界面生成尺寸受限的小缩略图。 * * 原始 File 绝不能直接挂到 img,否则 60MP 压缩图会在主线程额外解码出数百 MB。 * 缩略图失败只影响选图展示,真正提交时仍会按任务详情规则重新校验和处理原图。 */ export async function prepareTaskDetailSelectionThumbnail( file: File, options: { signal?: AbortSignal timeoutMs?: number } = {}, ): Promise { const processed = await preparePerformanceSurveyImagesInBrowser( [file], undefined, { profile: 'task_detail_thumbnail', signal: options.signal, timeoutMs: options.timeoutMs, }, ) const thumbnail = processed.find((item) => item.kind === 'preview') if (!thumbnail) throw new Error('浏览器未生成选图缩略图') return thumbnail } /** * 在用户浏览器中逐张生成任务-详情预览。 * * 这里故意一次只传一张源图,避免把整批原图和 Blob 同时留在内存里。 * 详情长图只上传切片;普通主图/SKU图和短详情图上传一张预览。 */ export async function prepareTaskDetailImagePreview( file: File, assetKind: TaskDetailAssetKind, onProgress?: (label: string) => void, options: { signal?: AbortSignal timeoutMs?: number } = {}, ): Promise { const processed = await preparePerformanceSurveyImagesInBrowser( [file], onProgress, { profile: assetKind === 'detail' ? 'task_detail_detail' : 'task_detail_preview', signal: options.signal, timeoutMs: options.timeoutMs, }, ) if (assetKind === 'detail' && processed.some((item) => item.sliceCount > 1)) { return processed.filter((item) => item.kind === 'slice') } const preview = processed.filter((item) => item.kind === 'preview') if (preview.length > 0) return preview // 极旧浏览器/worker 兼容:没有 preview 时至少保留第一张切片,不能因预览缺失阻断原图上传。 return processed.filter((item) => item.kind === 'slice').slice(0, 1) }