2025-04-16 02:11:26 +01:00

208 lines
4.2 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="video-upload">
<view class="fileList" v-for="(item,index) in list" :key="index">
<video class="video" :id="item.videoId" @fullscreenchange="fullscreenchange" :show-fullscreen-btn="true"
:poster="item.url" :src="item.url">
<!-- cover-image 需要放到video组建里面 -->
<cover-image src="https://sancangshop.oss-cn-beijing.aliyuncs.com/frog/close.png" v-if="deletable" class="icon" @click.stop="deleteItem(index)">
</cover-image>
</video>
</view>
<view v-if="maxCount>list.length" class="uploadBox" @click="chooseVideo">
<u-icon class="icon" size="26" color="#D3D4D6" name="play-circle-fill"></u-icon>
</view>
<u-toast ref="uToast"></u-toast>
</view>
</template>
<script>
export default {
props: {
value: {
type: String,
default: ""
},
//单个文件上传大小M
maxSize: {
type: Number,
default: 1 //1M
},
//上传文件数量
maxCount: { // 限制数量
type: Number,
default: 2
},
//是否显示删除按钮
deletable: {
type: Boolean,
default: true
},
//视频来源
sourceType: {
type: Array,
default: () => {
return ["album", "camera"];
}
}
},
name: "video-upload",
data() {
return {
list: [],
VideoContext: null,
state: false,
videoId: null
};
},
watch: {
value: {
handler(val) {
if (val) {
this.list = val.split(',').map(url => {
return {
url: uni.$u.http.config.baseURL + url,
width: "100%",
videoId: Date.now() + Math.ceil(Math.random() * 10000000) + ''
}
})
}
}
},
state(state, oldValue) {
if (!state) {
this.VideoContext.pause();
} else {
this.VideoContext.play();
this.$nextTick(() => {
this.VideoContext.requestFullScreen();
});
}
},
list: {
handler(val) {
this.emits()
},
deep: true
}
},
methods: {
//文件上传接口
uploadFile(url) {
//这是用promise封装异步请求
return new Promise((resolve, reject) => {
uni.$u.http.upload('/common/upload', {
filePath: url,
name: 'file',
timeout: 60000 //超时时间设置为1分钟防止时间过短无法上传
}).then(res => {
resolve(res);
}).catch(error => {
reject(error)
});
});
},
chooseVideo() {
uni.chooseVideo({
sourceType: this.sourceType,
compressed: true,
success: async (file) => {
if (file.size > this.maxSize * 1024 * 1224) {
this.$refs.uToast.show({
type: 'error',
icon: false,
title: '视频超过大小',
message: "视频大小不超过" + this.maxSize + 'M',
});
return;
}
const {
url
} = await this.uploadFile(file.tempFilePath)
this.list.push({
url: url,
width: '100%',
videoId: Date.now() + Math.ceil(Math.random() * 10000000) + ''
})
}
})
},
fullscreenchange(e) {
this.state = e.detail.fullScreen;
},
changeState(id) {
this.VideoContext = uni.createVideoContext(id)
this.state = true
},
//删除元素
deleteItem(index) {
this.list[index].width = "0"
setTimeout(() => {
this.list.splice(index, 1)
}, 10)
},
emits() {
const {
list
} = this
const imgUrls = list.map((item) => {
const i = item.url.indexOf('/profile/upload')
return item.url.slice(i)
}).join(',')
this.$emit('input', imgUrls)
}
}
}
</script>
<style lang="scss">
.video-upload {
display: flex;
flex-wrap: wrap;
.fileList {
width: 320rpx;
height: 200rpx;
border-radius: 5rpx;
overflow: hidden;
position: relative;
margin-right: 20rpx;
margin-bottom: 20rpx;
.video {
height: 100%;
width: 100%;
}
.icon {
width: 40rpx;
height: 40rpx;
color: red;
position: absolute;
right: 0rpx;
top: 0rpx;
z-index: 200;
overflow: hidden;
.close {
position: absolute;
left: 10rpx;
bottom: 10rpx;
}
}
}
.uploadBox {
width: 320rpx;
height: 200rpx;
display: flex;
justify-content: center;
align-items: center;
background-color: #F4F5F7;
border-radius: 10rpx;
.icon {
margin: auto;
}
}
}
</style>