|
@@ -1,201 +1,130 @@
|
|
|
<template>
|
|
|
<div class="upload">
|
|
|
- <el-upload v-if="hidden" :action="newAction" :headers="headers" :multiple="multiple" :data="data"
|
|
|
- :accept="accept" :show-file-list="showFileList" :list-type="listType" :on-progress="onProgress"
|
|
|
- :on-error="onError" :on-success="onSuccess" :before-upload="beforeUpload" :disabled="disabled">
|
|
|
- <el-button v-if="listType !== 'picture-card'" :type="btnType">{{ newTitle }}</el-button>
|
|
|
- <i v-else class="el-icon-plus" />
|
|
|
+ <el-upload v-if="isBtn()" :action="action" :headers="headers" :multiple="multiple" :data="data"
|
|
|
+ :name="name" :show-file-list="showFileList" :drag="drag" :accept="accept" :listType="listType"
|
|
|
+ :autoUpload="autoUpload" :disabled="disabled" :before-upload="beforeUpload" :on-progress="onProgress"
|
|
|
+ :on-success="onSuccess" :on-error="onError">
|
|
|
+ <el-button v-if="listType === 'text'" :type="type" size="mini" ref="upload">
|
|
|
+ <slot v-if="percentage <= 0 && !form.file">点击上传</slot>
|
|
|
+ <span v-if="percentage > 0 && !form.file">{{ title }}</span>
|
|
|
+ <span v-if="form.file">上传成功</span>
|
|
|
+ </el-button>
|
|
|
+ <div v-else>
|
|
|
+ <i class="el-icon-plus" />
|
|
|
+ </div>
|
|
|
</el-upload>
|
|
|
- <el-progress v-if="isShow()" type="circle" :percentage="percent" :status="isStatus" />
|
|
|
- <div class="upload-image" v-if="newUrl">
|
|
|
- <el-image :src="newUrl" />
|
|
|
- <i v-if="disabled === false" class="el-icon-delete" @click="getDelete" />
|
|
|
+ <el-progress v-if="isPercentage()" type="circle" :percentage="percentage" :status="status"
|
|
|
+ @click.native="handleUpload" :width="146" />
|
|
|
+ <div class="img" v-if="isImg()">
|
|
|
+ <i class="el-icon-delete" v-if="!disabled" @click="onDelete" />
|
|
|
+ <el-image :src="form.file" />
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
const baseUrl = process.env.VUE_APP_BASE_API
|
|
|
-import { getToken } from "@/utils/auth";
|
|
|
+import { getToken } from '@/utils/auth'
|
|
|
export default {
|
|
|
props: {
|
|
|
- action: {
|
|
|
- type: String,
|
|
|
- default: ''
|
|
|
- },
|
|
|
- // 图片
|
|
|
+ // 回显图片
|
|
|
url: String,
|
|
|
- // 类型
|
|
|
- listType: {
|
|
|
- type: String,
|
|
|
- default: 'text'
|
|
|
+ // 是否支持多选文件
|
|
|
+ multiple: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
},
|
|
|
- // 是否显示已上传文件列表
|
|
|
+ // 是否显示文件列表
|
|
|
showFileList: {
|
|
|
type: Boolean,
|
|
|
default: false
|
|
|
},
|
|
|
- // 是否支持多选文件
|
|
|
- multiple: {
|
|
|
+ // 是否支持拖拽上传
|
|
|
+ drag: {
|
|
|
type: Boolean,
|
|
|
default: false
|
|
|
},
|
|
|
+ // 上传类型
|
|
|
+ listType: {
|
|
|
+ type: String,
|
|
|
+ default: 'text'
|
|
|
+ },
|
|
|
+ // 是否支持自动上传
|
|
|
+ autoUpload: {
|
|
|
+ type: Boolean,
|
|
|
+ default: true
|
|
|
+ },
|
|
|
// 是否禁用
|
|
|
disabled: {
|
|
|
type: Boolean,
|
|
|
default: false
|
|
|
},
|
|
|
- // 上传按钮文字
|
|
|
- title: {
|
|
|
- type: String,
|
|
|
- default: '文件上传'
|
|
|
- },
|
|
|
+ // 最大允许上传个数
|
|
|
+ limit: Number,
|
|
|
// 图片尺寸
|
|
|
- measure: {
|
|
|
- type: String,
|
|
|
- default: ''
|
|
|
- },
|
|
|
+ width: Number,
|
|
|
+ height: Number,
|
|
|
// 文件大小
|
|
|
size: Number
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
+ // 上传类型
|
|
|
+ obj: {
|
|
|
+ 'text': `${baseUrl}/system/file/file/upload`,
|
|
|
+ 'picture-card': `${baseUrl}/system/file/picture/upload`
|
|
|
+ },
|
|
|
// 上传地址
|
|
|
- newAction: baseUrl + this.action,
|
|
|
- // 请求头
|
|
|
+ action: '#',
|
|
|
+ // 请求头部
|
|
|
headers: {
|
|
|
- Authorization: "Bearer " + getToken(),
|
|
|
+ Authorization: "Bearer " + getToken()
|
|
|
},
|
|
|
- // 附带参数
|
|
|
+ // 额外参数
|
|
|
data: {},
|
|
|
- // 文件字段名
|
|
|
- name: '',
|
|
|
- // 是否显示上传按钮
|
|
|
- hidden: true,
|
|
|
- // 按钮文字
|
|
|
- newTitle: this.title,
|
|
|
- // 按钮颜色
|
|
|
- btnType: 'primary',
|
|
|
+ // 文件名
|
|
|
+ name: 'multipartFile',
|
|
|
+ // 文件类型
|
|
|
+ accept: '',
|
|
|
// 进度条
|
|
|
- percent: 0,
|
|
|
- // 上传失败进度条
|
|
|
- isStatus: null,
|
|
|
- // 显示图片
|
|
|
- newUrl: this.url,
|
|
|
- // 传给父级的参数
|
|
|
- form: {},
|
|
|
- // 上传图片的尺寸
|
|
|
- width: Number(this.measure.split('*')[0]),
|
|
|
- height: Number(this.measure.split('*')[1]),
|
|
|
- // 上传的文件格式
|
|
|
- accept: ''
|
|
|
+ percentage: 0,
|
|
|
+ title: '',
|
|
|
+ // 进度条状态
|
|
|
+ status: null,
|
|
|
+ type: 'primary',
|
|
|
+ // 表单
|
|
|
+ form: {
|
|
|
+ size: 0,
|
|
|
+ file: ''
|
|
|
+ }
|
|
|
}
|
|
|
},
|
|
|
- watch: {
|
|
|
- measure(val) {
|
|
|
- this.width = Number(val.split('*')[0])
|
|
|
- this.height = Number(val.split('*')[1])
|
|
|
- },
|
|
|
+ watch:{
|
|
|
url(val) {
|
|
|
- this.newUrl = val ? val : ''
|
|
|
- this.hidden = val ? false : true
|
|
|
+ this.form.file = val
|
|
|
}
|
|
|
},
|
|
|
- mounted() {
|
|
|
- if (!this.action) {
|
|
|
- if (this.listType === 'picture-card') {
|
|
|
- this.newAction = `${baseUrl}/system/file/picture/upload`
|
|
|
- this.accept = '.jpg, .jpeg, .png, .bmp, .icon, .gif'
|
|
|
- } else if (this.listType === 'text') {
|
|
|
- this.newAction = `${baseUrl}/system/file/file/upload`
|
|
|
- } else if (this.listType === 'audio') {
|
|
|
- this.newAction = `${baseUrl}/system/file/mp3/upload`
|
|
|
- this.accept = '.mp3, .wav, .aiff, .midi, .wma'
|
|
|
- }
|
|
|
- }
|
|
|
- this.newUrl = this.url ? this.url : ''
|
|
|
- this.hidden = this.url ? false : true
|
|
|
+ created() {
|
|
|
+ // 根据上传类型 变更 上传地址
|
|
|
+ this.action = this.obj[this.listType]
|
|
|
+ // 根据上传类型 变更 文件类型
|
|
|
+ this.accept = this.listType === 'picture-card' ? '.jpg, .jpeg, .png, .bmp, .icon, .gif' : ''
|
|
|
+ // 回显图片
|
|
|
+ this.form.file = this.url
|
|
|
},
|
|
|
methods: {
|
|
|
// 上传之前
|
|
|
- async beforeUpload(file) {
|
|
|
- this.btnType = 'primary'
|
|
|
- if (this.measure || this.size) {
|
|
|
- await this.measureChecked(file).then((res) => {
|
|
|
- if (res) {
|
|
|
- this.isUpload(file)
|
|
|
- }
|
|
|
- })
|
|
|
- } else {
|
|
|
- this.isUpload(file)
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- // 上传
|
|
|
- isUpload(file) {
|
|
|
- this.data.multipartFile = file
|
|
|
- this.name = file.name
|
|
|
- if (this.listType !== 'picture-card') {
|
|
|
- this.form.size = file.size
|
|
|
- } else {
|
|
|
- this.hidden = false
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- // 上传过程中
|
|
|
- onProgress(e) {
|
|
|
- this.percent = parseInt(e.percent)
|
|
|
- this.newTitle = `已上传${parseInt(e.percent - 1)}%`
|
|
|
- this.$emit('loading')
|
|
|
- this.visible = true
|
|
|
- },
|
|
|
-
|
|
|
- // 上传失败
|
|
|
- onError() {
|
|
|
- this.newTitle = `上传失败`
|
|
|
- this.btnType = `danger`
|
|
|
- this.isStatus = 'exception'
|
|
|
- this.$emit('upload')
|
|
|
- },
|
|
|
-
|
|
|
- // 上传成功
|
|
|
- onSuccess(res) {
|
|
|
- if (this.listType === 'picture-card') {
|
|
|
- // 显示图片
|
|
|
- this.newUrl = res.data
|
|
|
- } else {
|
|
|
- // 按钮文字
|
|
|
- this.newTitle = '上传成功'
|
|
|
- this.btnType = 'success'
|
|
|
- }
|
|
|
- // 传参
|
|
|
- this.form.file = res.data
|
|
|
- this.$emit('upload', this.form)
|
|
|
- },
|
|
|
-
|
|
|
- // 删除图片
|
|
|
- getDelete() {
|
|
|
- if (this.listType == 'picture-card') {
|
|
|
- this.hidden = true
|
|
|
- this.percent = 0
|
|
|
- this.newUrl = ''
|
|
|
- }
|
|
|
- this.$emit('upload', this.form = {})
|
|
|
- },
|
|
|
-
|
|
|
- // 是否显示图片进度条
|
|
|
- isShow() {
|
|
|
- if (this.listType == 'picture-card') {
|
|
|
- return !this.hidden && this.newUrl === '' ? true : false
|
|
|
- } else {
|
|
|
- return false
|
|
|
+ beforeUpload(file) {
|
|
|
+ if ((this.width && this.height) || this.size) {
|
|
|
+ this.checked(file)
|
|
|
}
|
|
|
+ this.form.size = file.size
|
|
|
},
|
|
|
|
|
|
// 判断图片尺寸 或 文件大小
|
|
|
- measureChecked(file) {
|
|
|
+ checked(file) {
|
|
|
return new Promise((resolve, reject) => {
|
|
|
- if (this.measure) {
|
|
|
+ if (this.listType === 'picture-card') {
|
|
|
let reader = new FileReader()
|
|
|
reader.readAsDataURL(file)
|
|
|
reader.onload = () => {
|
|
@@ -203,8 +132,8 @@ export default {
|
|
|
img.src = reader.result
|
|
|
img.onload = () => {
|
|
|
if (img.width !== this.width || img.height !== this.height) {
|
|
|
- this.$message.error(`请上传${this.measure}尺寸的图片`)
|
|
|
- reject
|
|
|
+ this.$message.error(`请上传${this.width}x${this.height}尺寸的图片`)
|
|
|
+ reject(false)
|
|
|
} else {
|
|
|
resolve(true)
|
|
|
}
|
|
@@ -212,15 +141,56 @@ export default {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (this.size) {
|
|
|
- if ((file.size / 1024 / 1024) > this.size) {
|
|
|
- this.$message.error(`上传文件过大`)
|
|
|
- reject
|
|
|
- } else {
|
|
|
- resolve(true)
|
|
|
- }
|
|
|
+ if (this.size !== '' && ((file.size / 1024 / 1024) > this.size)) {
|
|
|
+ this.$message.error(`文件大小不超过${this.size}`)
|
|
|
+ reject(false)
|
|
|
+ } else {
|
|
|
+ resolve(true)
|
|
|
}
|
|
|
})
|
|
|
+ },
|
|
|
+
|
|
|
+ // 上传过程中
|
|
|
+ onProgress(file) {
|
|
|
+ this.percentage = parseInt(file.percent - 1)
|
|
|
+ this.title = `已上传 ${parseInt(file.percent - 1)}%`
|
|
|
+ },
|
|
|
+
|
|
|
+ // 上传成功
|
|
|
+ onSuccess(file) {
|
|
|
+ this.form.file = file.data
|
|
|
+ this.$emit('upload', this.form)
|
|
|
+ },
|
|
|
+
|
|
|
+ // 上传失败
|
|
|
+ onError() {
|
|
|
+ this.status = 'exception'
|
|
|
+ this.type = 'danger'
|
|
|
+ this.title = '上传失败'
|
|
|
+ },
|
|
|
+
|
|
|
+ // 删除
|
|
|
+ onDelete() {
|
|
|
+ this.form.file = ''
|
|
|
+ this.percentage = 0
|
|
|
+ },
|
|
|
+
|
|
|
+ // 如果上传失败 重新上传
|
|
|
+ handleUpload() {
|
|
|
+ this.percentage = 0
|
|
|
+ },
|
|
|
+
|
|
|
+ // 上传按钮
|
|
|
+ isBtn() {
|
|
|
+ return this.listType === 'text' || (this.listType === 'picture-card' && this.percentage == 0 && !this.form.file)
|
|
|
+ },
|
|
|
+ // 显示进度条
|
|
|
+ isPercentage() {
|
|
|
+ return this.listType === 'picture-card' && this.percentage !== 0 && !this.form.file
|
|
|
+ },
|
|
|
+ // 显示图片
|
|
|
+ isImg() {
|
|
|
+ return this.listType === 'picture-card' && this.form.file
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -230,39 +200,42 @@ export default {
|
|
|
.upload {
|
|
|
display: inline-block;
|
|
|
|
|
|
- .el-button {
|
|
|
- margin: 0;
|
|
|
+ .el-icon-plus {
|
|
|
+ line-height: 146px;
|
|
|
}
|
|
|
|
|
|
- .upload-image {
|
|
|
+ .img {
|
|
|
position: relative;
|
|
|
- width: 148px;
|
|
|
-
|
|
|
- .el-image {
|
|
|
- display: block;
|
|
|
- }
|
|
|
+ width: 146px;
|
|
|
+ height: 146px;
|
|
|
+ border-radius: 5px;
|
|
|
|
|
|
.el-icon-delete {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
position: absolute;
|
|
|
top: 50%;
|
|
|
left: 50%;
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
transform: translate(-50%, -50%);
|
|
|
- background: rgb(0 0 0 / 50%);
|
|
|
+ text-align: center;
|
|
|
+ line-height: 146px;
|
|
|
+ z-index: 99;
|
|
|
+ opacity: 0;
|
|
|
+ font-size: 24px;
|
|
|
color: #fff;
|
|
|
transition: all 0.3s;
|
|
|
- font-size: 24px;
|
|
|
- opacity: 0;
|
|
|
- display: flex;
|
|
|
- justify-content: center;
|
|
|
- align-items: center;
|
|
|
+ background: rgb(0 0 0 / 50%);
|
|
|
}
|
|
|
|
|
|
- i:hover {
|
|
|
+ .el-icon-delete:hover {
|
|
|
opacity: 1;
|
|
|
cursor: pointer;
|
|
|
}
|
|
|
+
|
|
|
+ .el-image {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
</style>
|