|
|
<template> <div class="customer-css"> <el-dialog title="导入IFS库存数据" :close-on-click-modal="false" :visible.sync="visible" width="450px" class="customer-dialog" @close="handleDialogClose" :show-close="!uploading"> <el-form :inline="true" label-position="top" label-width="80px"> <el-row> <el-form-item label=" "> <el-button type="primary" icon="el-icon-download" :disabled="uploading" @click="downloadTemplate"> 下载 Excel 模板 </el-button> </el-form-item> </el-row> <el-row> <el-col :span="24"> <el-upload class="customer-upload" drag action="javascript:void(0);" ref="uploadFile" :limit="1" accept=".xlsx,.xls" :before-upload="beforeUploadHandle" :on-change="onChange" :auto-upload="false" :disabled="uploading" style="text-align: left;"> <i class="el-icon-upload"></i> <div class="el-upload__text"> {{ uploading ? '正在上传中,请稍候...' : '将文件拖到此处,或点击上传' }} </div> </el-upload> </el-col> </el-row> <el-row style="margin-top: 15px;"> <el-alert title="导入说明" type="info" :closable="false" show-icon> <div style="font-size: 12px; line-height: 1.8;"> 1. 请先下载模板,按模板格式填写数据<br/> 2. 必填字段:Site、Part No、Lot/Batch No、Location No、Qty On Hand<br/> 3. A-K列:库存信息(保存到inventory_stock_ifs表)<br/> 4. L-U列:料件属性信息(保存到part_attribute表,可选填)<br/> 5. 料件属性如已存在会自动跳过,不会报错<br/> 6. 日期格式:YYYY/M/D 或 YYYY-MM-DD </div> </el-alert> </el-row> </el-form> <span slot="footer" class="dialog-footer"> <el-button type="primary" @click="saveUploadFile" :loading="uploading" :disabled="uploading"> {{ uploading ? '上传中...' : '开始导入' }} </el-button> <el-button @click="closeDialog" :disabled="uploading">关闭</el-button> </span> </el-dialog> </div></template>
<script>import { uploadIfsInventoryExcel } from '@/api/warehouse/ifsInventoryInit.js'
export default { name: 'ifsInventoryUploadExcel', data() { return { visible: false, fileList: [], uploading: false // 上传状态标志
} }, methods: { /** * 初始化组件 */ init() { this.fileList = [] this.uploading = false this.visible = true },
/** * 上传之前的验证 */ beforeUploadHandle(file) { let extName = file.name.substring(file.name.lastIndexOf('.')).toLowerCase() if (!(extName === '.xlsx' || extName === '.xls')) { this.$message.error('数据导入失败,请选择正确的xlsx或xls格式的Excel文件') return false } return true },
/** * 选择上传文件时 */ onChange(file) { // 清空之前的文件列表,确保只有一个文件
this.fileList = [] this.fileList.push(file) },
/** * 关闭弹窗 */ closeDialog() { this.deleteFile() this.visible = false },
/** * 处理弹窗关闭事件(包括右上角X按钮) */ handleDialogClose() { if (this.uploading) { this.$message.warning('正在上传中,请稍候...') return } this.deleteFile() },
/** * 清除文件 */ deleteFile() { this.fileList = [] this.uploading = false // 清空文件上传记录
this.$refs.uploadFile.clearFiles() // 刷新父页面
this.$emit('refreshTable') },
/** * 格式化错误信息为HTML列表 */ formatErrorMessages(errorMessages) { if (!errorMessages || errorMessages.length === 0) { return '' }
// 限制显示的错误数量(前20条)
const displayMessages = errorMessages.slice(0, 20) const hasMore = errorMessages.length > 20
let html = '<div style="text-align: left; max-height: 400px; overflow-y: auto;">' html += '<p style="color: #E6A23C; font-weight: bold; margin-bottom: 10px;">以下数据导入失败:</p>' html += '<ol style="padding-left: 20px; line-height: 1.8;">'
displayMessages.forEach(msg => { html += `<li style="color: #F56C6C; margin-bottom: 5px;">${msg}</li>` })
html += '</ol>'
if (hasMore) { html += `<p style="color: #909399; margin-top: 10px;">...还有 ${errorMessages.length - 20} 条错误</p>` }
html += '</div>'
return html },
/** * 下载Excel模板 */ downloadTemplate() { const loading = this.$loading({ lock: true, text: '正在下载模板...', spinner: 'el-icon-loading', background: 'rgba(0, 0, 0, 0.7)' })
this.$http({ url: this.$http.adornUrl('/ifsInventoryInit/downloadTemplate'), method: 'get', responseType: 'blob' }).then(response => { loading.close() // 创建下载链接
const blob = new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }) const url = window.URL.createObjectURL(blob) const link = document.createElement('a') link.href = url link.download = 'IFS库存导入模板.xlsx' document.body.appendChild(link) link.click() document.body.removeChild(link) window.URL.revokeObjectURL(url) this.$message.success('模板下载成功') }).catch(error => { loading.close() console.error('模板下载失败:', error) this.$message.error('模板下载失败,请联系管理员') }) },
/** * 保存上传文件 */ saveUploadFile() { // 判断文件是否上传
if (null == this.fileList || 0 === this.fileList.length) { this.$message.error("请先选择要上传的Excel文件!") return false }
// 再次校验文件格式
const file = this.fileList[0].raw const fileName = file.name const fileExtension = fileName.substring(fileName.lastIndexOf('.')).toLowerCase()
if (!('.xls' === fileExtension || '.xlsx' === fileExtension)) { this.$message.error('文件格式不正确,只支持.xls和.xlsx格式的Excel文件') return false }
// 设置上传状态
this.uploading = true
// 创建FormData对象
const formData = new FormData() formData.append("file", file) formData.append("site", localStorage.getItem('site')) formData.append("uploadBy", this.$store.state.user.name)
// 调用上传接口
uploadIfsInventoryExcel(formData).then(({ data }) => { if (data.code === 0) { // 检查是否有错误信息
const errorMessages = data.errorMessages || []
if (errorMessages.length > 0) { // 有错误信息,使用弹窗显示详细错误列表
const errorHtml = this.formatErrorMessages(errorMessages) this.$alert(errorHtml, '导入完成(部分数据失败)', { confirmButtonText: '确定', dangerouslyUseHTMLString: true, customClass: 'import-error-dialog' }).then(() => { // 关闭窗口并刷新页面
this.closeDialog() }) } else { // 完全成功,显示成功提示
this.$message({ message: data.msg || 'IFS库存数据导入成功', type: 'success', duration: 2000 }) // 关闭窗口并刷新页面
this.closeDialog() } } else { this.$alert(data.msg, '错误', { confirmButtonText: '确定' }) } }).catch(error => { console.error('Excel上传异常:', error) this.$message.error('Excel文件上传异常,请检查文件格式和内容') }).finally(() => { // 无论成功还是失败,都重置上传状态
this.uploading = false }) } }}</script>
<style scoped>.customer-css .customer-upload { width: 100%;}
.customer-css .el-upload { width: 100%;}
.customer-css .el-upload-dragger { width: 100%;}</style>
<style>/* 导入错误弹窗样式 */.import-error-dialog { width: 600px !important;}
.import-error-dialog .el-message-box__message { max-height: 500px; overflow-y: auto;}</style>
|