3 changed files with 407 additions and 2 deletions
-
3src/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