完善接单平台上传与物品规则

This commit is contained in:
yml2213
2026-07-25 15:56:18 +08:00
parent f6d3f00f21
commit a2587eda01
40 changed files with 4978 additions and 1008 deletions
+86
View File
@@ -0,0 +1,86 @@
const IMAGE_UPLOAD_MAX_SIDE: Record<string, number> = {
'worker-acceptance': 1920,
'collect-material': 1920,
avatar: 512,
}
const IMAGE_UPLOAD_QUALITY: Record<string, number> = {
'worker-acceptance': 0.86,
'collect-material': 0.86,
avatar: 0.82,
}
export async function optimizeImageForUpload(file: File, scene: string) {
if (!file.type.startsWith('image/')) return file
if (!['image/jpeg', 'image/png', 'image/webp'].includes(file.type))
return file
if (typeof document === 'undefined') return file
const maxSide = IMAGE_UPLOAD_MAX_SIDE[scene] ?? 1600
const quality = IMAGE_UPLOAD_QUALITY[scene] ?? 0.84
try {
const image = await loadImage(file)
const { width, height } = fitSize(
image.naturalWidth,
image.naturalHeight,
maxSide,
)
const canvas = document.createElement('canvas')
canvas.width = width
canvas.height = height
const context = canvas.getContext('2d')
if (!context) return file
context.fillStyle = '#ffffff'
context.fillRect(0, 0, width, height)
context.drawImage(image, 0, 0, width, height)
const blob = await canvasToBlob(canvas, 'image/webp', quality)
if (!blob || blob.size >= file.size) return file
return new File([blob], replaceFileExt(file.name, 'webp'), {
type: 'image/webp',
lastModified: Date.now(),
})
} catch {
return file
}
}
function loadImage(file: File) {
return new Promise<HTMLImageElement>((resolve, reject) => {
const url = URL.createObjectURL(file)
const image = new Image()
image.onload = () => {
URL.revokeObjectURL(url)
resolve(image)
}
image.onerror = () => {
URL.revokeObjectURL(url)
reject(new Error('图片读取失败'))
}
image.src = url
})
}
function fitSize(width: number, height: number, maxSide: number) {
if (width <= 0 || height <= 0) return { width: 1, height: 1 }
const scale = Math.min(1, maxSide / Math.max(width, height))
return {
width: Math.max(1, Math.round(width * scale)),
height: Math.max(1, Math.round(height * scale)),
}
}
function canvasToBlob(
canvas: HTMLCanvasElement,
type: string,
quality: number,
) {
return new Promise<Blob | null>((resolve) => {
canvas.toBlob(resolve, type, quality)
})
}
function replaceFileExt(filename: string, ext: string) {
const base = filename.replace(/\.[^.]+$/, '')
return `${base || 'image'}.${ext}`
}