【升级】支持视频上传、视频预览、上传成功事件

pull/251/head
bubu 2025-03-29 10:16:45 +08:00 committed by 小诺
parent 56360738cc
commit e8ee651e5c
2 changed files with 65 additions and 21 deletions

View File

@ -31,7 +31,7 @@
|----|--------|---------------------------------------|-----------------------------| |----|--------|---------------------------------------|-----------------------------|
| 1 | value | 根据uploadResultType、completeResult 而定 | 当选择用户后通过v-model:value绑定到组件上 | | 1 | value | 根据uploadResultType、completeResult 而定 | 当选择用户后通过v-model:value绑定到组件上 |
| 2 | onChange | 根据uploadResultType、completeResult 而定 | 通过@onChange 方法返回上传的数据 | | 2 | onChange | 根据uploadResultType、completeResult 而定 | 通过@onChange 方法返回上传的数据 |
| 3 | onSuccessful | fileUrl | 通过@onSuccessful 方法接收上传成功的文件url |
### slot定义 ### slot定义
| 序号 | 插槽名 | 用途 | | 序号 | 插槽名 | 用途 |

View File

@ -18,6 +18,27 @@
</a-button> </a-button>
</a-upload> </a-upload>
<a-upload
v-if="props.uploadMode === 'video'"
v-model:file-list="fileList"
name="file"
:action="action"
:headers="headers"
:maxCount="props.uploadNumber"
:before-upload="beforeUpload"
list-type="picture-card"
@change="handleChange"
@preview="handlePreview"
:progress="progress"
:showUploadList="props.showUploadList"
:accept="accept"
>
<div class="clearfix" v-if="fileList.length < props.uploadNumber">
<plus-outlined />
<div style="margin-top: 8px">{{ props.uploadText }}</div>
</div>
</a-upload>
<a-upload <a-upload
v-if="props.uploadMode === 'image'" v-if="props.uploadMode === 'image'"
v-model:file-list="fileList" v-model:file-list="fileList"
@ -38,14 +59,24 @@
<div style="margin-top: 8px">{{ props.uploadText }}</div> <div style="margin-top: 8px">{{ props.uploadText }}</div>
</div> </div>
</a-upload> </a-upload>
<a-modal
v-if="props.uploadMode === 'image'" <!-- 文件预览 -->
:open="previewVisible" <a-modal :open="previewVisible" :title="previewTitle" :footer="null" @cancel="handleCancel">
:title="previewTitle" <template v-if="props.uploadMode === 'image'">
:footer="null" <img alt="example" style="width: 100%" :src="previewObj" />
@cancel="handleCancel" </template>
> <template v-else-if="props.uploadMode === 'video'">
<img alt="example" style="width: 100%" :src="previewImage" /> <video width="100%" controls type="video" id="video">
<source :src="previewObj" type="video/mp4" />
<object :data="previewObj" width="100%">
<embed :src="previewObj" width="100%" />
</object>
您的浏览器不支持video标签哦请联系管理员
</video>
</template>
<template v-else>
暂不支持该文件预览
</template>
</a-modal> </a-modal>
<a-upload-dragger <a-upload-dragger
@ -80,10 +111,10 @@
import { message, Upload } from 'ant-design-vue' import { message, Upload } from 'ant-design-vue'
import { cloneDeep } from 'lodash-es' import { cloneDeep } from 'lodash-es'
const fileList = ref([]) const fileList = ref([])
const emit = defineEmits(['update:value', 'onChange']) const emit = defineEmits(['update:value', 'onChange', 'onSuccessful'])
const previewVisible = ref(false) const previewVisible = ref(false)
const previewTitle = ref('') const previewTitle = ref('')
const previewImage = ref('') const previewObj = ref('')
const headers = ref({ const headers = ref({
token: tool.data.get('TOKEN') token: tool.data.get('TOKEN')
}) })
@ -107,7 +138,7 @@
default: convertUrl('/dev/file/download?id='), default: convertUrl('/dev/file/download?id='),
required: false required: false
}, },
// file || drag || image // file || video || drag || image
uploadMode: { uploadMode: {
type: String, type: String,
default: 'file', default: 'file',
@ -268,28 +299,37 @@
} }
// image // image
const beforeUpload = (file) => { const beforeUpload = (file) => {
const isPNG = file.type.startsWith('image/') if (props.uploadMode == 'image') {
if (!isPNG) { const isPNG = file.type.startsWith('image/')
message.warning('只能上传图片类型文件') if (!isPNG) {
message.warning('只能上传图片类型文件')
}
return isPNG || Upload.LIST_IGNORE
}
else if (props.uploadMode == 'video') {
const isVideo = file.type.startsWith('video/')
if (!isVideo) {
message.warning('只能上传视频类型文件')
}
return isVideo || Upload.LIST_IGNORE
} }
return isPNG || Upload.LIST_IGNORE
} }
// //
const handlePreview = async (file) => { const handlePreview = async (file) => {
previewVisible.value = true previewVisible.value = true
previewTitle.value = file.name previewTitle.value = file.name
// id // id
if (props.uploadResultType === 'id') { if (props.uploadResultType === 'id') {
previewImage.value = sysConfig.API_URL + props.uploadIdDownloadUrl + file.response.data previewObj.value = sysConfig.API_URL + props.uploadIdDownloadUrl + file.response.data
} else { } else {
previewImage.value = file.response.data previewObj.value = file.response.data
} }
} }
// //
const handleCancel = () => { const handleCancel = () => {
previewVisible.value = false previewVisible.value = false
previewTitle.value = '' previewTitle.value = ''
previewImage.value = '' previewObj.value = ''
} }
// //
const handleChange = (uploads) => { const handleChange = (uploads) => {
@ -308,6 +348,7 @@
data.response.data + (resultIntervalValue.value ? ',' + resultIntervalValue.value : '') data.response.data + (resultIntervalValue.value ? ',' + resultIntervalValue.value : '')
}) })
emit('update:value', resultIntervalValue) emit('update:value', resultIntervalValue)
emit('onSuccessful',resultIntervalValue)
emit('onChange', resultIntervalValue) emit('onChange', resultIntervalValue)
} else if (props.uploadResultCategory === 'array') { } else if (props.uploadResultCategory === 'array') {
if (props.completeResult) { if (props.completeResult) {
@ -319,13 +360,16 @@
} }
}) })
emit('update:value', newResult) emit('update:value', newResult)
emit('onSuccessful',newResult)
emit('onChange', newResult) emit('onChange', newResult)
} else { }
else {
const resultArrayValue = ref([]) const resultArrayValue = ref([])
result.forEach((data) => { result.forEach((data) => {
resultArrayValue.value.push(data.response.data) resultArrayValue.value.push(data.response.data)
}) })
emit('update:value', resultArrayValue) emit('update:value', resultArrayValue)
emit('onSuccessful',resultArrayValue)
emit('onChange', resultArrayValue) emit('onChange', resultArrayValue)
} }
} }