You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

259 lines
6.5 KiB

7 months ago
<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>