Files
zhxg_pc/src/components/affix/index.vue
2025-12-06 20:59:16 +08:00

359 lines
12 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>
<div>
<el-upload
:style="uploadStyle"
action=""
:class="['cm-affix', {'is-disabled': inputDisabled}]"
:disabled="inputDisabled"
:multiple="true"
:http-request="handleUpload"
:file-list="fileList"
:accept="accpet"
:show-file-list="false"
:before-upload="handleBeforeUpload"
>
<el-button v-if="inputDisabled !== true" id="affix1" :disabled="notupload" size="small" type="primary"><i class='el-icon-upload2'></i>点击上传</el-button>
<el-button
v-if="this.affixId !== null && this.affixId !== '' && this.fileList.length > 0"
id="affix2"
size="small"
@click.stop="downloadPack()"
>
<div v-if="downloading" class="el-icon-loading file-upload" style="margin-left: 0px;margin-right: 3px;font-size: 14px;" />
打包下载
</el-button>
</el-upload>
<div v-for="(item, index) in fileList" :key="index" class="file">
<div class="file-item" :class="[{'is-disabled': inputDisabled}]">
<div class="file-name">{{ item.name }}</div>
<div v-if="item.status===1" class="el-icon-loading file-upload" title="上传中..." />
<div v-if="item.status===2" class="el-icon-download file-download" title="下载" @click="downloadFile(item)" />
<div v-if="item.status===2" class="el-icon-delete file-delete" title="删除" @click="deleteFile(item)" />
<div v-if="isImageURL(item.name) && item.status === 2" class="el-icon-picture" title="预览" @click="preview(item)" />
</div>
</div>
<el-image v-show="false" ref="preview"
class="preview"
:src="hiddenSrc"
:preview-src-list="previewList"
/>
</div>
</template>
<script>
import { deleteAffix, download, downloadAll, queryAffixs, upload } from '@/api/affix/affix'
export default {
name: 'CmAffix',
inject: {
elForm: {
default: ''
}
},
props: {
notupload:{
type:Boolean,
default:false
},
value: String, // 父组件值
disabled: Boolean,
maxSize:{
type: Number,
default: 20
},
accpet:{
type:String,
default:'*'
},
uploadStyle:
{
type: String,
default: ''
},
},
data() {
return {
uploadCnt: 0,
affixId: '',
fileList: [],
downloading:false,//控制打包下载loading动画
baseurl: process.env.VUE_APP_BASE_API ,
hiddenSrc:'',
previewList:[],
}
},
computed: {
inputDisabled() {
return this.disabled || (this.elForm || {}).disabled
}
},
watch: {
// 父组件值监听事件
value: {
handler: function(newVal/*, oldVal*/) {
if (newVal === undefined || newVal == null || newVal === ''
|| this.affixId === undefined || this.affixId == null || this.affixId === ''
|| newVal !== this.affixId) {
this.loadData()
}
}
}
},
created() {
this.loadData()
},
methods: {
// 预览
preview(item){
this.hiddenSrc = item.savePath
this.$refs.preview.showViewer = true
},
isImageURL(url) {
// let imgRegex = /(\jpg|\jpeg|\png|\gif|\webp)$/i;
const regex = /(\jpg|\jpeg|\png|\gif|\webp)$/i
return regex.test(url)
},
handleUpload(file) {
upload({'file': file.file, 'affixId': this.affixId}).then(res => {
this.uploadCnt--
if (res.code == 200) {
for (let i = 0; i < this.fileList.length; i++) {
let item = this.fileList[i]
console.log(res.savePath)
if(item.name == res.trueName && item.status == 1){
this.fileList[i].id = res.id
this.fileList[i].status = 2
this.fileList[i].savePath = this.baseurl + res.savePath
if(this.isImageURL(res.savePath)){
this.previewList.push( this.fileList[i].savePath)
}
// this.fileList[i].savePaths =[this.baseurl + res.savePath];
// 上传成功后向外传递当前文件的完整信息包含后端返回的res数据
this.$emit('fileUploaded', {
fileId: res.id, // 文件ID
fileName: res.trueName, // 文件名
filePath: res.savePath, // 文件相对路径不含baseurl
fullPath: this.fileList[i].savePath, // 完整路径含baseurl
fileType: this.getFileType(res.trueName), // 文件类型
originalFile: file.file // 原始文件对象(可选)
});
}
}
} else {
this.$message.error(res.message)
}
}).catch(() => {
this.uploadCnt--
})
},
// 获取文件类型的方法Affix组件中新增
getFileType(fileName) {
if (!fileName) return '';
const lastDotIndex = fileName.lastIndexOf('.');
return lastDotIndex > -1 ? fileName.substring(lastDotIndex + 1).toLowerCase() : '';
},
handleBeforeUpload(file) {
if (this.affixId == null || this.affixId === '') {
this.affixId = this.$tool.uuid()
this.$emit('input', this.affixId)
}
let isLt20M = file.size / 1024 / 1024 < this.maxSize
if (!isLt20M) {
this.$message.error('上传大小不能超过 '+this.maxSize+'MB!')
} else {
this.fileList.push({name: file.name, status: 1})
this.uploadCnt++
}
return isLt20M
},
getFileName(id){
for (let i = 0; i < this.fileList.length; i++) {
let item = this.fileList[i]
if(item.id == id){
console.log(item)
return item.name
}
}
},
downloadFile(file) {
download(file.id).then((res) => {
console.log(res)
let fileName = this.getFileName(file.id).replace(/"/g, '')
var blob = new Blob([res], {type: 'application/octet-stream;'})
var downloadElement = document.createElement('a')
var href = window.URL.createObjectURL(blob) // 创建下载的链接
downloadElement.href = href
downloadElement.download = decodeURI(fileName) // 下载后文件名
document.body.appendChild(downloadElement)
downloadElement.click() // 点击下载
document.body.removeChild(downloadElement) // 下载完成移除元素
window.URL.revokeObjectURL(href) // 释放掉blob对象
}).catch((res) => {
this.$message.error(res.message)
})
},
downloadPack() {
if (this.affixId === null || this.affixId === '') {
this.$message.error('暂无附件!')
return
}
//如果只有一个文件就不打包下载
if(this.fileList.length == 1){
this.downloadFile(this.fileList[0])
}else{
this.downloading = true
downloadAll(this.affixId).then((res) => {
var blob = new Blob([res], {type: 'application/octet-stream'})
var downloadElement = document.createElement('a')
var href = window.URL.createObjectURL(blob) // 创建下载的链接
downloadElement.href = href
downloadElement.download = decodeURI('download.zip') // 下载后文件名
document.body.appendChild(downloadElement)
downloadElement.click() // 点击下载
document.body.removeChild(downloadElement) // 下载完成移除元素
window.URL.revokeObjectURL(href) // 释放掉blob对象
this.downloading = false
}).catch(() => {
this.downloading = false
})
}
},
deleteFile(file) {
this.$confirm('请确认是否删除此文件?', '提示', {type: 'info'}).then(() => {
deleteAffix(file.id).then((res) => {
if (res.code == 200) {
this.fileList = this.fileList.filter(item => item.id !== file.id)
this.previewList = this.previewList.filter(item => item !== file.savePath)//删除图片
if(this.fileList.length == 0){
this.affixId = ''
}
// 关键:触发自定义事件,传递被删除的文件名
// 事件名建议delete-file参数file.name文件名
this.$emit('delete-file', file.name);
} else {
this.$message.error(res.message)
}
})
})
},
loadData() {
this.fileList = []
if (typeof this.value !== 'undefined' && this.value !== null && this.value !== '') {
queryAffixs(this.value).then((res) => {
if (res.code ==200) {
if(res.data.length > 0){
this.affixId = this.value
for (var i=0;i<res.data.length;i++) {
if(this.isImageURL(res.data[i].savePath)){
this.previewList.push(this.baseurl+ res.data[i].savePath)
}
this.fileList.push({name: res.data[i].trueName, id: res.data[i].id, status: 2,savePath:this.baseurl+ res.data[i].savePath})
}
} else {
this.affixId = ''
}
} else {
this.$message.error(res.msg)
}
}).catch((res) => {
this.editLoading = false
this.$message.error(res.message)
})
} else {
this.affixId = ''
}
},
clearData() {
this.affixId = ''
this.fileList = []
}
}
}
</script>
<style scoped>
.cm-affix >>>.el-upload{
padding: 0px 10px;
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
margin-bottom: 10px;
}
.file {
width: 100%;
}
.file-item {
white-space: nowrap;
display: flex;
justify-content: start;
align-items: center;
gap: 8px;
}
.file-item div {
display: inline-block;
white-space: nowrap;
}
.file-upload {
font-size: 18px;
margin-left: 5px;
}
.file-download, .file-delete{
font-size: 18px;
cursor: pointer;
}
.file-download:hover, .file-delete:hover {
color: #409EFF;
}
.file-item[class~=is-disabled] .file-delete {
display: none;
}
.download-pack:hover {
background: #409eff;
border-color: #3999a8;
color: #fafbfd;
}
.preview .file-preview{
font-size: 19px;
cursor: pointer;
}
.preview >>>.el-image__inner{
width: 18px;
height: 18px;
}
</style>