<template> <div> <button type="primary" @click="showModal">批量导入</button> <a-modal v-model:visible="visible" @ok="handleOk" width="900px"> <div class="sumart-nursing-confim"> <ExclamationCircleOutlined style="color: #0ed2bf" /> <span>请按照模板的格式准备要导入的数据。</span> <a @click="download">下载模板</a> </div> <div class="import-content"> <div class="message-left"> <p>匹配类型:按照身份证号进行匹配</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' }" /> <span>点击或将文件拖拽到这里上传</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 message" :key="item">{{ item.label }}</p> </div> </div> </a-modal> </div> </template> <script> import { defineComponent, ref } from 'vue'; import { ExclamationCircleOutlined } from '@ant-design/icons-vue'; import { NsMessage } from '/nerv-lib/component/message'; import { http } from '/nerv-lib/util/http'; export default defineComponent({ name: 'NsUploadModal', components: { ExclamationCircleOutlined, }, props: { message: { type: Array, default: () => { return [ { label: '1、若身份证不填写,则不能进行导入操作' }, { label: '2、当身份证号重复时,则更新数据。' }, { label: '3、数据将从模版的第五行进行导入。' }, { label: '4、文件导入勿超过5MB。' }, ]; }, }, maxSize: { type: Number, default: 5242880, }, url: { type: String, default: '/api/community/community/objs/Owner/Import', }, downloadUrl: { type: String, default: 'public/file/ownerImport.xls', }, excelName: { type: String, default: '防区信息导入模版.xls', }, uploadFileName: { type: String, default: 'file', }, }, setup(props) { const visible = ref(false); const currentFile = ref({}); const fileName = ref(''); 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 = async () => { if (currentFile.value === {}) { NsMessage.warning('请选择需要上传的文件'); } const formData = new FormData(); formData.append(props.uploadFileName, currentFile.value); const config = { headers: { 'Content-Type': 'multipart/form-data', }, }; // 上传成功,服务器会自动解析并加入数据库中,前端要做的是刷新页面或者重新调用获取业主列表的接口 http .post(props.url, formData, config) .then(() => { NsMessage.success('上传成功'); }) .catch(() => { NsMessage.error('上传失败,请重试'); }); visible.value = false; }; const showModal = () => { visible.value = true; }; // 下载功能还没有测试,上传文件格式出错后的自动下载出错的Excel功能 还没有做 function download() { downloadFile(props.excelName, props.downloadUrl); } 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 { visible, currentFile, fileName, showModal, handleOk, handleInputClick, download, downloadFile, fake_click, }; }, }); </script> <style lang="less" scoped> .sumart-nursing-confim { background: #e6f7ff; margin-top: 20px; padding: 8px 16px; } .sumart-nursing-confim span { margin-left: 10px; } .import-content { display: flex; margin-top: 20px; } .upload-container { display: flex; } .file-upload { width: 70px; } .upload-area { width: 0px; height: 165px; } .import-fun { width: 300px; 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: 80px; padding: 16px; display: inline-table; > span { color: rgba(255, 153, 1, 1); font-weight: 500; font-size: 14px; line-height: 26px; } p { margin-bottom: 0; } } </style>