Files
xgy-oa/klp-ui/src/views/wms/report/js/calc.js
砂糖 0223102269 feat(wms/report): 添加差值计算和异常信息展示功能
refactor(wms/report): 替换合计信息为差值显示
feat(wms/coil): 增加创建时间和创建人字段
feat(crm/contract): 添加合同导出按钮
2026-03-31 18:37:17 +08:00

222 lines
8.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const calcSummary = (list, lossList) => {
// 总钢卷数量、总重、均重
const outCount = list.length
const outTotalWeight = list.reduce((acc, cur) => acc + (parseFloat(cur.netWeight) || 0), 0) // 增加容错
const outAvgWeight = outCount > 0 ? (outTotalWeight / outCount)?.toFixed(2) : 0
// 损失钢卷数量、总重、均重
const lossCount = lossList.length
const lossTotalWeight = lossList.reduce((acc, cur) => acc + (parseFloat(cur.netWeight) || 0), 0) // 增加容错
const lossAvgWeight = lossCount > 0 ? (lossTotalWeight / lossCount)?.toFixed(2) : 0
// 合计数量、总重、均重
const totalCount = outCount + lossCount
const totalWeight = parseFloat((outTotalWeight + lossTotalWeight).toFixed(2))
const totalAvgWeight = totalCount > 0 ? (totalWeight / totalCount)?.toFixed(2) : 0
// 计算数量、总重、均重的插值
const countDiff = Math.abs(outCount - lossCount)
const weightDiff = Math.abs(parseFloat((outTotalWeight - lossTotalWeight).toFixed(2)))
const avgWeightDiff = Math.abs(parseFloat((outAvgWeight - lossAvgWeight).toFixed(2)))
// 成品比率
const passRate = outCount > 0 && lossTotalWeight > 0 ? (outTotalWeight / lossTotalWeight) : 0
// 损失比率
const lossRate = totalCount > 0 ? (1 - passRate) : 0
// 异常率,成品在warehouseId在'2019583656787259393',
// '2019583325311414274',
// '2019583429955104769',
// '2019583137616310273',这四个库中的占比
const abRate = totalCount != 0 ? list.filter(item => {
return item.warehouseId == '2019583656787259393' || item.warehouseId == '2019583325311414274' || item.warehouseId == '2019583429955104769' || item.warehouseId == '2019583137616310273'
}).length / totalCount : 0
// 正品率1-异常率)
const passRate2 = totalCount != 0 ? (1 - abRate) : 0
return {
outCount,
outTotalWeight: outTotalWeight.toFixed(2),
outAvgWeight,
lossCount,
lossTotalWeight: lossTotalWeight.toFixed(2),
lossAvgWeight,
totalCount,
totalWeight: totalWeight.toFixed(2),
totalAvgWeight,
countDiff,
weightDiff,
avgWeightDiff,
passRate: (passRate * 100)?.toFixed(2) + '%',
lossRate: (lossRate * 100)?.toFixed(2) + '%',
abRate: (abRate * 100)?.toFixed(2) || 0,
passRate2: (passRate2 * 100)?.toFixed(2) || 0,
}
}
const calcAbSummary = (list) => {
// 异常统计,统计四个异常库中的各自的数量和总重
let o = {
jishuCount: 0,
miniCount: 0,
rubbishCount: 0,
returnCount: 0,
jishuWeight: 0,
miniWeight: 0,
rubbishWeight: 0,
returnWeight: 0,
// 计入技术部的钢卷占比
jishuRate: 0,
// 计入小钢卷库的钢卷占比
miniRate: 0,
// 计入废品库的钢卷占比
rubbishRate: 0,
// 计入退货库的钢卷占比
returnRate: 0,
}
const totalCount = list.length
for (let i = 0; i < list.length; i++) {
// { label: '技术部', value: '2019583656787259393' },
// { label: '小钢卷库', value: '2019583325311414274' },
// { label: '废品库', value: '2019583429955104769' },
// { label: '退货库', value: '2019583137616310273' },
// 技术部
const coil = list[i];
// 技术部
if (coil.warehouseId == '2019583656787259393' || coil.qualityStatus == 'O') {
o['jishuCount'] = o['jishuCount'] + 1
o['jishuWeight'] = o['jishuWeight'] + parseFloat(coil.netWeight) || 0
}
// 小刚卷库
else if (coil.warehouseId == '2019583325311414274') {
o['miniCount'] = o['miniCount'] + 1
o['miniWeight'] = o['miniWeight'] + parseFloat(coil.netWeight) || 0
}
// 废品库, 或者之状态为D-,DD+,C-CC+其中之一
else if (coil.warehouseId == '2019583429955104769'
|| coil.qualityStatus == 'D-' ||
coil.qualityStatus == 'D' ||
coil.qualityStatus == 'D+' ||
coil.qualityStatus == 'C-' ||
coil.qualityStatus == 'C' ||
coil.qualityStatus == 'C+') {
o['rubbishCount'] = o['rubbishCount'] + 1
o['rubbishWeight'] = o['rubbishWeight'] + parseFloat(coil.netWeight) || 0
}
// 退货库
else if (coil.warehouseId == '2019583137616310273') {
o['returnCount'] = o['returnCount'] + 1
o['returnWeight'] = o['returnWeight'] + parseFloat(coil.netWeight) || 0
}
}
return [
{ label: '技术部钢卷数', value: o['jishuCount'] },
{ label: '小钢卷库钢卷数', value: o['miniCount'] },
{ label: '废品库钢卷数', value: o['rubbishCount'] },
{ label: '退货库钢卷数', value: o['returnCount'] },
{ label: '技术部钢卷重量', value: o['jishuWeight'].toFixed(2) },
{ label: '小钢卷库钢卷重量', value: o['miniWeight'].toFixed(2) },
{ label: '废品库钢卷重量', value: o['rubbishWeight'].toFixed(2) },
{ label: '退货库钢卷重量', value: o['returnWeight'].toFixed(2) },
{ label: '技术部占比', value: totalCount > 0 ? (o['jishuCount'] / totalCount * 100).toFixed(2) + '%' : '0.00%' },
{ label: '小钢卷库占比', value: totalCount > 0 ? (o['miniCount'] / totalCount * 100).toFixed(2) + '%' : '0.00%' },
{ label: '废品库占比', value: totalCount > 0 ? (o['rubbishCount'] / totalCount * 100).toFixed(2) + '%' : '0.00%' },
{ label: '退货库占比', value: totalCount > 0 ? (o['returnCount'] / totalCount * 100).toFixed(2) + '%' : '0.00%' },
]
}
const calcTeamSummary = (list) => {
// 按照班组汇总信息
const teamSummary = {}
for (let i = 0; i < list.length; i++) {
const coil = list[i];
if (!teamSummary[coil.team]) {
teamSummary[coil.team] = {
count: 0,
weight: 0,
}
}
teamSummary[coil.team].count = teamSummary[coil.team].count + 1
teamSummary[coil.team].weight = teamSummary[coil.team].weight + parseFloat(coil.netWeight) || 0
}
return teamSummary
}
const calcMSummary = (list, lossList) => {
// 统计需要二外处理M卷也就是钢卷的currentCoilNo中带有M的钢卷在统计产出钢卷的数量和重量时需要忽略并记录并且在统计消耗钢卷的总重量时也需要移除
// 筛选出 M 卷
const mCoils = list.filter(item => item.currentCoilNo && item.currentCoilNo.includes('M'))
// 非 M 卷
const nonMCoils = list.filter(item => !item.currentCoilNo || !item.currentCoilNo.includes('M'))
// 非 M 卷作为产出统计
const outCount = nonMCoils.length
const outTotalWeight = nonMCoils.reduce((acc, cur) => acc + (parseFloat(cur.netWeight) || 0), 0)
const outAvgWeight = outCount > 0 ? (outTotalWeight / outCount)?.toFixed(2) : 0
// 计算产出的 M 卷总重量
const mOutTotalWeight = mCoils.reduce((acc, cur) => acc + (parseFloat(cur.netWeight) || 0), 0)
// 消耗钢卷统计(数量包括所有卷,但总重量减去产出的 M 卷重量)
const lossCount = lossList.length
const lossTotalWeight = lossList.reduce((acc, cur) => acc + (parseFloat(cur.netWeight) || 0), 0) - mOutTotalWeight
const lossAvgWeight = lossCount > 0 ? (lossTotalWeight / lossCount)?.toFixed(2) : 0
// 合计
const totalCount = outCount + lossCount
const totalWeight = parseFloat((outTotalWeight + lossTotalWeight).toFixed(2))
const totalAvgWeight = totalCount > 0 ? (totalWeight / totalCount)?.toFixed(2) : 0
// 数量差值
const countDiff = Math.abs(outCount - lossCount)
// 总重差值
const weightDiff = Math.abs(parseFloat((outTotalWeight - lossTotalWeight).toFixed(2)))
// 均重差值
const avgWeightDiff = Math.abs(parseFloat((outAvgWeight - lossAvgWeight).toFixed(2)))
// 成品比率
const passRate = outCount > 0 && lossTotalWeight > 0 ? (outTotalWeight / lossTotalWeight) : 0
// 损失比率
const lossRate = totalCount > 0 ? (1 - passRate) : 0
// 异常率,成品在warehouseId在'2019583656787259393',
// '2019583325311414274',
// '2019583429955104769',
// '2019583137616310273',这四个库中的占比
const abRate = totalCount != 0 ? nonMCoils.filter(item => {
return item.warehouseId == '2019583656787259393' || item.warehouseId == '2019583325311414274' || item.warehouseId == '2019583429955104769' || item.warehouseId == '2019583137616310273'
}).length / totalCount : 0
// 正品率1-异常率)
const passRate2 = totalCount != 0 ? (1 - abRate) : 0
return {
outCount,
outTotalWeight: outTotalWeight.toFixed(2),
outAvgWeight,
lossCount,
lossTotalWeight: lossTotalWeight.toFixed(2),
lossAvgWeight,
totalCount,
totalWeight: totalWeight.toFixed(2),
totalAvgWeight,
countDiff,
weightDiff: weightDiff.toFixed(2),
avgWeightDiff,
passRate: (passRate * 100)?.toFixed(2) + '%',
lossRate: (lossRate * 100)?.toFixed(2) + '%',
abRate: (abRate * 100)?.toFixed(2) || 0,
passRate2: (passRate2 * 100)?.toFixed(2) || 0,
}
}
export {
calcSummary,
calcAbSummary,
calcTeamSummary,
calcMSummary,
}