push
This commit is contained in:
4
lib/component/xlsx/index.ts
Normal file
4
lib/component/xlsx/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import { withInstall } from '/nerv-lib/util';
|
||||
import nsXlsxImport from './xlsx-import.vue';
|
||||
|
||||
export const NsXlsxImport = withInstall(nsXlsxImport);
|
||||
313
lib/component/xlsx/xlsx-import.vue
Normal file
313
lib/component/xlsx/xlsx-import.vue
Normal file
@@ -0,0 +1,313 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user