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.

314 lines
8.5 KiB

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