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.

297 lines
8.4 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 :visible.sync="dialogVisible" title="数据导入" width="740px" top="1vh">
<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,
course_id: course_id ? course_id : '',
...tableData
}" :headers="{
Authorization: `Bearer ${getToken()}`,
}" :on-success="uploadSuccess" :on-error="uploadFail" :file-list="fileList" accept=".xls, .xlsx">
<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 :height="350" :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 * as XLSX from "xlsx";
import {
saveAs
} from "file-saver";
import {
getToken
} from "@/utils/auth";
import {
imports
} from "@/api/system/baseForm";
import {
realTableShow
} from "@/api/system/customForm";
import request from '@/utils/request'
export default {
props: {
formInfo: {
type: Array,
default: () => [],
},
tableName: String,
course_id: String,
},
data() {
return {
action: `${process.env.VUE_APP_BASE_API}/api/admin/base-form/excel-show`,
import_action: '',
dialogVisible: false,
// 多个键值对目前keep_status
tableData: {},
headers: [],
tableList: [],
table: [],
fileList: []
};
},
methods: {
getToken,
show() {
this.dialogVisible = true;
},
hidden() {
this.dialogVisible = false;
},
// 获取表头
async getHeaders() {
let _except = []
// 学员去除一些信息
if (this.tableName === 'users') {
_except = ['plate', 'is_import', 'is_vip', 'is_schoolmate', 'appointment_total', 'letter', 'score', 'code',
'pid'
]
}
const res = await realTableShow({
table_name: this.tableName,
except: _except
})
let b = [];
for (let key in res) {
if (!this.base.isNull(res[key])) {
b.push({
key: key,
title: res[key],
width:120
});
}
}
// 课表
if (this.tableName === 'course_contents') {
b.push({
key: '',
title: '老师简介',
width:120
});
b.map(item => {
if (item.key === 'teacher_id') {
item.key = 'teacher_name'
}
})
}
// 考勤
if (this.tableName === 'course_keeps') {
b.map(item => {
if (item.key === 'user_id') {
item.key = 'user_name'
}
if (item.key === 'status') {
item.key = 'status_name'
}
})
}
// 学员 + 课程
if (this.tableName === 'users') {
b.unshift({
key: 'course_name',
title: '课程名字',
width:120
});
}
this.table = this.headers = b
},
//上传
uploadFail(err) {
console.log(err);
this.$message({
message: "上传失败",
type: "error",
});
},
uploadSuccess(response, file, fileList) {
console.log(response, file, fileList)
console.log("window.screen.height", window.screen.height)
if (response && response.hasOwnProperty("errcode")) {
this.$message({
message: response.errmsg || "上传失败",
type: "error",
duration: 2000,
offset: window.screen.height / 4
});
this.fileList = []
this.tableList = []
return
}
// 考勤导入
if (this.tableName === 'course_keeps') {
response.map(item => {
item.status_name = item.status === 1 ? '正常' : '缺勤'
})
}
// 学员导入
if (this.tableName === 'users') {
response.map(item => {
item.is_schoolmate = 1
})
}
this.tableList = response;
this.fileList = fileList
this.$message({
message: `上传成功`,
type: "success",
offset: window.screen.height / 2
});
},
exportExcel(sheetName) {
const data = [this.headers.map((header) => header.title)];
const wb = XLSX.utils.book_new();
const ws = XLSX.utils.aoa_to_sheet(data);
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() {
if(this.tableName=='users'){
this.tableList.map(item=>{
item.username = item.name
})
}
request({
method: "post",
url: this.import_action,
data: {
table_name: this.tableName,
course_id: this.course_id ? this.course_id : '',
data: this.tableList
}
}).then(res => {
console.log(res)
this.$message({
type: 'success',
message: `成功导入${res.total}`
})
this.hidden();
this.$emit('refresh')
})
}
},
computed: {},
watch: {
formInfo(newVal) {
console.log("formInfo", newVal)
if (newVal && newVal instanceof Array) {
this.table = this.headers = newVal.map((i) => {
return {
key: i.field,
title: i.name,
};
});
}
},
dialogVisible(newval) {
console.log("newval", newval, this.tableName, this.formInfo)
if (newval) {
let changeTableName = this.tableName.replace('_', '-')
this.action = `${process.env.VUE_APP_BASE_API}/api/admin/${changeTableName}/excel-show`
this.import_action = `/api/admin/${changeTableName}/import`
// 学员导入
if (this.tableName === 'users') {
this.import_action = `/api/admin/${changeTableName}/import-study`
}
// if(this.tableName==='users'){
// this.import_action = `/api/admin/${changeTableName}/import-study`
// this.table = this.headers = this.formInfo.map((i) => {
// if(i.prop){
// console.log("i.prop",i.prop)
// return {
// key: i.prop,
// title: i.label,
// };
// }
// });
// console.log("this.table",this.headers)
// }else{
this.getHeaders()
// }
console.log("action", this.action, this.import_action)
} else {
this.tableList = []
this.table = []
this.headers = []
this.tableData = []
this.fileList = []
}
}
},
};
</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>