<template>
|
<div class="file">
|
<div class="file_list">
|
<div class="file_list_item" :style="{width: width, height: height}" v-for="(item, index) in list" :key="index">
|
<div class="dele" @click="deleItem(index)">
|
<i class="el-icon-close"></i>
|
</div>
|
<img :src="item.url" v-if="fileType(item.url) === 'img'" />
|
<video controls autoplay :src="item.url" v-else></video>
|
</div>
|
<div class="file_list_item" :style="{width: width, height: height, cursor: 'pointer'}" @click="$refs.file.click()">
|
<i class="el-icon-plus"></i>
|
</div>
|
</div>
|
<div style="display: block;">
|
<input type="file" ref="file" :accept="accept" @change="getFile" />
|
<!-- <progress id="progressBar" value="0" max="100" ></progress>-->
|
<!-- <span id="status">0%</span>-->
|
</div>
|
</div>
|
</template>
|
|
<script>
|
import axios from 'axios'
|
export default {
|
props: {
|
width: {
|
type: String,
|
default: '90px'
|
},
|
height: {
|
type: String,
|
default: '90px'
|
},
|
list: {
|
type: Array,
|
// eslint-disable-next-line vue/require-valid-default-prop
|
default: []
|
},
|
accept: {
|
type: String,
|
default: ''
|
},
|
folder: {
|
type: String,
|
default: ''
|
}
|
},
|
data () {
|
return {
|
loading:null,
|
uuid: null,
|
timer: null,
|
message:'开始上传',
|
uploadImgUrl: process.env.VUE_APP_API_PREFIX + '/public/upload',
|
uploadProgressUrl: process.env.VUE_APP_API_PREFIX + '/public'
|
}
|
},
|
|
methods: {
|
fileType (url) {
|
if (url.indexOf('.mp4') !== -1) {
|
return 'video'
|
} else {
|
return 'img'
|
}
|
},
|
getFile (e) {
|
if (e.target && e.target.files.length > 0) {
|
var that = this
|
const config = {
|
onUploadProgress: function (progressEvent) {
|
console.log(progressEvent)
|
const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total)
|
// document.getElementById('progressBar').value = percentCompleted
|
// document.getElementById('status').textContent = '准备' + percentCompleted + '%'
|
that.loading.setText('准备【 ' + percentCompleted + ' 】%')
|
},
|
headers: {
|
'Content-Type': 'multipart/form-data'
|
}
|
}
|
this.loading = this.$loading({
|
lock: true,
|
text: '上传中,请等待',
|
spinner: 'el-icon-loading',
|
customClass: 'loadingclz',
|
background: 'rgba(0, 0, 0, 0.7)'
|
})
|
this.$emit('loading')
|
const formdate = new FormData()
|
this.uuid = this.generateUUID().replaceAll('-', '')
|
formdate.append('file', e.target.files[0])
|
formdate.append('folder', this.folder)
|
formdate.append('uuid', this.uuid)
|
axios.post(this.uploadImgUrl, formdate, config)
|
.then(res => {
|
if(res.data.data == null || res.data.data.imgaddr == null){
|
this.$message.error('数据上传失败!')
|
}else{
|
this.$emit('success', res.data.data)
|
}
|
})
|
.catch(e => {
|
if(this.timer){
|
clearInterval(this.timer)
|
}
|
this.$message.error(e)
|
})
|
.finally(() => {
|
if(this.timer){
|
clearInterval(this.timer)
|
}
|
that.loading.close()
|
this.$refs.file.value = null
|
})
|
this.startProgress()
|
}
|
},
|
startProgress () {
|
var that = this
|
this.timer = setInterval(function () {
|
axios.get(that.uploadProgressUrl + '/' + that.uuid)
|
.then(res => {
|
if (res != null && res.data && res.data.data) {
|
if (res.data.data.status === 1) {
|
const percentCompleted = Math.round(res.data.data.rate || 0)
|
// document.getElementById('progressBar').value = percentCompleted
|
// document.getElementById('status').textContent = '上传中' + percentCompleted + '%'
|
that.loading.setText('上传中 【 ' + percentCompleted + ' 】%')
|
} else if (res.data.data.status === 2) {
|
// document.getElementById('progressBar').value = 100
|
// document.getElementById('status').textContent = '已完成' + 100 + '%'
|
that.loading.setText( '已完成 【 ' + 100 + ' 】%')
|
clearInterval(that.timer)
|
} else if (res.data.data.status === 3){
|
const percentCompleted = Math.round(res.data.data.rate || 0)
|
// document.getElementById('progressBar').value = percentCompleted
|
// document.getElementById('status').textContent = '上传失败' + percentCompleted + '%'
|
that.loading.setText('上传失败 【 ' + percentCompleted + ' 】%')
|
clearInterval(that.timer)
|
}
|
}
|
})
|
}, 1000)
|
},
|
generateUUID () {
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
const r = (Math.random() * 16) | 0
|
const v = c === 'x' ? r : (r & 0x3) | 0x8
|
return v.toString(16)
|
})
|
},
|
deleItem (index) {
|
this.$emit('dele', index)
|
}
|
}
|
}
|
</script>
|
<style>
|
.loadingclz {
|
.el-loading-text{
|
font-size: 18px !important;
|
color: #2977f8 !important;
|
}
|
.el-loading-spinner i {
|
color: #2977f8 !important;
|
}
|
}
|
</style>
|
<style lang="scss" scoped>
|
.file {
|
/*width: 100%;*/
|
/*height: 90px;*/
|
padding: 10px;
|
box-sizing: border-box;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
position: relative;
|
margin-bottom: 10px;
|
/* margin-right: 20px; */
|
/* margin: 10px 0;*/
|
input {
|
opacity: 0;
|
}
|
.file_list {
|
width: 100%;
|
height: 100%;
|
display: flex;
|
align-items: center;
|
flex-wrap: wrap;
|
.file_list_item {
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
justify-content: center;
|
overflow: hidden;
|
border-radius: 5px;
|
border: 1px solid #d5d5d5;
|
margin-left: 15px;
|
position: relative;
|
&:first-child {
|
margin: 0 !important;
|
}
|
.dele {
|
position: absolute;
|
right: 0;
|
top: 0;
|
width: 20px;
|
height: 20px;
|
background: red;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
cursor: pointer;
|
.el-icon-close {
|
color: #ffffff;
|
font-size: 19px;
|
}
|
}
|
.el-icon-plus {
|
font-size: 30px;
|
color: black;
|
}
|
img {
|
width: 100%;
|
}
|
video {
|
width: 100%;
|
height: 100%;
|
}
|
}
|
}
|
}
|
</style>
|