可以做装修效果图的网站有哪些/全网网站快速排名推广软件
一、初始代码
1. 初始使用组件代码片段
<!-- 上传 -->
<DialogUploadFile ref="uploadFile" @success="refresh" />
// 上传
const uploadHandle = () => {if (selections.value.length != 1) {onceMessage.warning('请选择一条数据操作')return}uploadFile.value.show(selections.value[0])
}
2. 上传组件初始代码 DialogUploadFile.vue
<template><div class="no-modal-dialog"><el-dialog v-model="dialogVisible" :title="dialogTitle" width="800px" :close-on-click-modal="false"><el-row :gutter="20"><el-col :span="12"><div class="title">选择附件</div><el-uploadclass="upload-box"multiple:show-file-list="false":accept="fileTypes":before-upload="beforeUpload":drag="true"@drop.native="e => beforeUploadHandler(e.dataTransfer.files)"><div><el-button type="primary">点击选择附件</el-button><p class="el-upload__text">或将附件拖到这里</p><p class="el-upload__text">请上传pdf、pptx、ppt、docx、doc、zip、mp3格式</p></div></el-upload></el-col><el-col :span="12"><div class="title">附件列表</div><div class="list-header list-item"><div class="left">名称</div><div class="right">上传状态</div></div><ul class="list-box"><template v-if="fileList && fileList.length > 0"><li :class="['list-item', item.statusName == '上传中' ? 'gray' : '']" v-for="item of fileList" :key="item.id"><div class="left">{{ item.fileName }}</div><div :class="['right', item.statusName == '上传失败' ? 'error' : '']"><span>{{ item.statusName }}</span><el-icon v-if="item.statusName != '上传中'" class="del-icon" @click="delFile(item)"><Close /></el-icon></div></li></template><el-empty v-else description="暂无数据" /></ul></el-col></el-row><template #footer><el-button @click="onReset" v-out>取消</el-button><el-button @click="onSubmit" :disabled="disabledBtn" :loading="submitLoading" type="primary" v-out>确定</el-button></template></el-dialog></div>
</template>
<script setup lang="ts" name="DialogUploadFile">
import lodash from 'lodash'
import { appendixList, uploadFileApi, singleUploadBook } from '@/api/product-manage/electronic'
import { ElMessageBox } from 'element-plus'
import type { UploadProps } from 'element-plus'
import { onMounted, ref, inject, nextTick } from 'vue'
import type { productItem, fileItem } from '@/models/product'
import { compactEmpty } from '@/utils/tool'const onceMessage: any = inject('$onceMessage')
const dialogTitle = ref<string>('')
const submitLoading = ref<boolean>(false)
const dialogVisible = ref<boolean>(false)
const disabledBtn = ref<boolean>(false)
const productInfo = ref<productItem>({})
const fileTypes = ref<string>('.pdf, .doc, .docx, .ppt, .pptx,.zip,.mp3')
const fileList = ref<fileItem[]>([])
const delList = ref<fileItem[]>([])// 抛出事件
const emits = defineEmits<{(e: 'success'): void
}>()const show = (row: productItem) => {dialogVisible.value = trueproductInfo.value = rowdelList.value = []getFileList(row.serialNo)dialogTitle.value = `上传:${row.productName}`
}
defineExpose({ show })// 设置文件类型
const setType = (str: string) => {let index = str.lastIndexOf('.')let fileType = str.substring(index + 1, str.length)let shortName = str.substring(0, index)return {fileType,shortName}
}// 获取附件列表
const getFileList = (serialNo: string) => {if (!serialNo) {return}appendixList(serialNo).then(res => {let arr = res.data || []arr.forEach((item: fileItem, index: number) => {item.statusName = '已完成'let e = setType(item.fileName)item.fileType = e.fileTypeitem.shortName = e.shortName})fileList.value = arr})
}// 拖拽校验文件类型
const beforeUploadHandler = (obj: {}) => {for (var i in obj) {let e = setType(obj[i].name)let types = ['pdf', 'doc', 'docx', 'ppt', 'pptx', 'zip', 'mp3']if (types.indexOf(e.fileType) == -1) {ElMessageBox.confirm(`请上传pdf、pptx、ppt、docx、doc、zip、mp3格式`, obj[i].name + '格式错误', {confirmButtonText: '确定',showCancelButton: false,type: 'warning',closeOnClickModal: false}).then(() => {}).catch(() => {})}}
}// 上传之前
const beforeUpload: UploadProps['beforeUpload'] = rawFile => {let e = setType(rawFile.name)let exit = falseif (['doc', 'docx'].indexOf(e.fileType) != -1) {// word文档let arr = lodash.filter(fileList.value, function (item) {return ['doc', 'docx'].indexOf(item.fileType) != -1})arr.forEach(item => {if (item.shortName == e.shortName) {exit = true}})} else if (['ppt', 'pptx'].indexOf(e.fileType) != -1) {// pptlet arr = lodash.filter(fileList.value, function (item) {return ['ppt', 'pptx'].indexOf(item.fileType) != -1})arr.forEach(item => {if (item.shortName == e.shortName) {exit = true}})} else {fileList.value.forEach(item => {if (item.shortName == e.shortName && item.fileType == e.fileType) {exit = true}})}if (exit) {ElMessageBox.confirm(`附件列表中存在为${rawFile.name}的文件?`, '重名提示', {confirmButtonText: '替换附件列表文件',cancelButtonText: '跳过文件',type: 'warning',closeOnClickModal: false}).then(() => {fileList.value.forEach((item: fileItem, index: number) => {let files = setType(item.fileName)if (['doc', 'docx'].indexOf(e.fileType) != -1 && ['doc', 'docx'].indexOf(files.fileType) != -1 && e.shortName == files.shortName) {// word文档item.statusName = '上传中'item.filePath = ''item.id = item.id ? item.id : rawFile.uid + ''item.fileName = rawFile.nameitem.fileType = e.fileTypeitem.shortName = e.shortNameitem.updateFlag = item.updateFlag == 0 ? 0 : 1uploadFile(rawFile, item.id)} else if (['ppt', 'pptx'].indexOf(e.fileType) != -1 && ['ppt', 'pptx'].indexOf(files.fileType) != -1 && e.shortName == files.shortName) {// pptitem.statusName = '上传中'item.filePath = ''item.id = item.id ? item.id : rawFile.uid + ''item.fileName = rawFile.nameitem.fileType = e.fileTypeitem.shortName = e.shortNameitem.updateFlag = item.updateFlag == 0 ? 0 : 1uploadFile(rawFile, item.id)} else if (item.fileName == rawFile.name) {//其他item.statusName = '上传中'item.filePath = ''item.id = item.id ? item.id : rawFile.uid + ''item.fileName = rawFile.nameitem.fileType = e.fileTypeitem.shortName = e.shortNameitem.updateFlag = item.updateFlag == 0 ? 0 : 1uploadFile(rawFile, item.id)}})}).catch(() => {})} else {let item = {id: rawFile.uid + '',fileName: rawFile.name,filePath: '',statusName: '上传中',fileType: e.fileType,shortName: e.shortName,updateFlag: 0}fileList.value.push(item)uploadFile(rawFile, item.id)}return false
}// 上传附件
const uploadFile = (e: any, id: string | number, markFlag: any = 1) => {let params = new FormData()params.append('file', e)params.append('folderId', '')params.append('markFlag', markFlag)uploadFileApi(params).then(res => {fileList.value.forEach(item => {if (item.id == id) {item.filePath = res.dataitem.statusName = '已完成'}})}).catch(err => {fileList.value.forEach(item => {if (item.id == id) {item.statusName = '上传失败'}})})
}// 删除附件
const delFile = (e: fileItem) => {fileList.value = lodash.filter(fileList.value, function (item) {return item.id != e.id})if (compactEmpty(e.updateFlag)) {delList.value.push(e)}
}
// 取消
const onReset = () => {dialogVisible.value = false
}
// 提交
const onSubmit = () => {let updateArr = lodash.filter(fileList.value, function (item) {return item.statusName == '已完成' && !compactEmpty(item.updateFlag)})// 未修改不调用接口if (delList.value.length < 1 && updateArr.length < 1) {dialogVisible.value = falseallMark.value = falsemarkFlag.value = nullreturn} let param = {bookName: productInfo.value.productName,serialNo: productInfo.value.serialNo}let appendixes: fileItem[] = []fileList.value.forEach((item: fileItem) => {if (item.statusName == '已完成' && !compactEmpty(item.updateFlag)) {appendixes.push({id: item.updateFlag == 0 ? '' : item.id,fileName: item.fileName,filePath: item.filePath,updateFlag: item.updateFlag})}})delList.value.forEach((item: fileItem) => {if (item.statusName == '已完成') {appendixes.push({id: item.id,fileName: item.fileName,filePath: item.filePath,updateFlag: 2})}})submitLoading.value = truesingleUploadBook({...param,appendixes}).then(res => {emits('success')onceMessage.success('上传成功')submitLoading.value = falsedialogVisible.value = false}).catch(e => {submitLoading.value = false})
}
</script>
<style lang="scss">
.el-overlay {background-color: transparent;
}
.upload-box {.ep-upload.is-drag {display: block;height: 60vh;width: 100%;.ep-upload-dragger {width: 100%;height: 100%;display: flex;align-items: center;justify-content: center;background-color: transparent;border: 2px dashed #e5e6eb;&:hover {border-color: #e5e6eb;}}}
}
</style><style lang="scss" scoped>
.title {font-size: $text_color;font-size: 16px;font-weight: 600;margin-bottom: $spacing;
}
.upload-box {height: 60vh;width: 100%;display: flex;justify-content: center;align-items: center;.el-upload__text {color: $gray_text_color;margin-top: $spacing;}
}
.list-box {height: calc(60vh - 30px);box-sizing: border-box;overflow: auto;
}
.list-item {display: flex;justify-content: flex-start;align-items: center;border-top: 1px solid $border_color;padding: 5px 0;.left {width: 70%;padding-right: 24px;box-sizing: border-box;}.right {width: 30%;display: flex;justify-content: space-between;align-items: center;}.del-icon {cursor: pointer;&:hover {color: $primary_color;}}
}
.list-header {border: none;font-weight: bold;
}
.gray {color: $gray_text_color;
}
.error {color: $danger_color;
}
</style>
二、需求
- 上传文件前判断是否是pdf文件,如果是则弹出如下是否增加水印提示框
- 批量选择文件,碰到pdf文件,依次弹出如上提示框
- 若勾选了为后续pdf文件执行相同操作,则不再弹出如上提示框
- 若选择的文件中只有一个pdf文件,则不显示提示框中的复选框和“为后续pdf文件执行相同操作”文字
- 添加批量上传功能
三、需求实现
1. 修改后使用组件代码片段
<!-- 上传 -->
<DialogUploadFile ref="uploadFile" @success="refresh" />
<!-- 批量上传 -->
<DialogUploadFile ref="batchUploadFile" :isBatch="true" />
// 上传
const uploadHandle = () => {if (selections.value.length != 1) {onceMessage.warning('请选择一条数据操作')return}uploadFile.value.show(selections.value[0])
}// 批量上传
const batchUploadHandle = () => {batchUploadFile.value.show()
}
2. 是否增加水印弹窗代码 DialogWatermark.vue
<template><div><el-dialog v-model="dialogVisible" title="是否增加水印提示" width="500px" :show-close="false" :close-on-click-modal="false"><div class="txt center">附件“{{ fileName || '' }}”是否增加水印?</div><div class="btns-box center"><el-button class="btn" type="primary" size="small" @click="handleYes">是</el-button><el-button class="btn" size="small" @click="handleNo">否</el-button></div><div class="center" v-if="showCheck"><el-checkbox v-model="checked">为后续pdf文件执行相同操作</el-checkbox></div></el-dialog></div>
</template><script setup lang="ts" name="DialogWatermark">
import { ref } from 'vue'// 抛出事件
const emits = defineEmits(['on-change'])const dialogVisible = ref<boolean>(false)
const showCheck = ref<boolean>(true)
const checked = ref<boolean>(false)
const info = ref<any>()
const fileName = ref<any>('')
const listIndex = ref<any>(null)const show = (e: any, index: any, bool: boolean) => {checked.value = false // 重置复选框listIndex.value = indexif (String(index) != 'null') {info.value = e || {}fileName.value = e?.nameshowCheck.value = bool} else {info.value = e || []fileName.value = e && e.length ? e[0].name : ''showCheck.value = e && e.length == 1 ? false : true}dialogVisible.value = true
}defineExpose({ show })// 点击是
const handleYes = () => {dialogVisible.value = falselet obj = {data: info.value,index: listIndex.value,check: checked.value,flag: 1}emits('on-change', obj)
}
// 点击否
const handleNo = () => {dialogVisible.value = falselet obj = {data: info.value,index: listIndex.value,check: checked.value,flag: 0}emits('on-change', obj)
}
</script><style lang="scss" scoped>
.txt {font-size: 16px;line-height: 32px;margin-bottom: $spacing * 2;
}
.btns-box {margin-bottom: $spacing * 2;:deep(.ep-button--small) {width: 60px;}.btn + .btn {margin-left: $spacing * 6;}
}.center {text-align: center;
}
</style>
3. 上传组件修改后代码 DialogUploadFile.vue
<template><div class="no-modal-dialog"><el-dialog v-model="dialogVisible" :title="dialogTitle" width="800px" :close-on-click-modal="false"><!-- 此处代码不变,省略...... --></el-dialog><!-- 是否增加水印弹窗 --><DialogIFWatermark ref="dialogIFWatermarkRef" @on-change="changeWatermark" /><!-- 批量上传结果弹窗 --><DialogErrorUpload ref="dialogErrorUploadRef" /></div>
</template><script setup lang="ts" name="DialogUploadFile">
import lodash from 'lodash'
import { appendixList, uploadFileApi, singleUploadBook, batchUploadBook } from '@/api/product-manage/electronic'
import { ElMessageBox, ElCheckbox, ElButton } from 'element-plus'
import type { UploadProps } from 'element-plus'
import { onMounted, ref, inject, nextTick, h } from 'vue'
import type { productItem, fileItem } from '@/models/product'
import { compactEmpty } from '@/utils/tool'
import DialogIFWatermark from './DialogIFWatermark.vue'
import DialogErrorUpload from './DialogErrorUpload.vue'const props = defineProps({isBatch: {type: Boolean,default: false}
})const onceMessage: any = inject('$onceMessage')
const dialogTitle = ref<string>('')
const submitLoading = ref<boolean>(false)
const dialogVisible = ref<boolean>(false)
const disabledBtn = ref<boolean>(false)const allMark = ref<boolean>(false)
const markFlag = ref<any>(null)const productInfo = ref<productItem>({})
const fileTypes = ref<string>('.pdf, .doc, .docx, .ppt, .pptx,.zip,.mp3')
const fileList = ref<fileItem[]>([])
const delList = ref<fileItem[]>([])const tempList = ref<fileItem[]>([])
const pdfList = ref<any>([])
const dialogIFWatermarkRef = ref<any>()
const dialogErrorUploadRef = ref<any>()// 抛出事件
const emits = defineEmits<{(e: 'success'): void
}>()const show = (row: productItem) => {dialogVisible.value = trueif (!props.isBatch) {productInfo.value = rowdelList.value = []getFileList(row.serialNo)dialogTitle.value = `上传:${row.productName}`} else {fileList.value = []delList.value = []tempList.value = []pdfList.value = []dialogTitle.value = '批量上传'}
}
defineExpose({ show })// 设置文件类型
const setType = (str: string) => {// 此处代码不变,省略......
}// 获取附件列表
const getFileList = (serialNo: string) => {// 此处代码不变,省略......
}// 拖拽校验文件类型
const beforeUploadHandler = (obj: {}) => {// 此处代码不变,省略......
}// 是否加水印
const changeWatermark = (e: any) => {allMark.value = e.checkmarkFlag.value = e.flagif (String(e.index) != 'null') {let rawFile = e.data || {}let obj = setType(rawFile.name)// 列表有重名文件进行覆盖操作的情况fileList.value.map((item, index) => {if (index == e.index) {item.statusName = '上传中'item.filePath = ''item.id = item.id ? item.id : rawFile.uid + ''item.fileName = rawFile.nameitem.fileType = obj.fileTypeitem.shortName = obj.shortNameitem.updateFlag = item.updateFlag == 0 ? 0 : 1uploadFile(rawFile, item.id, e.flag)pdfList.value.shift()}})} else {// 列表无重名文件进行上传操作的情况/* 第一、第二次尝试 */// let item = {// id: rawFile.uid + '',// fileName: rawFile.name,// filePath: '',// statusName: '上传中',// fileType: obj.fileType,// shortName: obj.shortName,// updateFlag: 0// }// fileList.value.push(item)// uploadFile(rawFile, item.id, e.flag)/* 最终实现 */let list = e.data || []handleUpload(list, allMark.value)}
}// 循环上传
const handleUpload = (list: any, isChecked: boolean) => {if (isChecked) {list.map((item: any) => {let o = setType(item.name)let obj = {id: item.uid + '',fileName: item.name,filePath: '',statusName: '上传中',fileType: o.fileType,shortName: o.shortName,updateFlag: 0}fileList.value.push(obj)uploadFile(item, obj.id, markFlag.value)})tempList.value = []} else {// 每次都上传数组的第0项,上传完把数组第0项删除let o = setType(list[0].name)let obj = {id: list[0].uid + '',fileName: list[0].name,filePath: '',statusName: '上传中',fileType: o.fileType,shortName: o.shortName,updateFlag: 0}fileList.value.push(obj)uploadFile(list[0], obj.id, markFlag.value)nextTick(() => {list.shift()if (list.length) {dialogIFWatermarkRef.value.show(list, null)}})}
}// 上传之前
const beforeUpload: UploadProps['beforeUpload'] = rawFile => {allMark.value = falsemarkFlag.value = nulllet e = setType(rawFile.name)let exit = falseif (['doc', 'docx'].indexOf(e.fileType) != -1) {// word文档let arr = lodash.filter(fileList.value, function (item) {return ['doc', 'docx'].indexOf(item.fileType) != -1})arr.forEach(item => {if (item.shortName == e.shortName) {exit = true}})} else if (['ppt', 'pptx'].indexOf(e.fileType) != -1) {// pptlet arr = lodash.filter(fileList.value, function (item) {return ['ppt', 'pptx'].indexOf(item.fileType) != -1})arr.forEach(item => {if (item.shortName == e.shortName) {exit = true}})} else {fileList.value.forEach(item => {if (item.shortName == e.shortName && item.fileType == e.fileType) {exit = true}})}if (exit) {let selectList = pdfList.value || []selectList.push(rawFile)pdfList.value = selectList.filter((item: any) => setType(item.name).fileType == 'pdf')ElMessageBox.confirm(`附件列表中存在为${rawFile.name}的文件?`, '重名提示', {confirmButtonText: '替换附件列表文件',cancelButtonText: '跳过文件',type: 'warning',closeOnClickModal: false}).then(() => {fileList.value.forEach((item: fileItem, index: number) => {let files = setType(item.fileName)if (['doc', 'docx'].indexOf(e.fileType) != -1 && ['doc', 'docx'].indexOf(files.fileType) != -1 && e.shortName == files.shortName) {// word文档item.statusName = '上传中'item.filePath = ''item.id = item.id ? item.id : rawFile.uid + ''item.fileName = rawFile.nameitem.fileType = e.fileTypeitem.shortName = e.shortNameitem.updateFlag = item.updateFlag == 0 ? 0 : 1uploadFile(rawFile, item.id)} else if (['ppt', 'pptx'].indexOf(e.fileType) != -1 && ['ppt', 'pptx'].indexOf(files.fileType) != -1 && e.shortName == files.shortName) {// pptitem.statusName = '上传中'item.filePath = ''item.id = item.id ? item.id : rawFile.uid + ''item.fileName = rawFile.nameitem.fileType = e.fileTypeitem.shortName = e.shortNameitem.updateFlag = item.updateFlag == 0 ? 0 : 1uploadFile(rawFile, item.id)} else if (['pdf'].indexOf(e.fileType) != -1 && ['pdf'].indexOf(files.fileType) != -1 && e.shortName == files.shortName) {// pdf(这一块的判断一直是正常的)if (allMark.value) {item.statusName = '上传中'item.filePath = ''item.id = item.id ? item.id : rawFile.uid + ''item.fileName = rawFile.nameitem.fileType = e.fileTypeitem.shortName = e.shortNameitem.updateFlag = item.updateFlag == 0 ? 0 : 1uploadFile(rawFile, item.id, markFlag.value)pdfList.value.shift()} else {let bool = pdfList.value && pdfList.value.length == 1 ? false : truedialogIFWatermarkRef.value.show(rawFile, index, bool)}} else if (item.fileName == rawFile.name) {// 其他item.statusName = '上传中'item.filePath = ''item.id = item.id ? item.id : rawFile.uid + ''item.fileName = rawFile.nameitem.fileType = e.fileTypeitem.shortName = e.shortNameitem.updateFlag = item.updateFlag == 0 ? 0 : 1uploadFile(rawFile, item.id)}})}).catch(() => {if (e.fileType.indexOf('pdf') != -1) {pdfList.value.shift()}})} else {// ------------------------------- 踩坑的地方主要在这块位置,上面的代码都正常 -------------------------------/* 第一次尝试使用的是dialog弹出框,即上面用el-dialog写的那个是否增加水印的组件,写法如下问题:选中多个pdf文件上传,只弹出来一次是否增加水印的弹出框,且是最后一个pdf的,而不是依次弹出*/// if (['pdf'].indexOf(e.fileType) != -1) {// // pdf// if (allMark.value) {// let item = {// id: rawFile.uid + '',// fileName: rawFile.name,// filePath: '',// statusName: '上传中',// fileType: e.fileType,// shortName: e.shortName,// updateFlag: 0// }// fileList.value.push(item)// uploadFile(rawFile, item.id, markFlag.value)// } else {// dialogIFWatermarkRef.value.show(rawFile, null)// }// } else {// let item = {// id: rawFile.uid + '',// fileName: rawFile.name,// filePath: '',// statusName: '上传中',// fileType: e.fileType,// shortName: e.shortName,// updateFlag: 0// }// fileList.value.push(item)// uploadFile(rawFile, item.id)// }/* 考虑到上面ElMessageBox中的代码效果正常,是否增加水印弹出框能够正常的依次弹出所以第二次尝试使用ElMessageBox,写法如下问题:1.弹出框是可以依次弹出了,但是勾选复选框后续文件执行相同操作,弹出框还是会弹出,不会关闭,因为它不会再走上面判断allMark.value了;2.这里还要注意使用的ElCheckbox的modelValue值绑定的时候不能直接绑定allMark.value,否则会出现值变化了,但是复选框样式没有发生改变的问题*/// let item = {// id: rawFile.uid + '',// fileName: rawFile.name,// filePath: '',// statusName: '上传中',// fileType: e.fileType,// shortName: e.shortName,// updateFlag: 0// }// if (['pdf'].indexOf(e.fileType) != -1) {// // pdf// if (allMark.value) {// fileList.value.push(item)// uploadFile(rawFile, item.id, markFlag.value)// } else {// const checked = ref<any>(null)// // checked.value = allMark.value ? 1 : 0// ElMessageBox({// title: `附件“${rawFile.name}”是否增加水印?`,// center: true,// showCancelButton: true,// confirmButtonText: '是',// cancelButtonText: '否',// showClose: false,// closeOnClickModal: false,// message: h(ElCheckbox, {// modelValue: checked.value,// label: '为后续pdf文件执行相同操作',// // trueLabel: 1,// // falseLabel: 0,// 'onUpdate:modelValue': (val: any) => {// checked.value = val// // allMark.value = val == 1 ? true : false// allMark.value = val// }// })// })// .then(res => {// fileList.value.push(item)// uploadFile(rawFile, item.id, 1)// })// .catch(err => {// fileList.value.push(item)// uploadFile(rawFile, item.id, 0)// })// }// } else {// fileList.value.push(item)// uploadFile(rawFile, item.id)// }/* 最终实现 */let originList = tempList.value || []let obj: any = rawFileif (['pdf'].indexOf(e.fileType) != -1) {originList.push(obj)tempList.value = originListdialogIFWatermarkRef.value.show(tempList.value, null)} else {let item = {id: rawFile.uid + '',fileName: rawFile.name,filePath: '',statusName: '上传中',fileType: e.fileType,shortName: e.shortName,updateFlag: 0}fileList.value.push(item)uploadFile(rawFile, item.id)}}return false
}// 上传附件
const uploadFile = (e: any, id: string | number, markFlag: any = 1) => {let params = new FormData()params.append('file', e)params.append('folderId', '') params.append('markFlag', markFlag) // 加了一个是否添加水印的参数,其他逻辑不变uploadFileApi(params).then(res => {fileList.value.forEach(item => {if (item.id == id) {item.filePath = res.dataitem.statusName = '已完成'}})}).catch(err => {fileList.value.forEach(item => {if (item.id == id) {item.statusName = '上传失败'}})})
}// 删除附件
const delFile = (e: fileItem) => {// 此处代码不变,省略......
}// 取消
const onReset = () => {dialogVisible.value = falseallMark.value = falsemarkFlag.value = null
}// 提交
const onSubmit = () => {let updateArr = lodash.filter(fileList.value, function (item) {return item.statusName == '已完成' && !compactEmpty(item.updateFlag)})// 未修改不调用接口if (delList.value.length < 1 && updateArr.length < 1) {dialogVisible.value = falseallMark.value = falsemarkFlag.value = nullreturn}if (props.isBatch) {// 批量上传let arr: any = []if (fileList.value && fileList.value.length) {fileList.value.forEach(item => {arr.push({fileName: item.fileName,filePath: item.filePath})})}submitLoading.value = truebatchUploadBook(arr).then(res => {dialogErrorUploadRef.value.show(res.data)submitLoading.value = falsedialogVisible.value = falseallMark.value = falsemarkFlag.value = null}).catch(err => {submitLoading.value = falseallMark.value = falsemarkFlag.value = null})} else {// 上传-原逻辑保持不变let param = {bookName: productInfo.value.productName,serialNo: productInfo.value.serialNo}let appendixes: fileItem[] = []fileList.value.forEach((item: fileItem) => {if (item.statusName == '已完成' && !compactEmpty(item.updateFlag)) {appendixes.push({id: item.updateFlag == 0 ? '' : item.id,fileName: item.fileName,filePath: item.filePath,updateFlag: item.updateFlag})}})delList.value.forEach((item: fileItem) => {if (item.statusName == '已完成') {appendixes.push({id: item.id,fileName: item.fileName,filePath: item.filePath,updateFlag: 2})}})submitLoading.value = truesingleUploadBook({...param,appendixes}).then(res => {emits('success')onceMessage.success('上传成功')submitLoading.value = falsedialogVisible.value = falseallMark.value = falsemarkFlag.value = null}).catch(e => {submitLoading.value = falseallMark.value = falsemarkFlag.value = null})}
}
</script><style lang="scss">
/* 此处代码不变,省略...... */
</style>
相关文章:

【el-upload】批量上传图片时在before-upload中添加弹窗判断时的踩坑记录
一、初始代码 1. 初始使用组件代码片段 <!-- 上传 --> <DialogUploadFile ref"uploadFile" success"refresh" />// 上传 const uploadHandle () > {if (selections.value.length ! 1) {onceMessage.warning(请选择一条数据操作)return}u…...

【Java基础】- JVM之Dump文件详解
Java基础 - JVM之Dump文件详解 文章目录 Java基础 - JVM之Dump文件详解一、什么是Dump三、为什么需要Dump分析思路 四、Dump记录哪些内容4.1 Java dump 文件的格式和内容段格式行格式 4.2 常用分类heap dump和thread dumpheap dumpthread dump 五、如何生产Dump文件5.1 获取hea…...

基于Vue+wangeditor实现富文本编辑
目录 前言分析实现具体解决的问题有具体代码实现如下效果图总结前言 一个网站需要富文本编辑器功能的原因有很多,以下是一些常见的原因: 方便用户编辑内容:富文本编辑器提供了类似于Office Word的编辑功能,使得那些不太懂HTML的用户也能够方便地编辑网站内容。提高用户体验…...

深入理解 Spring 中的 @RequestBody 和 @ResponseBody 注解及其区别
引言 在现代的 Web 开发中,处理 HTTP 请求和响应是不可或缺的任务。Spring Framework 提供了丰富的功能来简化这些任务,并使开发人员能够更专注于业务逻辑。在本文中,我们将深入探讨 Spring 中的 RequestBody 和 ResponseBody 注解࿰…...

【论文阅读】EULER:通过可扩展时间链接预测检测网络横向移动(NDSS-2022)
作者:乔治华盛顿大学-Isaiah J. King、H. Howie Huang 引用:King I J, Huang H H. Euler: Detecting Network Lateral Movement via Scalable Temporal Graph Link Prediction [C]. Proceedings 2022 Network and Distributed System Security Symposium…...

手动创建一个DOCKER镜像
1. 我们先使用C语言写一个hello-world程序 vim hello.c # include <stdio.h>int main() {print("hello docker\n"); } 2. 将hello.c文件编译成二进制文件, 需要安装工具 yum install gcc yum install glibc-static 开始编译 gcc -static hello.c -o hello 编译…...

SSM(Vue3+ElementPlus+Axios+SSM前后端分离)--搭建Vue 前端工程[一]
文章目录 SSM--搭建Vue 前端工程--项目基础界面实现功能01-搭建Vue 前端工程需求分析/图解代码实现搭建Vue 前端工程下载node.js LTS 并安装: node.js 的npm创建Vue 项目使用idea 打开ssm_vue 项目, 并配置项目启动 Vue3 项目目录结构梳理Vue3 项目结构介绍 配置Vue 服务端口El…...

Idea使用Docker插件实现maven打包自动构建镜像
Docker 开启TCP 服务 vi /lib/systemd/system/docker.service改写以下内容 ExecStart/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock重启服务 #重新加载配置文件 systemctl daemon-reload #重启服务 systemctl restart docker.service此时docker已…...

Tailwind css优于Bootstrap 7个原因
在某些情况下,Tailwind css 比 Bootstrap 更好,因为它是一个低级 CSS 框架,可让您根据需要构建自己的自定义组件。如果使用得当,它非常注重性能,可以显着减少 CSS 负载并确保更快的渲染。如果 Web 性能和自定义是您的首…...

IDEA简单拷贝一份新项目记录
IDEA简单拷贝项目记录 拷贝后改项目名,然后iml 配置文件改项目名,然后 .idea 中的compiler.xml 里面的name标签改项目名。 就可以了...

华为OD真题--字符串加密
2023华为OD统一考试(AB卷)题库清单-带答案(持续更新)or2023年华为OD真题机考题库大全-带答案(持续更新) "给你一串未加密的字符串str,通过对字符串的每一个字母进行改变来实现加密…...

UML-状态图
目录 状态图 状态图的图符 状态机 状态 转换 电话机状态图 活动图和状态图区别: 状态图 状态图(Statechart Diagram)是描述一个实体基于事件反应的动态行为,显示了该实体如何根据当前所处的状态对不同的事件做出反应。通常我们创建一个UML状态…...

chrome插件开发实例07- Vue调试插件vue-devtools
目录 一、为什么使用vue-devtools插件 二、如何安装 三、使用源码方式,安装Vue-devtools插件...

HTML <span> 标签
定义和用法 <span> 标签被用来组合文档中的行内元素。 浏览器支持 元素ChromeIEFirefoxSafariOpera<span>YesYesYesYesYes所有浏览器都支持 <span> 标签。 HTML 与 XHTML 之间的差异 NONE 提示和注释: 提示:请使用 <span> 来组合行内元素,以便…...

【PythonGIS】Python处理矢量数据的基本操作(查询、修改、删除、新建)
ogr库是一个处理地理空间矢量数据的开源库。它可以读取多种数据格式,进行地理处理、属性表操作、数据分析等操作。目前ogr和osr库已集成到GDAL库中,可以对栅格数据、矢量数据进行处理分析,被3S的研究人员广泛应用。感兴趣的可以自己去了解一下…...

15.2 【Linux】仅执行一次的工作调度
15.2.1 atd 的启动与 at 运行的方式 要使用单一工作调度时,我们的 Linux 系统上面必须要有负责这个调度的服务,那就是 atd 。 不过并非所有的 Linux distributions 都默认会把他打开的,所以,某些时刻我们必须要手动将他启用才行。…...

时间复杂度与空间复杂度的详解
目录 1.时间复杂度 2.时间复杂度计算例题 3.空间复杂度 1.时间复杂度 算法中的基本操作的执行次数,为算法的时间复杂度。 如何表达 时间复杂度? 大O的渐进表示法 实际中我们计算时间复杂度时,我们其实并不一定要计算精确的执行次数…...

每日一学:什么是 Harbor ?
目录 什么是 Harbor ? 一、Harbor 的优势 二、Harbor 架构构成 三、Core services 这是 Harbor 的核心功能 什么是 Harbor ? Harbor 是 VMware 公司开源的企业级 Docker Registry 项目,其目标是帮助用户迅速搭建一个企业级的 Docker Reg…...

灰度均衡变换之c++实现(qt + 不调包)
1.基本原理 灰度均衡是以累计分布函数变换为基础的直方图修正法,它可以产生一副灰度级分布概率均匀的图像。也就是说,经过灰度均衡后的图像在没一级灰度上像素点的数量相差不大。公式见下图,为灰度值为x的像素点的个数,n为总像素点…...

flink1.17 自定义trigger ContinuousEventTimeTrigger
在 ContinuousEventTimeTrigger 的基础上新增了timeout,如果超时后窗口都没关闭,那么就硬输出一波,避免间断数据,留存窗口太久. ContinuousEventTimeTrigger ContinuousEventTimeTrigger连续事件时间触发器与ContinuousProcessingTimeTrigger连续处理时间触发器,指定一个固定…...

AIGC:【LLM(五)】——Faiss:高效的大规模相似度检索库
文章目录 一.简介1.1 什么是Faiss1.2 Faiss的安装 二.Faiss检索流程2.1 构建向量库2.2 构建索引2.3 top-k检索 三.Faiss构建索引的多种方式3.1 Flat :暴力检索3.2 IVFx Flat :倒排暴力检索3.3 IVFxPQy 倒排乘积量化3.4 LSH 局部敏感哈希3.5 HNSWx 一.简介…...

自然语言处理从入门到应用——LangChain:记忆(Memory)-[记忆的类型Ⅱ]
分类目录:《自然语言处理从入门到应用》总目录 对话知识图谱记忆(Conversation Knowledge Graph Memory) 这种类型的记忆使用知识图谱来重建记忆: from langchain.memory import ConversationKGMemory from langchain.llms impo…...

桥接模式-java实现
桥接模式 桥接模式的本质,是解决一个基类,存在多个扩展维度的的问题。 比如一个图形基类,从颜色方面扩展和从形状上扩展,我们都需要这两个维度进行扩展,这就意味着,我们需要创建一个图形子类的同时&#x…...

Linux systemd管理常用的几个小案例
systemd是目前Linux系统上主要的系统守护进程管理工具,配置文件要以.service结尾且放到 /usr/lib/systemd/system/目录下面 1、systemd管理ElasticSearch [Unit] DescriptionElasticsearch Service[Service] Typeforking Userelastic Groupelastic ExecStart/home…...

38、IPv6过渡技术
本节内容作为IPv6相关知识的最后一节内容,同时也作为我们本专栏网络层知识的最后一节内容,主要介绍从IPv4地址到IPv6地址过渡的相关技术。在这里我们只学习各类考试中常考的三种技术。 IPv4向IPv6的过渡 在前面的知识中,我们学习到了两种IP地…...

HMMER-序列分析软件介绍
HMMER是一个软件包,它提供了制作蛋白质和DNA序列域家族概率模型的工具,称为轮廓隐马尔可夫模型、轮廓HMM或仅轮廓,并使用这些轮廓来注释新序列、搜索序列数据库以寻找其他同源物,以及进行深度多重序列比对。HMMER是已知蛋白质和DN…...

【项目学习1】如何将java对象转化为XML字符串
如何将java对象转化为XML字符串 将java对象转化为XML字符串,可以使用Java的XML操作库JAXB,具体操作步骤如下: 主要分为以下几步: 1、创建JAXBContext对象,用于映射Java类和XML。 JAXBContext jaxbContext JAXBConte…...

nginx负载均衡
负载均衡:反向代理来实现 正向代理的配置方法。 1、NGINX的七层代理和四层代理: 七层是最常用的反向代理方式,只能配置在nginx配置文件的http模块。而且配置方法名称:upstream 模块,不能写在server中,也…...

【毕业项目】自主设计HTTP
博客介绍:运用之前学过的各种知识 自己独立做出一个HTTP服务器 自主设计WEB服务器 背景目标描述技术特点项目定位开发环境WWW介绍 网络协议栈介绍网络协议栈整体网络协议栈细节与http相关的重要协议 HTTP背景知识补充特点uri & url & urn网址url HTTP请求和…...

关于安卓jar包修改并且重新发布
背景: 对于某些jar包,其内部是存在bug的,解决的方法无外乎就有以下几种方法: (1)通过反射,修改其赋值逻辑 (2)通过继承,重写其方法 (3࿰…...