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.
pingAnQiYeWeb/src/components/upload.vue

483 lines
18 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="img-upload-container">
<div class="img-upload" :class="{ 'limit-num': fileList.length >= limit, 'mini': size === 'small' }">
<el-upload class="avatar-uploader" ref="upload" :action="url" :headers="{ 'Authorization': token }"
:file-list="fileList" list-type="picture-card" :on-success="handleSuccess" :on-remove="handleRemove"
:data="{ fileType, villageCode }" :limit="1" :on-preview="handlePictureCardPreview"
:before-upload="beforeAvatarUpload">
<i class="el-icon-plus"></i>
<p class="el-upload__tip" slot="tip" v-if="tips">{{ tips }}</p>
<p class="el-upload__tip" slot="tip" v-if="tips2">{{ tips2 }}</p>
<div slot="file" slot-scope="{file}" class="img-con">
<img class="el-upload-list__item-thumbnail" :src="file.url" alt="">
<span class="el-upload-list__item-actions">
<span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
<i class="el-icon-zoom-in"></i>
</span>
<span class="el-upload-list__item-delete" @click="handleRemove(file)">
<i class="el-icon-delete"></i>
</span>
<span v-if="size === 'small'" style="display:block;marginLeft:0" class="el-upload-list__item-delete"
@click="onChangeHandle(file)">
<i class="el-icon-edit"></i>
</span>
<span v-else class="el-upload-list__item-delete" @click="onChangeHandle(file)">
<i class="el-icon-edit"></i>
</span>
</span>
</div>
</el-upload>
<el-dialog :visible.sync="dialogVisible">
<img width="100%" append-to-body :src="dialogImageUrl" alt />
</el-dialog>
</div>
</div>
</template>
<script>
import { getToken } from '@/utils/auth'
export default {
name: 'ImgUpload',
componentName: 'ImgUpload',
data() {
return {
imgWidth: 0,
imgHeight: 0,
// url: `http://${window.location.host}/hjapi/common/upload`, // 图片上传接口地址
url: `http://192.168.0.188:8118/zhapi/common/upload`, // 图片上传接口地址
fileList: [],
dialogImageUrl: '',
dialogVisible: false,
picIndex: -1,
vmodelType: '',
token: '',
villageData: {},
imageUrl: ''
}
},
props: {
value: {
type: [String, Array]
},
tips: {
type: String,
default: ''
},
tips2: {
type: String,
default: ''
},
size: {
type: String,
default: 'medium' // small
},
limit: {
type: Number,
default: 2
},
limitSize: {
type: Number,
default: 10
},
valueType: {
type: String,
default: 'String' // Object
},
// 是否校验图片尺寸,默认不校验
isCheckPicSize: {
type: Boolean,
default: false
},
checkWidth: {
type: Number,
default: 0 // 图片限制宽度
},
checkHeight: {
type: Number,
default: 0 // 图片限制高度
},
topLimitWidth: {
type: Number,
default: 0 // 图片限制宽度上限(有时需要校验上传图片宽度在一个范围内)
},
topLimitHeight: {
type: Number,
default: 0 // 图片限制高度上限(有时需要校验上传图片高度在一个范围内)
},
busiType: {
type: Number,
default: 2
},
index: {
type: Number,
default: -1 // 当前图片index限制可以上传多张时针对某一张进行操作需要知道当前的index
},
limitType: {
type: String,
default: '' // gif,webp/gif/webp (限制上传格式)
},
fileType: {
type: String,
default: 'userpic'
},
villageCode: {
default: ''
}
},
watch: {
value: {
deep: true,
handler: function (val) {
if (val) {
if (this.valueType === 'Object') {
this.fileList = this.value.map(item => ({ id: item.id, url: item.url, name: item.name }))
} else {
if (this.vmodelType === 'array') {
this.fileList = this.value.map(item => ({ url: item }))
} else {
this.fileList = [{ url: val }]
}
}
} else {
this.fileList = []
}
}
}
},
created() {
this.agetToken()
if (this.valueType === 'Object') {
this.vmodelType = 'array'
} else {
const res = this.isString(this.value)
if (res === true) {
this.vmodelType = 'string'
} else {
this.vmodelType = 'array'
}
}
// console.log('created vmodelType', this.vmodelType)
if (this.value) {
if (this.valueType === 'Object') {
this.fileList = this.value.map(item => ({
id: item.id ? item.id : '',
url: item.url,
name: item.name
}))
} else {
if (this.vmodelType === 'array') {
this.fileList = this.value.map(item => ({ url: item }))
} else {
this.fileList = [{ url: this.value }]
}
}
}
},
mounted() {
},
methods: {
agetToken() {
this.token = 'Bearer ' + getToken()
},
findItem(uid) {
this.fileList.forEach((ele, i) => {
if (uid === ele.uid) {
this.picIndex = i
}
})
},
onChangeHandle(file) {
// console.log('onChangeHandle', file, this.fileList)
this.findItem(file.uid)
this.$refs.upload.$refs['upload-inner'].handleClick()
},
beforeAvatarUpload(file) {
const imgType = file.type
const isLtSize = file.size / 1024 / 1024 < this.limitSize
const TYPE_NOGIFWEBP = ['image/png', 'image/jpeg', 'image/jpg']
const TYPE_NOGIF = ['image/png', 'image/jpeg', 'image/jpg', 'image/webp']
const TYPE_NOWEBP = ['image/png', 'image/jpeg', 'image/jpg', 'image/gif']
const TYPE_ALL = ['image/png', 'image/jpeg', 'image/jpg', 'image/gif', 'image/webp']
let isType = true
if (this.limitType && this.limitType.indexOf('gif') !== -1 && this.limitType.indexOf('webp') !== -1) {
if (TYPE_NOGIFWEBP.indexOf(imgType) === -1) {
isType = false
this.$message.error('仅支持上传 jpg、png、jpeg、gif、webp 格式的图片!')
}
} else if (this.limitType && this.limitType.indexOf('gif') === -1 && this.limitType.indexOf('webp') === -1) {
if (TYPE_NOGIFWEBP.indexOf(imgType) === -1) {
isType = false
this.$message.error('仅支持上传 jpg、png、jpeg 格式的图片!')
}
} else if (this.limitType && this.limitType.indexOf('webp') !== -1) {
if (TYPE_NOGIF.indexOf(imgType) === -1) {
isType = false
this.$message.error('仅支持上传 jpg、png、jpeg、webp 格式的图片!')
}
} else if (this.limitType && this.limitType.indexOf('gif') !== -1) {
if (TYPE_NOWEBP.indexOf(imgType) === -1) {
isType = false
this.$message.error('仅支持上传 jpg、png、jpeg、gif 格式的图片!')
}
} else {
if (TYPE_ALL.indexOf(imgType) === -1) {
isType = false
this.$message.error('仅支持上传 jpg、png、jpeg、webp、gif 格式的图片!')
}
}
if (!isLtSize) {
this.$message.error(`上传图片大小不能超过${this.limitSize}MB!`)
}
if (this.isCheckPicSize === true) {
const width = this.checkWidth
const height = this.checkHeight
const topWidth = this.topLimitWidth
const topHeight = this.topLimitHeight
const that = this
const isSize = new Promise((resolve, reject) => {
// window对象将blob或file读取成一个url
const _URL = window.URL || window.webkitURL
const img = new Image()
// image对象的onload事件当图片加载完成后执行的函数
img.onload = () => {
that.imgWidth = img.width
that.imgHeight = img.height
if (width && height) { // 校验图片的宽度和高度
let valid = false
if (topWidth && topHeight) {
// 校验图片宽度和高度范围
valid = ((width <= img.width) && (img.width <= topWidth)) && ((height <= img.height) && (img.height <= topHeight))
} else if (topHeight) {
// 校验图片高度范围
valid = img.width === width && ((height <= img.height) && (img.height <= topHeight))
} else if (topWidth) {
// 校验图片宽度范围
valid = ((width <= img.width) && (img.width <= topWidth)) && img.height === height
} else {
// 校验图片宽度、高度固定值
valid = img.width === width && height === img.height
}
valid ? resolve() : reject(new Error('error'))
} else if (width) { // 只校验图片的宽度
let valid = false
if (topWidth) {
// 校验图片宽度范围
valid = (width <= img.width) && (img.width <= topWidth)
} else {
// 校验图片宽度固定值
valid = img.width === width
}
valid ? resolve() : reject(new Error('error'))
} if (height) { // 只校验图片的高度
let valid = false
if (topHeight) {
// 校验图片高度范围
valid = (height <= img.height) && (img.height <= topHeight)
} else {
// 校验图片高度固定值
valid = img.height === height
}
valid ? resolve() : reject(new Error('error'))
}
}
img.src = _URL.createObjectURL(file)
}).then(() => {
return file
}, () => {
let text = ''
if (width && height) {
if (topWidth && topHeight) {
text = `图片尺寸限制为:宽度${width}~${topWidth}px高度${height}~${topHeight}px`
} else if (topHeight) {
text = `图片尺寸限制为:宽度${width}px高度${height}~${topHeight}px`
} else if (topWidth) {
text = `图片尺寸限制为:宽度${width}~${topWidth}px高度${height}px`
} else {
text = `图片尺寸限制为:宽度${width}px高度${height}px`
}
} else if (width) {
if (topWidth) {
text = `图片尺寸限制为:宽度${width}~${topWidth}px`
} else {
text = `图片尺寸限制为:宽度${width}px`
}
} else if (height) {
if (topHeight) {
text = `图片尺寸限制为:高度${height}~${topHeight}px`
} else {
text = `图片尺寸限制为:高度${height}px`
}
}
this.$message.error(text)
return Promise.reject(new Error('error'))
})
return isType && isLtSize && isSize
} else {
// window对象将blob或file读取成一个url
const _URL = window.URL || window.webkitURL
const img = new Image()
img.onload = () => { // image对象的onload事件当图片加载完成后执行的函数
this.imgWidth = img.width
this.imgHeight = img.height
// console.log('getWidthAndHeight', this.imgWidth, this.imgHeight)
}
img.src = _URL.createObjectURL(file)
return isType && isLtSize
}
},
// 判断是否是String
isString(str) {
return ((str instanceof String) || (typeof str).toLowerCase() === 'string')
},
handleRemove(file) {
this.findItem(file.uid)
this.fileList.splice(this.picIndex, 1)
// fileList = JSON.parse(JSON.stringify(this.fileList))
// this.exportImg(fileList)
},
handleSuccess(res, file, fileList) {
console.log(fileList, 'success');
console.log(this.picIndex, 'this.picIndex');
if (this.picIndex !== -1) {
fileList.splice(this.picIndex, 1)
}
// this.exportImg(fileList)
console.log(res.url, 'res.url');
this.imageUrl = res.url
this.$emit('upSuccess', res.url)
},
handleError(err) {
this.$message.error(err)
},
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url
this.dialogVisible = true
},
exportImg(fileList = []) {
// console.log('exportImg fileList', fileList)
this.fileList = fileList
if (fileList.length !== 0) {
if (this.valueType === 'Object') {
const imgs = fileList.map(item => {
if (item.response && item.response.result) {
item.id = item.response.result[0].id
item.url = item.response.result[0].url + '&width=' + this.imgWidth + '&height=' + this.imgHeight
item.name = item.response.result[0].fileName
}
return {
id: item.id,
url: item.url,
name: item.name
}
})
this.$emit('input', imgs)
// console.log('exportImg imgs', imgs)
} else {
if (this.vmodelType === 'array') {
const imgs = fileList.map(item => {
if (item.response && item.response.result) {
item.url = item.response.result[0].url + '&width=' + this.imgWidth + '&height=' + this.imgHeight
}
return item.url
})
this.$emit('input', imgs)
// console.log('exportImg imgs', imgs)
} else {
const resUrl = fileList[0].response.result[0].url + '&width=' + this.imgWidth + '&height=' + this.imgHeight
this.$emit('input', resUrl)
// console.log('exportImg resUrl', resUrl)
}
}
} else {
this.$emit('input', '')
}
this.picIndex = -1
}
}
}
</script>
<style lang='less'>
@small-size: 80px;
.img-upload&&.limit-num {
.el-upload--picture-card {
display: none !important;
}
}
.el-upload--picture-card {
background: url("~@/assets/companyFile/uploadicon.png") center no-repeat !important;
background-size: 40% 40% !important;
.el-icon-plus {
display: none;
}
}
.img-upload&&.mini {
.el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.el-upload-list__item {
width: @small-size;
height: @small-size;
text-align: center;
/*去除upload组件过渡效果*/
transition: none !important;
}
.el-upload--picture-card {
width: @small-size;
height: @small-size;
line-height: @small-size;
text-align: center;
}
}
.el-upload-list__item&&.is-success {
.img-con {
width: 100%;
height: 100%;
}
}
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409eff;
}
.avatar-uploader-icon {
font-size: 28px;
position: relative;
color: #8c939d;
width: 220px;
height: 220px;
background: url("~@/assets/companyFile/uploadicon.png") center no-repeat !important;
background-size: 40% 40% !important;
div {
position: absolute;
top: 160px;
left: 16px;
font-size: 19px;
}
}
</style>