Files
laws-sinotruk-client/src/components/UploadFile.vue
T
2023-11-27 14:02:42 +08:00

450 lines
14 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<j-modal
:title="$t('uploadFile.file')"
:width="width"
:visible="visible"
switchFullscreen
:maskClosable="false"
:confirmLoading="confirmLoading"
:footer="null"
@cancel="close">
<a-upload-dragger
name="file"
:multiple="multiple"
:action="uploadAction"
:headers="headers"
:data="{'biz':bizPath}"
:fileList="fileList"
:beforeUpload="doBeforeUpload"
@change="handleChange"
:disabled="disabled"
:returnUrl="returnUrl"
:listType="complistType"
@preview="handlePreview"
@download="handleDownload"
:showUploadList="{
showDownloadIcon: isDownload
}"
v-bind="$attrs"
v-on="childListeners"
:class="{'uploadty-disabled': disabled}"
>
<p class="upload-drag-icon">
<a-icon type="cloud-upload" />
</p>
<p class="ant-upload-text">
{{ $t('uploadFile.clickOrDragUpload') }}
</p>
</a-upload-dragger>
<div id="images">
<div class="image" v-viewer="{movable: false}">
<img v-show="image" :src="imageUrl">
</div>
</div>
<a-empty v-if="disabled && (!fileList || fileList.length === 0)" />
</j-modal>
</template>
<script>
import { ACCESS_TOKEN } from '@/store/mutation-types'
import { downloadFile, getFileAccessHttpUrl } from '@/api/manage'
import { getFileInfo } from '@/api/api'
import { previewPdf } from '@/utils/previewPdf'
import Vue from 'vue'
const FILE_TYPE_ALL = 'all'
const FILE_TYPE_IMG = 'image'
const FILE_TYPE_IMGS = ['jpg', 'jpeg', 'png']
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 Base64 = require('js-base64').Base64
// 支持预览的文件后缀
const CAN_PREVIEW_FILE_SUFFIX = ['jpg', 'jpeg', 'png', 'pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx']
export default {
name: 'UploadFile',
props: {
text: {
type: String,
required: false,
default: '点击上传'
},
fileType: {
type: String,
required: false,
default: CAN_UPLOAD_FILE_TYPE
},
/* 这个属性用于控制文件上传的业务路径 */
bizPath: {
type: String,
required: false,
default: 'temp'
},
value: {
type: [String, Array],
required: false
},
// update-begin- --- author:wangshuai ------ date:20190929 ---- for:Jupload组件增加是否能够点击
disabled: {
type: Boolean,
required: false,
default: false
},
// update-end- --- author:wangshuai ------ date:20190929 ---- for:Jupload组件增加是否能够点击
// 此属性被废弃了
triggerChange: {
type: Boolean,
required: false,
default: false
},
/**
* update -- author:lvdandan -- date:20190219 -- for:Jupload组件增加是否返回url
* true:仅返回url
* false:返回fileName filePath fileSize
*/
returnUrl: {
type: Boolean,
required: false,
default: true
},
number: {
type: Number,
required: false,
default: 0
},
multiple: {
type: Boolean,
default: true
},
beforeUpload: {
type: Function
},
isDownload: {
type: Boolean,
default: true
},
disabledUpload: {
type: Boolean,
default: false
},
fileMaxSize: {
type: Number,
required: false,
default: 500
}
},
data () {
return {
width: 600,
visible: false,
confirmLoading: false,
uploadAction: window._CONFIG.domianURL + '/sys/common/upload',
headers: {},
fileList: [],
fileIds: null, // 文件id,可以是数组,也可以是字符串
image: false,
imageUrl: null
}
},
computed: {
// 透传给下级组件的事件,需要排除本组件使用的change事件
childListeners () {
const result = Object.assign({},
this.$listeners
)
delete result.change
return result
},
complistType () {
return this.fileType === FILE_TYPE_IMG ? 'picture-card' : 'text'
}
},
methods: {
open (fileIds) {
this.headers = { 'X-Access-Token': Vue.ls.get(ACCESS_TOKEN) }
this.fileIds = fileIds
this.initFileList()
this.visible = true
},
initFileList () {
if (!this.fileIds) {
return
}
let fileIdArr = []
if (Array.isArray(this.fileIds)) {
fileIdArr = this.fileIds
} else {
fileIdArr = this.fileIds.split(',')
}
const fileList = []
fileIdArr.forEach(async id => {
const fileInfo = await this.getFileInfoByFileId(id)
if (fileInfo) {
fileList.push(fileInfo)
}
})
this.fileList = fileList
console.log(this.fileList)
},
getFileInfoByFileId (id) {
return new Promise(resolve => {
let file
getFileInfo({ id: id }).then(res => {
if (res.success) {
const fileInfo = res.result || {}
file = {
uid: fileInfo.id,
name: fileInfo.fileName,
status: 'done',
url: fileInfo.url,
// response用于下载和预览
response: {
success: true,
result: {
id: fileInfo.id,
fileName: fileInfo.fileName
},
status: 'history'
}
}
}
}).finally(() => {
resolve(file)
})
})
},
close () {
this.visible = false
setTimeout(() => {
this.fileList = []
}, 500)
},
handleChange (info) {
console.log(info, this.uploadGoOn)
if (!info.file.status && this.uploadGoOn === false) {
info.fileList.pop()
}
console.log(info.fileList)
let fileList = info.fileList
if (info.file.status === 'done') {
console.log(this.number)
if (this.number > 0) {
console.log(fileList)
fileList = fileList.slice(-this.number)
console.log(fileList)
}
if (info.file.response.success) {
fileList = fileList.map((file) => {
console.log(file)
if (file.response) {
// const reUrl = `${file.response.result.id}?token=${Vue.ls.get(ACCESS_TOKEN)}&fullfilename=${file.response.result.fileName}`
// TODO getFileAccessHttpUrl方法会追加token,在之后拼参数
file.url = getFileAccessHttpUrl(file.response.result.id) + '&fullfilename=' + file.response.result.fileName
}
// 校验不通过的文件需要筛出去
if (file.uploadGoOn === false) {
return null
}
return file
})
} else {
this.$message.warning(info.file.response.message)
}
// this.$message.success(`${info.file.name} 上传成功!`);
} else if (info.file.status === 'error') {
this.$message.warning(`${info.file.name} ${this.$t('uploadFile.uploadFailed')}.`)
} else if (info.file.status === 'removed') {
this.handleDelete(info.file)
}
fileList = fileList.filter(tt => !!tt)
console.log(fileList)
// 二次过滤不符合要求的(uploadGoOn为false的),否则只上传多个不符合要求的只会有一个不出现在列表中
fileList = fileList.filter(tt => tt.uploadGoOn === undefined || tt.uploadGoOn === null || tt.uploadGoOn === true)
this.fileList = fileList
if (info.file.status === 'done' || info.file.status === 'removed') {
// returnUrl为true时仅返回文件路径
if (this.returnUrl) {
this.handlePathChange()
} else {
// returnUrl为false时返回文件名称、文件路径及文件大小
this.newFileList = []
for (let a = 0; a < fileList.length; a++) {
// update-begin-author:lvdandan date:20200603 for:【TESTA-514】【开源issue】多个文件同时上传时,控制台报错
if (fileList[a].status === 'done') {
const fileJson = {
id: fileList[a].response.result.id,
fileName: fileList[a].name,
filePath: fileList[a].url,
fileSize: fileList[a].size
}
this.newFileList.push(fileJson)
} else {
return
}
// update-end-author:lvdandan date:20200603 for:【TESTA-514】【开源issue】多个文件同时上传时,控制台报错
}
this.$emit('change', this.newFileList)
}
}
},
handlePreview (file) {
if (!file || !file.url) {
return
}
// 截取文件后缀名
const fileSuffix = (file.name ? file.name.split('.')[file.name.split('.').length - 1] : '').toLowerCase()
const canPreview = CAN_PREVIEW_FILE_SUFFIX.some(tt => fileSuffix === tt)
// 判断是否为可预览格式的文件
if (!canPreview) {
this.$message.loading(this.$t('uploadFile.cannotPreview')).then(() => {
this.handleDownload(file)
})
return
}
const fileFullUrl = `${window._CONFIG.domianWebSocketURL}/sys/common/view/${file.response.result.id}?token=${Vue.ls.get(ACCESS_TOKEN)}&fullfilename=${file.name}`
console.log(fileSuffix)
// 图片预览,使用自己添加的组件
if (FILE_TYPE_IMGS.includes(fileSuffix)) {
this.imageUrl = getFileAccessHttpUrl(file.response.result.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.response.result.id)
window.open(url)
return
}
// 其余可预览文件仍使用KKFile进行预览
const url = `${window._CONFIG.onlinePreviewDomainURL}?url=${encodeURIComponent(Base64.encode(fileFullUrl))}`
window.open(url)
},
handleDownload (file) {
// 下载文件
downloadFile(`/sys/common/download/${file.response.result.id}`, file.name)
},
doBeforeUpload (file) {
this.uploadGoOn = true
file.uploadGoOn = true
const fileSize = file.size // 上传的文件大小
if (fileSize === 0) {
this.$message.warning(this.$t('uploadFile.cannotUploadEmpty'))
this.uploadGoOn = false
file.uploadGoOn = false
return false
}
if (this.fileMaxSize && fileSize > 1024 * 1024 * this.fileMaxSize) {
this.$message.warning(this.$t('uploadFile.pleaseUpload') + this.fileMaxSize + this.$t('uploadFile.theFollowingDocuments'))
this.uploadGoOn = false
file.uploadGoOn = false
return false
}
if (fileSize > 1024 * 1024 * 500) {
this.$message.warning(this.$t('uploadFile.maxSize'))
this.uploadGoOn = false
file.uploadGoOn = false
return false
}
if (this.fileType === FILE_TYPE_ALL) {
return true
}
const fileType = file.type
// 截取文件后缀名
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.warning(this.$t('uploadFile.onlyUploadPic'))
this.uploadGoOn = false
file.uploadGoOn = false
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.warning(this.$t('uploadFile.pleaseUpload') + FILE_TYPE_IMGS.join('、') + this.$t('uploadFile.file'))
this.uploadGoOn = false
file.uploadGoOn = false
return false
}
if (this.fileType.indexOf(fileSuffix) === -1) {
this.$message.warning(this.$t('uploadFile.pleaseUpload') + `${this.fileType}` + this.$t('uploadFile.file'))
this.uploadGoOn = false
file.uploadGoOn = false
return false
}
// 扩展 beforeUpload 验证
if (typeof this.beforeUpload === 'function') {
return this.beforeUpload(file)
}
return true
},
handlePathChange () {
const uploadFiles = this.fileList
let path = ''
if (!uploadFiles || uploadFiles.length === 0) {
path = ''
}
const arr = []
for (let a = 0; a < uploadFiles.length; a++) {
if (uploadFiles[a].status === 'done') {
arr.push(uploadFiles[a].url)
} else {
return
}
}
if (arr.length > 0) {
path = arr.join(',')
}
this.$emit('change', path)
},
handleDelete (file) {
// 如有需要新增 删除逻辑
console.log(file)
}
}
}
</script>
<style scoped lang="less">
.upload-drag-icon {
font-size: 70px;
color: #c0c4cc;
}
/*禁用情况下,不显示上传操作区域*/
/deep/ .ant-upload.ant-upload-disabled {
display: none;
}
// 索赔上传需要根据传入的值判断是否可以上传
.upload-disabled {
/deep/ .ant-upload {
display: none;
}
}
// 不可删除文件
.delete-disabled {
/deep/ .ant-upload-list-item-card-actions {
a:nth-child(2) {
display: none;
}
}
}
</style>