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.

195 lines
4.9 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div>
<el-dialog :append-to-body="true" :visible.sync="dialogVisible" title="数据导入" width="70%">
<div class="title">模板下载</div>
<el-button
style="margin-top: 10px"
size="small"
type="primary"
@click="exportExcel(new Date().getTime().toString())"
>模板下载</el-button
>
<div style="color: red; margin-top: 10px">
导入的时候请勿修改模版的标题名称
</div>
<el-upload
style="margin-top: 10px"
drag
:action="action"
:data="{
table_name: tableName,
}"
:headers="{
Authorization: `Bearer ${getToken()}`,
}"
:on-success="uploadSuccess"
:on-error="uploadFail"
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip">只能上传xls/xlsx文件</div>
</el-upload>
<div class="title" style="margin-top: 10px;">数据预览</div>
<Table :data="tableList" :columns="table" style="margin-top: 10px;"></Table>
<div style="font-size: 12px;zoom: 0.8;">总共数据{{ tableList.length }}</div>
<el-button type="primary" size="small" style="margin-top: 10px;" @click="imports"></el-button>
</el-dialog>
</div>
</template>
<script>
import XLSX from "xlsx-js-style";
// import * as XLSX from "xlsx";
import { saveAs } from "file-saver";
import { getToken } from "@/utils/auth";
import { imports } from "@/api/system/baseForm";
export default {
props: {
formInfo: {
type: Array,
default: () => [],
},
tableName: String,
},
data() {
return {
action: `${process.env.VUE_APP_BASE_API}api/admin/base-form/excel-show`,
dialogVisible: false,
headers: [],
tableList: [],
table: [],
};
},
methods: {
getToken,
show() {
this.dialogVisible = true;
},
hidden() {
this.dialogVisible = false;
},
//上传
uploadFail(err) {
console.log(err);
this.$message({
message: "上传失败",
type: "error",
});
},
uploadSuccess(response) {
this.headers.forEach(header => {
if (header._params) {
response.forEach(row => {
if (row.hasOwnProperty(header.key)) {
row[header.key] = header._params.find(i => i.key == row[header.key]) ? header._params.find(i => i.key == row[header.key]).value : row[header.key]
}
for (let key in row) {
if (row[key].hasOwnProperty('date')) {
row[key] = row[key]['date']
}
}
})
}
})
this.tableList = response;
this.$message({
message: `上传成功`,
type: "success",
});
},
exportExcel(sheetName) {
function numberToLetter(num) {
// 检查输入是否为非负整数
if (num < 0 || !Number.isInteger(num)) {
throw new Error("请输入一个非负整数");
}
// 计算对应的字母
return String.fromCharCode(65 + num);
}
const data = [this.headers.map((header) => header.title)];
const wb = XLSX.utils.book_new();
const ws = XLSX.utils.aoa_to_sheet(data);
this.headers.forEach((header, index) => {
if (header.required) {
ws[`${numberToLetter(index)}1`].s = {
font: {
bold: true,
color: { rgb: "FFFF0000" }
}
}
}
})
XLSX.utils.book_append_sheet(wb, ws, sheetName);
const wbout = XLSX.write(wb, {
bookType: "xlsx",
bookSST: true,
type: "array",
});
saveAs(
new Blob([wbout], { type: "application/octet-stream" }),
`${sheetName}.xlsx`
);
},
imports() {
imports({
table_name: this.tableName,
data: this.tableList
}).then(res => {
console.log(res)
this.$message({
type: 'success',
message: `总计${res.total},成功导入${res.total-res.fail}`
})
this.hidden();
this.$emit('refresh')
})
}
},
computed: {},
watch: {
formInfo(newVal) {
if (newVal && newVal instanceof Array) {
console.log(33, newVal)
this.table = this.headers = newVal.map((i) => {
return {
key: i.field,
title: i.name,
width: 200,
required: !!i.validation?.find(i => i === 'required'),
_params: i._params
};
});
}
},
},
};
</script>
<style scoped lang="scss">
.title {
font-size: 15px;
font-weight: 600;
padding: 8px 4px;
position: relative;
&::before {
content: '';
width: 4px;
background: $primaryColor;
position: absolute;
top: 8px;
bottom: 8px;
left: -8px;
}
}
</style>