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
314 lines
8.5 KiB
6 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>
|