当前位置: 首页 > wzjs >正文

郑州网站制作报价百度帐号管家

郑州网站制作报价,百度帐号管家,阿里巴巴批发网站上面怎么做微商,凡科建站是不是免费的一、问题 antDesign的Upload组件设置了direcotry属性,允许上传文件夹后;点击上传时无法 选择单个文件。刚开始的做法是直接重新写了upload组件上传框的点击事件,手动调用 window.showOpenFilePicker允许点击上传单个文件;但是需求…

一、问题

antDesign的Upload组件设置了direcotry属性,允许上传文件夹后;点击上传时无法 选择单个文件。刚开始的做法是直接重新写了upload组件上传框的点击事件,手动调用 window.showOpenFilePicker允许点击上传单个文件;但是需求又要求点击的时候既支持 选择文件和文件夹。由于文件夹和文件选择框的弹出API不同,必须分解为两个交互。

一个框支持上传单个文件,一个支持批量上传。

二、解决方法

1.点击上传:弹出文件夹选择框和文件选择框因选择的 文件类型完全不同,交互也不相同,所以对应不同的API;选择文件和文件夹的交互必须分开

文件夹选择框:window.showDirectoryPicker()

文件选择框:window.showOpenFilePicker()

2.拖拽上传:拖拽文件夹和文件的本质是相同的,可以一次性实现拖拽文件夹和文件,交互无须分开

因为浏览器http协议限制不允许一次性访问本地的文件夹,所以无论是 点击还是拖拽的批量上传文件或文件夹,本质上都是一个一个的上传文件

axios直接传文件夹会报错: net::ERR_FILE_NOT_FOUND,所以只能一个一个的遍历上传

3.拖拽时文件夹上传框,不允许上传单个文件

drop回调 判断如果是单个文件element.webkitGetAsEntry().isFile,则从文件列表中删除

4.拖拽时文件上传框,不允许上传文件夹

不开启dircotry选项

5.完整代码

