Compare commits

...

2 Commits

Author SHA1 Message Date
76497eece7 Merge branch '0.8.X' of http://49.232.154.205:10100/DeXun/klp-oa into 0.8.X 2026-06-09 09:02:47 +08:00
d231d3619a feat(wms/report): add length/thickness diff columns and abnormal alert
1. 调整产品内容工具函数,移除冗余的quantity和taxPrice字段返回
2. 重新编排报表列配置,新增长度/厚度差值列并调整字段顺序
3. 实现差值计算逻辑与异常标红展示,从配置获取告警阈值
2026-06-09 09:02:44 +08:00
3 changed files with 58 additions and 27 deletions

View File

@@ -195,8 +195,6 @@ export function calculateProductFields(product, changedField = 'quantity') {
return {
...product,
quantity,
taxPrice: round3(taxPrice),
noTaxPrice: round3(noTaxPrice),
taxTotal: round3(taxTotal),
noTaxTotal: round3(noTaxTotal),

View File

@@ -1,28 +1,9 @@
<template>
<div class="coil-table">
<div class="table-controls">
<!-- <div class="filter-section">
<el-input v-model="filterKeyword" placeholder="输入关键词筛选" clearable @input="handleFilterChange"
style="width: 200px; margin-right: 10px" />
<el-select v-model="filterColumn" placeholder="选择筛选字段" @change="handleFilterChange"
style="width: 200px; margin-right: 10px" multiple collapse-tags>
<el-option v-for="column in columns" :key="column.prop" :label="column.title" :value="column.prop" />
</el-select>
</div> -->
<!-- <div class="sort-section">
<el-select v-model="sortField" placeholder="选择排序字段" @change="handleSortChange"
style="width: 150px; margin-right: 10px">
<el-option v-for="column in columns" :key="column.prop" :label="column.title" :value="column.prop" />
</el-select>
<el-select v-model="sortDirection" placeholder="选择排序方向" @change="handleSortChange" style="width: 100px">
<el-option label="升序" value="asc" />
<el-option label="降序" value="desc" />
</el-select>
</div> -->
<el-pagination layout="total, sizes, prev, pager, next, jumper" :total="paginationTotal" :page-size="effectivePageSize"
:current-page="pageNum" :page-sizes="[10, 20, 50, 100, 200, 500, 1000]" @size-change="handleSizeChange"
@current-change="handleCurrentChange" />
<slot name="settings"></slot>
</div>
@@ -49,6 +30,19 @@
{{ formatProductionDuration(scope.row.productionDuration) }}
</template>
<!-- 质量状态点击后会出现弹窗显示详细信息 -->
<template v-else-if="column.prop === 'lengthDiff'">
<span :style="{ color: isLengthAbnormal(scope.row) ? 'red' : '' }">
{{ scope.row.lengthDiff != null ? scope.row.lengthDiff.toFixed(3) : '' }}
<template v-if="scope.row.lengthDiff != null && scope.row.theoreticalLength">
({{ (Math.abs(scope.row.lengthDiff) / scope.row.theoreticalLength).toFixed(3) }})
</template>
</span>
</template>
<template v-else-if="column.prop === 'thicknessDiff'">
<span :style="{ color: isThicknessAbnormal(scope.row) ? 'red' : '' }">
{{ scope.row.thicknessDiff != null ? scope.row.thicknessDiff.toFixed(3) : '' }}
</span>
</template>
<template v-else-if="column.prop === 'qualityStatus'">
<div @click="handleQualityStatusClick(scope.row)" style="cursor: pointer; background-color: #f5f7fa;">
<dict-tag v-if="scope.row.qualityStatus" :options="dict.type.coil_quality_status" :value="scope.row.qualityStatus"></dict-tag>
@@ -78,6 +72,7 @@ import CoilNo from "@/components/KLPService/Renderer/CoilNo.vue";
import { listCoilAbnormal } from '@/api/wms/coilAbnormal'
import AbnormalTable from '@/views/wms/coil/components/AbnormalTable.vue'
import { getConfigKey } from '@/api/system/config'
export default {
name: 'CoilTable',
@@ -135,12 +130,17 @@ export default {
data: {},
loading: false,
currentCoil: {},
}
},
lengthThreshold: 0,
thicknessThreshold: 0,
thicknessMaxThreshold: 0,
thicknessMinThreshold: 0,
}
},
mounted() {
// 默认选中所有列
this.filterColumn = this.columns.map(column => column.prop)
this.getAlarmThreshold()
},
computed: {
isServerPagination() {
@@ -149,12 +149,19 @@ export default {
effectivePageSize() {
return this.pageSize > 0 ? this.pageSize : this.innerPageSize
},
enrichedData() {
return this.data.map(row => ({
...row,
lengthDiff: (row.actualLength || 0) - (row.theoreticalLength || 0),
thicknessDiff: (row.theoreticalThickness || 0) - (row.computedThickness || 0)
}))
},
// 处理排序和筛选后的数据(服务端分页模式下跳过筛选排序)
processedData() {
if (this.isServerPagination) {
return this.data
return this.enrichedData
}
let result = [...this.data]
let result = [...this.enrichedData]
// 筛选逻辑
if (this.filterColumn.length > 0 && this.filterKeyword) {
@@ -205,7 +212,7 @@ export default {
// 内部实现前端分页逻辑(服务端分页模式下直接返回数据)
tableData() {
if (this.isServerPagination) {
return this.data
return this.enrichedData
}
return this.processedData.slice((this.pageNum - 1) * this.effectivePageSize, this.pageNum * this.effectivePageSize)
},
@@ -291,6 +298,11 @@ export default {
// 获取行类名
getRowClassName({ row, rowIndex }) {
const { rows } = this.highlightConfig
if (this.isLengthAbnormal(row) || this.isThicknessAbnormal(row)) {
return 'warning-row'
}
if (!rows || (Array.isArray(rows) && rows.length === 0)) {
return ''
}
@@ -324,6 +336,20 @@ export default {
}
return shouldHighlight ? style : {}
},
isLengthAbnormal(row) {
const theoreticalLength = row.theoreticalLength || 1
return Math.abs(row.lengthDiff) / theoreticalLength > this.lengthThreshold
},
isThicknessAbnormal(row) {
return row.thicknessDiff > this.thicknessThreshold
},
// 获取报警阈值参数
getAlarmThreshold() {
getConfigKey('material.warning.length').then(response => { this.lengthThreshold = response.msg || 0 })
getConfigKey('material.warning.thickness').then(response => { this.thicknessThreshold = response.msg || 0 })
// getConfigKey('material.warning.Maxthickness').then(response => { this.thicknessMaxThreshold = response.msg || 0 })
// getConfigKey('material.warning.Minthickness').then(response => { this.thicknessMinThreshold = response.msg || 0 })
}
}
}

View File

@@ -147,18 +147,25 @@ export default {
{ label: '产品类型', value: 'itemId' },
{ label: '品名', value: 'itemName' },
{ label: '宽度', value: 'computedWidth' },
{ label: '厚度', value: 'computedThickness' },
{ label: '规格', value: 'specification' },
{ label: '材质', value: 'material' },
{ label: '厂家', value: 'manufacturer' },
{ label: '表面处理', value: 'surfaceTreatmentDesc' },
{ label: '镀层质量', value: 'zincLayer' },
{ label: '实测长度', value: 'actualLength' },
{ label: '理论长度', value: 'theoreticalLength' },
{ label: '长度差值', value: 'lengthDiff' },
{ label: '厚度', value: 'computedThickness' },
{ label: '实测厚度', value: 'actualThickness' },
{ label: '理论厚度', value: 'theoreticalThickness' },
{ label: '厚度差值', value: 'thicknessDiff' },
{ label: '宽度', value: 'computedWidth' },
{ label: '实测宽度', value: 'actualWidth' },
{ label: '毛重', value: 'grossWeight' },
{ label: '净重', value: 'netWeight' },
{ label: '创建时间', value: 'createTime' },