work-order/work-order-uniapp/components/media-input/media-input.vue
2025-07-27 20:34:15 +08:00

301 lines
6.9 KiB
Vue

<template>
<view class="pre-box">
<template v-if="fileList.length > 0 ">
<view class="pre-item" v-for="(item, index) in fileList" :key="index">
<template v-if="item.progress === 100">
<image
v-if="isImage(item.url)"
class="pre-item-content"
:src="item.url"
mode="aspectFill"
@tap="previewImage(item)"
></image>
<video
v-if="isVideo(item.url)"
class="pre-item-content"
:src="item.url"
muted
></video>
</template>
<view v-if="item.progress === 0">上传中...</view>
<view v-if="item.progress === -1" @click="uploadAction(item)">上传失败<br/>点击重试</view>
<view class="u-delete-icon" @tap="deleteImage(index)">
<u-icon name="close" size="20" color="#ffffff"></u-icon>
</view>
</view>
</template>
<!-- 上传按钮 -->
<view @tap="chooseVideoImage2" class="pre-item upload-btn" v-if="fileList.length < limit">
<view style="display: flex; justify-content: center; width: 100%; height: 100%">
<u-icon name="photo" size="48" color="#666666"></u-icon>
</view>
</view>
</view>
</template>
<script>
import {uploadFile} from "@/api/common";
import {getMediaType, IMAGE, VIDEO} from "@/utils/media";
import {getRealUrl} from "@/utils";
var sourceType = [
['camera'],
['album'],
['camera', 'album']
]
export default {
name: "MediaInput",
props: {
value: {
type: String,
default: ""
},
limit: {
type: Number,
default: 9
}
},
data() {
return {
fileList: [], // 文件列表
sourceTypeIndex: 2,
sourceType: ['拍摄', '相册', '拍摄或相册'],
cameraList: [{
value: 'back',
name: '后置摄像头',
checked: 'true'
}, {
value: 'front',
name: '前置摄像头'
}],
cameraIndex: 0,
};
},
computed: {
isImage() {
return (url) => {
return getMediaType(url) === IMAGE;
}
},
isVideo() {
return (url) => {
return getMediaType(url) === VIDEO;
}
},
},
watch: {
value: {
handler(val) {
if (val) {
// 首先将值转为数组
let list = Array.isArray(val) ? val : this.value.split(',');
this.fileList = list.map(item => {
return {
url: item,
progress: 100
}
})
} else {
this.fileList = [];
}
},
deep: true,
immediate: true
}
},
onShow() {
this.sourceTypeIndex = 2;
this.sourceType = ['拍摄', '相册', '拍摄或相册'];
},
methods: {
getFileSplits() {
return this.fileList.map(item => getRealUrl(item.url)).join(",");
},
// 点击上传图片或视频
chooseVideoImage() {
uni.showActionSheet({
title: '选择上传类型',
itemList: ['图片', '视频'],
success: res => {
if (res.tapIndex == 0) {
this.chooseImages(); //选择上传图片
} else {
this.chooseVideo(); //选择上传视频
}
}
});
},
chooseVideoImage2() {
uni.chooseMedia({
count: 50,
mediaType: ['mix'],
sourceType: ['album', 'camera'],
maxDuration: 60,
camera: 'back',
success: res => {
console.log("chooseMedia", res);
res.tempFiles.forEach(item => {
this.fileList.push({
url: item.tempFilePath,
progress: 0
})
})
this.startUpload();
}
})
},
// 上传图片
chooseImages() {
uni.chooseImage({
count: 5, //总限制5张
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], //从相册选择
success: res => {
console.log("res", res);
res.tempFilePaths.forEach(url => {
this.fileList.push({
url: url,
progress: 0
})
})
console.log("fileList", this.fileList);
this.startUpload();
},
})
},
// 上传视频
chooseVideo() {
uni.chooseVideo({
maxDuration: 60, //拍摄视频最长拍摄时间,单位秒。最长支持 60 秒
count: 1,
camera: this.cameraList[this.cameraIndex].value, //'front'、'back',默认'back'
sourceType: sourceType[this.sourceTypeIndex],
success: res => {
this.fileList.push({
url: res.tempFilePath,
progress: 0
})
this.startUpload();
}
})
},
// 开始上传
startUpload() {
this.fileList.forEach((item) => {
if (item.progress === 0) {
this.uploadAction(item)
}
})
},
// 上传接口
uploadAction(file) {
let timeout = 10000;
if (this.isVideo(file.url)) {
timeout = 60000;
}
uploadFile(file.url, timeout).then(res => {
if (res.code === 200) {
file.url = res.url;
file.progress = 100;
} else {
file.progress = -1;
}
}).catch((e) => {
file.progress = -1;
})
},
// 预览图片
previewImage(e) {
console.log('预览图片', e)
var current = e;
uni.previewImage({
current: current,
urls: this.fileList
});
},
// 删除文件
deleteImage(index) {
// if( this.fileList.some(item => item.progress === 0) ) {
// return uni.showToast({
// title: '请等待文件上传完成',
// icon: 'none'
// })
// }
uni.showModal({
title: '提示',
content: '是否要删除该图片',
success: res => {
if (res.confirm) {
this.fileList.splice(index, 1);
}
}
});
}
}
}
</script>
<style lang="scss" scoped>
.pre-box {
position: relative;
width: 100%;
height: fit-content;
padding: 8rpx;
display: flex;
justify-content: flex-start;
flex-wrap: wrap;
.pre-item {
position: relative;
width: 33%;
height: auto;
padding: 8rpx;
aspect-ratio: 1/1;
.pre-item-content {
width: 100%;
height: 100%;
}
}
.upload-btn {
border-radius: 16rpx;
border: 1px dashed #CCCCCC;
}
}
.u-progress {
position: absolute;
bottom: 10rpx;
left: 8rpx;
right: 8rpx;
z-index: 9;
width: auto;
}
.u-delete-icon {
position: absolute;
top: 4rpx;
right: 4rpx;
z-index: 10;
background-color: #CCCCCC;
border-radius: 100rpx;
width: 36rpx;
height: 36rpx;
display: flex;
align-items: center;
justify-content: center;
}
.u-progress {
position: absolute;
bottom: 10rpx;
left: 8rpx;
right: 8rpx;
z-index: 9;
width: auto;
}
</style>