537 lines
19 KiB
Vue
537 lines
19 KiB
Vue
<template>
|
||
<div>
|
||
<div v-if="uploadType === 'btnUpload'" class="zc-flex" style="justify-content: space-between;">
|
||
<template v-if="isImg===false"><!--表示其他非图片文件-->
|
||
<div class="div-left-flex">
|
||
<span v-for="(item,index) in uploadList" class="file" :key="index">
|
||
{{item.name}}
|
||
<Icon class="pl-10" type="ios-eye-outline" @click.native="handleView(item,index)"></Icon>
|
||
<Icon class="pl-10" type="ios-trash-outline" @click.native="handleRemove(item,index)"></Icon>
|
||
</span>
|
||
</div>
|
||
</template>
|
||
<template v-else>
|
||
<div class="attach-container">
|
||
<div class="upload-container">
|
||
<div class="upload-list" v-for="(item,index) in uploadList" :key="index">
|
||
<template v-if="(item.status === 'finished') || !item.status">
|
||
<!-- <img :src="item.url ? item.url : item.response.data.url" /> -->
|
||
<!-- thum1 详情返回缩略图字段,thumb_url 上传时返回缩略图字段 -->
|
||
<div v-if="item.response">
|
||
<img :src="item.thum1?item.thum1:item.response.data.thumb_url" v-if="item.response.data.ext == 'jpg' || item.response.data.ext == 'jpeg' || item.response.data.ext == 'png'"/>
|
||
<img src="@/assets/images/zip.png" v-else-if="item.response.data.ext == 'zip'"/>
|
||
<img src="@/assets/images/pptx.png" v-else-if="item.response.data.ext == 'pptx' || item.response.data.ext == 'ppt'"/>
|
||
<img src="@/assets/images/xlsx.png" v-else-if="item.response.data.ext == 'xlsx' || item.response.data.ext == 'xls' || item.response.data.ext == 'csv'"/>
|
||
<img src="@/assets/images/pdf.png" v-else-if="item.response.data.ext == 'pdf'"/>
|
||
<img src="@/assets/images/docx.png" v-else-if="item.response.data.ext == 'doc' || item.response.data.ext == 'docx'"/>
|
||
<img src="@/assets/images/file.png" v-else />
|
||
<!--显示文件名称-->
|
||
<div class="file-name">{{item.name}}</div>
|
||
</div>
|
||
<div v-else>
|
||
<img :src="item.thum1?item.thum1:item.thumb_url" v-if="item.ext == 'jpg' || item.ext == 'jpeg' || item.ext == 'png'"/>
|
||
<img src="@/assets/images/zip.png" v-else-if="item.ext == 'zip'"/>
|
||
<img src="@/assets/images/pptx.png" v-else-if="item.ext == 'pptx' || item.ext == 'ppt'"/>
|
||
<img src="@/assets/images/xlsx.png" v-else-if="item.ext == 'xlsx' || item.ext == 'xls' || item.ext == 'csv'"/>
|
||
<img src="@/assets/images/pdf.png" v-else-if="item.ext == 'pdf'"/>
|
||
<img src="@/assets/images/docx.png" v-else-if="item.ext == 'doc' || item.ext == 'docx'"/>
|
||
<img src="@/assets/images/file.png" v-else />
|
||
<!--显示文件名称-->
|
||
<div class="file-name">{{item.name}}</div>
|
||
</div>
|
||
|
||
<div class="upload-list-cover">
|
||
<Icon type="ios-eye-outline" @click.native="handleView(item,index)"></Icon>
|
||
<Icon type="ios-trash-outline" @click.native="handleRemove(item,index)"></Icon>
|
||
</div>
|
||
</template>
|
||
<template v-else>
|
||
<Progress v-if="item.showProgress" :percent="item.percentage" hide-info></Progress>
|
||
</template>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
<div class="mt-10">
|
||
<Upload
|
||
ref="upload"
|
||
:show-upload-list="false"
|
||
:default-file-list="defaultList"
|
||
:on-success="handleSuccess"
|
||
:format="format || defaultFormat"
|
||
:max-size="maxSize?maxSize:$config.maxSize"
|
||
:on-format-error="handleFormatError"
|
||
:on-exceeded-size="handleMaxSize"
|
||
:before-upload="handleUpload"
|
||
:on-progress="handleProgress"
|
||
multiple
|
||
type="drag"
|
||
name="pic"
|
||
:headers="uploadHeader"
|
||
:action="isUploadUrl == 'fbb'?$config.appUploadUrl:$config.uploadUrl"
|
||
>
|
||
<Button>上传附件</Button>
|
||
</Upload>
|
||
</div>
|
||
</div>
|
||
<div v-if="!uploadType">
|
||
<div class="attach-container">
|
||
<div class="upload-container">
|
||
<div class="upload-list" v-for="(item,index) in uploadList" :key="index">
|
||
<template v-if="(item.status === 'finished') || !item.status">
|
||
<img :src="item.url ? item.url : item.response.data.url" />
|
||
<div class="upload-list-cover">
|
||
<Icon type="ios-eye-outline" @click.native="handleView(item,index)"></Icon>
|
||
<Icon type="ios-trash-outline" @click.native="handleRemove(item)"></Icon>
|
||
</div>
|
||
</template>
|
||
<template v-else>
|
||
<Progress v-if="item.showProgress" :percent="item.percentage" hide-info></Progress>
|
||
</template>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="zc-left mr-10">
|
||
<Upload
|
||
ref="upload"
|
||
:show-upload-list="false"
|
||
:default-file-list="defaultList"
|
||
:on-success="handleSuccess"
|
||
:format="format || defaultFormat"
|
||
:max-size="maxSize?maxSize:$config.maxSize"
|
||
:on-format-error="handleFormatError"
|
||
:on-exceeded-size="handleMaxSize"
|
||
:before-upload="handleUpload"
|
||
:on-progress="handleProgress"
|
||
multiple
|
||
type="drag"
|
||
name="pic"
|
||
:headers="uploadHeader"
|
||
:action="isUploadUrl == 'fbb'?$config.appUploadUrl:$config.uploadUrl"
|
||
>
|
||
<div class="add-upload">
|
||
<Icon type="ios-add" size="20"></Icon>
|
||
</div>
|
||
</Upload>
|
||
</div>
|
||
</div>
|
||
<div v-if="uploadType === 'showImg'" class="attach-container">
|
||
<div class="upload-container">
|
||
<div class="upload-list" v-for="(item,index) in haveUpload" :key="index">
|
||
<template>
|
||
<img :src="item.url ? item.url : item.response.data.url" />
|
||
<div class="upload-list-cover">
|
||
<Icon type="ios-eye-outline" @click.native="handleView(item,index)"></Icon>
|
||
</div>
|
||
</template>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div v-if="uploadType === 'showDraggable'">
|
||
<draggable v-model="uploadList" @update="datadragEnd">
|
||
<div class="upload-list" v-for="(item,index) in uploadList" :key="index">
|
||
<template v-if="(item.status === 'finished') || !item.status">
|
||
<!-- <img :src="item.url ? item.url : item.response.data.url" /> -->
|
||
<!-- thum1 详情返回缩略图字段,thumb_url 上传时返回缩略图字段 -->
|
||
<img :src="item.thum1?item.thum1:item.response.data.thumb_url" />
|
||
<div class="upload-list-cover">
|
||
<Icon type="ios-eye-outline" @click.native="handleView(item,index)"></Icon>
|
||
</div>
|
||
</template>
|
||
<template v-else>
|
||
<Progress v-if="item.showProgress" :percent="item.percentage" hide-info></Progress>
|
||
</template>
|
||
</div>
|
||
</draggable>
|
||
</div>
|
||
|
||
<div v-if="uploadType === 'showImgName'" class="attach-container">
|
||
<span class="file_Img" v-for="(item,index) in haveUpload" :key="index">
|
||
{{item.name}}
|
||
<Icon style="padding-left: 5px;cursor: pointer;" type="ios-eye-outline" @click.native="handleView(item,index)"></Icon>
|
||
</span>
|
||
</div>
|
||
<div class="images" v-show="visible" v-viewer="{navbar: false,}">
|
||
<viewer :images="imagesList" ref='viewer' @inited='inited'>
|
||
<img v-for="(src,i) in imagesList" :src="src" :key="`${i}src`" />
|
||
</viewer>
|
||
</div>
|
||
<!-- 弹框查看图片/支持拖拉拽 -->
|
||
<Modal v-model="modal" width="850" :mask-closable="false" draggable>
|
||
<div class="header-title" slot="header"></div>
|
||
<img ref='modalImg' :src="url" style="width:825px; height:720px;transition:all .3s" />
|
||
<div slot="footer" class="text-center">
|
||
<Button type="primary" shape="circle" class="mr-10" @click="imgRotate(-90)"><Icon style='font-size: 20px;' type="ios-undo" /></Button>
|
||
<Button type="primary" shape="circle" class="mr-10" @click="imgRotate(90)"><Icon style='font-size: 20px;' type="ios-redo" /></Button>
|
||
</div>
|
||
</Modal>
|
||
<Modal v-model="validateModal" class-name="zc-modal" width="400" :mask-closable="false" >
|
||
<div class="header-title" slot="header">删除</div>
|
||
<div style="color:red;margin:20px 0;" class="text-center">是否确定删除?</div>
|
||
<div slot="footer" class="text-center">
|
||
<Button type="default" shape="circle" class="mr-10" @click="validateModal=false">取消</Button>
|
||
<Button type="primary" shape="circle" @click="submitRemove(index)">确定</Button>
|
||
</div>
|
||
</Modal>
|
||
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import draggable from 'vuedraggable'
|
||
import store from 'store'
|
||
export default {
|
||
components: { draggable },
|
||
props: [
|
||
'uploadType', // uploadType=上传文件按钮类型
|
||
'haveUpload', // 编辑时接收后端传回的数据
|
||
'isCanUploadVideo',
|
||
'getFlieList', // 编辑时的附件文件
|
||
'isUploadUrl', // fbb=app上传地址,zc=pc上传地址
|
||
'maxLength', // 文件上传件数
|
||
'format', // 上传文件的格式
|
||
'width', // 上传附件按钮的宽度
|
||
'btnName', // 上传按钮的名字
|
||
'isImg', // 是否是图片
|
||
'isModal', // 是否采用弹框显示(拖拉拽)
|
||
'deleteValidate', // 是否删除 boolean
|
||
'maxSize'
|
||
],
|
||
data () {
|
||
return {
|
||
modal: false, // 弹框
|
||
validateModal: false, // 确认删除弹框提醒
|
||
msgFlag: false, // 多选时,标识文件超出数据是否已发出提示 (methods:handleUpload)
|
||
uploadSum: 0, // 多选时,记录一次上传多少个文件
|
||
url: '',
|
||
visible: false,
|
||
uploadList: [], // 上传成功之后后端返回的图片数组
|
||
defaultList: [], // 默认已上传的文件列表
|
||
uploadHeader: {},
|
||
defaultFormat: ['jpg', 'png', 'jpeg', 'doc', 'docx', 'xls', 'xlsx', 'pdf', 'zip'],
|
||
imagesList: [], // 图片预览
|
||
defaultImagesList: [], // 图片预览
|
||
fileObj: {},
|
||
index: '',
|
||
isVisible:false,
|
||
activaIndex:0,
|
||
curDegree: 0
|
||
}
|
||
},
|
||
created () {
|
||
this.init()
|
||
if (this.isCanUploadVideo) {
|
||
this.defaultFormat = [
|
||
'jpg',
|
||
'png',
|
||
'jpeg',
|
||
'doc',
|
||
'docx',
|
||
'xls',
|
||
'xlsx',
|
||
'pdf',
|
||
'mp4',
|
||
'mpeg',
|
||
'.mpg',
|
||
'avi',
|
||
'mov',
|
||
'wmv',
|
||
'mkv',
|
||
'flv',
|
||
'zip'
|
||
]
|
||
}
|
||
if (this.getFlieList) {
|
||
this.uploadList = this.getFlieList
|
||
}
|
||
},
|
||
methods: {
|
||
init () {
|
||
this.uploadHeader = { ApiAuth: store.get('apiAuth') }
|
||
},
|
||
inited(viewer) {
|
||
this.$viewer = viewer;
|
||
},
|
||
handleFormatError (file) {
|
||
if (this.format !== undefined) {
|
||
this.$Notice.warning({
|
||
title: '文件类型不合法',
|
||
desc:
|
||
file.name +
|
||
'的文件类型不正确,请上传后缀为' + this.format + '的文件。'
|
||
})
|
||
} else {
|
||
this.$Notice.warning({
|
||
title: '文件类型不合法',
|
||
desc:
|
||
file.name +
|
||
'的文件类型不正确,请上传后缀为jpg、png、doc、docx、xls、xlsx、pdf、zip的文件。'
|
||
})
|
||
}
|
||
},
|
||
clearUpload () { // 清除图片列表
|
||
this.uploadList = []
|
||
this.$refs.upload.clearFiles()
|
||
},
|
||
handleSuccess (response, file, fileList) {
|
||
// this.$emit('getFilelist', { response, fileList })
|
||
// if (response && response.code === 1) {
|
||
// this.uploadList = fileList
|
||
// // this.uploadList.push(file)
|
||
|
||
// // 上传成功之后后端返回的图片数组 清空数据
|
||
|
||
// // 多选时,标识文件超出数据是否已发出提示 清空数据
|
||
// }
|
||
console.log('uploadList', this.uploadList)
|
||
this.$emit('getFilelist', { response, fileList: this.uploadList })
|
||
},
|
||
handleProgress (event, file, fileList) {
|
||
// console.log('上传中', event) // 继承了原生函数的 event 事件
|
||
// console.log('上传中 file', file) // 上传的文件
|
||
// console.log('上传中 fileList', fileList) // 上传文件列表包含file
|
||
|
||
// uploadList 就是 原文档中的那个渲染的 uplist 是个数组,所以要把filelist 赋值给他
|
||
this.uploadList = fileList
|
||
|
||
// 调用监听 上传进度 的事件
|
||
event.target.onprogress = (event) => {
|
||
let uploadPercent = parseFloat(((event.loaded / event.total) * 100).toFixed(2)) // 保留两位小数,具体根据自己需求做更改
|
||
|
||
// 手动设置显示上传进度条 以及上传百分比
|
||
file.showProgress = true
|
||
file.percentage = uploadPercent
|
||
}
|
||
},
|
||
handleUpload (file, fileList) {
|
||
// console.log('handleUpload')
|
||
if (this.maxLength) {
|
||
const check = (this.uploadList.length) < this.maxLength
|
||
if (!check) {
|
||
// 多选时,标识文件超出数据是否已发出提示(否则会出现多个提示)
|
||
|
||
this.$Notice.warning({
|
||
title: `最多上传${this.maxLength}份文件`
|
||
})
|
||
} else {
|
||
// this.uploadList.push(file)
|
||
}
|
||
return check
|
||
}
|
||
},
|
||
handleMaxSize (file) {
|
||
this.$Notice.warning({
|
||
title: '文件大小不合法',
|
||
desc: file.name + `太大啦请上传小于${this.maxSize ==undefined?2:(this.maxSize/1024)}M的文件。`
|
||
})
|
||
},
|
||
// 删除图片
|
||
handleRemove (file, index) {
|
||
if (this.deleteValidate) {
|
||
this.validateModal = true
|
||
this.fileObj = file
|
||
this.index = index
|
||
} else {
|
||
this.uploadList.splice(this.uploadList.indexOf(file), 1)
|
||
this.$emit('getFilelist', { response: {}, fileList: this.uploadList, type: 'handleRemove', file: file, index, fileId: file.id ? file.id : file.response.data.id })
|
||
}
|
||
},
|
||
// 确定删除图片
|
||
submitRemove (index) {
|
||
this.uploadList.splice(this.uploadList.indexOf(this.fileObj), 1)
|
||
this.$emit('getFilelist', { response: {}, fileList: this.uploadList, type: 'handleRemove', file: this.fileObj, index, fileId: this.fileObj.id ? this.fileObj.id : this.fileObj.response.data.id })
|
||
this.validateModal = false
|
||
},
|
||
|
||
// 移动图片顺序
|
||
async datadragEnd (evt) {
|
||
evt.preventDefault()
|
||
// console.log('拖动前的索引 :' + evt.oldIndex)
|
||
// console.log('拖动后的索引 :' + evt.newIndex)
|
||
|
||
// 遍历数组,将索引值赋值到对应的sort_order上面,完成排序
|
||
// console.log(evt)
|
||
// let uploadList = JSON.parse(JSON.stringify(this.uploadList))
|
||
|
||
// if (evt.oldIndex > evt.newIndex) {
|
||
// uploadList.splice(evt.newIndex, 0, uploadList[evt.oldIndex])
|
||
// uploadList.splice(evt.oldIndex + 1, 1)
|
||
// } else {
|
||
// uploadList.splice(evt.newIndex + 1, 0, uploadList[evt.oldIndex])
|
||
// uploadList.splice(evt.oldIndex, 1)
|
||
// }
|
||
this.$emit('datadragEnd', { fileList: this.uploadList })
|
||
},
|
||
handleView (item, index) {
|
||
let type = ''
|
||
this.activaIndex = index
|
||
if (item.ext) {
|
||
type = item.ext.toLowerCase()
|
||
} else if (item.response) {
|
||
type = (item.response.data.ext || '').toLowerCase()
|
||
}
|
||
if (type === 'jpg' || type === 'png' || type === 'jpeg') {
|
||
this.url = item.url ? item.url : item.response.data.url
|
||
if (this.isModal) { // 使用弹框查看图片
|
||
this.modal = true
|
||
return false
|
||
}
|
||
this.isVisible=true
|
||
this.visible = false
|
||
if (this.isImg === false) {
|
||
this.getImagesUrl([this.uploadList[index]])
|
||
} else {
|
||
this.getImagesUrl(this.uploadList)
|
||
}
|
||
// 调用图片查看器
|
||
this.$viewer.view(index);
|
||
} else {
|
||
// window.open(item.response.data.url)
|
||
this.url = item.url ? item.url : item.response.data.url
|
||
window.open(this.url, item.name)
|
||
}
|
||
},
|
||
// 图片预览重组
|
||
group (index) {
|
||
if (index != 0) {
|
||
let newArray = this.defaultImagesList.slice(index, this.defaultImagesList.length)
|
||
let footArray = this.defaultImagesList.slice(0, index)
|
||
this.imagesList = newArray.concat(footArray)
|
||
} else {
|
||
this.imagesList = this.defaultImagesList
|
||
}
|
||
},
|
||
// 获取图片地址
|
||
getImagesUrl (list) {
|
||
this.imagesList = []
|
||
if (list.length != 0) {
|
||
console.log('list', list)
|
||
list.map(item => {
|
||
this.imagesList.push(item.url ? item.url : item.response.data.url)
|
||
this.defaultImagesList.push(item.url ? item.url : item.response.data.url)
|
||
})
|
||
}
|
||
},
|
||
// 图片旋转
|
||
imgRotate (degree) {
|
||
this.curDegree += degree
|
||
|
||
this.$refs.modalImg.style.transform = `rotate(${this.curDegree}deg)`
|
||
}
|
||
},
|
||
computed: {},
|
||
mounted () {
|
||
if (this.$refs.upload) {
|
||
this.uploadList = this.$refs.upload.fileList
|
||
this.getImagesUrl(this.$refs.upload.fileList)
|
||
}
|
||
},
|
||
watch: {
|
||
haveUpload: {
|
||
handler (newV, oldV) {
|
||
if (newV) {
|
||
this.defaultList = newV
|
||
this.uploadList = newV
|
||
this.getImagesUrl(newV)
|
||
}
|
||
},
|
||
immediate: true,
|
||
deep: true
|
||
},
|
||
getFlieList: {
|
||
handler (val) {
|
||
this.uploadList = val
|
||
this.getImagesUrl(val)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="less" scoped>
|
||
// .com_upload {
|
||
// float: right;
|
||
// // height: 72px;
|
||
// // line-height: 70px;
|
||
// background: #f1f5ff;
|
||
// color: #4e97d9;
|
||
// cursor: pointer;
|
||
// border-left: 1px solid #e6e6e6;
|
||
// }
|
||
|
||
.add-upload {
|
||
width: 100px;
|
||
height: 100px;
|
||
line-height: 100px;
|
||
border: 1px dashed #e6e6e6;
|
||
cursor: pointer;
|
||
}
|
||
.upload-list {
|
||
float: left;
|
||
width: 100px;
|
||
/*height: 100px;
|
||
line-height: 100px;*/
|
||
border: 1px solid transparent;
|
||
border-radius: 4px;
|
||
overflow: hidden;
|
||
background: #fff;
|
||
position: relative;
|
||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
|
||
margin-right: 4px;
|
||
text-align: center;
|
||
justify-content: center;
|
||
align-items: center;
|
||
}
|
||
.upload-list img {
|
||
width: 80px;
|
||
height: 80px;
|
||
}
|
||
.upload-list-cover {
|
||
display: none;
|
||
position: absolute;
|
||
top: 0;
|
||
bottom: 0;
|
||
left: 0;
|
||
right: 0;
|
||
background: rgba(0, 0, 0, 0.6);
|
||
}
|
||
.upload-list:hover .upload-list-cover {
|
||
display: block;
|
||
}
|
||
.upload-list-cover i {
|
||
color: #fff;
|
||
font-size: 20px;
|
||
cursor: pointer;
|
||
margin: 0 8px;
|
||
}
|
||
.upload-list .file-name {
|
||
font-size: 12px;
|
||
color: #666;
|
||
/*一行显示,超出部分省略号*/
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
.file_Img {
|
||
display: inline-block;
|
||
border: 1px solid #ccc;
|
||
border-radius: 3px;
|
||
padding: 0 5px;
|
||
}
|
||
.div-left-flex{
|
||
flex: 1;
|
||
text-align: left;
|
||
padding-top: 8px;
|
||
}
|
||
.file {
|
||
border: 1px solid #e6e6e6;
|
||
border-radius: 8px;
|
||
display: inline-block;
|
||
margin: 0 5px 5px 0;
|
||
padding: 5px 10px;
|
||
cursor: pointer;
|
||
vertical-align: text-bottom;
|
||
}
|
||
</style>
|