From 8e70b5bb3765bb0b316f79631d8bf2dbba85e774 Mon Sep 17 00:00:00 2001 From: fengyuan_yang <1976974459@qq.com> Date: Mon, 13 Oct 2025 17:33:07 +0800 Subject: [PATCH] =?UTF-8?q?2025-10-13=20=E9=94=80=E5=94=AE=E5=8F=91?= =?UTF-8?q?=E8=B4=A7=E8=A3=85=E7=AE=B1=E6=96=B0=E5=A2=9E=E7=9B=92=E6=B8=85?= =?UTF-8?q?=E5=8D=95=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/boxManage/boxManage.js | 6 + src/views/modules/boxManage/saleBoxManage.vue | 391 +++++++++++++++++- 2 files changed, 392 insertions(+), 5 deletions(-) diff --git a/src/api/boxManage/boxManage.js b/src/api/boxManage/boxManage.js index 41ea4a3..0ff5b8d 100644 --- a/src/api/boxManage/boxManage.js +++ b/src/api/boxManage/boxManage.js @@ -10,3 +10,9 @@ export const updateBoxStatus= data => createAPI('/boxForNotification/updateBoxSt export const scanBoxRoll= data => createAPI('/boxForNotification/scanBoxRoll','post',data) export const deleteBoxRoll= data => createAPI('/boxForNotification/deleteBoxRoll','post',data) export const searchRollForOrderNo= data => createAPI('/boxForNotification/searchRollForOrderNo','post',data) + +// 盒清单相关接口 +export const searchSoReceiveCasesData = data => createAPI('/boxForNotification/searchSoReceiveCasesData','post',data) +export const deleteSoReceiveCasesData = data => createAPI('/boxForNotification/deleteSoReceiveCasesData','post',data) +export const validateAndScanCaseRoll = data => createAPI('/boxForNotification/validateAndScanCaseRoll','post',data) +export const saveCaseRollList = data => createAPI('/boxForNotification/saveCaseRollList','post',data) \ No newline at end of file diff --git a/src/views/modules/boxManage/saleBoxManage.vue b/src/views/modules/boxManage/saleBoxManage.vue index c2bd48c..97485ce 100644 --- a/src/views/modules/boxManage/saleBoxManage.vue +++ b/src/views/modules/boxManage/saleBoxManage.vue @@ -81,7 +81,7 @@ - + + + + 新增 + 删除 + + + + + + + + + + + + + + + + + + + + + + @@ -184,8 +254,87 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 应用 + 保存 + 关闭 + + @@ -200,7 +349,13 @@ import { getOutboundDetailWithRoll, searchOutboundNotification } from '../../../api/qc/outbound_notification' -import {searchRollForOrderNo} from '../../../api/boxManage/boxManage' +import { + searchRollForOrderNo, + searchSoReceiveCasesData, + deleteSoReceiveCasesData, + validateAndScanCaseRoll, + saveCaseRollList +} from '../../../api/boxManage/boxManage' export default { @@ -231,6 +386,24 @@ export default { detailList:[], dataListLoading: false, 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: [ { userId: this.$store.state.user.name, @@ -542,6 +715,9 @@ export default { if(this.activeName==='rollDetail'){ this.refreshRollsTable(); } + if(this.activeName==='cases'){ + this.refreshCasesTable(); + } }, async exportExcel() { this.searchData.limit = -1 @@ -587,6 +763,211 @@ export default { 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() { //查询报表的类型