Files
order_site/apps/frontend/src/utils/image-identity.ts
T

53 lines
1.8 KiB
TypeScript

import type { UploadedFile } from '@/types/worker-platform'
/**
* 归一化图片身份标识,用于跨来源去重(files 与 imageUrls 可能同时包含同一张图)。
*
* 本项目的图片地址有两种形态:
* - 对象存储签名链接:`/api/v1/files/object?key=<objectKey>&expires=...&signature=...`
* (对象 key 在 query 里,路径对所有文件相同,不能只取路径)
* - 普通外链:`https://cdn.example.com/a.png`
*
* 优先级:objectKey 字段 > URL 中的 key 参数 > 去掉临时签名参数后的完整地址。
*/
export function getImageIdentity(file: {
objectKey?: string
url?: string
mediumUrl?: string
thumbnailUrl?: string
}): string {
const objectKey = String(file?.objectKey || '').trim()
if (objectKey) return objectKey
const url = String(file?.url || file?.mediumUrl || file?.thumbnailUrl || '').trim()
return getImageIdentityFromUrl(url)
}
export function getImageIdentityFromUrl(value: string): string {
const url = String(value || '').trim()
if (!url) return ''
const keyMatch = url.match(/[?&]key=([^&#]+)/)
if (keyMatch?.[1]) {
try {
return decodeURIComponent(keyMatch[1])
} catch {
return keyMatch[1]
}
}
// 普通地址:仅去掉临时签名参数(expires/signature),保留路径与其它参数
return url
.split('#', 1)[0]
.replace(/[?&](expires|signature)=[^&#]*/gi, '')
.replace(/[?&]+$/, '')
}
/** 供 UploadedFile 数组去重:按图片身份去重,保留第一张 */
export function uniqueUploadedFiles(files: UploadedFile[]): UploadedFile[] {
const seen = new Set<string>()
return files.filter((file) => {
const identity = getImageIdentity(file)
if (!identity || seen.has(identity)) return false
seen.add(identity)
return true
})
}