first commit

This commit is contained in:
annnj-company
2026-04-17 18:29:53 +08:00
parent e49fa5a215
commit 130c1026c4
5615 changed files with 1639145 additions and 0 deletions

View 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, // 多选时,标识文件超出数据是否已发出提示 methodshandleUpload
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>