|
|
|
|
@ -1,14 +1,24 @@ |
|
|
|
|
<template> |
|
|
|
|
<el-dialog :title="title" append-to-body :modelValue="importBox" width="555px" @close="closeDialog"> |
|
|
|
|
<avue-form :option="importOption" v-model="importForm" :upload-after="uploadAfter" |
|
|
|
|
:upload-error="uploadError"> |
|
|
|
|
<template #excelTemplate> |
|
|
|
|
<el-button type="primary" @click="handleTemplate"> |
|
|
|
|
点击下载<i class="el-icon-download el-icon--right"></i> |
|
|
|
|
</el-button> |
|
|
|
|
</template> |
|
|
|
|
</avue-form> |
|
|
|
|
</el-dialog> |
|
|
|
|
<el-dialog |
|
|
|
|
:title="title" |
|
|
|
|
append-to-body |
|
|
|
|
:modelValue="importBox" |
|
|
|
|
width="555px" |
|
|
|
|
@close="closeDialog" |
|
|
|
|
> |
|
|
|
|
<avue-form |
|
|
|
|
:option="importOption" |
|
|
|
|
v-model="importForm" |
|
|
|
|
:upload-after="uploadAfter" |
|
|
|
|
:upload-error="uploadError" |
|
|
|
|
> |
|
|
|
|
<template #excelTemplate> |
|
|
|
|
<el-button type="primary" @click="handleTemplate"> |
|
|
|
|
点击下载<i class="el-icon-download el-icon--right"></i> |
|
|
|
|
</el-button> |
|
|
|
|
</template> |
|
|
|
|
</avue-form> |
|
|
|
|
</el-dialog> |
|
|
|
|
</template> |
|
|
|
|
|
|
|
|
|
<script> |
|
|
|
|
@ -17,160 +27,171 @@ import website from '@/config/website'; |
|
|
|
|
import { getToken } from '@/utils/auth'; |
|
|
|
|
import { downloadXls } from '@/utils/util'; |
|
|
|
|
export default { |
|
|
|
|
props: { |
|
|
|
|
title:{ |
|
|
|
|
type:String, |
|
|
|
|
default:'导入' |
|
|
|
|
}, |
|
|
|
|
isShow:{ |
|
|
|
|
type:Boolean, |
|
|
|
|
default:false |
|
|
|
|
}, |
|
|
|
|
templateUrl:{ |
|
|
|
|
type:String, |
|
|
|
|
default:'' |
|
|
|
|
}, |
|
|
|
|
templateName:{ |
|
|
|
|
type:String, |
|
|
|
|
default:'模板' |
|
|
|
|
}, |
|
|
|
|
importUrl:{ |
|
|
|
|
type:String, |
|
|
|
|
default:'' |
|
|
|
|
}, |
|
|
|
|
showTips:{ |
|
|
|
|
type:String, |
|
|
|
|
default:'请上传 .xls,.xlsx 标准格式文件' |
|
|
|
|
} |
|
|
|
|
props: { |
|
|
|
|
title: { |
|
|
|
|
type: String, |
|
|
|
|
default: '导入', |
|
|
|
|
}, |
|
|
|
|
data(){ |
|
|
|
|
return{ |
|
|
|
|
importBox:false, |
|
|
|
|
importForm:{}, |
|
|
|
|
importOption:{ |
|
|
|
|
submitBtn: false, |
|
|
|
|
emptyBtn: false, |
|
|
|
|
column: [ |
|
|
|
|
{ |
|
|
|
|
label: '模板上传', |
|
|
|
|
prop: 'excelFile', |
|
|
|
|
type: 'upload', |
|
|
|
|
drag: true, |
|
|
|
|
loadText: '模板上传中,请稍等', |
|
|
|
|
span: 24, |
|
|
|
|
propsHttp: { |
|
|
|
|
res: 'data', |
|
|
|
|
}, |
|
|
|
|
tip: this.showTips, |
|
|
|
|
action: this.importUrl, |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
label: '模板下载', |
|
|
|
|
prop: 'excelTemplate', |
|
|
|
|
formslot: true, |
|
|
|
|
span: 24, |
|
|
|
|
}, |
|
|
|
|
], |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
isShow: { |
|
|
|
|
type: Boolean, |
|
|
|
|
default: false, |
|
|
|
|
}, |
|
|
|
|
watch: { |
|
|
|
|
isShow(newVal) { |
|
|
|
|
this.importBox = newVal; |
|
|
|
|
} |
|
|
|
|
templateUrl: { |
|
|
|
|
type: String, |
|
|
|
|
default: '', |
|
|
|
|
}, |
|
|
|
|
mounted(){ |
|
|
|
|
console.log('isShowImport=================',this.isShow) |
|
|
|
|
this.importBox = this.isShow |
|
|
|
|
templateName: { |
|
|
|
|
type: String, |
|
|
|
|
default: '模板', |
|
|
|
|
}, |
|
|
|
|
methods:{ |
|
|
|
|
closeDialog(val) { |
|
|
|
|
this.importBox = false; |
|
|
|
|
this.$emit('closeDialog',val); |
|
|
|
|
}, |
|
|
|
|
handleTemplate() { |
|
|
|
|
const url = `${this.templateUrl}?${this.website.tokenHeader}=${getToken()}`; |
|
|
|
|
console.log('下载模板URL:', url); |
|
|
|
|
console.log('模板文件名:', this.templateName); |
|
|
|
|
importUrl: { |
|
|
|
|
type: String, |
|
|
|
|
default: '', |
|
|
|
|
}, |
|
|
|
|
showTips: { |
|
|
|
|
type: String, |
|
|
|
|
default: '请上传 .xls,.xlsx 标准格式文件', |
|
|
|
|
}, |
|
|
|
|
basicImportSearch: { |
|
|
|
|
type: Object, |
|
|
|
|
default: () => {}, |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
data() { |
|
|
|
|
return { |
|
|
|
|
importBox: false, |
|
|
|
|
importForm: {}, |
|
|
|
|
importOption: { |
|
|
|
|
submitBtn: false, |
|
|
|
|
emptyBtn: false, |
|
|
|
|
column: [ |
|
|
|
|
{ |
|
|
|
|
label: '模板上传', |
|
|
|
|
prop: 'excelFile', |
|
|
|
|
type: 'upload', |
|
|
|
|
drag: true, |
|
|
|
|
loadText: '模板上传中,请稍等', |
|
|
|
|
span: 24, |
|
|
|
|
propsHttp: { |
|
|
|
|
res: 'data', |
|
|
|
|
}, |
|
|
|
|
// 传递参数 |
|
|
|
|
data: this.basicImportSearch, |
|
|
|
|
tip: this.showTips, |
|
|
|
|
action: this.importUrl, |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
label: '模板下载', |
|
|
|
|
prop: 'excelTemplate', |
|
|
|
|
formslot: true, |
|
|
|
|
span: 24, |
|
|
|
|
}, |
|
|
|
|
], |
|
|
|
|
}, |
|
|
|
|
}; |
|
|
|
|
}, |
|
|
|
|
watch: { |
|
|
|
|
isShow(newVal) { |
|
|
|
|
this.importBox = newVal; |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
mounted() { |
|
|
|
|
console.log('isShowImport=================', this.isShow); |
|
|
|
|
this.importBox = this.isShow; |
|
|
|
|
}, |
|
|
|
|
methods: { |
|
|
|
|
closeDialog(val) { |
|
|
|
|
this.importBox = false; |
|
|
|
|
this.$emit('closeDialog', val); |
|
|
|
|
}, |
|
|
|
|
handleTemplate() { |
|
|
|
|
const url = `${this.templateUrl}?${this.website.tokenHeader}=${getToken()}`; |
|
|
|
|
console.log('下载模板URL:', url); |
|
|
|
|
console.log('模板文件名:', this.templateName); |
|
|
|
|
|
|
|
|
|
exportBlob(url).then(res => { |
|
|
|
|
console.log('API返回状态:', res.status); |
|
|
|
|
console.log('res.data类型:', typeof res.data); |
|
|
|
|
console.log('res.data instanceof Blob:', res.data instanceof Blob); |
|
|
|
|
console.log('res.data size:', res.data?.size); |
|
|
|
|
console.log('res.data type:', res.data?.type); |
|
|
|
|
exportBlob(url) |
|
|
|
|
.then(res => { |
|
|
|
|
console.log('API返回状态:', res.status); |
|
|
|
|
console.log('res.data类型:', typeof res.data); |
|
|
|
|
console.log('res.data instanceof Blob:', res.data instanceof Blob); |
|
|
|
|
console.log('res.data size:', res.data?.size); |
|
|
|
|
console.log('res.data type:', res.data?.type); |
|
|
|
|
|
|
|
|
|
if (!res.data || res.data.size === 0) { |
|
|
|
|
this.$message.error('下载失败,文件内容为空'); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
if (!res.data || res.data.size === 0) { |
|
|
|
|
this.$message.error('下载失败,文件内容为空'); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 验证文件内容是否是有效的Excel文件 |
|
|
|
|
this.validateExcelBlob(res.data).then(isValid => { |
|
|
|
|
if (!isValid) { |
|
|
|
|
console.error('下载的文件不是有效的Excel文件'); |
|
|
|
|
this.$message.error('下载的文件格式不正确'); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
// 验证文件内容是否是有效的Excel文件 |
|
|
|
|
this.validateExcelBlob(res.data) |
|
|
|
|
.then(isValid => { |
|
|
|
|
if (!isValid) { |
|
|
|
|
console.error('下载的文件不是有效的Excel文件'); |
|
|
|
|
this.$message.error('下载的文件格式不正确'); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 确保文件名有正确的扩展名 |
|
|
|
|
let fileName = this.templateName; |
|
|
|
|
if (!fileName.endsWith('.xlsx') && !fileName.endsWith('.xls')) { |
|
|
|
|
fileName += '.xlsx'; |
|
|
|
|
} |
|
|
|
|
// 确保文件名有正确的扩展名 |
|
|
|
|
let fileName = this.templateName; |
|
|
|
|
if (!fileName.endsWith('.xlsx') && !fileName.endsWith('.xls')) { |
|
|
|
|
fileName += '.xlsx'; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
console.log('开始下载文件:', fileName); |
|
|
|
|
downloadXls(res.data, fileName); |
|
|
|
|
this.$message.success('模板下载成功'); |
|
|
|
|
}).catch(error => { |
|
|
|
|
console.error('验证文件失败:', error); |
|
|
|
|
// 即使验证失败也尝试下载 |
|
|
|
|
let fileName = this.templateName; |
|
|
|
|
if (!fileName.endsWith('.xlsx') && !fileName.endsWith('.xls')) { |
|
|
|
|
fileName += '.xlsx'; |
|
|
|
|
} |
|
|
|
|
downloadXls(res.data, fileName); |
|
|
|
|
this.$message.success('模板下载成功'); |
|
|
|
|
}); |
|
|
|
|
}).catch(error => { |
|
|
|
|
console.error('下载模板失败:', error); |
|
|
|
|
this.$message.error('下载失败,请检查网络或稍后重试'); |
|
|
|
|
console.log('开始下载文件:', fileName); |
|
|
|
|
downloadXls(res.data, fileName); |
|
|
|
|
this.$message.success('模板下载成功'); |
|
|
|
|
}) |
|
|
|
|
.catch(error => { |
|
|
|
|
console.error('验证文件失败:', error); |
|
|
|
|
// 即使验证失败也尝试下载 |
|
|
|
|
let fileName = this.templateName; |
|
|
|
|
if (!fileName.endsWith('.xlsx') && !fileName.endsWith('.xls')) { |
|
|
|
|
fileName += '.xlsx'; |
|
|
|
|
} |
|
|
|
|
downloadXls(res.data, fileName); |
|
|
|
|
this.$message.success('模板下载成功'); |
|
|
|
|
}); |
|
|
|
|
}, |
|
|
|
|
validateExcelBlob(blob) { |
|
|
|
|
return new Promise((resolve) => { |
|
|
|
|
const reader = new FileReader(); |
|
|
|
|
reader.onloadend = (e) => { |
|
|
|
|
const arr = new Uint8Array(e.target.result); |
|
|
|
|
const header = Array.from(arr.slice(0, 8)).map(b => b.toString(16).padStart(2, '0')).join(' '); |
|
|
|
|
console.log('文件头 (前8字节):', header); |
|
|
|
|
}) |
|
|
|
|
.catch(error => { |
|
|
|
|
console.error('下载模板失败:', error); |
|
|
|
|
this.$message.error('下载失败,请检查网络或稍后重试'); |
|
|
|
|
}); |
|
|
|
|
}, |
|
|
|
|
validateExcelBlob(blob) { |
|
|
|
|
return new Promise(resolve => { |
|
|
|
|
const reader = new FileReader(); |
|
|
|
|
reader.onloadend = e => { |
|
|
|
|
const arr = new Uint8Array(e.target.result); |
|
|
|
|
const header = Array.from(arr.slice(0, 8)) |
|
|
|
|
.map(b => b.toString(16).padStart(2, '0')) |
|
|
|
|
.join(' '); |
|
|
|
|
console.log('文件头 (前8字节):', header); |
|
|
|
|
|
|
|
|
|
// 检查XLSX (ZIP格式): 50 4B 03 04 |
|
|
|
|
const isXlsx = header.startsWith('50 4b 03 04'); |
|
|
|
|
// 检查XLS: D0 CF 11 E0 A1 B1 1A E1 |
|
|
|
|
const isXls = header.toLowerCase().startsWith('d0 cf 11 e0 a1 b1 1a e1'); |
|
|
|
|
// 检查XLSX (ZIP格式): 50 4B 03 04 |
|
|
|
|
const isXlsx = header.startsWith('50 4b 03 04'); |
|
|
|
|
// 检查XLS: D0 CF 11 E0 A1 B1 1A E1 |
|
|
|
|
const isXls = header.toLowerCase().startsWith('d0 cf 11 e0 a1 b1 1a e1'); |
|
|
|
|
|
|
|
|
|
console.log('是XLSX格式:', isXlsx); |
|
|
|
|
console.log('是XLS格式:', isXls); |
|
|
|
|
console.log('是XLSX格式:', isXlsx); |
|
|
|
|
console.log('是XLS格式:', isXls); |
|
|
|
|
|
|
|
|
|
resolve(isXlsx || isXls); |
|
|
|
|
}; |
|
|
|
|
reader.onerror = () => resolve(true); // 如果读取失败,假设文件是有效的 |
|
|
|
|
reader.readAsArrayBuffer(blob.slice(0, 8)); |
|
|
|
|
}); |
|
|
|
|
}, |
|
|
|
|
uploadAfter(res, done, loading, column) { |
|
|
|
|
this.closeDialog(true) |
|
|
|
|
done(); |
|
|
|
|
}, |
|
|
|
|
uploadError(error, column){ |
|
|
|
|
console.log('error-------------',error) |
|
|
|
|
this.closeDialog() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
resolve(isXlsx || isXls); |
|
|
|
|
}; |
|
|
|
|
reader.onerror = () => resolve(true); // 如果读取失败,假设文件是有效的 |
|
|
|
|
reader.readAsArrayBuffer(blob.slice(0, 8)); |
|
|
|
|
}); |
|
|
|
|
}, |
|
|
|
|
uploadAfter(res, done, loading, column) { |
|
|
|
|
this.closeDialog(true); |
|
|
|
|
done(); |
|
|
|
|
}, |
|
|
|
|
uploadError(error, column) { |
|
|
|
|
console.log('error-------------', error); |
|
|
|
|
this.closeDialog(); |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
}; |
|
|
|
|
</script> |
|
|
|
|
|
|
|
|
|
<style> |
|
|
|
|
|
|
|
|
|
</style> |