<template> <modal v-model:visible="visible" @ok="handleOk" v-bind="modelConfig"> <div class="sumart-nursing-confim" style="background: #ecfff4; margin-top: 0:"> <ExclamationCircleOutlined style="color: #0ed2bf" /> <span>请按照模板的格式准备要导入的数据。</span> <a @click="customDownloadFile">下载模板</a> <!-- <a :href="`${ENV.VITE_PUBLIC_PATH ? ENV.VITE_PUBLIC_PATH : '/'}asset/file/${ templateName.includes('.xls') ? templateName : templateName + '.xlsx' }`" :download="title + '录入信息'" target="_blank" >下载模板</a > --> </div> <div class="import-content"> <div class="message-left"> <p v-if="indexName">{{ `匹配类型:按照${indexName}进行匹配` }}</p> <p v-else style="opacity: 0">-</p> <div class="upload-container"> <span class="file-upload">文件上传:</span> <div class="upload-area"> <div class="import-fun"> <input type="file" accept=".xlsx, .xls" class="input-file" @change="handleInputClick" /> <div class="input-message"> <!-- <ExclamationCircleOutlined :style="{ color: '#0ed2bf', fontSize: '60px' }" /> --> <ContainerOutlined :style="{ color: '#0ed2bf', fontSize: '60px' }" /> <span style="margin-top: 10px">点击或将文件拖拽到这里上传</span> <span>支持扩展名: .xlsx, .xls</span> </div> </div> </div> <p class="file-name">{{ fileName }}</p> </div> </div> <div class="message-right"> <span>注意事项</span> <p v-for="item in messageFilted" :key="item">{{ item.label }}</p> </div> </div> </modal> </template> <script> import { defineComponent, ref, computed } from 'vue'; import { ExclamationCircleOutlined, ContainerOutlined } from '@ant-design/icons-vue'; import { Modal } from 'ant-design-vue'; import { NsMessage } from '/nerv-lib/component/message'; import { importFile } from '/nerv-lib/util/xlsx-util'; export default defineComponent({ name: 'NsXlsxImport', components: { ExclamationCircleOutlined, ContainerOutlined, Modal, }, props: { successBack: [Function], errorBack: [Function], reload: [Function], title: { type: String, default: '停车场', }, indexName: { type: String, default: '停车场编号', }, templateName: { type: String, default: 'ownerImport', }, customDonaleUrl: { type: String, }, message: { type: Array, default: () => [], }, maxSize: { type: Number, default: 5242880, }, api: { type: String, default: '', }, params: { type: Object, default: () => ({}), }, }, emits: ['change'], setup(props, context) { const visible = ref(true); const currentFile = ref(); const fileName = ref(''); const dealDonaleUrl = () => { if (props.customDonaleUrl) { return `${ENV.VITE_PUBLIC_PATH ? ENV.VITE_PUBLIC_PATH : '/'}${props.customDonaleUrl}`; } else { return `${ENV.VITE_PUBLIC_PATH ? ENV.VITE_PUBLIC_PATH : '/'}asset/file/${ props.templateName.includes('.xls') ? props.templateName : props.templateName + '.xlsx' }`; } }; const customDownloadFile = () => { let type = props.templateName.split('.').pop() || 'xlsx'; let filename = `${props.title}录入信息`; const link = `${ENV.VITE_PUBLIC_PATH ? ENV.VITE_PUBLIC_PATH : '/'}asset/file/${ props.templateName.includes('.xls') ? props.templateName : props.templateName + '.xlsx' }`; let DownloadLink = document.createElement('a'); DownloadLink.style = 'display: none'; // 创建一个隐藏的a标签 DownloadLink.download = filename; DownloadLink.href = link; document.body.appendChild(DownloadLink); DownloadLink.click(); // 触发a标签的click事件 document.body.removeChild(DownloadLink); // window.open( // `${ENV.VITE_PUBLIC_PATH ? ENV.VITE_PUBLIC_PATH : '/'}asset/file/${ // props.templateName.includes('.xls') ? props.templateName: props.templateName + '.xlsx' // }`, // ); }; const ENV = import.meta.env; const modelConfig = ref({ okText: '确定', cancelText: '取消', width: '700px', title: `批量导入${props.title}`, centered: true, destroyOnClose: true, }); let messageFilted = computed(() => { return Object.assign( props.message?.length ? props.message : [ { label: '1、若必填项未填写,则不能进行导入操作' }, { label: `2、当${props.indexName}重复时,则更新数据。` }, { label: '3、数据将从模版的第四行进行导入。' }, { label: '4、文件导入勿超过5MB。' }, ], ); }); const handleInputClick = (e) => { const file = e.target.files.item(0); if (!file) return; if (file.size > props.maxSize) { NsMessage.error(`文件大小不能超过${props.maxSize / 1024 / 1024}M`); } currentFile.value = file; fileName.value = file.name; // 清空,防止上传后再上传没有反应 e.target.value = ''; }; const handleOk = () => { // console.log(currentFile.value); if (!currentFile.value) { NsMessage.warning('请选择需要上传的文件'); return; } importFile(props, props.reload, currentFile.value, props.successBack, props.errorBack); context.emit('change', currentFile.value); visible.value = false; }; const showModal = () => { visible.value = true; currentFile.value = {}; fileName.value = ''; }; function downloadFile(name, url) { const save_link = document.createElementNS('http://www.w3.org/1999/xhtml', 'a'); save_link['href'] = url; save_link['download'] = name; fake_click(save_link); } function fake_click(obj) { // console.log(obj); const ev = document.createEvent('MouseEvents'); ev.initMouseEvent( 'click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null, ); obj.dispatchEvent(ev); //防止同步任务过快,导致在列表页面没有最新数据 } return { dealDonaleUrl, visible, currentFile, fileName, showModal, handleOk, handleInputClick, modelConfig, customDownloadFile, downloadFile, fake_click, messageFilted, ENV, }; }, }); </script> <style lang="less" scoped> .sumart-nursing-confim { background: #e6f7ff; margin-top: 0px; padding: 8px 16px; } .sumart-nursing-confim span { margin-left: 10px; } .import-content { display: flex; margin-top: 20px; padding-bottom: 70px; } .upload-container { display: flex; } .file-upload { width: 70px; } .upload-area { width: 0px; height: 165px; } .import-fun { width: 270px; height: 167px; border: 1px dashed rgba(0, 0, 0, 0.15); padding: 16px; -webkit-box-sizing: border-box; box-sizing: border-box; position: relative; } .input-file { position: absolute; width: 100%; height: 100%; opacity: 0; left: 0; top: 0; overflow: hidden; } .input-message { height: 167px; display: flex; flex-direction: column; text-align: center; } .file-name { width: 300px; margin-top: 170px; margin-bottom: 0; } .message-right { width: auto; background-color: rgba(255, 247, 235, 1); margin-left: 0px; padding: 10px; display: inline-table; margin-top: 35px; > span { color: rgba(255, 153, 1, 1); font-weight: 500; font-size: 14px; line-height: 26px; } p { margin-bottom: 0; line-height: 27px; } } </style>