|
|
|
@ -343,18 +343,18 @@ |
|
|
|
<el-form label-position="top" class="box-info-form"> |
|
|
|
<el-row :gutter="20"> |
|
|
|
<el-col :span="8"> |
|
|
|
<el-form-item label="毛重"> |
|
|
|
<el-input v-model="palletModelData.grossWeight" type="number" placeholder="请输入毛重"></el-input> |
|
|
|
<el-form-item label="箱数"> |
|
|
|
<el-input v-model="palletModelData.boxQty" type="number" placeholder="请输入箱数" @input="calculateWeightsByBoxQty"></el-input> |
|
|
|
</el-form-item> |
|
|
|
</el-col> |
|
|
|
<el-col :span="8"> |
|
|
|
<el-form-item label="净重"> |
|
|
|
<el-input v-model="palletModelData.netWeight" type="number" placeholder="请输入净重"></el-input> |
|
|
|
<el-form-item label="毛重"> |
|
|
|
<el-input v-model="palletModelData.grossWeight" type="number" placeholder="自动计算"></el-input> |
|
|
|
</el-form-item> |
|
|
|
</el-col> |
|
|
|
<el-col :span="8"> |
|
|
|
<el-form-item label="箱数"> |
|
|
|
<el-input v-model="palletModelData.boxQty" type="number" placeholder="请输入箱数"></el-input> |
|
|
|
<el-form-item label="净重"> |
|
|
|
<el-input v-model="palletModelData.netWeight" type="number" placeholder="自动计算"></el-input> |
|
|
|
</el-form-item> |
|
|
|
</el-col> |
|
|
|
</el-row> |
|
|
|
@ -380,12 +380,12 @@ |
|
|
|
<el-table-column prop="surplusQty" label="可装箱数量" align="right" width="80"></el-table-column> |
|
|
|
<el-table-column label="装箱数量" align="center" width="80"> |
|
|
|
<template slot-scope="scope"> |
|
|
|
<el-input v-model.number="scope.row.useQty" type="number" :min="0" :max="999999" size="mini"></el-input> |
|
|
|
<el-input v-model.number="scope.row.useQty" type="number" :min="0" :max="999999" size="mini" @input="calculateRolls(scope.row)"></el-input> |
|
|
|
</template> |
|
|
|
</el-table-column> |
|
|
|
<el-table-column label="Rolls" align="center" width="80"> |
|
|
|
<template slot-scope="scope"> |
|
|
|
<el-input v-model.number="scope.row.rolls" type="number" :min="0" :max="999999" size="mini"></el-input> |
|
|
|
<el-input v-model.number="scope.row.rolls" type="number" :min="0" :max="999999" size="mini" placeholder="自动计算"></el-input> |
|
|
|
</template> |
|
|
|
</el-table-column> |
|
|
|
<el-table-column label="操作" align="center" width="70"> |
|
|
|
@ -627,7 +627,8 @@ |
|
|
|
getNotifyPartDetail, |
|
|
|
searchPalletList, |
|
|
|
updateExportFlag, |
|
|
|
updateCodelPalletHeaderPalletQty |
|
|
|
updateCodelPalletHeaderPalletQty, |
|
|
|
getPartPackageProperties |
|
|
|
}from "@/api/ecss/ecss.js" |
|
|
|
import {getBuList}from '@/api/factory/site.js' |
|
|
|
import excel from "@/utils/excel-util.js"; |
|
|
|
@ -2322,6 +2323,231 @@ |
|
|
|
}, |
|
|
|
fillUseQty(row) { |
|
|
|
row.useQty = row.surplusQty || 0; |
|
|
|
// 全数装箱后也需要计算rolls |
|
|
|
this.calculateRolls(row); |
|
|
|
}, |
|
|
|
/** |
|
|
|
* 根据装箱数量自动计算Rolls(卷数) |
|
|
|
* 计算公式:Rolls = 装箱数量 / 每卷数量 |
|
|
|
* @param row 当前行数据 |
|
|
|
*/ |
|
|
|
calculateRolls(row) { |
|
|
|
// 如果装箱数量为空或为0,清空rolls |
|
|
|
if (!row.useQty || row.useQty <= 0) { |
|
|
|
this.$set(row, 'rolls', null); |
|
|
|
// 装箱数量变化后,重新计算总箱数和重量 |
|
|
|
this.calculateTotalBoxQtyAndWeights(); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// 如果已经有缓存的每卷数量,直接计算 |
|
|
|
if (row.rollQtyCache && row.rollQtyCache > 0) { |
|
|
|
const rolls = row.useQty / row.rollQtyCache; |
|
|
|
this.$set(row, 'rolls', parseFloat(rolls.toFixed(4))); |
|
|
|
// 装箱数量变化后,重新计算总箱数和重量 |
|
|
|
this.calculateTotalBoxQtyAndWeights(); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// 调用后端API获取每卷数量 |
|
|
|
const params = { |
|
|
|
site: this.currentRow.site, |
|
|
|
buNo: this.currentRow.buNo, |
|
|
|
partNo: row.partNo |
|
|
|
}; |
|
|
|
|
|
|
|
getPartPackageProperties(params).then(({data}) => { |
|
|
|
if (data && data.code === 0 && data.data) { |
|
|
|
const rollQty = data.data.rollQty; |
|
|
|
|
|
|
|
if (rollQty && rollQty > 0) { |
|
|
|
// 缓存每卷数量到row中,避免重复请求 |
|
|
|
this.$set(row, 'rollQtyCache', rollQty); |
|
|
|
this.$set(row, 'boxRollsCache', data.data.boxRolls); |
|
|
|
this.$set(row, 'boxWeightCache', data.data.boxWeight); |
|
|
|
|
|
|
|
// 计算rolls:装箱数量 / 每卷数量 |
|
|
|
const rolls = row.useQty / rollQty; |
|
|
|
this.$set(row, 'rolls', parseFloat(rolls.toFixed(4))); |
|
|
|
|
|
|
|
// 装箱数量变化后,重新计算总箱数和重量 |
|
|
|
this.calculateTotalBoxQtyAndWeights(); |
|
|
|
} else { |
|
|
|
this.$message.warning(`物料 ${row.partNo} 未配置每卷数量(ROLLQTY)属性,无法自动计算Rolls`); |
|
|
|
this.$set(row, 'rolls', null); |
|
|
|
} |
|
|
|
} else { |
|
|
|
console.error('获取物料包装属性失败:', data ? data.msg : '未知错误'); |
|
|
|
// 失败时不阻断用户操作,允许手动输入 |
|
|
|
this.$set(row, 'rolls', null); |
|
|
|
} |
|
|
|
}).catch(error => { |
|
|
|
console.error('获取物料包装属性异常:', error); |
|
|
|
// 异常时不阻断用户操作,允许手动输入 |
|
|
|
this.$set(row, 'rolls', null); |
|
|
|
}); |
|
|
|
}, |
|
|
|
/** |
|
|
|
* 根据物料装箱数量自动计算总箱数、毛重和净重 |
|
|
|
*/ |
|
|
|
calculateTotalBoxQtyAndWeights() { |
|
|
|
// 获取有装箱数量的物料列表 |
|
|
|
const selectedRows = this.dataList8.filter(item => item.useQty && item.useQty > 0); |
|
|
|
|
|
|
|
if (selectedRows.length === 0) { |
|
|
|
// 没有装箱数量时,清空 |
|
|
|
this.palletModelData.boxQty = null; |
|
|
|
this.palletModelData.grossWeight = null; |
|
|
|
this.palletModelData.netWeight = null; |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// 检查是否所有物料都已缓存包装属性 |
|
|
|
const allHaveCache = selectedRows.every(row => |
|
|
|
row.rollQtyCache && row.boxRollsCache && row.boxWeightCache |
|
|
|
); |
|
|
|
|
|
|
|
if (!allHaveCache) { |
|
|
|
// 如果有物料未缓存属性,不自动计算(避免数据不完整) |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// 计算总箱数和总重量 |
|
|
|
let totalBoxQty = 0; |
|
|
|
let totalGrossWeight = 0; |
|
|
|
|
|
|
|
selectedRows.forEach(row => { |
|
|
|
// 每箱EA = 每卷数量 × 每箱卷数 |
|
|
|
const eaPerBox = row.rollQtyCache * row.boxRollsCache; |
|
|
|
// 该物料的箱数(向上取整) |
|
|
|
const partBoxQty = Math.ceil(row.useQty / eaPerBox); |
|
|
|
// 该物料的毛重 = 箱数 × 箱重量 |
|
|
|
const partGrossWeight = partBoxQty * row.boxWeightCache; |
|
|
|
|
|
|
|
totalBoxQty += partBoxQty; |
|
|
|
totalGrossWeight += partGrossWeight; |
|
|
|
}); |
|
|
|
|
|
|
|
// 净重 = 毛重 - (箱数 / 2) |
|
|
|
const totalNetWeight = totalGrossWeight - (totalBoxQty / 2); |
|
|
|
|
|
|
|
// 自动填入箱数、毛重、净重 |
|
|
|
this.palletModelData.boxQty = totalBoxQty; |
|
|
|
this.palletModelData.grossWeight = parseFloat(totalGrossWeight.toFixed(2)); |
|
|
|
this.palletModelData.netWeight = parseFloat(totalNetWeight.toFixed(2)); |
|
|
|
}, |
|
|
|
/** |
|
|
|
* 根据箱数自动计算毛重和净重 |
|
|
|
* 计算公式(来自后端代码2991-2992行): |
|
|
|
* 毛重 = 箱数 × 箱重量 |
|
|
|
* 净重 = 毛重 - (箱数 / 2) |
|
|
|
*/ |
|
|
|
calculateWeightsByBoxQty() { |
|
|
|
// 如果箱数为空或为0,清空毛重和净重 |
|
|
|
if (!this.palletModelData.boxQty || this.palletModelData.boxQty <= 0) { |
|
|
|
this.palletModelData.grossWeight = null; |
|
|
|
this.palletModelData.netWeight = null; |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// 获取有装箱数量的物料列表 |
|
|
|
const selectedRows = this.dataList8.filter(item => item.useQty && item.useQty > 0); |
|
|
|
|
|
|
|
if (selectedRows.length === 0) { |
|
|
|
// 没有选择物料时,不自动计算,允许用户手动输入 |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// 检查是否所有物料都已缓存箱重量 |
|
|
|
const needFetchProperties = selectedRows.filter(row => !row.boxWeightCache); |
|
|
|
|
|
|
|
if (needFetchProperties.length === 0) { |
|
|
|
// 所有物料都有缓存,直接计算 |
|
|
|
this.calculateWeightsWithCache(selectedRows); |
|
|
|
} else { |
|
|
|
// 需要获取部分物料的属性 |
|
|
|
this.fetchBoxWeightsAndCalculate(selectedRows, needFetchProperties); |
|
|
|
} |
|
|
|
}, |
|
|
|
/** |
|
|
|
* 使用缓存的箱重量计算毛重和净重 |
|
|
|
*/ |
|
|
|
calculateWeightsWithCache(selectedRows) { |
|
|
|
// 根据装箱数量计算加权平均箱重量 |
|
|
|
let totalWeight = 0; |
|
|
|
let totalQty = 0; |
|
|
|
|
|
|
|
selectedRows.forEach(row => { |
|
|
|
if (row.boxWeightCache && row.boxWeightCache > 0 && row.rollQtyCache && row.rollQtyCache > 0 && row.boxRollsCache && row.boxRollsCache > 0) { |
|
|
|
// 每箱EA = 每卷数量 × 每箱卷数 |
|
|
|
const eaPerBox = row.rollQtyCache * row.boxRollsCache; |
|
|
|
// 该物料的箱数 |
|
|
|
const partBoxQty = Math.ceil(row.useQty / eaPerBox); |
|
|
|
// 累计重量和箱数 |
|
|
|
totalWeight += partBoxQty * row.boxWeightCache; |
|
|
|
totalQty += partBoxQty; |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
if (totalQty > 0) { |
|
|
|
// 计算平均箱重量 |
|
|
|
const avgBoxWeight = totalWeight / totalQty; |
|
|
|
this.calculateFinalWeights(avgBoxWeight); |
|
|
|
} else { |
|
|
|
// 如果无法计算平均重量,使用第一个物料的箱重量 |
|
|
|
const firstRow = selectedRows.find(row => row.boxWeightCache && row.boxWeightCache > 0); |
|
|
|
if (firstRow) { |
|
|
|
this.calculateFinalWeights(firstRow.boxWeightCache); |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
/** |
|
|
|
* 获取物料箱重量并计算毛重净重 |
|
|
|
*/ |
|
|
|
fetchBoxWeightsAndCalculate(selectedRows, needFetchProperties) { |
|
|
|
// 批量获取物料属性 |
|
|
|
const promises = needFetchProperties.map(row => { |
|
|
|
const params = { |
|
|
|
site: this.currentRow.site, |
|
|
|
buNo: this.currentRow.buNo, |
|
|
|
partNo: row.partNo |
|
|
|
}; |
|
|
|
return getPartPackageProperties(params).then(({data}) => { |
|
|
|
if (data && data.code === 0 && data.data) { |
|
|
|
// 缓存物料属性 |
|
|
|
this.$set(row, 'rollQtyCache', data.data.rollQty); |
|
|
|
this.$set(row, 'boxRollsCache', data.data.boxRolls); |
|
|
|
this.$set(row, 'boxWeightCache', data.data.boxWeight); |
|
|
|
return true; |
|
|
|
} |
|
|
|
return false; |
|
|
|
}).catch(error => { |
|
|
|
console.error(`获取物料 ${row.partNo} 属性失败:`, error); |
|
|
|
return false; |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
Promise.all(promises).then(() => { |
|
|
|
// 所有属性获取完成后,重新计算 |
|
|
|
this.calculateWeightsWithCache(selectedRows); |
|
|
|
}); |
|
|
|
}, |
|
|
|
/** |
|
|
|
* 计算最终的毛重和净重 |
|
|
|
* @param avgBoxWeight 平均箱重量 |
|
|
|
*/ |
|
|
|
calculateFinalWeights(avgBoxWeight) { |
|
|
|
const boxQty = parseFloat(this.palletModelData.boxQty); |
|
|
|
|
|
|
|
// 毛重 = 箱数 × 箱重量 |
|
|
|
const grossWeight = boxQty * avgBoxWeight; |
|
|
|
|
|
|
|
// 净重 = 毛重 - (箱数 / 2) |
|
|
|
const netWeight = grossWeight - (boxQty / 2); |
|
|
|
|
|
|
|
// 保留2位小数 |
|
|
|
this.palletModelData.grossWeight = parseFloat(grossWeight.toFixed(2)); |
|
|
|
this.palletModelData.netWeight = parseFloat(netWeight.toFixed(2)); |
|
|
|
}, |
|
|
|
savePalletHeader(type) { |
|
|
|
// 过滤出 useQty > 0 的行 |
|
|
|
@ -2810,7 +3036,7 @@ |
|
|
|
.warning-row td{ |
|
|
|
color: darkred !important; |
|
|
|
} |
|
|
|
/deep/ .zxClass .cell { |
|
|
|
.zxClass .cell { |
|
|
|
line-height: 24px; |
|
|
|
font-size: 12px; |
|
|
|
height: 24px; |
|
|
|
|