feat: 新增多类业务功能并优化页面展示
1. 新增钢卷周期对比查询API,增加冷轧卷、花纹板物料类型 2. 优化库存积压统计逻辑,支持成品和原料数据合并计算 3. 新增告警统计功能,实现长度/厚度告警的数量和重量统计 4. 替换岗位管理页面为冷轧厂业务流程泳道图页面
This commit is contained in:
@@ -126,6 +126,10 @@
|
||||
<span class="summary-label">消耗合计</span>
|
||||
<span class="summary-value">{{ totalLossCount }}卷 / {{ totalLossWeight }}t</span>
|
||||
</div>
|
||||
<div class="summary-item">
|
||||
<span class="summary-label">告警合计</span>
|
||||
<span class="summary-value">{{ totalAlertCount }}卷 / {{ totalAlertWeight }}t</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 折线图区域 -->
|
||||
@@ -190,6 +194,14 @@
|
||||
<el-table-column prop="mAbRubbishRate" label="废品库占比" min-width="85" />
|
||||
<el-table-column prop="mAbReturnRate" label="退货库占比" min-width="85" />
|
||||
</el-table-column>
|
||||
<el-table-column label="告警统计" align="center">
|
||||
<el-table-column prop="lengthAlertCount" label="长度告警数" min-width="85" />
|
||||
<el-table-column prop="thicknessAlertCount" label="厚度告警数" min-width="85" />
|
||||
<el-table-column prop="totalAlertCount" label="总告警数" min-width="75" />
|
||||
<el-table-column prop="lengthAlertWeight" label="长度告警总重(t)" min-width="105" />
|
||||
<el-table-column prop="thicknessAlertWeight" label="厚度告警总重(t)" min-width="105" />
|
||||
<el-table-column prop="totalAlertWeight" label="总告警总重(t)" min-width="95" />
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
@@ -198,7 +210,7 @@
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
import { listLightCoil } from '@/api/wms/coil'
|
||||
import { listForPeriodComparison } from '@/api/wms/coil'
|
||||
import { listLightPendingAction } from '@/api/wms/pendingAction'
|
||||
import MemoInput from '@/components/MemoInput'
|
||||
import MutiSelect from '@/components/MutiSelect'
|
||||
@@ -232,7 +244,9 @@ export default {
|
||||
],
|
||||
allOutList: [],
|
||||
allLossList: [],
|
||||
periodData: []
|
||||
periodData: [],
|
||||
lengthThreshold: 0,
|
||||
thicknessThreshold: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -252,6 +266,12 @@ export default {
|
||||
totalLossWeight() {
|
||||
return this.periodData.reduce((s, i) => s + (parseFloat(i.lossTotalWeight) || 0), 0).toFixed(2)
|
||||
},
|
||||
totalAlertCount() {
|
||||
return this.periodData.reduce((s, i) => s + (i.totalAlertCount || 0), 0)
|
||||
},
|
||||
totalAlertWeight() {
|
||||
return this.periodData.reduce((s, i) => s + (parseFloat(i.totalAlertWeight) || 0), 0).toFixed(2)
|
||||
},
|
||||
chartConfigs() {
|
||||
return [
|
||||
// ====== Row 1: 数量/总重 ======
|
||||
@@ -344,6 +364,27 @@ export default {
|
||||
],
|
||||
height: '280px'
|
||||
},
|
||||
// ====== Row 5: 告警统计 ======
|
||||
{
|
||||
title: '告警数量趋势',
|
||||
series: [
|
||||
{ key: 'lengthAlertCount', label: '长度告警(卷)', color: '#f56c6c', yAxisIndex: 0 },
|
||||
{ key: 'thicknessAlertCount', label: '厚度告警(卷)', color: '#e6a23c', yAxisIndex: 0 },
|
||||
{ key: 'totalAlertCount', label: '总告警(卷)', color: '#409eff', yAxisIndex: 0 }
|
||||
],
|
||||
yAxis: [{ type: 'value', name: '数量(卷)' }],
|
||||
height: '280px'
|
||||
},
|
||||
{
|
||||
title: '告警总重趋势',
|
||||
series: [
|
||||
{ key: 'lengthAlertWeight', label: '长度告警总重(t)', color: '#f56c6c', yAxisIndex: 0 },
|
||||
{ key: 'thicknessAlertWeight', label: '厚度告警总重(t)', color: '#e6a23c', yAxisIndex: 0 },
|
||||
{ key: 'totalAlertWeight', label: '总告警总重(t)', color: '#409eff', yAxisIndex: 0 }
|
||||
],
|
||||
yAxis: [{ type: 'value', name: '重量(t)' }],
|
||||
height: '280px'
|
||||
},
|
||||
{
|
||||
title: 'M-异常库位分布(钢卷数与占比)',
|
||||
series: [
|
||||
@@ -422,6 +463,58 @@ export default {
|
||||
this.handleQuery()
|
||||
},
|
||||
|
||||
// ====== 告警阈值 ======
|
||||
getAlarmThreshold() {
|
||||
this.getConfigKey('material.warning.length').then(response => { this.lengthThreshold = parseFloat(response.msg) || 0 })
|
||||
this.getConfigKey('material.warning.thickness').then(response => { this.thicknessThreshold = parseFloat(response.msg) || 0 })
|
||||
},
|
||||
// 计算一个周期内产出钢卷的告警统计(长度告警、厚度告警、总告警的数量和总重)
|
||||
calcAlertSummary(outList) {
|
||||
const lt = this.lengthThreshold
|
||||
const tt = this.thicknessThreshold
|
||||
let lengthAlertCount = 0
|
||||
let thicknessAlertCount = 0
|
||||
let totalAlertCount = 0
|
||||
let lengthAlertWeight = 0
|
||||
let thicknessAlertWeight = 0
|
||||
let totalAlertWeight = 0
|
||||
|
||||
outList.forEach(row => {
|
||||
const actualLength = row.actualLength || 0
|
||||
const theoreticalLength = row.theoreticalLength || 1
|
||||
const lengthDiff = actualLength - theoreticalLength
|
||||
const theoreticalThickness = row.theoreticalThickness || 0
|
||||
const computedThickness = row.computedThickness || 0
|
||||
const thicknessDiff = theoreticalThickness - computedThickness
|
||||
const weight = parseFloat(row.netWeight) || 0
|
||||
|
||||
const isLengthAbnormal = Math.abs(lengthDiff) / theoreticalLength > lt
|
||||
const isThicknessAbnormal = thicknessDiff > tt
|
||||
|
||||
if (isLengthAbnormal) {
|
||||
lengthAlertCount++
|
||||
lengthAlertWeight += weight
|
||||
}
|
||||
if (isThicknessAbnormal) {
|
||||
thicknessAlertCount++
|
||||
thicknessAlertWeight += weight
|
||||
}
|
||||
if (isLengthAbnormal || isThicknessAbnormal) {
|
||||
totalAlertCount++
|
||||
totalAlertWeight += weight
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
lengthAlertCount,
|
||||
thicknessAlertCount,
|
||||
totalAlertCount,
|
||||
lengthAlertWeight: lengthAlertWeight.toFixed(2),
|
||||
thicknessAlertWeight: thicknessAlertWeight.toFixed(2),
|
||||
totalAlertWeight: totalAlertWeight.toFixed(2)
|
||||
}
|
||||
},
|
||||
|
||||
// ====== 数据获取 ======
|
||||
handleQuery() {
|
||||
this.fetchData()
|
||||
@@ -439,6 +532,7 @@ export default {
|
||||
this.disposeCharts()
|
||||
this.chartInstances = []
|
||||
this.periodData = []
|
||||
this.getAlarmThreshold()
|
||||
|
||||
try {
|
||||
const baseQuery = {
|
||||
@@ -482,11 +576,11 @@ export default {
|
||||
})
|
||||
|
||||
const [outRes, lossRes] = await Promise.all([
|
||||
listLightCoil({
|
||||
listForPeriodComparison({
|
||||
...baseQuery, coilIds: outIds, startTime: '', endTime: '',
|
||||
selectType: 'product', pageSize: 99999, pageNum: 1
|
||||
}),
|
||||
lossIds ? listLightCoil({
|
||||
lossIds ? listForPeriodComparison({
|
||||
...baseQuery, coilIds: lossIds, startTime: '', endTime: '',
|
||||
selectType: 'raw_material', pageSize: 99999, pageNum: 1
|
||||
}) : Promise.resolve({ data: [] })
|
||||
@@ -535,6 +629,9 @@ export default {
|
||||
const mAbMap = {}
|
||||
mAbSummary.forEach(i => { mAbMap[i.label] = i.value })
|
||||
|
||||
// 告警统计(长度告警、厚度告警的数量和总重)
|
||||
const alertSummary = this.calcAlertSummary(outList)
|
||||
|
||||
return {
|
||||
periodLabel: p.label,
|
||||
// 基础统计
|
||||
@@ -567,7 +664,9 @@ export default {
|
||||
mAbTechRate: mAbMap['技术部占比'] || '0.00%',
|
||||
mAbMiniRate: mAbMap['小钢卷库占比'] || '0.00%',
|
||||
mAbRubbishRate: mAbMap['废品库占比'] || '0.00%',
|
||||
mAbReturnRate: mAbMap['退货库占比'] || '0.00%'
|
||||
mAbReturnRate: mAbMap['退货库占比'] || '0.00%',
|
||||
// 告警统计
|
||||
...alertSummary
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user