@@ -422,6 +422,10 @@ function processStatusLabel(status: string | undefined) {
return inboundStatusLabel ( status , inboundProcessStatusLabels )
}
function measurementRowClassName ( { row } : { row : EditableMeasurementItem } ) {
return validationErrors . value [ row . clientKey ] ? . length ? 'measurement-table__row--error' : ''
}
watch (
( ) => [ customerId . value , props . inboundId , canView . value ] as const ,
( ) => {
@@ -548,12 +552,12 @@ defineExpose({ saveDraft, submitForReview, mayMaintain, maySubmit, saving, submi
< div class = "measurement-section__heading" >
< div > < h3 > 原单数据 < / h3 > < p > 原单值仅用于审核对比 , 不参与前端计算 。 < / p > < / div >
< / div >
< div class = "measurement-f orm-grid " >
< label > < span > 原单据号码 ( CKW ) < / span > < el-input : model -value = " form.originalDocumentNo | | ' — ' " readonly / > < / label >
< label > < span > 原单据毛重 ( T . K . GW ) < / span > < el-input :model-value = "formatNumber(form.originalGrossWeightKg)" readonly / > < / label >
< label > < span > 原单据总体积 ( T . CBM ) < / span > < el-input : model -value = " formatNumber ( form.originalVolumeCbm , 4 ) " readonly / > < / label >
< label > < span > 实际品名 < / span > < el-input : model -value = " form.actualGoodsName | | ' — ' " readonly / > < / label >
< / div >
< dl class = "measurement-order-summary " >
< div > < dt > 原单据号码 ( CKW ) < / dt > < dd > { { form . originalDocumentNo || '—' } } < / dd > < / div >
< div > < dt > 原单据毛重 ( T . K . GW ) < / dt > < dd > { { formatNumber ( form . originalGrossWeightKg ) } } < / dd > < / div >
< div > < dt > 原单据总体积 ( T . CBM ) < / dt > < dd > { { formatNumber ( form . originalVolumeCbm , 4 ) } } < / dd > < / div >
< div > < dt > 实际品名 < / dt > < dd > { { form . actualGoodsName || '—' } } < / dd > < / div >
< / dl >
< / section >
< section class = "measurement-section measurement-items-section" >
@@ -562,31 +566,72 @@ defineExpose({ saveDraft, submitForReview, mayMaintain, maySubmit, saving, submi
< el-button v-if = "canManualEntry" type="primary" plain :disabled="!mayCreateManualEntry" @click="openManualEntry"><Plus :size="15" / > 手动录入箱规 < / el-button >
< / div >
< el-empty v-if = "!form.items.length" description="暂无扫描箱测量数据" / >
< article v-for = "(item, index) in form.items" :key="item.clientKey" class="measurement-item" :class="{ 'has-error': validationErrors[item.clientKey]?.length }" >
< header >
< div > < strong > 扫描箱 { { index + 1 } } < / strong > < span > { { item . boxCode || '未关联箱号' } } · { { item . machineNo || '人工录入' } } < / span > < / div >
< / header >
< div class = "measurement-item__grid" >
< label > < span > 箱号 < / span > < el-input : model -value = " item.boxCode | | ' — ' " readonly / > < / label >
< label > < span > 测量长 ( cm ) < / span > < el-input :model-value = "formatNumber(item.lengthCm)" readonly / > < / label >
< label > < span > 测量宽 ( cm ) < / span > < el-input :model-value = "formatNumber(item.widthCm)" readonly / > < / label >
< label > < span > 测量高 ( cm ) < / span > < el-input :model-value = "formatNumber(item.heightCm)" readonly / > < / label >
< label > < span > 确认箱数 * < / span > < el-input-number v-model = "item.packageCount" :min="1" :max="1000000" :step="1" step-strictly co ntrols-position="right" / > < / label >
< label > < span > 每箱毛重 ( kg ) < / span > < el-input :model-value = "formatNumber(item.unitWeightKg)" readonly / > < / label >
< label > < span > 机器编号 < / span > < el-input : model -value = " item.machineNo | | ' — ' " readonly / > < / label >
< label > < span > 测量时间 < / span > < el-input : model -value = " item.measuredAt ? item.measuredAt.replace ( ' T ' , ' ' ) : ' — ' " readonly / > < / label >
< label class = "measurement-image-field" > < span > 当前有效图片 < / span > < el-button :disabled = "!item.intelligentImageFileId" @click ="previewImage(item.intelligentImageFileId)" > < Image :size = "15" / > { { item . intelligentImageFileId ? '预览图片' : '暂无图片 ' } } < / el-button > < / label >
< / div >
< dl class = "measurement-item__results" aria -label = " 服务端计算结果 " >
< div > < dt > 箱规周长 < / dt > < dd > { { formatNumber ( item . serverValues . girthCm ) } } cm < / dd > < / div >
< div > < dt > 单箱体积 < / dt > < dd > { { formatNumber ( item . serverValues . unitVolumeCbm , 4 ) } } CBM < / dd > < / div >
< div > < dt > 总毛重 < / dt > < dd > { { formatNumber ( item . serverValues . totalWeightKg ) } } KG < / dd > < / div >
< div > < dt > 总体积 < / dt > < dd > { { formatNumber ( item . serverValues . totalVolumeCbm , 4 ) } } CBM < / dd > < / div >
< div > < dt > 总材积重 < / dt > < dd > { { formatNumber ( item . serverValues . volumeWeightKg ) } } KG < / dd > < / div >
< / dl >
< / article >
< el-table
v-if = "form.items.length"
:data = "form.items"
border
stripe
table -layout = " fixed "
class = "measurement-table"
:row-class-name = "measurementRowClassName"
>
< el-table-column type = "expand" width = "42" >
< template # default = "{ row }" >
< dl class = "measureme nt- row-details" >
< div > < dt > 机器编号 < / dt > < dd > { { row . machineNo || '人工录入' } } < / dd > < / div >
< div > < dt > 测量时间 < / dt > < dd > { { row . measuredAt ? row . measuredAt . replace ( 'T' , ' ' ) : '—' } } < / dd > < / div >
< div > < dt > 箱规周长 < / dt > < dd > { { formatNumber ( row . serverValues . girthCm ) } } cm < / dd > < / div >
< div > < dt > 备注 < / dt > < dd > { { row . remark || '— ' } } < / dd > < / div >
< / dl >
< / template >
< / el-table-column >
< el-table-column type = "index" label = "#" width = "48" align = "center" / >
< el-table-column label = "箱号" min -width = " 156 " show -overflow -tooltip >
< template # default = "{ row }" > < span class = "measurement-box-code" > { { row . boxCode || '—' } } < / span > < / template >
< / el-table-column >
< el-table-column label = "尺寸 长×宽×高(cm)" width = "166" align = "center" >
< template # default = "{ row }" > { { formatNumber ( row . lengthCm ) } } × { { formatNumber ( row . widthCm ) } } × { { formatNumber ( row . heightCm ) } } < / template >
< / el-table-column >
< el-table-column label = "确认箱数" width = "132" align = "center" >
< template # default = "{ row }" >
< el-input-number
v-model = "row.packageCount"
class = "measurement-count-editor"
aria -label = " 确认箱数 "
:min = "1"
:max = "1000000"
:step = "1"
step -strictly
controls -position = " right "
/ >
< / template >
< / el-table-column >
< el-table-column label = "每箱毛重(kg)" width = "106" align = "right" >
< template # default = "{ row }" > { { formatNumber ( row . unitWeightKg ) } } < / template >
< / el-table-column >
< el-table-column label = "单箱体积(m³)" width = "112" align = "right" >
< template # default = "{ row }" > { { formatNumber ( row . serverValues . unitVolumeCbm , 4 ) } } < / template >
< / el-table-column >
< el-table-column label = "总毛重(kg)" width = "104" align = "right" >
< template # default = "{ row }" > { { formatNumber ( row . serverValues . totalWeightKg ) } } < / template >
< / el-table-column >
< el-table-column label = "总体积(m³)" width = "108" align = "right" >
< template # default = "{ row }" > { { formatNumber ( row . serverValues . totalVolumeCbm , 4 ) } } < / template >
< / el-table-column >
< el-table-column label = "总材积重(kg)" width = "116" align = "right" >
< template # default = "{ row }" > { { formatNumber ( row . serverValues . volumeWeightKg ) } } < / template >
< / el-table-column >
< el-table-column label = "图片" width = "82" align = "center" >
< template # default = "{ row }" >
< el-tooltip : content = "row.intelligentImageFileId ? '预览测量图片' : '暂无测量图片'" >
< el-button text type = "primary" :disabled = "!row.intelligentImageFileId" aria -label = " 预览测量图片 " @click ="previewImage(row.intelligentImageFileId)" >
< Image :size = "16" / >
< / el-button >
< / el-tooltip >
< / template >
< / el-table-column >
< / el-table >
< el-empty v-else description = "暂无扫描箱测量数据" / >
< / section >
< / fieldset >
< / form >
@@ -675,10 +720,13 @@ defineExpose({ saveDraft, submitForReview, mayMaintain, maySubmit, saving, submi
. measurement - section _ _heading { display : flex ; align - items : flex - start ; justify - content : space - between ; gap : 18 px ; margin - bottom : 16 px ; }
. measurement - section _ _heading > div { min - width : 0 ; }
. measurement - form - grid { display : grid ; grid - template - columns : repeat ( 2 , minmax ( 0 , 1 fr ) ) ; gap : 15 px ; }
. measurement - item _ _grid { display : grid ; grid - template - columns : repeat ( 4 , minmax ( 0 , 1 fr ) ) ; gap : 15 px ; }
. measurement - form label , . measurement - item label { display : flex ; min - width : 0 ; flex - direction : column ; gap : 7 px ; color : # 344054 ; font - size : 12 px ; font - weight : 650 ; }
. measurement - form label { display : flex ; min - width : 0 ; flex - direction : column ; gap : 7 px ; color : # 344054 ; font - size : 12 px ; font - weight : 650 ; }
. measurement - form : deep ( . el - input - number ) , . measurement - form : deep ( . el - input ) { width : 100 % ; }
. measurement - image - field : deep ( . el - button ) { width : 100 % ; margin : 0 ; }
. measurement - order - summary { display : grid ; grid - template - columns : repeat ( 4 , minmax ( 0 , 1 fr ) ) ; margin : 0 ; border : 1 px solid var ( -- cc - border ) ; border - radius : 6 px ; background : # fff ; }
. measurement - order - summary > div { min - width : 0 ; padding : 11 px 13 px ; border - right : 1 px solid var ( -- cc - border ) ; }
. measurement - order - summary > div : last - child { border - right : 0 ; }
. measurement - order - summary dt { color : var ( -- cc - muted ) ; font - size : 11 px ; }
. measurement - order - summary dd { margin : 4 px 0 0 ; overflow - wrap : anywhere ; color : var ( -- cc - text ) ; font - size : 13 px ; font - weight : 650 ; }
. measurement - image - preview { display : grid ; min - height : 240 px ; place - items : center ; }
. measurement - image - preview img { display : block ; width : auto ; max - width : 100 % ; max - height : 68 vh ; object - fit : contain ; }
. manual - entry - alert { margin - bottom : 16 px ; }
@@ -686,35 +734,29 @@ defineExpose({ saveDraft, submitForReview, mayMaintain, maySubmit, saving, submi
. manual - entry - form : deep ( . el - input - number ) , . manual - entry - form : deep ( . el - date - editor ) { width : 100 % ; }
. manual - entry - upload { width : 100 % ; }
. measurement - items - section { background : # fafbfc ; }
. measurement - item { overflow : hidden ; margin - top : 14 px ; border : 1 px solid var ( -- cc - border ) ; border - radius : 9 px ; background : # fff ; }
. measurement - item . has - error { border - color : var ( -- el - color - danger - light - 5 ) ; }
. measurement - item > header { display : flex ; align - items : center ; justify - content : space - between ; gap : 14 px ; padding : 12 px 15 px ; border - bottom : 1 px solid var ( -- cc - border ) ; background : # f8fafc ; }
. measurement - item > header > div { display : flex ; min - width : 0 ; flex - direction : column ; gap : 3 px ; }
. measurement - item > header strong { color : var ( -- cc - text ) ; font - size : 13 px ; }
. measurement - item > header span { overflow : hidden ; color : var ( -- cc - muted ) ; font - size : 11 px ; text - overflow : ellipsis ; white - space : nowrap ; }
. measurement - item _ _grid { padding : 16 px ; }
. measurement - item _ _advanced { margin : 0 16 px 16 px ; border - top : 1 px solid var ( -- cc - border ) ; }
. measurement - item _ _advanced summary { padding : 12 px 0 0 ; color : var ( -- cc - primary ) ; font - size : 12 px ; font - weight : 700 ; cursor : pointer ; }
. measurement - item _ _advanced . measurement - item _ _grid { grid - template - columns : repeat ( 3 , minmax ( 0 , 1 fr ) ) ; padding : 14 px 0 0 ; }
. measurement - item _ _advanced . span - two { grid - column : span 3 ; }
. measurement - item _ _results { display : grid ; grid - template - columns : repeat ( 5 , minmax ( 0 , 1 fr ) ) ; margin : 0 ; border - top : 1 px solid var ( -- cc - border ) ; background : # fbfcfe ; }
. measurement - item _ _results > div { min - width : 0 ; padding : 11 px 14 px ; border - right : 1 px solid var ( -- cc - border ) ; }
. measurement - item _ _results > div : last - child { border - right : 0 ; }
. measurement - item _ _results dt { color : var ( -- cc - muted ) ; font - size : 10 px ; }
. measurement - item _ _results dd { margin : 4 px 0 0 ; overflow - wrap : anywhere ; color : # 344054 ; font - size : 12 px ; font - weight : 700 ; }
. measurement - table { width : 100 % ; font - size : 12 px ; }
. measurement - table : deep ( . el - table _ _header th ) { padding : 8 px 0 ; background : # f6f8fa ; color : # 475467 ; font - size : 11 px ; font - weight : 700 ; }
. measurement - table : deep ( . el - table _ _cell ) { padding : 7 px 0 ; }
. measurement - table : deep ( . cell ) { line - height : 1.35 ; }
. measurement - table : deep ( . measurement - table _ _row -- error > td . el - table _ _cell ) { background : var ( -- el - color - danger - light - 9 ) ; }
. measurement - box - code { font - weight : 650 ; }
. measurement - count - editor { width : 104 px ! important ; }
. measurement - row - details { display : grid ; grid - template - columns : repeat ( 4 , minmax ( 0 , 1 fr ) ) ; gap : 8 px 20 px ; margin : 0 ; padding : 4 px 18 px 8 px 62 px ; }
. measurement - row - details dt { color : var ( -- cc - muted ) ; font - size : 11 px ; }
. measurement - row - details dd { margin : 3 px 0 0 ; overflow - wrap : anywhere ; color : var ( -- cc - text ) ; font - size : 12 px ; font - weight : 600 ; }
. measurement - panel _ _footer { position : sticky ; bottom : 0 ; z - index : 2 ; display : flex ; align - items : center ; justify - content : space - between ; gap : 16 px ; padding : 13 px 20 px ; border - top : 1 px solid var ( -- cc - border ) ; background : rgba ( 255 , 255 , 255 , .97 ) ; box - shadow : 0 - 8 px 22 px rgba ( 15 , 23 , 42 , .05 ) ; }
. measurement - panel _ _footer > span { display : inline - flex ; align - items : center ; gap : 6 px ; color : var ( -- cc - muted ) ; font - size : 12 px ; }
. measurement - panel _ _footer > span : has ( svg ) { color : # b54708 ; font - weight : 650 ; }
. sr - only { position : absolute ; width : 1 px ; height : 1 px ; overflow : hidden ; clip : rect ( 0 , 0 , 0 , 0 ) ; white - space : nowrap ; }
@ media ( max - width : 960 px ) {
. measurement - form - grid , . measurement - item _ _grid { grid - template - columns : repeat ( 2 , minmax ( 0 , 1 fr ) ) ; }
. measurement - form - grid { grid - template - columns : repeat ( 2 , minmax ( 0 , 1 fr ) ) ; }
. measurement - order - summary , . measurement - row - details { grid - template - columns : repeat ( 2 , minmax ( 0 , 1 fr ) ) ; }
. measurement - order - summary > div : nth - child ( 2 ) { border - right : 0 ; }
. measurement - order - summary > div : nth - child ( - n + 2 ) { border - bottom : 1 px solid var ( -- cc - border ) ; }
. measurement - metrics { grid - template - columns : repeat ( 2 , minmax ( 0 , 1 fr ) ) ; }
. measurement - metrics > div : nth - child ( 2 ) { border - right : 0 ; }
. measurement - metrics > div : nth - child ( - n + 2 ) { border - bottom : 1 px solid var ( -- cc - border ) ; }
. measurement - item _ _results { grid - template - columns : repeat ( 3 , minmax ( 0 , 1 fr ) ) ; }
. measurement - item _ _results > div : nth - child ( 3 ) { border - right : 0 ; }
. measurement - item _ _results > div : nth - child ( - n + 3 ) { border - bottom : 1 px solid var ( -- cc - border ) ; }
}
@ media ( max - width : 720 px ) {
@@ -724,18 +766,13 @@ defineExpose({ saveDraft, submitForReview, mayMaintain, maySubmit, saving, submi
. measurement - tags { justify - content : flex - start ; }
. measurement - context , . measurement - section { padding - right : 14 px ; padding - left : 14 px ; }
. measurement - panel > : deep ( . el - alert ) , . measurement - alert { margin - right : 14 px ; margin - left : 14 px ; }
. measurement - form - grid , . measurement - item _ _grid , . measurement - item _ _advanced . measurement - item _ _grid { grid - template - columns : 1 fr ; }
. measurement - item _ _advanced . span - two { grid - column : auto ; }
. measurement - item _ _results { grid - template - columns : repeat ( 2 , minmax ( 0 , 1 fr ) ) ; }
. measurement - item _ _results > div { border - right : 1 px solid var ( -- cc - border ) ; border - bottom : 1 px solid var ( -- cc - border ) ; }
. measurement - item _ _results > div : nth - child ( even ) { border - right : 0 ; }
. measurement - item _ _results > div : last - child { border - bottom : 0 ; }
. measurement - form - grid { grid - template - columns : 1 fr ; }
. measurement - row - details { grid - template - columns : 1 fr ; padding - left : 54 px ; }
}
@ media ( max - width : 420 px ) {
. measurement - metrics , . measurement - item _ _results { grid - template - columns : 1 fr ; }
. measurement - metrics > div , . measurement - item _ _results > div { border - right : 0 ; border - bottom : 1 px solid var ( -- cc - border ) ; }
. measurement - metrics > div : last - child , . measurement - item _ _results > div : last - child { border - bottom : 0 ; }
. measurement - item > header { align - items : flex - start ; }
. measurement - metrics , . measurement - order - summary { grid - template - columns : 1 fr ; }
. measurement - metrics > div , . measurement - order - summary > div { border - right : 0 ; border - bottom : 1 px solid var ( -- cc - border ) ; }
. measurement - metrics > div : last - child , . measurement - order - summary > div : last - child { border - bottom : 0 ; }
}
< / style >