@@ -1,175 +1,179 @@
< template >
< div class = "trace-result-container" >
<!-- 二维码信息 -- >
<!-- < el-card shadow = "hover" class = "mb20" v-if = "traceResult && traceResult.qrcode " >
<!-- 操作步骤 ( 基于标准化step渲染 ) -- >
< el-card shadow = "hover" class = "mb20" v-if = "standardSteps && standardSteps.length > 0 " >
< div slot = "header" class = "card-header" >
< span class = "title-dot" > < / span >
< span class = "title-text" > 二维码信息 < / span >
< span class = "title-text" > 钢卷追溯操作步骤 < / span >
< / div >
< div class = "qrcode-info" >
< el-row class = "info-row" :gutter = "10" >
< el-col :span = "6 " c lass = "info-label" > 主序列号 : < / el-col >
< el-col :span = "18" class = "info-value" > { { traceResult . qrcode . serialNumber || '-' } } < / el-col >
< / el-row >
< el-row class = "info-row" :gutter = "10" >
< el-col :span = "6" class = "info-label" > 创建时间 : < / el-col >
< el-col :span = "18" class = "info-value" > { { traceResult . qrcode . createTime || '-' } } < / el-col >
< / el-row >
< el-row class = "info-row" :gutter = "10" v-if = "traceResult.all_qrcodes && traceResult.all_qrcodes.length > 1" >
< el -col :span = "6" class = "info-label" > 相关二维码 : < / el-col >
< el-col :span = "18" class = "info-value" > { { traceResult . all _qrcodes . length } } 个 < / el-col >
< / el-row >
< / div >
< / el-card > -- >
<!-- 操作步骤 -- >
< el-card shadow = "hover" class = "mb20" v-if = "traceResult && traceResult.steps && traceResult.steps.length > 0" >
< div slot = "header" class = "card-header" >
< span class = "title-dot" > < / span >
< span class = "title-text" > 操作步骤 < / span >
< / div >
< el-timeline >
< el-timeline-item
v-for = "(step, index) in traceResult.steps"
:key = "index"
: timestamp = "step.display_step || step.step"
placement = "top"
>
< el-timeline v-loading = "loadingCoilDetails" >
< el-timeline -item v-for = "(step, index) in standardSteps" :key="index"
: timestamp = "`步骤 ${step.original.display_step || step.original.step}` " p lacement = "top" >
< el-card shadow = "hover" >
< div class = "step-header" >
< span class = "step-action" > { { step . action } } < / span >
< el-tag size = "mini" type= "primary" v-if = "step.opera tion" > {{ step.operation }} < / el -tag >
< el-tag size = "mini" : type= "getStepTagType(step.ac tion) " >{ { step. original . operation || step . action
} } < / el-tag >
< el-tag size = "mini" type = "info" v-if = "step.operation" >
操作人 : {{ step.operation }}
< / el -tag >
< / div >
<!-- 标准化步骤详情 - 核心展示旧钢卷 / 新钢卷关键信息 -- >
< div class = "step-details" >
< el-row class = "detail-row" v-if = "step.current_coil_no" >
< el-col :span = "8" class = "detail-label" > 当前钢卷号 : < / el-col >
< el-col :span = "16 " class = "detail-value " > { { step . current _coil _no } } < / el-col >
<!-- 核心操作信息 -- >
< el-row class = "detail-row" v-if = "step.time" >
< el -col :span = "8 " class = "detail-label " > 操作时间 : < / el-col >
< el-col :span = "16" class = "detail-value" > { { step . time } } < / el-col >
< / el-row >
< el-row class = "detail-row" v-if = "step.old_current_coil_no" >
< el -col :span = "8" class = "detail-label" > 原钢卷号 : < / el-col >
< el-col :span = "16" class = "detail-value" > { { step . old _current _coil _no } } < / el-col >
< / el-row >
< el-row class = "detail-row" v-if = "step.new_current_coil_no" >
< el -col :span = "8" class = "detail-label" > 新钢卷号 : < / el-col >
< el-col :span = "16" class = "detail-value" > { { step . new _current _coil _no } } < / el-col >
< / el-row >
< el-row class = "detail-row" v-if = "step.new_current_coil_nos" >
< el -col :span = "8" class = "detail-label" > 分卷列表 : < / el-col >
<!-- 旧钢卷关键信息 ( 操作前 ) - 新增优化 : 展示核心字段 , hover弹窗更多信息 -- >
< el-row class = "detail-row" v-if = "step.oldCoilInfoList && step.oldCoilInfoList.length" >
< el -col :span = "8" class = "detail-label" > 操作前钢卷 : < / el-col >
< el-col :span = "16" class = "detail-value" >
< el-tag
v-for = "coilNo in step.new_ current_c oil_nos.split(',') "
:key = "coilNo"
type = "warning"
size = "mini"
class = "mr8"
>
{ { coilNo . trim ( ) } }
< / el-tag >
< div class = "coil-info-item" v-for = "(coil, idx) in step.oldCoilInfoList" :key="idx" >
< el -popover placement = "right" trigger = "hover" width = "400" v-if = "coil. currentC oilNo != '-' "
:loading = "loadingCoilDetails" >
< div class = "coil-detail-item" >
< p > < b > 入场卷号 : < / b > { { coil . enterCoilNo || '-' } } < / p >
< p > < b > 当前卷号 : < / b > { { coil . currentCoilNo || '-' } } < / p >
< p > < b > 物料类型 : < / b > { { coil . materialType || '-' } } < / p >
< p > < b > 物料名称 : < / b > { { coil . itemName || '-' } } < / p >
< p > < b > 规格 : < / b > { { coil . specification || '-' } } < / p >
< p > < b > 材质 : < / b > { { coil . material || '-' } } < / p >
< p > < b > 生产厂家 : < / b > { { coil . manufacturer || '-' } } < / p >
< p > < b > 净重 : < / b > { { coil . netWeight } } kg < / p >
< p > < b > 逻辑库区 : < / b > { { coil . warehouseName || '-' } } < / p >
< p > < b > 实际库存 : < / b > { { coil . actualWarehouseName || '-' } } < / p >
< p > < b > 镀层质量 : < / b > { { coil . zincLayer || '-' } } < / p >
< p > < b > 质量状态 : < / b > { { coil . qualityStatus || '-' } } < / p >
< p > < b > 创建时间 : < / b > { { coil . createTime || '-' } } < / p >
< / div >
< div slot = "reference" class = "coil-info-summary" >
{ { coil . currentCoilNo || '-' } } { { coil . itemName } } ( { { coil . specification } } ) - { {
coil . materialType } } - { { coil . netWeight } } kg
< / div >
< / el-popover >
< div class = "coil-info-summary coil-info-deleted" v-else > 该钢卷已被回滚操作删除 , 无法查询到信息 < / div >
< / div >
< / el -col >
< / el-row >
< el-row class = "detail-row" v-if = "step.parent_coil_nos" >
< el -col :span = "8" class = "detail-label" > 合卷来源 : < / el-col >
<!-- 新钢卷关键信息 ( 操作后 ) - 新增优化 : 展示核心字段 , hover弹窗更多信息 -- >
< el-row class = "detail-row" v-if = "step.newCoilInfoList && step.newCoilInfoList.length" >
< el -col :span = "8" class = "detail-label" > 操作后钢卷 : < / el-col >
< el-col :span = "16" class = "detail-value" >
< el-tag
v-for = "coilNo in step.pa rent_c oil_nos.split(',') "
:key = "coilNo"
type = "success"
size = "mini"
class = "mr8"
>
{ { coilNo . trim ( ) } }
< / el-tag >
< div class = "coil-info-item" v-for = "(coil, idx) in step.newCoilInfoList" :key="idx" >
< el -popover placement = "right" trigger = "hover" width = "400" v-if = "coil.cur rentC oilNo != '-' "
:loading = "loadingCoilDetails" >
< div class = "coil-detail-item" >
< p > < b > 入场卷号 : < / b > { { coil . enterCoilNo || '-' } } < / p >
< p > < b > 当前卷号 : < / b > { { coil . currentCoilNo || '-' } } < / p >
< p > < b > 物料类型 : < / b > { { coil . materialType || '-' } } < / p >
< p > < b > 物料名称 : < / b > { { coil . itemName || '-' } } < / p >
< p > < b > 规格 : < / b > { { coil . specification || '-' } } < / p >
< p > < b > 材质 : < / b > { { coil . material || '-' } } < / p >
< p > < b > 生产厂家 : < / b > { { coil . manufacturer || '-' } } < / p >
< p > < b > 净重 : < / b > { { coil . netWeight } } kg < / p >
< p > < b > 逻辑库区 : < / b > { { coil . warehouseName || '-' } } < / p >
< p > < b > 实际库存 : < / b > { { coil . actualWarehouseName || '-' } } < / p >
< p > < b > 镀层质量 : < / b > { { coil . zincLayer || '-' } } < / p >
< p > < b > 质量状态 : < / b > { { coil . qualityStatus || '-' } } < / p >
< p > < b > 创建时间 : < / b > { { coil . createTime || '-' } } < / p >
< / div >
< div slot = "reference" class = "coil-info-summary" >
{ { coil . currentCoilNo || '-' } } { { coil . itemName } } ( { { coil . specification } } ) - { {
coil . materialType } } - { { coil . netWeight } } kg
< / div >
< / el-popover >
< div class = "coil-info-summary coil-info-deleted" v-else > 该钢卷已被回滚操作删除 , 无法查询到信息 < / div >
< / div >
< / el -col >
< / el-row >
< el-row class = "detail-row" v-if = "step.child_coils && step.child_coils.length > 0" >
< el -col :span = "8" class = "detail-label" > 子钢卷 : < / el-col >
<!-- 更新专属 : 修改内容 ( 保留原有逻辑 , 适配上下文 ) -- >
< el-row class = "detail-row" v-if = "step.changedFields" >
< el -col :span = "8" class = "detail-label" > 修改内容 : < / el-col >
< el-col :span = "16" class = "detail-value" >
< el-tag
v-for = "coilNo in step.child_coils"
:key = "coilNo"
type = "info"
size = "mini"
class = "mr8"
>
{ { coilNo } }
< / el-tag >
< div class = "changed-field-item" v-for = "(item, idx) in parseChangedFields(step.changedFields)"
:key = "idx" >
{ { item . field } } : < span class = "old-value" > { { item . oldVal } } < / span > → < span class = "new-value" > { {
item . newVal } } < / span >
< / div >
< / el-col >
< / el-row >
<!-- < el-row class = "detail-row" v-if = "step.qrcode_serial" >
< el -col :span = "8" class = "detail-label" > 二维码序列 : < / el-col >
< el-col :span = "16" class = "detail-value" > { { step . qrcode _serial } } < / el-col >
<!-- 回滚专属 : 删除 / 恢复钢卷信息 ( 优化为关键信息展示 ) -- >
<!-- < el-row class = "detail-row" v-if = "step.action === '回滚'" >
< el -col :span = "8" class = "detail-label" > 删除钢卷 : < / el-col >
< el-col :span = "16" class = "detail-value" >
< div class = "coil-info-item" v-if = "step.deletedCoilInfo" >
< el -popover
placement = "right"
trigger = "hover"
width = "400"
:loading = "loadingCoilDetails"
>
< div class = "coil-detail-item" >
< p > < b > 物料类型 : < / b > { { step . deletedCoilInfo . materialType || '-' } } < / p >
< p > < b > 物料名称 : < / b > { { step . deletedCoilInfo . itemName || '-' } } < / p >
< p > < b > 规格 : < / b > { { step . deletedCoilInfo . specification || '-' } } < / p >
< p > < b > 材质 : < / b > { { step . deletedCoilInfo . material || '-' } } < / p >
< p > < b > 净重 : < / b > { { step . deletedCoilInfo . netWeight } } kg < / p >
< p > < b > 创建时间 : < / b > { { step . deletedCoilInfo . createTime || '-' } } < / p >
< / div >
< div slot = "reference" class = "coil-info-summary" >
{ { step . deletedCoilInfo . currentCoilNo || '-' } } { { step . deletedCoilInfo . itemName } } ( { { step . deletedCoilInfo . specification } } ) - { { step . deletedCoilInfo . materialType } }
< / div >
< / el-popover >
< / div >
< span v-else > 无 < / span >
< / el -col >
< / el-row >
< el-row class = "detail-row" v-if = "step.action === '回滚'" >
< el -col :span = "8" class = "detail-label" > 恢复钢卷 : < / el-col >
< el-col :span = "16" class = "detail-value" >
< div class = "coil-info-item" v-if = "step.restoredCoilInfo" >
< el -popover
placement = "right"
trigger = "hover"
width = "400"
:loading = "loadingCoilDetails"
>
< div class = "coil-detail-item" >
< p > < b > 物料类型 : < / b > { { step . restoredCoilInfo . materialType || '-' } } < / p >
< p > < b > 物料名称 : < / b > { { step . restoredCoilInfo . itemName || '-' } } < / p >
< p > < b > 规格 : < / b > { { step . restoredCoilInfo . specification || '-' } } < / p >
< p > < b > 材质 : < / b > { { step . restoredCoilInfo . material || '-' } } < / p >
< p > < b > 净重 : < / b > { { step . restoredCoilInfo . netWeight } } kg < / p >
< p > < b > 创建时间 : < / b > { { step . restoredCoilInfo . createTime || '-' } } < / p >
< / div >
< div slot = "reference" class = "coil-info-summary" >
{ { step . restoredCoilInfo . currentCoilNo || '-' } } { { step . restoredCoilInfo . itemName } } ( { { step . restoredCoilInfo . specification } } ) - { { step . restoredCoilInfo . materialType } }
< / div >
< / el-popover >
< / div >
< span v-else > 无 < / span >
< / el -col >
< / el-row > -- >
< el-row class = "detail-row" v-if = "step.operator" >
< el -col :span = "8" class = "detail-label" > 操作者 : < / el-col >
< el-col :span = "16" class = "detail-value" > { { step . operator } } < / el-col >
< / el-row >
< / div >
< / el-card >
< / el-timeline-item >
< / el-timeline >
< / el-card >
<!-- 钢卷分支图 -- >
<!-- < el-card shadow = "hover" class = "mb20" v-if = "traceResult && traceResult.records && traceResult.records.length > 0" >
< div slot = "header" class = "card-header" >
< span class = "title-dot" > < / span >
< span class = "title-text" > 钢卷分支图 < / span >
< / div >
< div class = "branch-container" >
< div
class = "branch-group"
v-for = "(group, index) in groupedRecords"
:key = "index"
>
< div class = "branch-group-header" >
< el-tag :type = "getGroupTypeTag(group.groupColor)" size = "medium" > { { group . title } } < / el-tag >
< span class = "branch-count" > { { group . coils . length } } 个钢卷 < / span >
< / div >
< el-row :gutter = "20" class = "branch-coils" >
< el-col
:span = "8"
v-for = "coil in group.coils"
:key = "coil.coilId"
>
< el-card shadow = "hover" class = "coil-card" >
< div class = "coil-header" >
< span class = "coil-no" > { { coil . currentCoilNo } } < / span >
< el-tag : type = "coil.dataType === 1 ? 'success' : 'danger'" size = "mini" >
{ { coil . dataType === 1 ? '当前' : '历史' } }
< / el-tag >
< / div >
< div class = "coil-info" >
< p class = "coil-detail" > 入场号 : { { coil . enterCoilNo } } < / p >
< p class = "coil-detail" v-if = "coil.team" > 班组 : {{ coil.team }} < / p >
< p class = "coil-detail" v-if = "coil.warehouse && coil.warehouse.warehouseName" >
库区 : {{ coil.warehouse.warehouseName }}
< / p >
< p class = "coil-detail" v-if = "coil.parentCoilNos && coil.hasMergeSplit === 1" >
< el -tag type = "warning" size = "mini" > 来自母卷 : { { coil . parentCoilNos } } < / el-tag >
< / p >
< p class = "coil-detail" v-if = "coil.parentCoilNos && coil.hasMergeSplit === 0 && coil.dataType === 0" >
< el -tag type = "info" size = "mini" > 分为子卷 : { { coil . parentCoilNos } } < / el-tag >
< / p >
< p class = "coil-detail" v-if = "coil.parentCoilNos && coil.hasMergeSplit === 2" >
< el -tag type = "success" size = "mini" > 合并自 : { { coil . parentCoilNos } } < / el-tag >
< / p >
< p class = "coil-detail" > { { coil . createTime } } < / p >
< / div >
< / el-card >
< / el-col >
< / el-row >
< / div >
< / div >
< / el-card > -- >
<!-- 无记录提示 -- >
< div class = "empty-tip" v-if = "!traceResult || (traceResult && !traceResult.records && !traceResult.steps) " >
< div class = "empty-tip" v-if = "!standardSteps || standardSteps.length === 0 " >
< el -empty description = "未找到相关钢卷记录" > < / el-empty >
< / div >
< / div >
< / template >
< script >
import { listMaterialCoil } from '@/api/wms/coil' ;
export default {
name : 'CoilTraceResult' ,
props : {
@@ -179,99 +183,309 @@ export default {
default : null
}
} ,
data ( ) {
return {
qrcodeDialogVisible : false ,
currentQrcodeContent : '' ,
coilDetails : { } , // 钢卷详情缓存:{coilId: 详情对象, ...}( 仅按coilId缓存, 移除coilNo缓存)
loadingCoilDetails : false , // 钢卷详情加载状态
} ;
} ,
computed : {
// 按时间线和分支关系分组钢卷记录
groupedRecord s( ) {
if ( ! this . traceResult || ! this . traceResult . records ) {
// 生成标准化步骤列表( 核心: 基于原始steps转换, 新增旧/新钢卷信息列表)
standardStep s( ) {
if ( ! this . traceResult || ! this . traceResult . steps || this . traceResult . steps . length === 0 ) {
return [ ] ;
}
const groups = [ ] ;
// 按创建时间排序所有记录
const sortedRecords = [ ... this . traceResult . records ] . sort ( ( a , b ) =>
new Date ( a . createTime ) - new Date ( b . createTime )
) ;
// 按数据类型分组,但保持时间顺序
const currentCoils = sortedRecords . filter ( record => record . dataType === 1 ) ;
const historyCoils = sortedRecords . filter ( record => record . dataType === 0 ) ;
// 当前数据分组
if ( currentCoils . length > 0 ) {
const currentByOperation = this . groupByOperation ( currentCoils ) ;
groups . push ( ... currentByOperation ) ;
}
// 历史数据分组
if ( historyCoils . length > 0 ) {
const historyByOperation = this . groupByOperation ( historyCoils , true ) ;
groups . push ( ... historyByOperation ) ;
}
return groups ;
// 遍历原始步骤,转换为标准化步骤(包含旧/新钢卷关键信息)
return this . traceResult . steps . map ( step => this . formatStep ( step ) ) ;
}
} ,
watch : {
traceResult : {
handler ( newVal ) {
if ( newVal ) {
console . log ( '追溯结果更新,已生成标准化步骤:' , this . standardSteps ) ;
// 步骤更新后,防抖获取钢卷详情(避免频繁请求)
this . debounceFetchCoilDetails ( ) ;
} else {
// 无追溯结果时,清空缓存
this . coilDetails = { } ;
}
} ,
deep : true
}
} ,
methods : {
// 按 操作类型分组
groupByOperation ( records , isHistory = false ) {
const operationGroups = { } ;
for ( const record of records ) {
let operationType = '原始数据 ';
let groupColor = 'default ';
if ( record . hasMergeSplit === 1 ) {
operationType = '分卷结果 ' ;
groupColor = 'split' ;
} else if ( record . hasMergeSplit === 2 ) {
operationType = '合卷结果' ;
groupColor = 'merge' ;
}
const groupKey = operationType ;
if ( ! operationGroups [ groupKey ] ) {
operationGroups [ groupKey ] = {
operationType : operationType ,
groupColor : groupColor ,
coils : [ ]
} ;
}
operationGroups [ groupKey ] . coils . push ( record ) ;
}
// 转换为数组
const groups = [ ] ;
for ( const key in operationGroups ) {
const group = operationGroups [ key ] ;
groups . push ( {
type : isHistory ? 'history' : 'current' ,
operationType : group . operationType ,
groupColor : group . groupColor ,
title : ` ${ group . operationType } ${ isHistory ? '(历史)' : '(当前)' } ` ,
coils : group . coils
} ) ;
}
return groups ;
// 根据 操作类型获取标签样式
getStepTagType ( action ) {
const typeMap = {
'创建' : 'success' ,
'更新' : 'primary' ,
'分卷' : 'warning ',
'合卷' : 'info ',
'回滚' : 'danger'
} ;
return typeMap [ action ] || 'default ' ;
} ,
// formatTime(step) {
// const times tamp = step.upda
// }
// 获取分组标签类型
getGroupTypeTag ( color ) {
switch ( color ) {
case 'split' : return 'warning' ;
case 'merge' : return 'success' ;
default : return 'primary' ;
// 格式化时间戳( 毫秒) 为YYYY-MM-DD HH:mm:ss
formatTime ( timeS tamp) {
if ( ! timeStamp ) return '-' ;
const date = new Date ( timeStamp ) ;
const year = date . getFullYear ( ) ;
const month = String ( date . getMonth ( ) + 1 ) . padStart ( 2 , '0' ) ;
const day = String ( date . getDate ( ) ) . padStart ( 2 , '0' ) ;
const hour = String ( date . getHours ( ) ) . padStart ( 2 , '0' ) ;
const minute = String ( date . getMinutes ( ) ) . padStart ( 2 , '0' ) ;
const second = String ( date . getSeconds ( ) ) . padStart ( 2 , '0' ) ;
return ` ${ year } - ${ month } - ${ day } ${ hour } : ${ minute } : ${ second } ` ;
} ,
// 解析修改字段字符串为结构化数据
parseChangedFields ( changedFieldsStr ) {
if ( ! changedFieldsStr ) return [ ] ;
// 拆分每个修改项(分号分隔)
const items = changedFieldsStr . split ( ';' ) . filter ( item => item . trim ( ) ) ;
return items . map ( item => {
const [ fieldPart , valuePart ] = item . split ( ':' ) . map ( part => part . trim ( ) ) ;
if ( ! valuePart ) return { field : fieldPart , oldVal : '-' , newVal : '-' } ;
// 拆分新旧值(→分隔)
const [ oldVal , newVal ] = valuePart . split ( '→' ) . map ( val => {
const trimmedVal = val . trim ( ) ;
return trimmedVal === 'null' ? '-' : trimmedVal ;
} ) ;
return {
field : fieldPart ,
oldVal : oldVal || '-' ,
newVal : newVal || '-'
} ;
} ) ;
} ,
// 核心: 补全formatStep, 将原始step转换为标准化step( 新增旧/新钢卷信息列表)
formatStep ( originalStep ) {
// 初始化标准化step结构( 移除coilNo相关冗余字段, 新增钢卷信息列表)
const standardStep = {
// 基础字段
action : '' , // 创建/更新/分卷/合卷/回滚
time : '-' , // 操作时间
operation : '-' , // 操作人
oldCoilIds : [ ] , // 操作前钢卷ID列表( 替换原oldId, 适配多钢卷场景)
newCoilIds : [ ] , // 操作后钢卷ID列表( 替换原newId, 适配多钢卷场景)
changedFields : '' , // 更新操作的修改字段
// 新增:钢卷关键信息列表(用于展示)
oldCoilInfoList : [ ] , // 操作前钢卷关键信息列表
newCoilInfoList : [ ] , // 操作后钢卷关键信息列表
deletedCoilInfo : null , // 回滚删除的钢卷关键信息
restoredCoilInfo : null , // 回滚恢复的钢卷关键信息
// 保留原始step, 用于兼容原有逻辑
original : originalStep
} ;
// 1. 映射操作类型( 核心: 统一action命名)
if ( originalStep . action === '新增' ) {
standardStep . action = '创建' ;
} else if ( originalStep . action === '更新' ) {
if ( originalStep . operation === '信息更新' ) {
standardStep . action = '更新' ;
} else if ( originalStep . operation === '分卷' ) {
standardStep . action = '分卷' ;
} else if ( originalStep . operation === '合卷' ) {
standardStep . action = '合卷' ;
} else {
standardStep . action = '更新' ; // 兜底
}
} else if ( originalStep . action === '回滚' ) {
standardStep . action = '回滚' ;
} else {
standardStep . action = originalStep . action || '-' ;
}
}
// 2. 操作时间(优先取更新时间/回滚时间)
if ( originalStep . update _time ) {
standardStep . time = this . formatTime ( originalStep . update _time ) ;
} else if ( originalStep . rollback _time ) {
standardStep . time = this . formatTime ( originalStep . rollback _time ) ;
}
// 3. 操作人(优先昵称,其次账号)
standardStep . operation = originalStep . operator _nickname || originalStep . operator || '-' ;
// 4. 核心ID映射: oldCoilIds( 操作前钢卷ID列表)
switch ( standardStep . action ) {
case '创建' :
standardStep . oldCoilIds = [ ] ; // 创建无旧钢卷
break ;
case '更新' :
standardStep . oldCoilIds = originalStep . old _coil _id ? [ originalStep . old _coil _id . trim ( ) ] : [ ] ;
break ;
case '分卷' :
standardStep . oldCoilIds = originalStep . old _coil _id ? [ originalStep . old _coil _id . trim ( ) ] : [ ] ;
break ;
case '合卷' :
// 合卷操作前钢卷为多个来源ID
standardStep . oldCoilIds = originalStep . parent _coil _ids
? originalStep . parent _coil _ids . split ( ',' ) . map ( id => id . trim ( ) ) . filter ( Boolean )
: [ ] ;
break ;
case '回滚' :
// 回滚操作前钢卷为删除的钢卷ID
standardStep . oldCoilIds = originalStep . deleted _coil _id ? [ originalStep . deleted _coil _id . trim ( ) ] : [ ] ;
break ;
default :
standardStep . oldCoilIds = [ ] ;
}
// 5. 核心ID映射: newCoilIds( 操作后钢卷ID列表)
switch ( standardStep . action ) {
case '创建' :
standardStep . newCoilIds = originalStep . current _coil _id ? [ originalStep . current _coil _id . trim ( ) ] : [ ] ;
break ;
case '更新' :
console . log ( '更新操作后钢卷ID:' , originalStep . new _coil _id , originalStep ) ;
standardStep . newCoilIds = originalStep . new _coil _id ? [ originalStep . new _coil _id . trim ( ) ] : [ ] ;
break ;
case '分卷' :
// 分卷后钢卷为多个子钢卷ID
standardStep . newCoilIds = originalStep . child _coil _ids
? originalStep . child _coil _ids . split ( ',' ) . map ( id => id . trim ( ) ) . filter ( Boolean )
: [ ] ;
break ;
case '合卷' :
standardStep . newCoilIds = originalStep . new _coil _id ? [ originalStep . new _coil _id . trim ( ) ] : [ ] ;
break ;
case '回滚' :
// 回滚后钢卷为恢复的钢卷ID
standardStep . newCoilIds = originalStep . restored _coil _id ? [ originalStep . restored _coil _id . trim ( ) ] : [ ] ;
break ;
default :
standardStep . newCoilIds = [ ] ;
}
// 6. 更新专属: changedFields( 修改字段)
if ( standardStep . action === '更新' ) {
standardStep . changedFields = originalStep . changed _fields || '' ;
}
// 7. 映射旧/新钢卷关键信息(基于缓存的钢卷详情)
standardStep . oldCoilInfoList = this . mapCoilInfoList ( standardStep . oldCoilIds ) ;
standardStep . newCoilInfoList = this . mapCoilInfoList ( standardStep . newCoilIds ) ;
// 8. 回滚专属:删除/恢复钢卷信息映射
if ( standardStep . action === '回滚' ) {
standardStep . deletedCoilInfo = standardStep . oldCoilInfoList [ 0 ] || null ;
standardStep . restoredCoilInfo = standardStep . newCoilInfoList [ 0 ] || null ;
}
return standardStep ;
} ,
// 映射钢卷ID列表为关键信息列表( 适配接口返回结构)
mapCoilInfoList ( coilIds ) {
if ( ! coilIds || ! coilIds . length ) return [ ] ;
return coilIds . map ( coilId => {
const coil = this . coilDetails [ coilId ] || { } ;
// 提取关键信息( 对应list接口返回结构)
return {
enterCoilNo : coil . enterCoilNo || '-' ,
currentCoilNo : coil . currentCoilNo || '-' ,
materialType : coil . materialType || '-' ,
itemName : coil . itemName || '-' ,
specification : coil . specification || '-' ,
material : coil . material || '-' ,
netWeight : coil . netWeight || 0 ,
warehouseName : coil . warehouseName || '-' ,
actualWarehouseName : coil . actualWarehouseName || '-' ,
manufacturer : coil . manufacturer || '-' ,
zincLayer : coil . zincLayer || '-' ,
qualityStatus : coil . qualityStatus || '-' ,
createTime : coil . createTime || '-' ,
} ;
} ) ;
} ,
// 收集所有需要查询的coilIds( 基于标准化step, 仅保留coilId逻辑)
collectCoilIds ( ) {
if ( ! this . standardSteps . length ) return [ ] ;
const coilIds = new Set ( ) ;
this . standardSteps . forEach ( step => {
// 操作前钢卷ID
step . oldCoilIds . forEach ( id => id && coilIds . add ( id ) ) ;
// 操作后钢卷ID
step . newCoilIds . forEach ( id => id && coilIds . add ( id ) ) ;
} ) ;
return [ ... coilIds ] ;
} ,
// 防抖函数:避免频繁调用接口
debounce ( func , delay = 300 ) {
let timer = null ;
return ( ... args ) => {
if ( timer ) clearTimeout ( timer ) ;
timer = setTimeout ( ( ) => {
func . apply ( this , args ) ;
} , delay ) ;
} ;
} ,
// 防抖版获取钢卷详情
debounceFetchCoilDetails : function ( ) {
return this . debounce ( this . fetchCoilDetails ) ( ) ;
} ,
// 核心: 批量获取钢卷详情( 仅按coilId查询, 移除coilNo相关逻辑)
async fetchCoilDetails ( ) {
// 1. 收集所有唯一的coilId
const coilIds = this . collectCoilIds ( ) . filter ( id => id ) ;
if ( coilIds . length === 0 ) {
this . coilDetails = { } ;
return ;
}
// 2. 避免重复请求(加载中则返回)
if ( this . loadingCoilDetails ) return ;
this . loadingCoilDetails = true ;
try {
// 3. 调用listMaterialCoil接口, 传递coilIds参数( 适配接口要求)
const res = await listMaterialCoil ( { coilIds : coilIds . join ( ',' ) } ) ;
if ( res && res . code === 200 && res . rows ) {
const coilList = res . rows ;
// 4. 构建缓存: 仅按coilId缓存( 移除coilNo缓存)
const coilIdMap = { } ;
coilList . forEach ( coil => {
if ( coil . coilId ) coilIdMap [ coil . coilId ] = coil ;
} ) ;
this . coilDetails = coilIdMap ;
// 缓存更新后,重新映射标准化步骤的钢卷信息
this . standardSteps . forEach ( step => {
step . oldCoilInfoList = this . mapCoilInfoList ( step . oldCoilIds ) ;
step . newCoilInfoList = this . mapCoilInfoList ( step . newCoilIds ) ;
if ( step . action === '回滚' ) {
step . deletedCoilInfo = step . oldCoilInfoList [ 0 ] || null ;
step . restoredCoilInfo = step . newCoilInfoList [ 0 ] || null ;
}
} ) ;
console . log ( '更新后的标准化步骤:' , this . standardSteps ) ;
} else {
this . $message . warning ( '获取钢卷详情失败' ) ;
}
} catch ( error ) {
console . error ( '获取钢卷详情接口异常:' , error ) ;
this . $message . error ( '获取钢卷详情异常,请刷新重试' ) ;
} finally {
this . loadingCoilDetails = false ;
}
} ,
} ,
// 组件销毁前清空缓存,避免内存泄漏
beforeDestroy ( ) {
this . coilDetails = { } ;
}
} ;
< / script >
< style scoped >
/* 溯源结果样式 */
/* 原有基础样式保留,优化新增样式适配关键信息展示 */
. trace - result - container {
padding : 10 px 0 ;
}
@@ -300,31 +514,13 @@ export default {
margin - bottom : 20 px ;
}
/* 二维码信息样式 */
. qrcode - info {
padding : 10 px 0 ;
}
. info - row {
margin - bottom : 12 px ;
align - items : center ;
}
. info - label {
color : # 666 ;
font - weight : 500 ;
}
. info - value {
color : # 333 ;
font - weight : 500 ;
}
/* 操作步骤样式 */
/* 操作步骤样式增强 */
. step - header {
display : flex ;
align - items : center ;
margin - bottom : 12 px ;
flex - wrap : wrap ;
gap : 8 px ;
}
. step - action {
@@ -339,13 +535,14 @@ export default {
}
. detail - row {
margin - bottom : 8 px ;
align - items : center ;
margin - bottom : 12 px ;
align - items : flex - start ;
}
. detail - label {
color : # 666 ;
font - size : 14 px ;
padding - top : 4 px ;
}
. detail - value {
@@ -358,65 +555,68 @@ export default {
margin - bottom : 8 px ;
}
/* 钢卷分支图 样式 */
. branch - container {
padding : 10 px 0 ;
}
. branch - group {
margin - bottom : 20 px ;
}
. branch - group - header {
display : flex ;
align - items : center ;
margin - bottom : 12 px ;
justify - content : space - between ;
}
. branch - count {
color : # 666 ;
font - size : 14 px ;
}
. branch - coils {
margin - bottom : 10 px ;
}
. coil - card {
height : 100 % ;
display : flex ;
flex - direction : column ;
}
. coil - header {
display : flex ;
justify - content : space - between ;
align - items : center ;
margin - bottom : 10 px ;
}
. coil - no {
font - size : 15 px ;
font - weight : 600 ;
color : # 333 ;
}
. coil - info {
flex : 1 ;
}
. coil - detail {
font - size : 13 px ;
color : # 666 ;
/* 修改字段 样式 */
. changed - field - item {
margin - bottom : 4 px ;
margin : 0 ;
line - height : 1.5 ;
}
. old - value {
color : # F56C6C ;
}
. new - value {
color : # 67 C23A ;
}
/* 空提示样式 */
. empty - tip {
text - align : center ;
padding : 40 px 0 ;
}
/* 新增:钢卷详情弹窗样式(优化排版,展示更多信息) */
. coil - detail - item {
font - size : 13 px ;
line - height : 1.8 ;
color : # 333 ;
}
. coil - detail - item p {
margin : 0 ;
padding : 2 px 0 ;
display : flex ;
justify - content : space - between ;
}
. coil - detail - item p b {
color : # 666 ;
min - width : 80 px ;
}
/* 新增: 钢卷关键信息摘要样式( hover触发弹窗) */
. coil - info - item {
margin - bottom : 8 px ;
display : inline - block ;
margin - right : 12 px ;
}
. coil - info - summary {
cursor : pointer ;
color : # 409 EFF ;
background : # f5faff ;
padding : 4 px 8 px ;
border - radius : 4 px ;
border : 1 px solid # e6f7ff ;
white - space : nowrap ;
}
. coil - info - deleted {
color : # F56C6C ;
background : # fff5f5 ;
}
. coil - info - summary . deleted : hover {
background : # e6f7ff ;
}
< / style >