You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

392 lines
8.4 KiB

<template>
<view>
<p class="youhui" style="border-bottom: none;" v-if="showTitle">
<text class="text1">图片/视频</text>
<text class="text3" v-if="showColseBtn">(最多{{filesNum}}条)</text>
</p>
<view class="img_box" >
<view class="img_list" v-for="(item, index) in myFileList" :key="index">
<block v-if="item.type == 'img'">
<image :src="item.url" mode="" class="imgs"
@click="previewImg(item.url)">
</image>
<image z-index="9999" v-if="showColseBtn"
src="/static/images/search/close.png" mode="" class="close"
@tap="delFiles(index)">
</image>
</block>
<block v-if="item.type == 'video'">
<video :src="item.url" :poster="item.poster" :controls="false"
:show-center-play-btn="false" :show-play-btn="false"
:enable-progress-gesture="false">
<cover-view class="covers"></cover-view>
<cover-image v-if="!showVideo"
class="imgs" src="/static/images/goods/bofang.png" mode=""
@click="onshowVideo(item.url)">
</cover-image>
<cover-image v-if="!showVideo && showColseBtn"
src="/static/images/search/close.png" mode=""
class="video_close"
@tap="delFiles(index)">
</cover-image>
</video>
</block>
</view>
<view class="addImg"v-if="myFileList.length < filesNum && showColseBtn"
@tap="onChoose">
<image src="/static/images/shexiang.png" mode=""></image>
<p>添加图片/视频</p>
</view>
</view>
<view class="mask" v-if="showVideo"
@touchmove.stop.prevent="ondefault"
@click="hideShow">
<view class="close">
<image src="/static/images/goods/close.png"></image>
</view>
</view>
<view class="previewvideo" v-if="showVideo">
<view class="videos">
<video class="nowvideos" id="nowVideo" :src="video" :autoplay="showVideo"
:show-center-play-btn="true" :show-mute-btn="true" :show-fullscreen-btn="false"></video>
</view>
</view>
<!-- 用来承载H5预览视频的 -->
<view style="position: absolute;top: -999upx;left: -999upx;">
<video ref="newVideo" id="newVideo" :src="video"
:autoplay="showVideo"
:show-center-play-btn="false" :show-mute-btn="true" :show-fullscreen-btn="false">
</video>
</view>
</view>
</template>
<script>
import { uploadFile } from '@/api';
import CONFIG from '@/config'
export default {
created() {
this.platform = uni.getSystemInfoSync().platform //判断当前是安卓还是ios 然后进行适配
this.newVideo = uni.createVideoContext('newVideo');
},
data() {
return {
isH5: false,
platform: '',
video: '',
showVideo: false,
newVideo: null,
myFileList: []
}
},
props: {
value: {
type: Array,
default: () => ([])
},
showColseBtn: {
type: Boolean,
default: true
},
filesNum: {
type: Number,
default: 5
},
showTitle: {
type: Boolean,
default: true
},
data: {
type: Array,
default: () => ([])
},
},
watch: {
value: {
handler(newV) {
this.myFileList = [...newV]
},
deep: true,
immediate: true
}
},
methods: {
previewImg(url){ //预览图片
let arr = []
arr[0] = url
uni.previewImage({
urls:arr
})
},
onshowVideo(video) { //预览视频
this.video = video
// #ifndef H5
this.showVideo = true
this.newVideo && this.newVideo.play()
// #endif
// #ifdef H5
// h5 在真机上测试
if(this.platform == 'android'){ //判断是安卓还是ios来对视频做适配
this.isH5 = true
this.newVideo.play()
}else{
this.showVideo = true
}
// #endif
},
hideShow(){ //隐藏预览视频
this.showVideo = false
},
delFiles(index) {
this.myFileList.splice(index, 1);
},
onChoose(){
uni.showActionSheet({
title:"选择上传类型",
itemList: ['图片','视频'],
success: (res) => {
if(res.tapIndex == 0){
this.chooseImages()
} else {
this.chooseVideo()
}
}
})
},
chooseImages() { //上传图片
const that = this;
if(this.myFileList.length >= this.filesNum){ //最多上传3张 超出了提醒
this.$toast(`$最多上传{this.filesNum}个`)
return
}
uni.chooseImage({
//该方法是调出选择图片的方法
count: 1, //数量限制
sizeType: ['original', 'compressed'], //可选 原图 或缩略图
success: function(res) {
const tempFilePaths = res.tempFilePaths;
uploadFile(tempFilePaths[0]).then(img => {
that.myFileList.push({
type: 'img',
url: CONFIG.imgUrl + img,
_url: img
})
that.$emit('input', that.myFileList)
})
}
});
},
chooseVideo(){ //上传视频
const that = this;
if(this.myFileList.length >= this.filesNum){ //最多上传3张 超出了提醒
this.$toast(`$最多上传{this.filesNum}个`)
return
}
uni.chooseVideo({
count: 1,
sourceType: ['camera', 'album'],
success: function (res) {
const tempFilePaths = res.tempFilePath;
uploadFile(tempFilePaths).then(img => {
that.myFileList.push({
type: 'video',
url: CONFIG.imgUrl + img,
_url: img
})
that.$emit('input', that.myFileList)
})
}
});
},
ondefault(){
// 抛弃的方法
}
}
}
</script>
<style lang="scss" scoped>
.youhui {
height: 40upx;
line-height: 40upx;
padding: 20upx 30upx;
border-bottom: 1upx solid #f2f2f2;
box-sizing: content-box;
.text1 {
font-size: 28upx;
color: #333333;
}
.text2 {
float: right;
color: #999999;
font-size: 28upx;
margin-right: 5upx;
margin-top: 2upx;
}
.text3 {
font-size: 24upx;
color: #999999;
margin-left: 10upx;
}
image {
float: right;
width: 12upx;
height: 22upx;
margin-top: 12upx;
margin-left: 10upx;
}
}
.img_box {
overflow: hidden;
padding: 20upx 30upx;
.addImg {
width: 184upx;
height: 184upx;
background: #f2f2f2;
// background-color: pink;
border-radius: 20upx;
overflow: hidden;
transition: all 0.3s;
image {
width: 51upx;
height: 42upx;
display: block;
margin: 0 auto;
margin-top: 45upx;
}
p {
font-size: 24upx;
font-family: Microsoft YaHei;
font-weight: 400;
color: rgba(255,94,102,1);
text-align: center;
margin-top: 20upx;
}
&:active {
transform: scaleX(0.96);
}
}
}
.img_list {
width: 184upx;
height: 184upx;
float: left;
margin-right: 20upx;
position: relative;
overflow: hidden;
margin-bottom: 20upx;
image,video {
width: 100%;
height: 100%;
display: block;
}
video{
position: relative;
border-radius: 5upx;
overflow: hidden;
overflow: visible!important;
.covers{ //遮挡层
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 9990;
}
.imgs{
width: 72upx;
height: 72upx;
position: absolute;
top: 50%;
left: 50%;
z-index: 9999;
transform: translate(-50% ,-50%);
}
.video_close{
width: 40upx;
height: 40upx;
position: absolute;
display: block;
top: -6upx;
left: -6upx;
border-radius: 50%;
z-index: 9999;
}
}
.close {
width: 40upx;
height: 40upx;
position: absolute;
box-sizing: border-box;
top: -6upx;
left: -6upx;
border-radius: 50%;
}
}
/* 预览视频弹窗 */
.mask {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
background-color: rgba(0, 0, 0, .8);
z-index: 999;
}
.previewvideo {
width: 100vw;
height: 100vw;
position: fixed;
top: 50%;
left: 0;
transform: translateY(-50%);
background-color: #000;
z-index: 1000;
opacity: 1;
}
.close {
display: flex;
align-content: center;
align-items: flex-end;
position: absolute;
top: 100upx;
right: 20upx;
z-index: 900;
image {
width: 50upx;
height: 50upx;
display: block;
justify-content: center;
margin-left: 30upx;
margin-bottom: 20upx;
border-radius: 50%;
padding: 10upx;
background-color: rgba(0, 0, 0, 0.2);
}
}
.videos {
height: 100vw;
width: 100vw;
z-index: 10;
position: relative;
video {
width: 100%;
height: 100%;
}
}
.nowvideos {
width: 100%;
height: 100%;
margin: 0 auto;
}
</style>