199 lines
6.5 KiB
Vue
199 lines
6.5 KiB
Vue
<template>
|
|
<div class="sc-upload" v-loading="loading" element-loading-background="rgba(0, 0, 0, 0.5)" :style="style">
|
|
<div v-if="tempImg || img" class="sc-upload-file">
|
|
<div class="mask">
|
|
<span class="del" @click.stop="del"><i class="el-icon-delete"></i></span>
|
|
</div>
|
|
<el-image v-if="fileIsImg" class="image" :src="tempImg || img" :preview-src-list="[img]" fit="cover" hide-on-click-modal append-to-body :z-index="9999"></el-image>
|
|
<a v-else :href="img" class="file" target="_blank"><i class="el-icon-document"></i></a>
|
|
</div>
|
|
<div v-else class="sc-upload-uploader">
|
|
<el-upload ref="upload" class="uploader" :auto-upload="!cropper" :on-change="change" :accept="accept" :action="action" :show-file-list="false" :before-upload="before" :on-success="success" :on-error="error" :http-request="request">
|
|
<slot>
|
|
<div class="file-empty">
|
|
<i :class="icon"></i>
|
|
<h4 v-if="title">{{title}}</h4>
|
|
</div>
|
|
</slot>
|
|
</el-upload>
|
|
</div>
|
|
<el-dialog title="剪裁" v-model="cropperDialogVisible" :width="580" destroy-on-close>
|
|
<sc-cropper :src="cropperImg" :compress="compress" :aspectRatio="aspectRatio" ref="cropper"></sc-cropper>
|
|
<template #footer>
|
|
<el-button @click="cropperDialogVisible=false" >取 消</el-button>
|
|
<el-button type="primary" @click="cropperSave">确 定</el-button>
|
|
</template>
|
|
</el-dialog>
|
|
<el-input v-model="img" style="display:none"></el-input>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import config from "@/config/upload"
|
|
import scCropper from '@/components/scCropper';
|
|
|
|
|
|
export default {
|
|
props: {
|
|
height: {type: Number, default: 120},
|
|
width: {type: Number, default: 120},
|
|
modelValue: { type: String, default: "" },
|
|
action: { type: String, default: "" },
|
|
apiObj: { type: Object, default: () => {} },
|
|
accept: { type: String, default: "image/gif, image/jpeg, image/png" },
|
|
maxSize: { type: Number, default: config.maxSize },
|
|
title: { type: String, default: "" },
|
|
icon: { type: String, default: "el-icon-plus" },
|
|
cropper: { type: Boolean, default: false },
|
|
compress: {type: Number, default: 1},
|
|
aspectRatio: {type: Number, default: NaN},
|
|
onSuccess: { type: Function, default: () => { return true } }
|
|
},
|
|
components: {
|
|
scCropper
|
|
},
|
|
data() {
|
|
return {
|
|
loading: false,
|
|
fileIsImg: true,
|
|
img: "",
|
|
tempImg: "",
|
|
style: {
|
|
width: this.width + "px",
|
|
height: this.height + "px"
|
|
},
|
|
cropperDialogVisible: false,
|
|
cropperImg: "",
|
|
cropperUploadFile: null
|
|
}
|
|
},
|
|
watch:{
|
|
modelValue(){
|
|
this.isImg(this.modelValue)
|
|
this.img = this.modelValue;
|
|
},
|
|
img(){
|
|
this.$emit('update:modelValue', this.img);
|
|
}
|
|
},
|
|
mounted() {
|
|
this.isImg(this.modelValue)
|
|
this.img = this.modelValue;
|
|
},
|
|
methods: {
|
|
cropperSave(){
|
|
var uploadFile = this.$refs.upload.uploadFiles[0].raw
|
|
this.$refs.cropper.getCropFile(file => {
|
|
this.cropperUploadFile = file
|
|
this.$refs.upload.submit()
|
|
}, uploadFile.name, uploadFile.type)
|
|
this.cropperDialogVisible = false
|
|
},
|
|
isImg(fileUrl){
|
|
var strRegex = "(.jpg|.png|.gif|.jpeg)$";
|
|
var re = new RegExp(strRegex);
|
|
if (re.test(fileUrl.toLowerCase())){
|
|
this.fileIsImg=true;
|
|
}else{
|
|
this.fileIsImg=false;
|
|
}
|
|
},
|
|
change(file){
|
|
if(this.cropper && file.status=='ready'){
|
|
this.isImg(file.name)
|
|
if(!this.fileIsImg){
|
|
this.$notify.warning({
|
|
title: '上传文件警告',
|
|
message: '选择的文件非图像类文件'
|
|
})
|
|
return false
|
|
}
|
|
this.cropperDialogVisible = true
|
|
this.cropperImg = URL.createObjectURL(file.raw)
|
|
}
|
|
},
|
|
before(file){
|
|
file = this.cropper ? this.cropperUploadFile : file
|
|
const maxSize = file.size / 1024 / 1024 < this.maxSize;
|
|
if (!maxSize) {
|
|
this.$message.warning(`上传文件大小不能超过 ${this.maxSize}MB!`);
|
|
return false;
|
|
}
|
|
this.isImg(file.name)
|
|
this.tempImg = URL.createObjectURL(file);
|
|
this.loading = true;
|
|
},
|
|
success(res){
|
|
this.loading = false;
|
|
this.tempImg = "";
|
|
var os = this.onSuccess(res);
|
|
if(os!=undefined && os==false){
|
|
return false;
|
|
}
|
|
var response = config.parseData(res);
|
|
if(response.code != 200){
|
|
this.$message.warning(response.msg || "上传文件未知错误")
|
|
}else{
|
|
this.img = response.src;
|
|
}
|
|
},
|
|
error(err){
|
|
this.$notify.error({
|
|
title: '上传文件错误',
|
|
message: err
|
|
})
|
|
this.loading = false;
|
|
this.tempImg = "";
|
|
this.img = ""
|
|
},
|
|
del(){
|
|
this.img = ""
|
|
},
|
|
request(param){
|
|
var apiObj = config.apiObj;
|
|
if(this.apiObj){
|
|
apiObj = this.apiObj;
|
|
}
|
|
const data = new FormData();
|
|
var file = this.cropper ? this.cropperUploadFile : param.file
|
|
data.append("file", file);
|
|
apiObj.post(data).then(res => {
|
|
param.onSuccess(res)
|
|
}).catch(err => {
|
|
param.onError(err)
|
|
})
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
.sc-upload+.sc-upload {margin-left: 10px;}
|
|
</style>
|
|
|
|
<style scoped>
|
|
.el-form-item.is-error .sc-upload-uploader {border: 1px dashed #F56C6C;}
|
|
|
|
.sc-upload {width: 120px;height: 120px;display: inline-block;vertical-align: top;box-sizing: border-box;}
|
|
|
|
.sc-upload-file {position: relative;width: 100%;height: 100%;}
|
|
.sc-upload-file .mask {display: none;position: absolute;top:0px;right:0px;line-height: 1;z-index: 1;}
|
|
.sc-upload-file .mask span {display: inline-block;width: 25px;height:25px;line-height: 23px;text-align: center;cursor: pointer;color: #fff;}
|
|
.sc-upload-file .mask span i {font-size: 12px;}
|
|
.sc-upload-file .mask .del {background: #F56C6C;}
|
|
.sc-upload-file .image {width: 100%;height: 100%;}
|
|
.sc-upload-file .image img {vertical-align: bottom;}
|
|
.sc-upload-file .file {width: 100%;height: 100%;display: flex;flex-direction: column;align-items: center;justify-content: center;border: 1px solid #DCDFE6;}
|
|
.sc-upload-file .file i {font-size: 30px;color: #409EFF;}
|
|
.sc-upload-file:hover .mask {display: inline-block;}
|
|
|
|
.sc-upload-uploader {border: 1px dashed #d9d9d9;box-sizing: border-box;width: 100%;height: 100%;}
|
|
.sc-upload-uploader:hover {border: 1px dashed #409eff;}
|
|
.sc-upload-uploader .uploader {width: 100%;height: 100%;}
|
|
.sc-upload-uploader:deep(.el-upload) {width: 100%;height: 100%;}
|
|
|
|
.sc-upload-uploader .file-empty {width: 100%;height: 100%;line-height: 1;display: flex;flex-direction: column;align-items: center;justify-content: center;}
|
|
.sc-upload-uploader .file-empty i {font-size: 28px;color: #8c939d;}
|
|
.sc-upload-uploader .file-empty h4 {font-size: 12px;font-weight: normal;color: #8c939d;margin-top: 10px;}
|
|
</style>
|