first commit
This commit is contained in:
524
pgweb/src/components/upload/file-upload.vue
Normal file
524
pgweb/src/components/upload/file-upload.vue
Normal file
@@ -0,0 +1,524 @@
|
||||
<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>
|
||||
<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 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) {
|
||||
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>
|
||||
Reference in New Issue
Block a user