74 lines
2.3 KiB
TypeScript
74 lines
2.3 KiB
TypeScript
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<TaskDetailBrowserPreview> {
|
||
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<TaskDetailBrowserPreview[]> {
|
||
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)
|
||
}
|