aerwen_web_back/src/components/UploadVideo.vue
2023-06-28 18:44:28 +08:00

190 lines
5.0 KiB
Vue

<template>
<el-upload v-model="props.modelValue"
multiple
:action="videoUpload"
:file-list="uploadVideoArr"
:data="props.data"
:fileSize="props.fileSize"
@success="handle"
@error="handle"
@exceed="handleExceed"
:before-upload="beforeUpload"
:drag="true"
@preview="handleVideoPreview"
@remove="handleDelete"
list-type="picture-card"
>
<div class="previewVideoMask" v-if="previewIsShow" @click.stop="changPreview">
<video :src="previewViewSrc" class="previewVideo" controls></video>
</div>
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">只能上传视频格式文件(注:需等待全部上传成功再提交)</div>
</el-upload>
</template>
<script setup>
import {ElMessage} from "element-plus";
import {ref, watch} from "vue";
import { videoUpload } from "~/service/common";
let uploadIdx = ref(0)
let previewIsShow = ref(false)
let previewViewSrc = ref('')
let uploadVideoArr = ref([])
let uploadList = ref([])
let number = ref(0)
const emit = defineEmits()
const props = defineProps({
modelValue : String,
data:Object,
fileType: {
type: Array,
default: () => ['mov', 'mp4', 'wmv', 'flv', 'avi','avchd','webm'],
},
})
const changPreview = function (){
previewIsShow.value = !previewIsShow.value
}
const handleExceed = function (arg){
console.log(arg)
}
watch(
() => props.modelValue,
(val) => {
if (val) {
let temp = 1
// 首先将值转为数组
const list = Array.isArray(val) ? val : props.modelValue.split(',')
// 然后将数组转为对象数组
uploadVideoArr.value = list.map((item) => {
if (typeof item === 'string') {
item = { url: item }
}
item.uid = item.uid || new Date().getTime() + temp++
return item
})
// uploadList.value = fileList
} else {
uploadVideoArr.value = []
return []
}
updateVideoDom()
},
{ deep: true, immediate: true },
)
// 对象转成指定字符串分隔
function listToString(list, separator) {
let strs = ''
separator = separator || ','
for (let i in list) {
strs += list[i].url + separator
}
return strs != '' ? strs.substr(0, strs.length - 1) : ''
}
const handle=function (res){
if(res['code'] !== 0){
uploadVideoArr.value = []
ElMessage.error(res.msg)
return
}
const { url, } = res?.data
const tempFile = { url: url }
uploadList.value.push(tempFile)
if (uploadList.value.length === number.value) {
uploadVideoArr.value.map(item=>{
if(item?.response){
item.url = item.response.data.url
}
})
emit('update:modelValue', listToString(uploadVideoArr.value))
emit('success', listToString(uploadVideoArr.value))
// console.log(uploadVideoArr.value,'is local')
// console.log(props.modelValue,'is props')
uploadList.value = []
number.value = 0
console.log(uploadVideoArr.value,123)
ElMessage.success('全部上传成功')
}
updateVideoDom()
}
function updateVideoDom(){
setTimeout(()=>{
Array.prototype.slice.call(document.getElementsByClassName('is-success')).filter(item=>item.className.indexOf('el-upload-list__item')!==-1).map((item,idx)=>{
let tag = item.getElementsByClassName('el-upload-list__item-thumbnail')[0]
let attr = [tag.getAttribute('class'),tag.getAttribute('src')]
let videoTag = document.createElement('video')
videoTag.setAttribute('class',attr[0])
videoTag.setAttribute('src',attr[1])
item.replaceChild(videoTag,tag)
})
},)
}
const beforeUpload = function (file){
// 校检文件类型
if (props.fileType.length) {
let fileExtension = ''
if (file.name.lastIndexOf('.') > -1) {
fileExtension = file.name.slice(file.name.lastIndexOf('.') + 1)
}
const isTypeOk = props.fileType.some((type) => {
if (file.type.indexOf(type) > -1) return true
if (fileExtension && fileExtension.indexOf(type) > -1) return true
return false
})
if (!isTypeOk) {
ElMessage.error(`文件格式不正确, 请上传${props.fileType.join('/')}格式文件!`)
return false
}
number.value+=1
}
}
const handleDelete=function (f,fl){
let index
console.log(f,props.modelValue.split(','))
props.modelValue.split(',').map((item,idx)=>{
if(item===f.url){
index = idx
}
})
uploadVideoArr.value.splice(index, 1)
emit('update:modelValue', listToString(uploadVideoArr.value))
}
const handleVideoPreview = function (f){
changPreview()
previewViewSrc.value = f.url
}
</script>
<style scoped lang="scss">
.previewVideoMask{
height: 100vh;
width: 100vw;
background: rgba(0,10,10,0.5);
position: fixed;
left: 0;
bottom: 0;
z-index: 99999;
display: flex;
justify-content: center;
align-content: center;
flex-direction: column;
.previewVideo{
height: 80%;
width: 80%;
margin: 0 auto;
}
}
</style>