429 lines
13 KiB
Vue
429 lines
13 KiB
Vue
<template>
|
||
<div class="upload-file-wrap">
|
||
<el-row>
|
||
<el-col :span="span" v-if="isInCount">
|
||
<div class="el-col-ctn-box">
|
||
<div class="el-col-upload-box">
|
||
<el-upload
|
||
class="el-upload-box"
|
||
ref="upload"
|
||
action=""
|
||
:accept="accept"
|
||
:show-file-list="false"
|
||
:http-request="httpRequest"
|
||
>
|
||
<div class="upload-file">
|
||
<i class="el-icon-plus uploader-file-icon"></i>
|
||
<!-- <div class="font-size-12 color-BCDFFD text-center">上传材料</div> -->
|
||
</div>
|
||
</el-upload>
|
||
<div class="font-size-12 color-a9a9a9 text-center line-height-20">{{ uploadName }}</div>
|
||
</div>
|
||
|
||
</div>
|
||
</el-col>
|
||
<!--上传的图片预览-->
|
||
<el-col :span="span" v-for="(item,i) in lists" :key="i">
|
||
<div class="el-col-ctn-box "
|
||
@click="handlePreview(item)">
|
||
<div class="el-col-upload-box">
|
||
<div class="upload-preview-box">
|
||
<img v-if="item.deletable && !readOnly"
|
||
class="upload-delete-icon" src="../assets/image/icon_close.png" alt=""
|
||
@click.stop.prevent="handleDelete(item, i)">
|
||
<div class="upload-file">
|
||
<!-- svg展示 -->
|
||
<svgViewer v-if="item.fileType == 'svg'" :src="item.iconFrontSrc" class="el-image-upload"></svgViewer>
|
||
<!-- 其他展示 -->
|
||
<el-image v-else class="el-image-upload" :src="item.iconFrontSrc" fit="scale-down"></el-image>
|
||
</div>
|
||
</div>
|
||
|
||
<div v-if="!showFileName" class="font-size-12 color-a9a9a9 text-center line-height-20">
|
||
{{ showFileName ? item.fileName : maxCount === 1 ? uploadName : '' }}
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<!-- 大图预览 -->
|
||
<dialogPreview v-if="editImgFlag" :visible.sync="editImgFlag" :previewUrl="previewPath" :isSvg="isSvg" />
|
||
<pdfPreview v-if="editPdfFlag" :visible.sync="editPdfFlag" :previewUrl="previewPath"/>
|
||
<videoPreview v-if="editMp4Flag" :visible.sync="editMp4Flag" :previewUrl="previewPath"/>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import commonFun from "../services/projectConfig";
|
||
|
||
export default {
|
||
name: "uploadFile",
|
||
components: {
|
||
svgViewer: () => import('./svg-viewer'),
|
||
dialogPreview: () => import('./dialogPreview'),
|
||
pdfPreview: () => import('./pdfPreview.vue'),//查看PDF文件
|
||
videoPreview: () => import('./videoPreview.vue'),//查看视频文件
|
||
},
|
||
props: {
|
||
span: {
|
||
// layout组件参数,每排排列几个
|
||
type: Number,
|
||
default: 5
|
||
},
|
||
accept: {
|
||
type: String,
|
||
default: '*',
|
||
},
|
||
imageHeight: {
|
||
// 图片、上传框的高度
|
||
type: String,
|
||
default: ''
|
||
},
|
||
imageMode: {
|
||
// 图片裁剪、缩放的模式,具体参考uni image
|
||
type: String,
|
||
default: 'aspectFit'
|
||
},
|
||
readOnly: {
|
||
// 只读,true-是,false-否
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
|
||
fileList: {
|
||
// 已上传的文件列表
|
||
type: [Array, Object],
|
||
default: () => {
|
||
return [
|
||
//{ url:文件地址, fileName: 文件名}
|
||
]
|
||
}
|
||
},
|
||
uploadName: {
|
||
// 要上传的文件昵称
|
||
type: String,
|
||
default: '上传'
|
||
},
|
||
maxCount: {
|
||
// 允许上传文件的最大总数
|
||
type: Number,
|
||
default: 1
|
||
},
|
||
selectCount: {
|
||
// 每次上传时,允许用户选择的文件数量
|
||
type: Number,
|
||
default: 1
|
||
},
|
||
customUpload: {
|
||
// 自定义上传按钮的样式
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
autoUpload: {
|
||
// 是否自动上传
|
||
type: Boolean,
|
||
default: true
|
||
},
|
||
showFileName: {
|
||
// 是否显示文件名
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
splitFileTitle: {
|
||
// 是否在显示效果上分割文件、文件名
|
||
type: Boolean,
|
||
default: true
|
||
},
|
||
isImg: {
|
||
// 是否在显示图片预览
|
||
type: Boolean,
|
||
default: true
|
||
},
|
||
fileSize: {
|
||
// 上传文件大小-单位M
|
||
type: Number,
|
||
default: 10
|
||
},
|
||
serveType: {
|
||
// 服务类型 1线下 2线上
|
||
type: Number,
|
||
default: 1
|
||
}
|
||
},
|
||
data() {
|
||
return {
|
||
lists: [
|
||
//{url: 文件地址, fileName: 文件名, deletable: 是否可删除, readStatus: 是否显示阅读状态, iconFrontSrc: 图标样式}
|
||
],
|
||
dialogVisible: false,
|
||
isSvg: true,
|
||
editPdfFlag:false,
|
||
editMp4Flag:false,
|
||
editImgFlag: false,
|
||
previewPath:'',
|
||
testList:[]
|
||
}
|
||
},
|
||
computed: {
|
||
isInCount() {
|
||
return (this.lists.length < this.maxCount) && !this.readOnly
|
||
},
|
||
},
|
||
watch: {
|
||
// 监听文件列表的变化,重新整理内部数据
|
||
fileList: {
|
||
immediate: true,
|
||
handler() {
|
||
this.formatFileList()
|
||
}
|
||
},
|
||
|
||
},
|
||
|
||
methods: {
|
||
async formatFileList() {
|
||
let fileList = this.fileList || []
|
||
fileList = JSON.parse(JSON.stringify(fileList))
|
||
// console.log('upload===========formatFileList()方法==========fileList:', fileList)
|
||
// const lists = fileList.map(item => {
|
||
// let obj = Object.assign(item)
|
||
// obj.deletable = typeof (obj.deletable) === 'boolean' ? obj.deletable : true
|
||
// let text = obj.url || obj.fileName
|
||
// obj.fileType = this.$util.getFileExtension(text)
|
||
// obj.iconFrontSrc = this.$util.getIcon(obj)
|
||
|
||
// // console.log(obj.url,'obj.urlobj.urlobj.urlobj.url')
|
||
// // let previewUrl = `${projectConfig.fileHost}${obj.url}`
|
||
// let previewUrl = `/mediate/minio/preview/${obj.url}`
|
||
// if(obj.url.includes('http')){
|
||
// previewUrl = obj.url
|
||
// }
|
||
// else
|
||
// {
|
||
// previewUrl = this.$fetchApi.viewFullFile({path: obj.url})
|
||
// }
|
||
|
||
// obj.previewUrl = previewUrl
|
||
// if(this.$util.getFileType(text) === 'image') {
|
||
// // 如果是图片,直接显示图片
|
||
// obj.iconFrontSrc = obj.previewUrl
|
||
// }
|
||
// console.log(obj,'urlurlurlurlurlurlurl')
|
||
// return obj
|
||
// });
|
||
// this.lists = lists
|
||
await this.getpreviewfull()
|
||
this.lists = this.testList
|
||
// console.log('uploadFile----:', this.lists)
|
||
},
|
||
async getpreviewfull() {
|
||
for (const item of this.fileList) {
|
||
try {
|
||
let obj = Object.assign(item)
|
||
obj.deletable = typeof (obj.deletable) === 'boolean' ? obj.deletable : true
|
||
let text = obj.url || obj.fileName
|
||
obj.fileType = this.$util.getFileExtension(text)
|
||
obj.iconFrontSrc = this.$util.getIcon(obj)
|
||
if(obj.url.includes('http')){
|
||
obj.previewUrl = obj.url
|
||
}
|
||
else
|
||
{
|
||
obj.previewUrl = await this.$fetchApi.viewFullFile({path: item.url})
|
||
}
|
||
if(this.$util.getFileType(text) === 'image') {
|
||
// 如果是图片,直接显示图片
|
||
obj.iconFrontSrc = obj.previewUrl
|
||
}
|
||
this.testList.push(obj);
|
||
} catch (error) {
|
||
console.error(`调用接口失败,错误:`, error);
|
||
// 可以在这里添加重试逻辑
|
||
}
|
||
}
|
||
},
|
||
async httpRequest(param) {
|
||
console.log(this.accept,'httpRequest上传文件:', param)
|
||
let fileType = this.$util.getFileExtension(param.file.name)
|
||
// 上传图片类型:png,jpg,bmp
|
||
if (this.accept !== '*' && this.accept.indexOf(fileType) === -1) {
|
||
this.$message({message: `不能上传${fileType}格式的文件`, type: 'warning'});
|
||
return
|
||
}
|
||
// 上传大小 100M
|
||
const uploadfileSize = param.file.size
|
||
if (uploadfileSize.toFixed(2) > (this.fileSize * 1024 * 1024)) {
|
||
this.$message({message: `请上传大小需在${this.fileSize}MB以内的文件`, type: 'warning'});
|
||
return
|
||
}
|
||
|
||
try {
|
||
// let formData = new FormData()
|
||
// formData.append('file', param.file)
|
||
// if (this.serveType === 1){
|
||
// let uploadFileRes = await commonFun.uploadFile(formData);
|
||
// let fileList = JSON.parse(JSON.stringify(this.fileList))
|
||
// fileList.push({
|
||
// url: uploadFileRes.minioUrl,
|
||
// previewUrl: uploadFileRes.preSignDownload,
|
||
// fileType: this.$util.getFileExtension(uploadFileRes.minioUrl)
|
||
// })
|
||
// this.$emit('handleUploadFile', fileList)
|
||
// }else {
|
||
// let uploadFileRes = await commonFun.uploadFile2(formData);
|
||
// let fileList = JSON.parse(JSON.stringify(this.fileList))
|
||
// fileList.push({
|
||
// url: uploadFileRes.url,
|
||
// previewUrl: uploadFileRes.fullUrl,
|
||
// fileType: this.$util.getFileExtension(uploadFileRes.url),
|
||
// fileName: uploadFileRes.objectName
|
||
// })
|
||
// this.$emit('handleUploadFile', fileList)
|
||
// }
|
||
let formData = new FormData()
|
||
formData.append('file', param.file)
|
||
let uploadFileRes = await this.$fetchApi.uploadFile(formData);
|
||
let fileList = JSON.parse(JSON.stringify(this.fileList))
|
||
fileList.push({
|
||
url: uploadFileRes.url,
|
||
fileSize: uploadFileRes.size,
|
||
fileType: this.$util.getFileExtension(uploadFileRes.url),
|
||
fileName: uploadFileRes.objectName,
|
||
objectName: uploadFileRes.fileName
|
||
})
|
||
this.$emit('handleUploadFile', fileList)
|
||
|
||
} catch (e) {
|
||
this.$message.error(e.msg)
|
||
}
|
||
},
|
||
async handlePreview(item) {
|
||
// try {
|
||
// let res = await this.$fetchApi.getMinioToken({objectName: item.url})
|
||
// window.open(`${item.previewUrl}?token=${res}`, '_target')
|
||
// }catch (e) {
|
||
// this.$message.error(e.msg || e)
|
||
// }
|
||
|
||
if (!this.isImg) {return}
|
||
this.isSvg = false;
|
||
let analysisType = this.$util.getFileType(item.fileType);
|
||
if (item.fileType === 'svg'){
|
||
this.previewPath = item.iconFrontSrc
|
||
this.isSvg = true;
|
||
this.editImgFlag = true;
|
||
}else if (analysisType === 'image'){
|
||
if (item.previewUrl) {
|
||
this.previewPath = item.previewUrl
|
||
}else {
|
||
this.previewPath = await commonFun.viewFile2({url: item.url})
|
||
}
|
||
this.editImgFlag = true;
|
||
}else if(analysisType.toLowerCase() === 'mp4' || analysisType.toLowerCase() === 'video'){
|
||
if (item.previewUrl) {
|
||
this.previewPath = item.previewUrl
|
||
}else {
|
||
this.previewPath = await commonFun.viewFile2({url: item.url})
|
||
}
|
||
this.editMp4Flag = true;
|
||
}else if(analysisType.toLowerCase() === 'pdf'){
|
||
if (item.previewUrl) {
|
||
this.previewPath = item.previewUrl
|
||
}else {
|
||
this.previewPath = await commonFun.viewFile2({url: item.url})
|
||
}
|
||
this.editPdfFlag = true;
|
||
}else {
|
||
let res = await commonFun.viewFile2({url: item.url})
|
||
window.open(`${res}`, '_target')
|
||
}
|
||
},
|
||
handleDelete(item, i) {
|
||
this.lists.splice(i, 1)
|
||
let fileList = JSON.parse(JSON.stringify(this.fileList))
|
||
fileList.splice(i, 1)
|
||
this.$emit('handleUploadFile', fileList)
|
||
}
|
||
},
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss">
|
||
.el-col-ctn-box {
|
||
width: 100%;
|
||
// height: 154px;
|
||
}
|
||
|
||
.el-col-upload-box {
|
||
width: 120px;
|
||
// height: 154px;
|
||
border-radius: 4px;
|
||
// overflow: hidden;
|
||
}
|
||
|
||
.el-upload-box {
|
||
width: 100%;
|
||
height: 120px;
|
||
background: #eeeeee;
|
||
border: 1px dashed #dcdcdc;
|
||
border-radius: 4px;
|
||
}
|
||
|
||
.el-col-ctn-box .el-upload,
|
||
.el-col-ctn-box .upload-file {
|
||
width: 100% !important;
|
||
}
|
||
|
||
.el-col-ctn-box .upload-preview-box {
|
||
position: relative;
|
||
height: 120px;
|
||
border: 1px solid rgba(151, 168, 177, 0.2);
|
||
border-radius: 4px;
|
||
}
|
||
|
||
.el-col-ctn-box .upload-delete-icon {
|
||
width: 30px;
|
||
height: auto;
|
||
position: absolute;
|
||
right: 0;
|
||
top: 0;
|
||
cursor: pointer;
|
||
z-index: 11111;
|
||
}
|
||
|
||
.el-col-ctn-box .upload-file {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 100%;
|
||
height: 120px;
|
||
}
|
||
|
||
.el-col-ctn-box .uploader-file-icon {
|
||
font-size: 32px;
|
||
color: #000;
|
||
}
|
||
|
||
.el-col-ctn-box .el-image-upload {
|
||
border-radius: 4px;
|
||
padding: 5px;
|
||
box-sizing: border-box;
|
||
|
||
svg {
|
||
width: 120px;
|
||
height: 120px;
|
||
}
|
||
}
|
||
|
||
.el-col-ctn-box .txt-center {
|
||
height: 40px;
|
||
line-height: 20px;
|
||
}
|
||
|
||
.line-height-30 {
|
||
line-height: 30px;
|
||
}
|
||
</style> |