Files
SaaS-lib/lib/component/xlsx/xlsx-import.vue
xuziqiang d0155dbe3c push
2024-05-15 17:29:42 +08:00

314 lines
8.5 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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