add 文件上传组件
This commit is contained in:
@@ -3,6 +3,12 @@
|
||||
<template v-if="fileList && fileList.length > 0">
|
||||
<div v-for="file in fileList" :key="file.id" class="file-name" @click="handlePreview(file)">{{ file.fileName }}</div>
|
||||
</template>
|
||||
|
||||
<div id="images">
|
||||
<div class="image" v-viewer="{movable: false}">
|
||||
<img v-show="image" :src="imageUrl" alt="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -32,7 +38,9 @@ export default {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
fileList: []
|
||||
fileList: [],
|
||||
image: false,
|
||||
imageUrl: null
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<van-field
|
||||
v-model="selectedDataNames"
|
||||
:label="label"
|
||||
:placeholder="$t('clickSelect') + label"
|
||||
:placeholder="$t('pleaseSelect') + label"
|
||||
readonly
|
||||
rows="1"
|
||||
autosize
|
||||
|
||||
@@ -0,0 +1,260 @@
|
||||
<template>
|
||||
<div class="upload-comp">
|
||||
<div class="upload-box">
|
||||
<input type="file" class="upload-box-input" @change="handleUpload" />
|
||||
<van-button type="primary" plain>
|
||||
<template #icon>
|
||||
<van-icon class="iconfont" class-prefix="icon" name="shangchuan" />
|
||||
</template>
|
||||
{{ $t('clickToUpload') }}
|
||||
</van-button>
|
||||
</div>
|
||||
<!--文件列表-->
|
||||
<div class="file-list" v-if="fileList && fileList.length > 0">
|
||||
<div class="file-item" v-for="file in fileList" :key="file.id">
|
||||
<div class="file-item-name" @click="handlePreview(file)">{{ file.fileName }}</div>
|
||||
<van-icon name="delete-o" @click="handleDelete(file)" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="images">
|
||||
<div class="image" v-viewer="{movable: false}">
|
||||
<img v-show="image" :src="imageUrl" alt="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getFileInfo, uploadFile } from '../api/api'
|
||||
import { previewPdf } from '../utils/previewPdf'
|
||||
import Vue from 'vue'
|
||||
import { ACCESS_TOKEN } from '../store/mutation-types'
|
||||
import { getFileAccessHttpUrl } from '../api/manage'
|
||||
|
||||
const FILE_TYPE_ALL = 'all'
|
||||
const FILE_TYPE_IMG = 'image'
|
||||
const FILE_TYPE_IMGS = ['jpg', 'jpeg', 'png', 'raw']
|
||||
const FILE_TYPE_PDF = 'pdf'
|
||||
// 本系统限制可以上传的文件格式
|
||||
const CAN_UPLOAD_FILE_TYPE = 'pdf,docx,doc,xlsx,xls,ppt,pptx,rar,zip,jpg,jpeg,png,avi,wmv,mov,rm,mp4,cad'
|
||||
// 支持预览的文件后缀
|
||||
const CAN_PREVIEW_FILE_SUFFIX = ['jpg', 'jpeg', 'png', 'pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx']
|
||||
|
||||
const Base64 = require('js-base64').Base64
|
||||
|
||||
export default {
|
||||
name: 'ZUpload',
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: null
|
||||
},
|
||||
// 文件最大大小,默认500MB
|
||||
fileMaxSize: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 500
|
||||
},
|
||||
// 可以上传文件的类型
|
||||
fileType: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: CAN_UPLOAD_FILE_TYPE
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
fileList: [],
|
||||
image: false,
|
||||
imageUrl: null
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value: {
|
||||
handler () {
|
||||
this.fileList = []
|
||||
if (this.value) {
|
||||
this.getFileList()
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleUpload (event) {
|
||||
const e = window.event || event
|
||||
const file = e.target.files[0]
|
||||
/* 进行相关校验 */
|
||||
const checkResult = this.beforeUpload(file)
|
||||
if (!checkResult) {
|
||||
return
|
||||
}
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
formData.append('biz', 'temp')
|
||||
uploadFile(formData).then(res => {
|
||||
if (res.success) {
|
||||
this.fileList.push(res.result)
|
||||
this.$emit('change', this.fileList.map(item => item.id).join(','))
|
||||
} else {
|
||||
this.$message(res.message)
|
||||
}
|
||||
})
|
||||
},
|
||||
beforeUpload (file) {
|
||||
// 校验大小
|
||||
const fileSize = file.size
|
||||
if (fileSize === 0) {
|
||||
this.$message(this.$t('uploadFile.cannotUploadEmpty'))
|
||||
return false
|
||||
}
|
||||
if (this.fileMaxSize && fileSize > 1024 * 1024 * this.fileMaxSize) {
|
||||
this.$message(this.$t('uploadFile.pleaseUpload') + this.fileMaxSize + this.$t('uploadFile.theFollowingDocuments'))
|
||||
return false
|
||||
}
|
||||
if (fileSize > 1024 * 1024 * 500) {
|
||||
this.$message(this.$t('uploadFile.maxSize'))
|
||||
return false
|
||||
}
|
||||
// 校验格式
|
||||
const fileType = file.type
|
||||
if (this.fileType === FILE_TYPE_ALL) {
|
||||
return true
|
||||
}
|
||||
// 截取文件后缀名
|
||||
const fileSuffix = (file.name ? file.name.split('.')[file.name.split('.').length - 1] : '').toLowerCase()
|
||||
if (this.fileType === CAN_UPLOAD_FILE_TYPE && CAN_UPLOAD_FILE_TYPE.split(',').includes(fileSuffix)) {
|
||||
return true
|
||||
}
|
||||
if (this.fileType === FILE_TYPE_IMG && fileType.indexOf('image') < 0) {
|
||||
this.$message(this.$t('uploadFile.onlyUploadPic'))
|
||||
return false
|
||||
}
|
||||
if (this.fileType === FILE_TYPE_IMG && FILE_TYPE_IMGS.includes(fileSuffix)) {
|
||||
return true
|
||||
}
|
||||
if (this.fileType === FILE_TYPE_IMG && !FILE_TYPE_IMGS.includes(fileSuffix)) {
|
||||
this.$message(this.$t('uploadFile.pleaseUpload') + FILE_TYPE_IMGS.join('、') + this.$t('uploadFile.file'))
|
||||
return false
|
||||
}
|
||||
if (this.fileType.indexOf(fileSuffix) === -1) {
|
||||
this.$message(this.$t('uploadFile.pleaseUpload') + `${this.fileType}` + this.$t('uploadFile.file'))
|
||||
return false
|
||||
}
|
||||
return true
|
||||
},
|
||||
getFileList () {
|
||||
this.fileList = []
|
||||
const fileIdArr = this.value.split(',')
|
||||
fileIdArr.forEach(async id => {
|
||||
const fileObj = await this.getFileInfo(id)
|
||||
if (fileObj.id) {
|
||||
this.fileList.push(fileObj)
|
||||
}
|
||||
})
|
||||
},
|
||||
getFileInfo (id) {
|
||||
let result = {}
|
||||
return new Promise(resolve => {
|
||||
getFileInfo({ id }).then(res => {
|
||||
if (res.success) {
|
||||
result = res.result
|
||||
}
|
||||
}).finally(() => {
|
||||
resolve(result)
|
||||
})
|
||||
})
|
||||
},
|
||||
handlePreview (file) {
|
||||
if (!file || !file.url) {
|
||||
return
|
||||
}
|
||||
// 截取文件后缀名
|
||||
const fileSuffix = (file.fileName ? file.fileName.split('.')[file.fileName.split('.').length - 1] : '').toLowerCase()
|
||||
const canPreview = CAN_PREVIEW_FILE_SUFFIX.some(tt => fileSuffix === tt)
|
||||
// 判断是否为可预览格式的文件
|
||||
if (!canPreview) {
|
||||
this.$message(this.$t('uploadFile.cannotPreview'))
|
||||
return
|
||||
}
|
||||
const fileFullUrl = `${window._CONFIG.domianWebSocketURL}/sys/common/view/${file.id}?token=${Vue.ls.get(ACCESS_TOKEN)}&fullfilename=${file.fileName}`
|
||||
// 图片预览,使用自己添加的组件
|
||||
if (FILE_TYPE_IMGS.includes(fileSuffix)) {
|
||||
this.imageUrl = getFileAccessHttpUrl(file.id)
|
||||
// 获取viewer实例
|
||||
const viewer = this.$el.querySelector('.image').$viewer
|
||||
// 调用show方法进行显示预览图
|
||||
viewer.show()
|
||||
// this.$refs.imagePreviewModal.open(file)
|
||||
return
|
||||
}
|
||||
// pdf预览
|
||||
if (FILE_TYPE_PDF.includes(fileSuffix)) {
|
||||
const url = previewPdf(file.id)
|
||||
window.open(url)
|
||||
return
|
||||
}
|
||||
// 其余可预览文件仍使用KKFile进行预览
|
||||
const url = `${window._CONFIG.onlinePreviewDomainURL}?url=${encodeURIComponent(Base64.encode(fileFullUrl))}`
|
||||
window.open(url)
|
||||
},
|
||||
handleDelete (file) {
|
||||
const index = this.fileList.findIndex(tt => tt.id === file.id)
|
||||
const fileTempList = JSON.parse(JSON.stringify(this.fileList))
|
||||
this.fileList.splice(index, 1)
|
||||
this.$emit('change', this.fileList.map(item => item.id).join(','))
|
||||
}
|
||||
},
|
||||
model: {
|
||||
event: 'change',
|
||||
prop: 'value'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
@import '~@/assets/less/common.less';
|
||||
|
||||
.upload-comp {
|
||||
padding: 0.2rem 0.32rem;
|
||||
}
|
||||
|
||||
.upload-box {
|
||||
position: relative;
|
||||
width: fit-content;
|
||||
|
||||
&-input {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.van-button--normal {
|
||||
font-size: 0.28rem;
|
||||
}
|
||||
|
||||
.file-list {
|
||||
margin-top: 0.16rem;
|
||||
}
|
||||
|
||||
.file-item {
|
||||
color: @primary-color;
|
||||
margin-bottom: 0.16rem;
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
|
||||
&-name {
|
||||
word-break: break-word;
|
||||
margin-right: 0.16rem;
|
||||
}
|
||||
}
|
||||
|
||||
.file-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user