| | |
| | | |
| | | import { IconifyIcon } from '@vben/icons'; |
| | | import { $t } from '@vben/locales'; |
| | | import { checkFileType, isFunction, isImage, isObject, isString } from '@vben/utils'; |
| | | import { checkFileType, isFunction, isObject, isString } from '@vben/utils'; |
| | | |
| | | import { Button, message, Upload } from 'ant-design-vue'; |
| | | |
| | | import { requestClient } from '#/api/request'; |
| | | import { FilePreviewModal, useFilePreview } from '#/components/file-preview'; |
| | | |
| | | import { UploadResultStatus } from './typing'; |
| | | import { useUpload, useUploadType } from './use-upload'; |
| | |
| | | } |
| | | } |
| | | |
| | | const { openPreview, previewState } = useFilePreview(); |
| | | |
| | | /** 处理文件预览 */ |
| | | async function handlePreview(file: UploadFile) { |
| | | function handlePreview(file: UploadFile) { |
| | | const url = (file as any)?.url || (file as any)?.response?.url || (file as any)?.response; |
| | | if (!url) { |
| | | message.warning('文件地址不存在,无法预览'); |
| | | return; |
| | | } |
| | | const name = file.name || (file as any)?.fileName || ''; |
| | | if (isImage(name || url)) { |
| | | window.open(url, '_blank'); |
| | | return; |
| | | } |
| | | try { |
| | | // 将绝对 URL 转为相对路径,走 Vite 代理避免跨域 |
| | | const path = typeof url === 'string' ? url.replace(/^https?:\/\/[^/]+/, '') : url; |
| | | const blob = await requestClient.download(path); |
| | | const blobUrl = URL.createObjectURL(blob as Blob); |
| | | openPreview(blobUrl, name); |
| | | emit('preview', file); |
| | | } catch { |
| | | message.error('文件加载失败'); |
| | | } |
| | | window.open(url, '_blank'); |
| | | emit('preview', file); |
| | | } |
| | | |
| | | /** 处理文件数量超限 */ |
| | |
| | | 格式文件 |
| | | </div> |
| | | </Upload> |
| | | <FilePreviewModal |
| | | v-model:visible="previewState.visible.value" |
| | | :file-url="previewState.fileUrl.value" |
| | | :file-name="previewState.fileName.value" |
| | | /> |
| | | </div> |
| | | </template> |
| | | |