父组件:
<el-col :span="6">
<el-form-item label="凭证" prop="voucher">
<OssUpload
ref="ossUpload"
:styles="imgStyle"
:picture-type="'4'"
:file-upload.sync="paymentPartsForm.voucher"
@handleVoucherInfo = 'handleVoucherInfo'
/>
</el-form-item>
</el-col>
// 引入子组件
import OssUpload from '@/components/Upload/uploadVoucher'
// data 中定义样式
imgStyle: "width:100px;height:50px;",
// 清空上传的文件
this.$refs.ossUpload.deleteFile()
// 处理文件信息
handleVoucherInfo(e) {
this.paymentPartsForm.voucher = e
}
子组件:
<template>
<div class="oss-upload">
<div class="show-oss">
<div
v-if="isString(fileUpload) && fileUpload && voucher_style !== 'pdf'"
class="show-oss-item"
:style="styles">
<div style="width: 100%; height: 100%">
<!--图片-->
<i
v-if="!disabled"
class="el-icon-circle-close"
@click="removeFile(fileUpload)" />
<div v-viewer style="width: 100%; height: 100%">
<img v-lazy="fileUpload" />
</div>
<!--其他格式单独处理-->
</div>
</div>
<div v-if="voucher_style === 'pdf'">
<div v-if="fileName" class="export-purchase-flie">
<i class="el-icon-document"></i>
<a @click="operateHandler">{{ fileName }}</a>
<i type="error" class="el-icon-delete" @click="deleteFile" />
</div>
<!-- <p>支持文件格式.pdf,单个文件不能超过5M</p> -->
</div>
</div>
<!--上传-->
<el-upload
v-if="!disabled && uploadFileNumber < limit && voucher_style == ''"
ref="uploadRef"
class="uploadBox"
action=""
:style="styles"
:image-size="imageSize"
:multiple="false"
:http-request="beforeUploadOss"
:before-upload="beforeUpload">
<i class="el-icon-plus" />
<div slot="file" slot-scope="{ file }" />
</el-upload>
<!--图片预览-->
<ImagePreview
:visible="imageDialogVisible"
:image-data="dialogImageUrl"
@closeDialog="imageDialogVisible = false" />
</div>
</template>
<script>
import request from '@/utils/request'
import ImagePreview from './imagePreview'
import { importFile } from '@/api/protocolConfig'
import { exportExcelMixin } from '@/utils/exportExcelMixin'
export default {
components: {
ImagePreview
},
mixins: [exportExcelMixin],
props: {
styles: {
type: String
},
disabled: {
type: Boolean,
default: false
},
multiple: {
type: Boolean,
default: false // 默认单图上传
},
limit: {
type: Number,
default: 1 // 上传文件
},
fileUpload: [String, Array],
content: {
type: String,
default: '' // 图片标识
},
imageSize: {
type: Number,
default: 5
},
pictureType: {
type: String,
default: '' // 图片标识
}
},
data() {
return {
fileName: '',
file_url: '',
files: {},
voucher_style: '',
maxImgSize: 1, // 默认图片上传最大5M
imageDialogVisible: false, // 图片预览弹框
dialogImageUrl: '', // 图片预览地址
}
},
computed: {
uploadFileNumber() {
return Array.isArray(this.fileUpload)
? this.fileUpload.length
: this.fileUpload
? 1
: 0
}
},
mounted() {
console.log(this.fileUpload)
},
methods: {
isString(item) {
return Object.prototype.toString.call(item) == '[object String]'
},
beforeUploadOss(file) {
// 上传阿里云
this.uploadOss(file)
},
// 覆盖默认的上传行为,可以自定义上传的实现
uploadOss(e) {
if (this.voucher_style == 'pdf') {
const formData = new FormData()
formData.append('file_meta', e.file)
formData.append('picture_type', '13')
this.file_loading = true
importFile(formData)
.then(res => {
// 上传请求
this.$message({
type: 'success',
message: '文件上传成功!'
})
let file_name = res.result.oss_path
this.file_url = res.result.oss_path
this.$emit('handleVoucherInfo', file_name)
})
.catch(e => {
this.file_loading = false
this.deleteFile()
if (!e.response) {
this.$message({
type: 'error',
message: '上传失败,请稍后再试'
})
}
})
} else {
const formData = new FormData()
formData.append('picture', e.file)
formData.append('picture_type', this.pictureType)
request({
url: '/api/web/upload/picture',
method: 'post',
data: formData
}).then(res => {
const ImageUrl = process.env.VUE_APP_OSS_URL + res.data.filename
if (this.multiple) {
if (this.limit == 1) {
this.fileUpload.splice(0, 1, ImageUrl)
} else {
this.fileUpload.push(ImageUrl)
}
} else {
this.$emit('update:fileUpload', ImageUrl)
}
console.log(this.fileUpload)
}).catch((e)=> {
this.deleteFile()
this.$message({
type: 'error',
message: '上传失败,请稍后再试'
})
})
}
},
// 图片校验
imageCheck(file) {
if (
!(
file.type === 'image/png' ||
file.type === 'image/gif' ||
file.type === 'image/jpg' ||
file.type === 'image/jpeg' ||
file.type === 'application/pdf'
)
) {
this.$message.warning(
'请上传格式为png, gif, jpg, jpeg, pdf的格式的图片或文件'
)
return false
}
if(file.type === 'application/pdf') {
this.voucher_style = 'pdf'
}
if (this.voucher_style == 'pdf') {
const isLt5M = file.size / 1024 / 1024 < 5
if (!isLt5M) {
this.$message.warning('上传文件大小不能超过 5MB!')
this.deleteFile()
return false
} else {
this.fileName = file.name
return true
}
} else {
const size = file.size / 1024 / 1024
if (size > this.maxImgSize) {
this.$message.warning(`图片大小必须小于${this.maxImgSize}M`)
this.deleteFile()
return false
}
if (this.uploadFileNumber >= this.limit) {
this.$message.warning(`文件最多上传${this.limit}张`)
return false
}
return true
}
},
beforeUpload(file) {
this.files = file
this.maxImgSize = this.imageSize
if (!this.imageCheck(file)) {
return false
}
},
// 删除oss图片
removeFile(src, index) {
if (this.multiple) {
this.fileUpload.splice(index, 1)
} else {
this.$emit('update:fileUpload', '')
}
this.voucher_style = ''
console.log(this.fileUpload)
},
deleteFile() {
this.fileUpload = ''
this.voucher_style = ''
this.fileName = '';
this.file = {}
},
operateHandler() {
// 下载查看
this.exportUrlFile(this.file_url, this.fileName)
},
}
}
</script>
<style lang="scss" scoped>
.fade-enter-active,
.fade-leave-active {
transition: opacity 1s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
opacity: 0;
}
.previewDia {
img {
width: 100%;
}
}
.uploadBox {
width: 100px;
height: 100px;
}
/deep/.el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.oss-upload {
display: flex;
.show-oss {
display: flex;
.show-os-trans {
display: flex;
}
.show-oss-item {
width: 100px;
height: 100px;
margin-right: 10px;
border-radius: 6px;
position: relative;
overflow: hidden;
img {
width: 100%;
height: 100%;
border-radius: 6px;
}
.el-icon-circle-close {
position: absolute;
right: 0;
top: 0;
font-size: 20px;
cursor: pointer;
}
}
}
}
</style>
踩坑: 判断文件类型的时候,文件名slice 截取 file.name.split(".")[1] === "xls";对于文件名中存在特殊符号“.” 会出现问题 如:测试3.0.xls 校验过不去
,所以用file.type 判断比较精准