|
|
@ -81,7 +81,7 @@ |
|
|
<el-tab-pane label="出库单明细" name="outboundDetail"> |
|
|
<el-tab-pane label="出库单明细" name="outboundDetail"> |
|
|
<el-table |
|
|
<el-table |
|
|
:data="detailList" |
|
|
:data="detailList" |
|
|
:height="height - 20" |
|
|
|
|
|
|
|
|
:height="height - 8" |
|
|
border |
|
|
border |
|
|
style="width: 100%;"> |
|
|
style="width: 100%;"> |
|
|
<el-table-column |
|
|
<el-table-column |
|
|
@ -101,7 +101,77 @@ |
|
|
</el-table-column> |
|
|
</el-table-column> |
|
|
</el-table> |
|
|
</el-table> |
|
|
</el-tab-pane> |
|
|
</el-tab-pane> |
|
|
<el-tab-pane label="装箱清单" name="boxing" style=""> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<el-tab-pane label="盒清单" name="cases"> |
|
|
|
|
|
<el-form label-position="top" style="margin-left: 2px;"> |
|
|
|
|
|
<el-button type="primary" size="small" @click="openCaseDialog">新增</el-button> |
|
|
|
|
|
<el-button type="danger" size="small" @click="deleteCaseRecord">删除</el-button> |
|
|
|
|
|
</el-form> |
|
|
|
|
|
<el-table |
|
|
|
|
|
ref="caseTable" |
|
|
|
|
|
:data="casesList" |
|
|
|
|
|
:height="height - 30" |
|
|
|
|
|
border |
|
|
|
|
|
@selection-change="handleCaseSelectionChange" |
|
|
|
|
|
style="width: 100%;"> |
|
|
|
|
|
<el-table-column |
|
|
|
|
|
type="selection" |
|
|
|
|
|
width="55" |
|
|
|
|
|
align="center"> |
|
|
|
|
|
</el-table-column> |
|
|
|
|
|
<el-table-column |
|
|
|
|
|
prop="casesNo" |
|
|
|
|
|
header-align="center" |
|
|
|
|
|
align="center" |
|
|
|
|
|
min-width="120" |
|
|
|
|
|
label="盒标签"> |
|
|
|
|
|
</el-table-column> |
|
|
|
|
|
<el-table-column |
|
|
|
|
|
prop="rollNo" |
|
|
|
|
|
header-align="center" |
|
|
|
|
|
align="center" |
|
|
|
|
|
min-width="120" |
|
|
|
|
|
label="卷标签"> |
|
|
|
|
|
</el-table-column> |
|
|
|
|
|
<el-table-column |
|
|
|
|
|
prop="rollQty" |
|
|
|
|
|
header-align="center" |
|
|
|
|
|
align="right" |
|
|
|
|
|
min-width="100" |
|
|
|
|
|
label="卷数量"> |
|
|
|
|
|
</el-table-column> |
|
|
|
|
|
<el-table-column |
|
|
|
|
|
prop="partNo" |
|
|
|
|
|
header-align="center" |
|
|
|
|
|
align="left" |
|
|
|
|
|
min-width="120" |
|
|
|
|
|
label="物料编码"> |
|
|
|
|
|
</el-table-column> |
|
|
|
|
|
<el-table-column |
|
|
|
|
|
prop="partDesc" |
|
|
|
|
|
header-align="center" |
|
|
|
|
|
align="left" |
|
|
|
|
|
min-width="200" |
|
|
|
|
|
label="物料名称"> |
|
|
|
|
|
</el-table-column> |
|
|
|
|
|
<el-table-column |
|
|
|
|
|
prop="createDate" |
|
|
|
|
|
header-align="center" |
|
|
|
|
|
align="center" |
|
|
|
|
|
min-width="160" |
|
|
|
|
|
label="创建时间"> |
|
|
|
|
|
</el-table-column> |
|
|
|
|
|
<el-table-column |
|
|
|
|
|
prop="createBy" |
|
|
|
|
|
header-align="center" |
|
|
|
|
|
align="center" |
|
|
|
|
|
min-width="100" |
|
|
|
|
|
label="创建人"> |
|
|
|
|
|
</el-table-column> |
|
|
|
|
|
</el-table> |
|
|
|
|
|
</el-tab-pane> |
|
|
|
|
|
|
|
|
|
|
|
<el-tab-pane label="箱清单" name="boxing"> |
|
|
<boxing ref="boxing"></boxing> |
|
|
<boxing ref="boxing"></boxing> |
|
|
</el-tab-pane> |
|
|
</el-tab-pane> |
|
|
<el-tab-pane label="已扫描卷" name="rollDetail"> |
|
|
<el-tab-pane label="已扫描卷" name="rollDetail"> |
|
|
@ -184,8 +254,87 @@ |
|
|
</el-tab-pane> |
|
|
</el-tab-pane> |
|
|
</el-tabs> |
|
|
</el-tabs> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 盒清单新增对话框 --> |
|
|
|
|
|
<el-dialog title="装盒扫描" :visible.sync="caseDialogVisible" width="70%" :close-on-click-modal="false" @close="closeCaseDialog"> |
|
|
|
|
|
<el-form :inline="true" label-position="top" style="margin-left: 7px;margin-top: -5px;"> |
|
|
|
|
|
<el-form-item label="盒标签"> |
|
|
|
|
|
<el-input ref="caseNoInput" v-model="caseForm.casesNo" @keyup.enter.native="focusRollNoInput" placeholder="请扫描盒标签" style="width: 200px"></el-input> |
|
|
|
|
|
</el-form-item> |
|
|
|
|
|
<el-form-item label="卷标签"> |
|
|
|
|
|
<el-input ref="rollNoInput" v-model="caseForm.rollNo" @keyup.enter.native="scanCaseRoll" placeholder="请扫描卷标签" style="width: 200px"></el-input> |
|
|
|
|
|
</el-form-item> |
|
|
|
|
|
<el-form-item label="盒数量"> |
|
|
|
|
|
<el-input v-model="caseStatistics.casesCount" readonly style="width: 100px"></el-input> |
|
|
|
|
|
</el-form-item> |
|
|
|
|
|
<el-form-item label="卷数量"> |
|
|
|
|
|
<el-input v-model="caseStatistics.rollCount" readonly style="width: 100px"></el-input> |
|
|
|
|
|
</el-form-item> |
|
|
|
|
|
<el-form-item label="物料总数"> |
|
|
|
|
|
<el-input v-model="caseStatistics.totalQty" readonly style="width: 100px"></el-input> |
|
|
|
|
|
</el-form-item> |
|
|
|
|
|
</el-form> |
|
|
|
|
|
<!-- 中部分:扫描列表 --> |
|
|
|
|
|
<el-table |
|
|
|
|
|
:data="caseRollList" |
|
|
|
|
|
border |
|
|
|
|
|
height="300" |
|
|
|
|
|
style="width: 100%; margin-top: 10px;"> |
|
|
|
|
|
<el-table-column |
|
|
|
|
|
type="index" |
|
|
|
|
|
label="序号" |
|
|
|
|
|
width="50" |
|
|
|
|
|
header-align="center" |
|
|
|
|
|
align="right"> |
|
|
|
|
|
</el-table-column> |
|
|
|
|
|
<el-table-column |
|
|
|
|
|
prop="casesNo" |
|
|
|
|
|
label="盒标签" |
|
|
|
|
|
min-width="120" |
|
|
|
|
|
header-align="center" |
|
|
|
|
|
align="left"> |
|
|
|
|
|
</el-table-column> |
|
|
|
|
|
<el-table-column |
|
|
|
|
|
prop="rollNo" |
|
|
|
|
|
label="卷标签" |
|
|
|
|
|
min-width="120" |
|
|
|
|
|
header-align="center" |
|
|
|
|
|
align="left"> |
|
|
|
|
|
</el-table-column> |
|
|
|
|
|
<el-table-column |
|
|
|
|
|
prop="rollQty" |
|
|
|
|
|
label="卷数量" |
|
|
|
|
|
min-width="100" |
|
|
|
|
|
header-align="center" |
|
|
|
|
|
align="right"> |
|
|
|
|
|
</el-table-column> |
|
|
|
|
|
<el-table-column |
|
|
|
|
|
prop="partNo" |
|
|
|
|
|
label="物料编码" |
|
|
|
|
|
min-width="120" |
|
|
|
|
|
header-align="center" |
|
|
|
|
|
align="left"> |
|
|
|
|
|
</el-table-column> |
|
|
|
|
|
<el-table-column |
|
|
|
|
|
prop="partDesc" |
|
|
|
|
|
label="物料名称" |
|
|
|
|
|
min-width="200" |
|
|
|
|
|
header-align="center" |
|
|
|
|
|
align="left"> |
|
|
|
|
|
</el-table-column> |
|
|
|
|
|
<el-table-column |
|
|
|
|
|
prop="batchNo" |
|
|
|
|
|
label="合约号" |
|
|
|
|
|
min-width="120" |
|
|
|
|
|
header-align="center" |
|
|
|
|
|
align="left"> |
|
|
|
|
|
</el-table-column> |
|
|
|
|
|
</el-table> |
|
|
|
|
|
<el-footer style="height:35px;margin-top: 15px;text-align:center"> |
|
|
|
|
|
<el-button type="primary" @click="applyCaseScan">应用</el-button> |
|
|
|
|
|
<el-button type="success" @click="saveCaseScan">保存</el-button> |
|
|
|
|
|
<el-button @click="closeCaseDialog">关闭</el-button> |
|
|
|
|
|
</el-footer> |
|
|
|
|
|
</el-dialog> |
|
|
|
|
|
|
|
|
</div> |
|
|
</div> |
|
|
</template> |
|
|
</template> |
|
|
@ -200,7 +349,13 @@ import { |
|
|
getOutboundDetailWithRoll, |
|
|
getOutboundDetailWithRoll, |
|
|
searchOutboundNotification |
|
|
searchOutboundNotification |
|
|
} from '../../../api/qc/outbound_notification' |
|
|
} from '../../../api/qc/outbound_notification' |
|
|
import {searchRollForOrderNo} from '../../../api/boxManage/boxManage' |
|
|
|
|
|
|
|
|
import { |
|
|
|
|
|
searchRollForOrderNo, |
|
|
|
|
|
searchSoReceiveCasesData, |
|
|
|
|
|
deleteSoReceiveCasesData, |
|
|
|
|
|
validateAndScanCaseRoll, |
|
|
|
|
|
saveCaseRollList |
|
|
|
|
|
} from '../../../api/boxManage/boxManage' |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export default { |
|
|
export default { |
|
|
@ -231,6 +386,24 @@ export default { |
|
|
detailList:[], |
|
|
detailList:[], |
|
|
dataListLoading: false, |
|
|
dataListLoading: false, |
|
|
activeName: 'outboundDetail', |
|
|
activeName: 'outboundDetail', |
|
|
|
|
|
// 盒清单相关数据 |
|
|
|
|
|
casesList: [], |
|
|
|
|
|
caseDialogVisible: false, |
|
|
|
|
|
caseForm: { |
|
|
|
|
|
casesNo: '', |
|
|
|
|
|
rollNo: '', |
|
|
|
|
|
site: this.$store.state.user.site, |
|
|
|
|
|
buNo: '', |
|
|
|
|
|
notifyNo: '', |
|
|
|
|
|
partNo: '' |
|
|
|
|
|
}, |
|
|
|
|
|
caseRollList: [], |
|
|
|
|
|
caseStatistics: { |
|
|
|
|
|
casesCount: 0, |
|
|
|
|
|
rollCount: 0, |
|
|
|
|
|
totalQty: 0 |
|
|
|
|
|
}, |
|
|
|
|
|
selectedCaseRecords: [], |
|
|
columnArray1: [ |
|
|
columnArray1: [ |
|
|
{ |
|
|
{ |
|
|
userId: this.$store.state.user.name, |
|
|
userId: this.$store.state.user.name, |
|
|
@ -542,6 +715,9 @@ export default { |
|
|
if(this.activeName==='rollDetail'){ |
|
|
if(this.activeName==='rollDetail'){ |
|
|
this.refreshRollsTable(); |
|
|
this.refreshRollsTable(); |
|
|
} |
|
|
} |
|
|
|
|
|
if(this.activeName==='cases'){ |
|
|
|
|
|
this.refreshCasesTable(); |
|
|
|
|
|
} |
|
|
}, |
|
|
}, |
|
|
async exportExcel() { |
|
|
async exportExcel() { |
|
|
this.searchData.limit = -1 |
|
|
this.searchData.limit = -1 |
|
|
@ -587,6 +763,211 @@ export default { |
|
|
this.rollList = data.rows |
|
|
this.rollList = data.rows |
|
|
}) |
|
|
}) |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
// ===== 盒清单相关方法 ===== |
|
|
|
|
|
refreshCasesTable(){ |
|
|
|
|
|
let templateData = { |
|
|
|
|
|
site: this.currentRow.site, |
|
|
|
|
|
buNo: this.currentRow.buNo, |
|
|
|
|
|
notifyNo: this.currentRow.orderNo, |
|
|
|
|
|
} |
|
|
|
|
|
searchSoReceiveCasesData(templateData).then(({data}) => { |
|
|
|
|
|
this.casesList = data.rows || [] |
|
|
|
|
|
}) |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
openCaseDialog(){ |
|
|
|
|
|
if(!this.currentRow || !this.currentRow.orderNo){ |
|
|
|
|
|
this.$message.warning('请先选择一条出库单记录') |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
this.caseDialogVisible = true |
|
|
|
|
|
this.resetCaseForm() |
|
|
|
|
|
// 对话框打开后自动聚焦到盒标签输入框 |
|
|
|
|
|
this.$nextTick(() => { |
|
|
|
|
|
this.$refs.caseNoInput.focus() |
|
|
|
|
|
}) |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
resetCaseForm(){ |
|
|
|
|
|
this.caseForm = { |
|
|
|
|
|
casesNo: '', |
|
|
|
|
|
rollNo: '', |
|
|
|
|
|
site: this.currentRow.site, |
|
|
|
|
|
buNo: this.currentRow.buNo, |
|
|
|
|
|
notifyNo: this.currentRow.orderNo, |
|
|
|
|
|
partNo: '' |
|
|
|
|
|
} |
|
|
|
|
|
this.caseRollList = [] |
|
|
|
|
|
this.updateCaseStatistics() |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
focusRollNoInput(){ |
|
|
|
|
|
if(!this.caseForm.casesNo){ |
|
|
|
|
|
this.$message.warning('请先扫描盒标签') |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
this.$refs.rollNoInput.focus() |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
async scanCaseRoll(){ |
|
|
|
|
|
// 校验必填项 |
|
|
|
|
|
if(!this.caseForm.casesNo){ |
|
|
|
|
|
this.$message.warning('请先扫描盒标签') |
|
|
|
|
|
this.$refs.caseNoInput.focus() |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
if(!this.caseForm.rollNo){ |
|
|
|
|
|
this.$message.warning('请扫描卷标签') |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 尝试从所有出库单明细中匹配物料编码 |
|
|
|
|
|
// 这里我们传入所有可能的物料编码,让后端根据卷号自动匹配 |
|
|
|
|
|
let partNo = '' |
|
|
|
|
|
if(this.detailList && this.detailList.length > 0){ |
|
|
|
|
|
// 先尝试第一个物料编码 |
|
|
|
|
|
partNo = this.detailList[0].partNo |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
this.caseForm.partNo = partNo |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
const {data} = await validateAndScanCaseRoll(this.caseForm) |
|
|
|
|
|
if(data && data.code === 0 && data.rollInfo){ |
|
|
|
|
|
// 校验通过,将卷信息添加到列表最前面(后扫描的在上面) |
|
|
|
|
|
this.caseRollList.unshift({ |
|
|
|
|
|
casesNo: this.caseForm.casesNo, |
|
|
|
|
|
rollNo: data.rollInfo.rollNo, |
|
|
|
|
|
rollQty: data.rollInfo.rollQty, |
|
|
|
|
|
partNo: data.rollInfo.partNo, |
|
|
|
|
|
partDesc: data.rollInfo.partDesc, |
|
|
|
|
|
batchNo: data.rollInfo.batchNo, |
|
|
|
|
|
notifyNo: this.caseForm.notifyNo, |
|
|
|
|
|
site: this.caseForm.site, |
|
|
|
|
|
buNo: this.caseForm.buNo |
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
// 更新统计信息 |
|
|
|
|
|
this.updateCaseStatistics() |
|
|
|
|
|
|
|
|
|
|
|
// 重置两个输入框,准备下一次扫描 |
|
|
|
|
|
this.caseForm.casesNo = '' |
|
|
|
|
|
this.caseForm.rollNo = '' |
|
|
|
|
|
|
|
|
|
|
|
// 光标回到盒标签输入框,继续按照规定顺序扫描 |
|
|
|
|
|
this.$nextTick(() => { |
|
|
|
|
|
this.$refs.caseNoInput.focus() |
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
this.$message.success('扫描成功') |
|
|
|
|
|
} else { |
|
|
|
|
|
this.$message.error(data.msg || '扫描失败') |
|
|
|
|
|
} |
|
|
|
|
|
} catch (error) { |
|
|
|
|
|
this.$message.error(error.msg || '扫描失败,请检查') |
|
|
|
|
|
// 清空卷标签输入框 |
|
|
|
|
|
this.caseForm.rollNo = '' |
|
|
|
|
|
this.$refs.rollNoInput.focus() |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
updateCaseStatistics(){ |
|
|
|
|
|
// 盒数量 = 去重的盒标签数量 |
|
|
|
|
|
const uniqueCases = new Set(this.caseRollList.map(item => item.casesNo)) |
|
|
|
|
|
this.caseStatistics.casesCount = uniqueCases.size |
|
|
|
|
|
|
|
|
|
|
|
// 卷数量 = 列表行数 |
|
|
|
|
|
this.caseStatistics.rollCount = this.caseRollList.length |
|
|
|
|
|
|
|
|
|
|
|
// 物料总数 = 所有行的卷数量求和 |
|
|
|
|
|
this.caseStatistics.totalQty = this.caseRollList.reduce((sum, item) => { |
|
|
|
|
|
return sum + (parseFloat(item.rollQty) || 0) |
|
|
|
|
|
}, 0) |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
applyCaseScan(){ |
|
|
|
|
|
if(this.caseRollList.length === 0){ |
|
|
|
|
|
this.$message.warning('请先扫描卷标签') |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 应用:保存但不关闭对话框,重置输入框、计数和列表 |
|
|
|
|
|
this.saveCaseData(false) |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
saveCaseScan(){ |
|
|
|
|
|
if(this.caseRollList.length === 0){ |
|
|
|
|
|
this.$message.warning('请先扫描卷标签') |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 保存:保存后关闭对话框 |
|
|
|
|
|
this.saveCaseData(true) |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
async saveCaseData(closeDialog){ |
|
|
|
|
|
try { |
|
|
|
|
|
const {data} = await saveCaseRollList(this.caseRollList) |
|
|
|
|
|
if(data && data.code === 0){ |
|
|
|
|
|
this.$message.success('保存成功') |
|
|
|
|
|
|
|
|
|
|
|
if(closeDialog){ |
|
|
|
|
|
// 关闭对话框 |
|
|
|
|
|
this.closeCaseDialog() |
|
|
|
|
|
} else { |
|
|
|
|
|
// 应用:重置表单继续扫描 |
|
|
|
|
|
this.resetCaseForm() |
|
|
|
|
|
this.$nextTick(() => { |
|
|
|
|
|
this.$refs.caseNoInput.focus() |
|
|
|
|
|
}) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 刷新盒清单列表 |
|
|
|
|
|
this.refreshCasesTable() |
|
|
|
|
|
} else { |
|
|
|
|
|
this.$message.error(data.msg || '保存失败') |
|
|
|
|
|
} |
|
|
|
|
|
} catch (error) { |
|
|
|
|
|
this.$message.error(error.msg || '保存失败') |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
closeCaseDialog(){ |
|
|
|
|
|
this.caseDialogVisible = false |
|
|
|
|
|
this.resetCaseForm() |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
handleCaseSelectionChange(selection){ |
|
|
|
|
|
this.selectedCaseRecords = selection |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
async deleteCaseRecord(){ |
|
|
|
|
|
if(this.selectedCaseRecords.length === 0){ |
|
|
|
|
|
this.$message.warning('请先选择要删除的记录') |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
this.$confirm('确定删除选中的记录吗?删除后将恢复库存卷的装盒状态', '提示', { |
|
|
|
|
|
confirmButtonText: '确定', |
|
|
|
|
|
cancelButtonText: '取消', |
|
|
|
|
|
type: 'warning' |
|
|
|
|
|
}).then(async () => { |
|
|
|
|
|
try { |
|
|
|
|
|
for(let record of this.selectedCaseRecords){ |
|
|
|
|
|
await deleteSoReceiveCasesData({ |
|
|
|
|
|
id: record.id, |
|
|
|
|
|
site: record.site, |
|
|
|
|
|
buNo: record.buNo |
|
|
|
|
|
}) |
|
|
|
|
|
} |
|
|
|
|
|
this.$message.success('删除成功') |
|
|
|
|
|
this.refreshCasesTable() |
|
|
|
|
|
} catch (error) { |
|
|
|
|
|
this.$message.error(error.msg || '删除失败') |
|
|
|
|
|
} |
|
|
|
|
|
}).catch(() => {}) |
|
|
|
|
|
}, |
|
|
}, |
|
|
}, |
|
|
created() { |
|
|
created() { |
|
|
//查询报表的类型 |
|
|
//查询报表的类型 |
|
|
|