3 changed files with 407 additions and 2 deletions
-
5src/api/warehouse/ifsInventoryInit.js
-
91src/views/modules/warehouse/ifsInventoryInit.vue
-
313src/views/modules/warehouse/ifsInventory_upload_excel.vue
@ -0,0 +1,313 @@ |
|||||
|
<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> |
||||
|
|
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue