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.
 
 
 
 
 
 

209 lines
5.1 KiB

<template>
<div class="d-flex align-items-end" style="position: relative;">
<button v-if="type=='file'" class="btn btn-light btn-sm change-file-button">
{{file&&file.name||$t('common.selectFile')}}
<input type="file" class="file" :required="required" :placeholder="placeholder" ref="file" @change="change" />
</button>
<div v-else class="el-upload-dragger mr-2 flex-shrink-0">
<label>
<input type="file" class="file" :required="required" :placeholder="placeholder" ref="file" @change="change" />
<img class="img" v-if="uploadImg" :src="imgFilter(uploadImg)" alt />
<template v-else>
<i class="el-icon-upload"></i>
<slot name="text"></slot>
</template>
</label>
</div>
<el-progress
v-if="boll"
:percentage="uploadProgress"
:status="uploadStatus"
:stroke-width="10"
class="my-2"
></el-progress>
<div v-if="file">
<p>{{file.name}}</p>
<!-- <button class="btn upload-btn btn-sm btn-primary" @click="upload" v-if="!value">{{$t('common.upload')}}</button> -->
<!-- v-else -->
<button class="btn upload-btn btn-sm btn-danger" @click="del" >{{$t('common.delete')}}</button>
</div>
</div>
</template>
<script>
import Member from "@/api/member";
export default {
props: ["value",'required','placeholder','type','allowSize'],
data() {
return {
file: undefined,
uploadImg: "",
isLoad: false,
uploadProgress: 0, // 新增进度状态
uploadStatus: null,// 新增状态类型
progressInterval: null,
boll:false,
continueUploading:true
};
},
watch:{
value(n){
this.uploadImg = n
},
file(v){
if(v && !this.value){
this.upload()
}
}
},
created(){
},
methods: {
del() {
this.uploadProgress = 0;
this.uploadStatus = null;
this.boll = false
this.file = undefined;
this.$emit("input", undefined);
this.$refs.file.value=''
},
imgFilter(img){
if(img.indexOf('http')!=-1||img.indexOf('data:')!=-1){
return img
}else{
return this.Globals.Server.Path.BASE+'/storage/'+img
}
},
change(ev) {
this.uploadProgress = 0;
this.uploadStatus = null;
let file = this.$refs.file.files[0];
let ele = this.$refs.file;
let option = {
ele,
allowSize:this.allowSize|| 5, // 单位为M
allowType: ["image/png", "image/jpg", "image/jpeg", "image/pdf"]
};
utils
.upload(option)
.then(result => {
if (result.isIMG) {
// 在预览区查看
this.$emit("input", undefined);
this.$nextTick(()=>{
this.uploadImg = result.data;
this.file = file
})
}
})
.catch(err => {
this.$refs.file.value=''
if (err.message == 102) {
this.$message.error(this.$t('common.tooBig')+`${option.allowSize}M`);
} else if (err.message == 101) {
this.$message.error(this.$t('common.errorType'));
}
});
},
upload() {
// let data = new FormData();
// data.append("image", this.file);
// Member.uploadImage(data).then(res => {
// this.$emit("input", res.path);
// });
this.uploadStatus = null // 重置状态
this.uploadProgress = 0 // 重置进度
this.boll = true
clearInterval(this.progressInterval); // 清除之前的定时器
this.progressInterval = setInterval(() => {
if (this.uploadProgress < 100&&this.continueUploading) {
this.uploadProgress += Math.floor(Math.random() * 5) + 1;
setTimeout(() => {
this.continueUploading = false;
// 暂停3秒后继续累加
setTimeout(() => {
this.continueUploading = true;
}, 3000); // 这里的3000毫秒表示暂停3秒后继续
}, 1000);
}
}, 50);
let data = new FormData()
data.append("image", this.file)
Member.uploadImage(data)
.then(res => {
this.$emit("input", res.path)
// 2秒后隐藏进度条
if(res.path){
setTimeout(() => {
this.uploadStatus = 'success'
this.uploadProgress = 100
clearInterval(this.progressInterval); // 清除之前的定时器
setTimeout(() => {
this.boll = false
},3000)
}, 2000)
}
})
.catch(err => {
this.uploadStatus = 'exception'
this.uploadProgress = 100
})
}
}
};
</script>
<style lang="scss" scope>
.change-file-button{
position: relative;
min-width: 100px;
height: 31px;
margin-right: 20px;
}
.file {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
opacity: 0;
}
.upload-btn {
width: 100px;
}
.el-upload-dragger {
width: 300px;
height: 150px;
position: relative;
label {
display: block;
}
.img {
width: 300px;
height: 150px;
object-fit: cover;
}
}
.el-progress {
position: absolute;
bottom: -25px;
left:18px;
width: 300px;
margin-top: 10px;
&-bar {
padding-right: 45px;
}
&__text {
font-size: 12px!important;
}
}
</style>