<template><!-- 批量上传电子发票 --><AModal visible title="批量上传电子发票" :maskClosable="false" centered :width="720" @cancel="handleClose"><ASteps :current="current" :items="stepArray" size="small" class="steps-wrap"><AStepv-for="(item, itemKey) of stepArray":key="itemKey":class="[{ 'font-semibold text-cb06 ': itemKey === current }]":title="item.title"></AStep></ASteps><div v-loading="loading" class="modal-area mt-6"><AForm><!-- 上传文件 --><template v-if="isUpload"><div><div class="tip-area flex justify-between"><div class="limit text-ctext02">仅支持<span>pdf</span>格式,<span>单个文件最大1M,最多可传50个</span>,文件名称需为<span>订单编号</span></div><div class="text-center"><ATooltip overlayClassName="white-tooltip file-tooltip" placement="bottom"><AButton size="small" type="link" @click.stop>查看示例图 </AButton><template #title><div class="text-center"><div class="text-[#000]"><SvgIcon name="pdf"></SvgIcon> <span class="bg-cr06 bg-opacity-30">订单ID</span> .pdf</div><div class="tip"><div class="text-cr06">需为订单编号</div><div class="text-ctext01">方便上传时快速识别订单</div></div></div></template></ATooltip></div></div><div class="upload-area flex gap-6"><div class="flex-1"><AUploadDraggerv-model:fileList="fileList"name="file"accept=".pdf":maxCount="50":show-upload-list="false":before-upload="beforeUpload"@change="handleChangeFile"><div class="p-4"><p><SvgIconfontsymbol-name="icon_a-download_linexiazai":class="[' text-[40px] text-cbd02']"></SvgIconfont></p><p class="flex justify-center items-center font-semibold !mt-4 !mb-2 text-ctext02"><SvgIconfontsymbol-name="icon_a-file_2_linewendang2"color="#B3B3B3"class="text-[16px]"></SvgIconfont><span class="ml-1">单个文件上传</span></p><p class="text-ctext02 text-[12px]">点击或将【文件】拖拽到这里上传</p></div></AUploadDragger></div><div class="flex-1"><AUploadDraggerv-model:fileList="fileList"name="file"multipledirectoryaccept=".pdf":maxCount="50":show-upload-list="false":before-upload="beforeUpload"@change="handleChangeFile"@drop="handleDropFile"><div class="p-4"><p><SvgIconfontsymbol-name="icon_a-download_linexiazai":class="[' text-[40px] text-cbd02']"></SvgIconfont></p><p class="flex justify-center items-center font-semibold !mt-4 !mb-2 text-ctext02"><SvgIconfontsymbol-name="icon_a-folder_linewenjianjia"color="#B3B3B3"class="text-[16px]"></SvgIconfont><span class="ml-1">文件夹上传</span></p><p class="text-ctext02 text-[12px]">点击或将【文件夹】拖拽到这里上传</p></div></AUploadDragger></div></div></div><!-- 文件列表 --><template v-if="fileList?.length"><ul class="file-list-area"><li v-for="(file, fileKey) of fileList" :key="fileKey"><div class="flex justify-between"><div><ASpin :indicator="indicator" :class="['!mr-1', { '!opacity-0': !file.loading }]" /><SvgIcon name="pdf"></SvgIcon><span :class="['ml-1', { 'text-cr06': file.errMsg }]">{{ file.name }}</span><template v-if="file.errMsg"><div class="text-sm text-cr06 ml-4">{{ file.errMsg }}</div></template></div><div :class="['delete', { '!block': file.errMsg }]" title="删除文件" @click="handleDelete(fileKey)"><SvgIconfontsymbol-name="icon_a-delect_lineshanchu":class="['text-[16px] text-ctext02', { '!text-cr06': file.errMsg }]"></SvgIconfont></div></div></li></ul></template></template><!-- 关联订单 --><template v-else-if="isRelatedOrder"><ATable :class="['mt-[22px]']" :columns="columns" :dataSource="tableData" bordered :pagination="false"><template #bodyCell="{ column, record }"><template v-if="column.key === 'filename'"><div class="h-8 leading-[32px]"><SvgIcon name="pdf"></SvgIcon> <span>{{ record.filename }}</span></div></template><template v-if="column.key === 'orderId'"><template v-if="record.isEdit.value"><!-- <AInput v-model:value="record.orderId.value" class="!w-max !rounded-[4px]"> </AInput> --><DigitInput v-model:value="record.orderId.value" class="!w-max !rounded-[4px]"> </DigitInput></template><template v-else><div class="h-8 leading-[32px]"><span v-if="record.orderId.value">{{ record.orderId.value }} </span><template v-else><SvgIconfont symbol-name="icon_a-error_warning_filljinggao" class="text-cr06 text-base"></SvgIconfont><span> 未识别到订单ID </span></template><EditOutlined :style="{ color: '#1890FF' }" @click="record.isEdit.value = true" /></div></template></template></template></ATable></template><!-- 上传完成 --><template v-else-if="isFinish"><div class="finish-wrap"><div class="finish-item mb-4"><SvgIconfontsymbol-name="icon_a-checkbox_circle_fillxuanzegouxuankuang":class="['text-cg06 text-[19px]']"></SvgIconfont>上传成功 <span> {{ finishResult.successCount }}</span>个</div><div class="flex justify-between finish-item"><div><SvgIconfontsymbol-name="icon_a-error_warning_filljinggao":class="['text-cr06 text-[19px]']"></SvgIconfont>上传失败<span class="text-cr06"> {{ finishResult.failCount }}</span>个</div><AButton v-if="finishResult.failCount" type="link" class="!text-base" @click="handleDownloadFailData">下载失败原因</AButton></div></div></template></AForm></div><template #footer><AButton v-if="isUpload" @click="handleClick('cancel')">取消</AButton><AButton v-if="isRelatedOrder" @click="handleClick('cancel')">上一步</AButton><AButton v-if="isUpload" type="primary" @click="handleClick('relatedOrder')">去关联订单</AButton><AButton v-if="isRelatedOrder" type="primary" @click="handleClick('confirmUpload')">确认上传</AButton><AButton v-if="isFinish" type="primary" @click="handleSure">确认</AButton></template></AModal>
</template>
<script lang="tsx" setup>
import DigitInput from '@/components/DigitInput.vue'import { requestUploadApplyInvoice, requestBatchInvoiceAssociatedOrder } from '@/api/order-management/apply-invoice'
import { Modal } from 'ant-design-vue'
import { EditOutlined, Loading3QuartersOutlined } from '@ant-design/icons-vue'
import { aoaToSheetXlsx } from '@/utils/excel'
import { h } from 'vue'
import type { BatchInvoiceResult } from '@/api/order-management/apply-invoice/model'const emit = defineEmits(['close', 'sure'])/*** 步骤条**/
const current = ref<number>(0)
const stepArray = [{ title: '上传发票' },{title: '关联未开发票的订单'},{title: '上传完成'}
]
function next() {current.value++
}
function previous() {current.value--
}const fileList = ref<FileList & { errMsg?: string; loading?: boolean; url?: string; uid?: string; name?: string }[]>([])
function handleClose() {emit('close')
}/*** 1.上传文件*/
const isUpload = computed(() => current.value === 0)
function beforeUpload() {return false
}
const maxSize = 1async function handleChangeFile({ file }) {fileList.value.splice(fileList.value.length - singleFileArray.length)singleFileArray = []let targetIndex = fileList.value.findIndex((element) => element.uid === file.uid)if (targetIndex === -1) {return}let targetFile = fileList.value[targetIndex]targetFile.loading = truedealFile(file, targetIndex)
}async function dealFile(file: File, targetIndex: number) {let { errMsg, url } = (await requestUploadApplyInvoice({ fileList: file }))[0]let targetFile = fileList.value[targetIndex]targetFile.errMsg = errMsgtargetFile.url = urltargetFile.loading = falseif (!(file.size / 1024 / 1024 <= maxSize)) {targetFile.errMsg = '单个文件最大1M'}
}let singleFileArray: any[] = []
async function handleDropFile(event: { dataTransfer: { items: any[] } }) {event.dataTransfer.items.forEach((element) => {/** 文件夹上传框不允许上传单个文件 */if (element.webkitGetAsEntry().isFile || element.type) {// console.log('单个文件', element, element.getAsFile())singleFileArray.push(element.getAsFile())} else {// console.log('文件夹', element, element.getAsFile())}})
}
/*** 删除*/
function handleDelete(fileIndex: number) {fileList.value = fileList.value.filter((element, elementIndex) => elementIndex !== fileIndex)
}//     <SvgIconfont symbol-name="icon_a-loading_linejiazai" class="text-base"></SvgIconfont>
const indicator = h(Loading3QuartersOutlined, {style: {fontSize: '12px',fontWeight: 'bold',color: '#B3B3B3'},spin: true
})/*** 操作*/
const loading = ref(false)
function handleClick(type: string) {switch (type) {case 'cancel':handleCancel()breakcase 'relatedOrder':handleRelatedOrder()breakcase 'confirmUpload':handleConfirmUpload()breakdefault:break}
}/*** 取消*/
function handleCancel() {if (isUpload.value) {handleClose()} else if (isRelatedOrder.value) {previous()}
}/*** 2.去关联订单*/
const columns = [{title: '电子发票pdf文件',key: 'filename'},{title: '关联订单',key: 'orderId',width: 400}
]const tableData = computed(() => {return fileList.value.map((element) => {return {filename: element.name,orderId: ref(getOrderId(element.name)),isEdit: ref(false),url: element.url}})
})
function getOrderId(filename: string) {let temp = filename.replace('.pdf', '')if (/^\d+$/.test(temp)) {return temp} else {return ''}
}
const isRelatedOrder = computed(() => current.value === 1)
function handleRelatedOrder() {if (fileList.value.length) {let hasError = fileList.value.find((element) => element.errMsg)if (hasError) {confirmModal('监测到您上传的部分文件不是PDF格式,请确认所有文件均为PDF格式且上传成功,再进行订单关联!')return}next()} else {confirmModal('请上传电子发票pdf文件后,再进行订单关联!')}
}function confirmModal(text: string) {Modal.confirm({content: text,icon: '',cancelButtonProps: {style: 'display:none'}})
}/*** 3.上传完成*/
const isFinish = computed(() => current.value === 2)
const finishResult = reactive<BatchInvoiceResult>({})
let loadingTimeout: ReturnType<typeof setTimeout> | null = null
async function handleConfirmUpload() {loading.value = truetry {let result = await requestBatchInvoiceAssociatedOrder({invoiceList: tableData.value.map((element) => {return {filename: element.filename,orderId: element.orderId.value,url: element.url}})})Object.assign(finishResult, result)if (loadingTimeout) {clearTimeout(loadingTimeout)loadingTimeout = null}loadingTimeout = setTimeout(() => {loading.value = falsenext()}, 1000)} catch (error) {loading.value = falseconsole.log('error', error)}
}function handleDownloadFailData() {aoaToSheetXlsx({ header: finishResult.header, data: finishResult.errList, filename: finishResult.filename })
}function handleSure() {emit('sure', { type: 'batchUploadInvoice' })handleClose()
}
</script>
<style lang="less" scoped>
@import url('@/styles/modal.less');:deep(.anticon-check) {font-size: 13px;
}
.steps-wrap {padding: 0 24px;.ant-steps-item {flex: none;&:nth-child(1) {width: 216px;}&:nth-child(2) {width: 296px;}.ant-steps-item-title,.ant-steps-icon {font-size: 16px;}}&.ant-steps-small.ant-steps-horizontal:not(.ant-steps-label-vertical) .ant-steps-item {padding-left: 8px;&:first-child {padding-left: 0;}}
}
.modal-area {.tip-area {margin-bottom: 16px;padding: 10px 16px;background: #e6f7ff;border: 1px solid #1890ff;border-radius: 4px;.limit {span {color: #f53f3f;}}}.file-list-area {li {padding: 10px 4px 10px 12px;border-bottom: 1px solid #f0f0f0;.delete {cursor: pointer;display: none;}&:hover {background: #f0f0f0;.delete {display: block;}}}}.finish-wrap {margin-top: 12px;font-size: 16px;.finish-item {padding: 16px;background: #fafafa;border-radius: 4px;}}
}
</style>
<style lang="less">
@import '@/styles/tooltip.less';
.file-tooltip {.tip {background: url('@/assets/fileTip.png');width: 230px;padding: 9px 0 6px;margin-top: 2px;}
}
</style>

三、总结

1.文件选择弹框和文件夹选择弹框api不一样,必须分开

2.拖拽上传可以同时支持文件和文件夹上传

3.批量上传的时候如果全部不符合想要的类型如何处理?

目前是发现一个不符合类型,就提示

没有判断是否全部不符合:需求上其实是希望如果全部不符合才提示(减少提示次数)—— 目前没有空处理(因为里面涉及到 文件夹中嵌套文件夹等递归问题,比较复杂,待完善)

4.欸,以前都没有做过,所以实现的时候没有思路,特此记录。

http://www.dtcms.com/wzjs/118026.html

相关文章:

  • 网站推广内容网站排名提高
  • flash网站制作教程 下载长沙全网覆盖的网络推广
  • 郑州移动网站建设seo标题优化步骤
  • 学php做网站2022最新永久地域网名
  • dw怎么用divcss做网站站长之家的作用
  • 电器网站建设规划书百度推广网站一年多少钱
  • 网站建设平台开发今日百度小说排行榜
  • 厦门企业如何建网站电话营销话术
  • 青浦网站制作公司无锡网站制作
  • 做公司网站域名怎么做记账凭证商丘seo公司
  • 玩具网站模板市场营销案例
  • 手机网站建设合同广告推广投放平台
  • 网站建设论坛社区怎么提交网址让百度收录
  • 网站建设 我们是专业的深圳seo顾问
  • 学网站建设要学什么搜索引擎营销的原理
  • 七星网络网站快手作品免费推广软件
  • 免费网站建设平台网站维护工程师
  • 学习网站开发软件网站自助建站系统
  • 锦州网站建设工作台州seo优化
  • 做外贸电商网站有哪个网络舆情管控
  • 腾讯云建设网站视频360免费建站教程
  • 官方网站下载打印机的驱动微信软文范例大全100
  • 分类目录放到首页wordpressseo排名优化培训怎样
  • 做网站必须要文网文吗seo外包优化
  • 成都景观设计公司有哪些seo外包公司专家
  • 手机上的网站是怎么做的最新国内你新闻
  • 成都网站设计服务商湖南优化电商服务有限公司
  • 做网站主要显哪些内容优化游戏的软件
  • 网站空间 默认文档公司快速建站
  • 烟台网站建设网站推广外包网络推广营销