上传组件修改

This commit is contained in:
bb_pan 2025-12-05 15:19:00 +08:00
parent 6bc7d0fc3b
commit d6145c0684
6 changed files with 321 additions and 7 deletions

BIN
src/assets/images/file.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -0,0 +1,314 @@
<template>
<div class="component-upload-image">
<el-upload
multiple
:action="uploadImgUrl"
list-type="picture-card"
:on-success="handleUploadSuccess"
:before-upload="handleBeforeUpload"
:limit="limit"
:on-error="handleUploadError"
:on-exceed="handleExceed"
ref="imageUpload"
:on-remove="handleDelete"
:show-file-list="true"
:headers="headers"
:file-list="fileList"
:on-preview="handlePictureCardPreview"
:class="{ hide: this.fileList.length >= this.limit }"
>
<i class="el-icon-plus"></i>
<template #file="{ file }">
<div class="custom-file-item">
<!-- 图片 -->
<img v-if="isImage(file)" :src="file.url" class="custom-file-img" />
<!-- PDF 图标 -->
<div v-else-if="isPDF(file)" class="custom-file-icon">
<img style="width: 120px; height: 120px" src="@/assets/images/pdf.png" fit="fill" />
</div>
<!-- Word 图标 -->
<div v-else-if="isWord(file)" class="custom-file-icon">
<img style="width: 120px; height: 120px" src="@/assets/images/word.png" fit="fill" />
</div>
<!-- 默认文件图标 -->
<div v-else class="custom-file-icon">
<img style="width: 120px; height: 120px" src="@/assets/images/file.png" fit="fill" />
</div>
<!-- 删除按钮 -->
<span class="el-upload-list__item-actions">
<span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
<i class="el-icon-zoom-in"></i>
</span>
<span class="el-upload-list__item-delete" @click="handleDelete(file)">
<i class="el-icon-delete"></i>
</span>
</span>
</div>
</template>
</el-upload>
<!-- 上传提示 -->
<div class="el-upload__tip" slot="tip" v-if="showTip">
请上传
<template v-if="fileSize">
大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b>
</template>
<template v-if="fileType">
格式为 <b style="color: #f56c6c">{{ fileType.join('、') }}</b>
</template>
的文件
</div>
<el-dialog :visible.sync="dialogVisible" title="预览" width="800" append-to-body>
<img :src="dialogImageUrl" style="display: block; max-width: 100%; margin: 0 auto" />
</el-dialog>
</div>
</template>
<script>
import { getToken } from '@/utils/auth'
export default {
props: {
value: [String, Object, Array],
//
limit: {
type: Number,
default: 5,
},
// (MB)
fileSize: {
type: Number,
default: 5,
},
// , ['png', 'jpg', 'jpeg']
fileType: {
type: Array,
default: () => ['png', 'jpg', 'jpeg'],
},
//
isShowTip: {
type: Boolean,
default: true,
},
},
data() {
return {
number: 0,
uploadList: [],
dialogImageUrl: '',
dialogVisible: false,
hideUpload: false,
uploadImgUrl: process.env.VUE_APP_BASE_API + '/file/upload', //
headers: {
Authorization: 'Bearer ' + getToken(),
},
fileList: [],
}
},
watch: {
value: {
handler(val) {
if (val) {
//
const list = Array.isArray(val) ? val : this.value.split(',')
//
this.fileList = list.map((item) => {
if (typeof item === 'string') {
item = { name: item, url: item }
}
return item
})
} else {
this.fileList = []
return []
}
},
deep: true,
immediate: true,
},
},
computed: {
//
showTip() {
return this.isShowTip && (this.fileType || this.fileSize)
},
},
methods: {
// loading
handleBeforeUpload(file) {
let isImg = false
if (this.fileType.length) {
let fileExtension = ''
if (file.name.lastIndexOf('.') > -1) {
fileExtension = file.name.slice(file.name.lastIndexOf('.') + 1)
}
isImg = this.fileType.some((type) => {
if (file.type.indexOf(type) > -1) return true
if (fileExtension && fileExtension.indexOf(type) > -1) return true
return false
})
} else {
isImg = file.type.indexOf('image') > -1
}
if (!isImg) {
this.$modal.msgError(`文件格式不正确, 请上传${this.fileType.join('/')}图片格式文件!`)
return false
}
if (this.fileSize) {
const isLt = file.size / 1024 / 1024 < this.fileSize
if (!isLt) {
this.$modal.msgError(`上传头像图片大小不能超过 ${this.fileSize} MB!`)
return false
}
}
this.$modal.loading('正在上传图片,请稍候...')
this.number++
},
//
handleExceed() {
this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`)
},
//
handleUploadSuccess(res, file) {
if (res.code === 200) {
this.uploadList.push({ name: res.data.url, url: res.data.url })
this.uploadedSuccessfully()
} else {
this.number--
this.$modal.closeLoading()
this.$modal.msgError(res.msg)
this.$refs.imageUpload.handleRemove(file)
this.uploadedSuccessfully()
}
},
//
handleDelete(file) {
const findex = this.fileList.map((f) => f.name).indexOf(file.name)
if (findex > -1) {
this.fileList.splice(findex, 1)
this.$emit('input', this.listToString(this.fileList))
}
},
//
handleUploadError() {
this.$modal.msgError('上传图片失败,请重试')
this.$modal.closeLoading()
},
//
uploadedSuccessfully() {
if (this.number > 0 && this.uploadList.length === this.number) {
this.fileList = this.fileList.concat(this.uploadList)
this.uploadList = []
this.number = 0
this.$emit('input', this.listToString(this.fileList))
this.$modal.closeLoading()
}
},
isImage(file) {
return /\.(png|jpg|jpeg|gif|bmp)$/i.test(file.name)
},
isPDF(file) {
return /\.pdf$/i.test(file.name)
},
isWord(file) {
return /\.(doc|docx)$/i.test(file.name)
},
//
handlePictureCardPreview(file) {
console.log('🚀 ~ file:', file)
const url = file.url || file.response?.data?.url
if (this.isPDF(file)) {
// PDF
window.open(url, '_blank')
return
}
if (this.isWord(file)) {
// Word
window.location.href = url
return
}
this.dialogImageUrl = file.url
this.dialogVisible = true
},
//
listToString(list, separator) {
let strs = ''
separator = separator || ','
for (let i in list) {
if (list[i].url) {
strs += list[i].url.replace(this.baseUrl, '') + separator
}
}
return strs != '' ? strs.substr(0, strs.length - 1) : ''
},
},
}
</script>
<style scoped lang="scss">
// .el-upload--picture-card
::v-deep.hide .el-upload--picture-card {
display: none;
}
//
::v-deep .el-list-enter-active,
::v-deep .el-list-leave-active {
transition: all 0s;
}
::v-deep .el-list-enter,
.el-list-leave-active {
opacity: 0;
transform: translateY(0);
}
.custom-file-item {
width: 148px;
height: 148px;
border: 1px solid #dcdfe6;
border-radius: 6px;
position: relative;
display: flex;
align-items: center;
justify-content: center;
background: #f5f7fa;
}
.custom-file-img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 6px;
}
.custom-file-icon {
font-size: 20px;
font-weight: bold;
color: white;
border-radius: 6px;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.el-upload-list__item-actions {
position: absolute;
top: 4px;
right: 4px;
i {
color: #fff;
font-size: 18px;
cursor: pointer;
}
}
</style>

View File

@ -18,7 +18,7 @@
</div>
<el-form
label-width="110px"
label-width="120px"
ref="formRef"
style="padding: 12px; overflow-y: auto; height: calc(100vh - 180px); width: 100%"
label-position="right"
@ -79,7 +79,7 @@
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="资产原值" prop="originalValue">
<el-form-item label="资产原值(万元)" prop="originalValue">
<el-input
@input="handlePriceInput"
autocomplete="off"
@ -289,7 +289,7 @@
:value="form.certificateList"
:limit="3"
:fileSize="10"
:fileType="['doc', 'docx', 'ppt', 'pdf']"
:fileType="['jpg', 'png', 'pdf']"
@change="handleCertificateChange"
/>
</el-form-item>
@ -334,7 +334,7 @@ import {
} from '@/api/EquipmentEntryApply'
import { getManufacturerSelectApi } from '@/api/EquipmentLedger/index.js'
import ImageUpload from '@/components/ImageUpload'
import FileUpload from '@/components/ImageUpload'
import FileUpload from '@/components/FileImageUpload'
export default {
name: 'EquipmentEntryEditDialog', //

View File

@ -322,7 +322,7 @@
getDetailApi // API
} from '@/api/EquipmentEntryApply'
import ImageUpload from '@/components/ImageUpload'
import FileUpload from '@/components/ImageUpload'
import FileUpload from '@/components/FileImageUpload'
export default {
name: 'EquipmentEntryEditDialog', //

View File

@ -295,7 +295,7 @@ import {
fourthToSixthLevel, getDetailApi
} from '@/api/EquipmentEntryApply'
import ImageUpload from '@/components/ImageUpload'
import FileUpload from '@/components/ImageUpload'
import FileUpload from '@/components/FileImageUpload'
export default {
name: 'EquipmentEntryEditDialog', //

View File

@ -195,7 +195,7 @@ import {
delContractApi,
updateStatus
} from '@/api/contract-manage/index'
import FileUpload from '@/components/ImageUpload'
import FileUpload from '@/components/FileImageUpload'
export default {
data() {