import { ElMessage } from 'element-plus' import { fetchAttachmentDownloadUrl } from '@/api/admin' export type AttachmentDownloadItem = { fileUrl?: string fileName?: string } /** 将 JSON 数组或逗号分隔的附件 URL 统一为逗号分隔字符串 */ export function normalizeAttachmentUrls(raw?: string | null): string { if (!raw) return '' const trimmed = String(raw).trim() if (!trimmed) return '' if (trimmed.startsWith('[')) { try { const parsed = JSON.parse(trimmed) if (Array.isArray(parsed)) { return parsed.map((url) => String(url).trim()).filter(Boolean).join(',') } } catch { /* ignore */ } } return trimmed } function triggerAnchorDownload(href: string, fileName: string) { const a = document.createElement('a') a.href = href a.download = fileName a.rel = 'noopener' document.body.appendChild(a) a.click() document.body.removeChild(a) } /** 附件下载:优先走后端预签名 URL,保证跨域场景下保留原始文件名与后缀。 */ export async function downloadAttachmentFile( file: AttachmentDownloadItem, options?: { fullFileUrl?: (url: string) => string } ) { const fileUrl = String(file.fileUrl || '').trim() if (!fileUrl) return const fileName = String(file.fileName || '').trim() || fileUrl.split('/').pop() || 'download' try { const res = await fetchAttachmentDownloadUrl({ fileUrl, fileName }) if (res?.downloadUrl) { triggerAnchorDownload(res.downloadUrl, fileName) return } } catch { // 预签名失败时回退直连 } const resolveUrl = options?.fullFileUrl || ((url: string) => url) const href = resolveUrl(fileUrl) if (!href) { ElMessage.error('无法下载附件') return } triggerAnchorDownload(href, fileName) }