Files
zkxw/web-admin/src/utils/attachment-zip.ts
T
2026-09-01 11:32:49 +08:00

89 lines
2.5 KiB
TypeScript

import { fetchAttachmentDownloadUrl } from '@/api/business'
import { attachmentFullUrl } from '@/composables/useAttachmentActions'
export { attachmentFullUrl }
export function sanitizeZipPathSegment(value: string, fallback = '未命名') {
const cleaned = String(value || '')
.replace(/[\\/:*?"<>|]/g, '_')
.replace(/\s+/g, ' ')
.trim()
return cleaned || fallback
}
export function getAttachmentExtension(file: { fileName?: string; fileUrl?: string }) {
const raw = String(file.fileName || file.fileUrl?.split('/').pop() || '')
.split('?')[0]
.trim()
const dot = raw.lastIndexOf('.')
if (dot > 0 && dot < raw.length - 1) {
return raw.slice(dot + 1).toLowerCase()
}
return ''
}
export function resolveAttachmentFileName(
file: { fileName?: string; fileUrl?: string },
index = 0
) {
const name = String(file.fileName || '').trim()
if (name) return name
const fromUrl = String(file.fileUrl || '')
.split('?')[0]
.split('/')
.pop()
if (fromUrl) return fromUrl
const ext = getAttachmentExtension(file)
return ext ? `附件${index + 1}.${ext}` : `附件${index + 1}`
}
export function ensureUniqueZipEntryName(name: string, used: Set<string>) {
if (!used.has(name)) {
used.add(name)
return name
}
const dot = name.lastIndexOf('.')
const base = dot > 0 ? name.slice(0, dot) : name
const ext = dot > 0 ? name.slice(dot) : ''
let n = 2
while (used.has(`${base}(${n})${ext}`)) n += 1
const unique = `${base}(${n})${ext}`
used.add(unique)
return unique
}
export function formatZipDateStamp(date = new Date()) {
const y = date.getFullYear()
const m = String(date.getMonth() + 1).padStart(2, '0')
const d = String(date.getDate()).padStart(2, '0')
return `${y}${m}${d}`
}
export async function fetchAttachmentBlob(
fileUrl: string,
fileName: string,
options?: { signal?: AbortSignal }
) {
const url = String(fileUrl || '').trim()
if (!url) return null
try {
const res = await fetchAttachmentDownloadUrl({ fileUrl: url, fileName })
if (res?.downloadUrl) {
const response = await fetch(res.downloadUrl, { signal: options?.signal })
if (response.ok) return await response.blob()
}
} catch (err) {
if (options?.signal?.aborted) throw err
}
const href = attachmentFullUrl(url)
if (!href) return null
try {
const response = await fetch(href, { signal: options?.signal })
if (response.ok) return await response.blob()
} catch (err) {
if (options?.signal?.aborted) throw err
return null
}
return null
}