@@ -1,7 +1,7 @@
< script setup lang = "ts" >
import { ref , watch } from 'vue'
import { ElMessage , ElMessageBox } from 'element-plus'
import { Clock3 , PackageCheck , RefreshCw , TriangleAlert } from '@lucide/vue'
import { ElMessage } from 'element-plus'
import { CircleAlert , Clock3 , PackageCheck , RefreshCw , TriangleAlert } from '@lucide/vue'
import { confirmMerchantInboundFee } from '@/modules/first-leg/api/inboundBilling'
import type { MerchantInboundBilling } from '@/modules/first-leg/types/inboundBilling'
import {
@@ -55,15 +55,6 @@ async function confirmFee() {
ElMessage . info ( '当前费用已经确认,无需重复操作' )
return
}
try {
await ElMessageBox . confirm (
` 请再次确认费用单 ${ fee . feeNo } ,合计 ${ formatInboundMoney ( fee . totalAmount , fee . currency ) } 。确认后该费用将锁定,平台不能再修改。 ` ,
'二次确认费用' ,
{ type : 'warning' , confirmButtonText : '确认费用无误' , cancelButtonText : '返回核对' } ,
)
} catch {
return
}
confirming . value = true
try {
await confirmMerchantInboundFee ( orderId , fee . feeVersion )
@@ -207,7 +198,7 @@ async function confirmFee() {
< / section >
< el-dialog v-model = "feeDialogOpen" title="确认测量与计费数据" width="min(9 80px, 94vw )" append-to-body @closed="emit('closed')" >
< el-dialog v-model = "feeDialogOpen" class="billing-confirm-dialog" title="确认测量与计费数据" width="min(11 80px, calc(100vw - 40px) )" append-to-body @closed="emit('closed')" >
< div v-if = "props.loading" class="inbound-billing-loading" aria-live="polite" aria-busy="true" >
< el -skeleton :rows = "4" animated / >
< span class = "sr-only" > 正在加载计费重 < / span >
@@ -222,19 +213,12 @@ async function confirmFee() {
< div > < strong > { { props . unavailableMessage } } < / strong > < span > 平台推送计费重后 , 可在这里核对并确认 。 < / span > < / div >
< / div >
< template v-else >
< dl class = "inbound-measurements fee-dialog-summary" >
< div > < dt > 计费总箱数 < / dt > < dd > { { formatInboundNumber ( props . data . measurementSummary . actualPackageCount , 0 ) } } < / dd > < / div >
< div > < dt > 计费总毛重 < / dt > < dd > { { formatInboundMeasure ( props . data . measurementSummary . actualGrossWeightKg , 'kg' ) } } < / dd > < / div >
< div > < dt > 外箱规总体积 < / dt > < dd > { { formatInboundMeasure ( props . data . measurementSummary . actualVolumeCbm , 'm³' ) } } < / dd > < / div >
< div > < dt > 外箱规总材积重 < / dt > < dd > { { formatInboundMeasure ( props . data . measurementSummary . volumeWeightKg , 'kg' ) } } < / dd > < / div >
< div > < dt > 计费体积 < / dt > < dd > { { formatInboundMeasure ( props . data . billingBasis . chargeableVolumeCbm , 'm³' ) } } < / dd > < / div >
< div > < dt > 计费重量 < / dt > < dd > { { formatInboundMeasure ( props . data . billingBasis . chargeableWeightKg , 'kg' ) } } < / dd > < / div >
< div > < dt > 对客单价 < / dt > < dd > { { formatInboundMoney ( props . data . latestFee . unitPrice , props . data . latestFee . currency ) } } / { { props . data . latestFee . chargeUnit } } < / dd > < / div >
< div > < dt > 基础费用 < / dt > < dd > { { formatInboundMoney ( props . data . latestFee . subtotalAmount , props . data . latestFee . currency ) } } < / dd > < / div >
< div > < dt > 附加费用 < / dt > < dd > { { formatInboundMoney ( props . data . latestFee . additionalAmount , props . data . latestFee . currency ) } } < / dd > < / div >
< div > < dt > 费用合计 < / dt > < dd > { { formatInboundMoney ( props . data . latestFee . totalAmount , props . data . latestFee . currency ) } } < / dd > < / div >
< dl class = "fee-dialog-summary" aria -label = " 计费汇总 " >
< div > < dt > 计算重 < / dt > < dd > { { formatInboundMeasure ( props . data . billingBasis . chargeableWeightKg , 'kg' ) } } < / dd > < / div >
< div > < dt > 单价 < / dt > < dd > { { formatInboundMoney ( props . data . latestFee . unitPrice , props . data . latestFee . currency ) } } / { { props . data . latestFee . chargeUnit . toUpperCase ( ) } } < / dd > < / div >
< div > < dt > 总金额 < / dt > < dd > { { formatInboundMoney ( props . data . latestFee . totalAmount , props . data . latestFee . currency ) } } < / dd > < / div >
< / dl >
< el-table v-if = "props.data?.measurementItems.length" class=" measurement-detail-table" :data= "props.data.measurementItems" border size="small" >
< el-table class = "measurement-detail-table fee-dialog -table" :data = "props.data.measurementItems" border empty -text = " 暂无箱规测量明细 " >
< el-table-column type = "index" label = "#" width = "54" / >
< el-table-column prop = "lengthCm" label = "箱规长(cm)" min -width = " 105 " / >
< el-table-column prop = "widthCm" label = "箱规宽(cm)" min -width = " 105 " / >
@@ -246,15 +230,11 @@ async function confirmFee() {
< el-table-column label = "箱规规则" min -width = " 170 " > < template # default = "{ row }" > { { getCalculationRuleLabel ( row . calculationRuleVersion ) } } < / template > < / el-table-column >
< el-table-column prop = "boxSpecification" label = "备注" min -width = " 130 " / >
< / el-table >
< el-alert
v-if = "props.data.latestFee.customerConfirmationStatus === 'CONFIRMED'"
class = "fee-confirmed-alert"
: title = "`客户已于 ${formatInboundDateTime(props.data.latestFee.customerConfirmedAt)} 确认,费用已锁定,不允许修改。`"
type = "success"
:closable = "false"
show -icon
/ >
< el-alert v-else class = "fee-confirmed-alert" title = "请核对计费量、对客单价和费用合计。确认后当前费用版本将锁定。" type = "warning" :closable = "false" show -icon / >
< div class = "fee-confirm-notice" : class = "{ 'is-confirmed': props.data.latestFee.customerConfirmationStatus === 'CONFIRMED' }" role = "status" >
< CircleAlert :size = "21" aria -hidden = " true " / >
< span v-if = "props.data.latestFee.customerConfirmationStatus === 'CONFIRMED'" > 客户已于 {{ formatInboundDateTime ( props.data.latestFee.customerConfirmedAt ) }} 确认 , 费用已锁定 , 不允许修改 。 < / span >
< span v-else > 请核对计算重 、 单价和总金额 。 确认后当前费用版本将锁定 。 < / span >
< / div >
< / template >
< template # footer >
< el-button @click ="feeDialogOpen = false" > 关闭 < / el -button >
@@ -290,8 +270,25 @@ async function confirmFee() {
. inbound - measurements { display : grid ; grid - template - columns : repeat ( 3 , minmax ( 0 , 1 fr ) ) ; margin : 10 px 0 0 ; background : # f6f8f8 ; }
. inbound - measurements > div { min - width : 0 ; padding : 12 px ; }
. measurement - detail - table { margin - top : 12 px ; }
. fee - dialog - summary { margin - top : 0 ; }
. fee - confirmed - alert { margin - top : 14 px ; }
. fee - dialog - summary { display : grid ; grid - template - columns : repeat ( 3 , minmax ( 0 , 1 fr ) ) ; gap : 12 px ; margin : 0 ; }
. fee - dialog - summary > div { position : relative ; min - width : 0 ; overflow : hidden ; padding : 13 px 17 px ; border : 1 px solid # e4e8f2 ; border - radius : 11 px ; background : linear - gradient ( 145 deg , # fff , # f8f9fc ) ; box - shadow : 0 5 px 16 px rgba ( 51 , 65 , 85 , .04 ) ; }
. fee - dialog - summary > div : : before { position : absolute ; inset : 0 auto 0 0 ; width : 4 px ; background : # a7b4ef ; content : '' ; }
. fee - dialog - summary > div : nth - child ( 2 ) : : before { background : # 7 d91eb ; }
. fee - dialog - summary > div : nth - child ( 3 ) { border - color : # cdd7ff ; background : linear - gradient ( 145 deg , # f8faff , # eef2ff ) ; box - shadow : 0 8 px 22 px rgba ( 82 , 110 , 232 , .09 ) ; }
. fee - dialog - summary > div : nth - child ( 3 ) : : before { background : # 526 ee8 ; }
. fee - dialog - summary dt { margin : 0 0 3 px ; color : # 7 b8494 ; font - size : 13 px ; font - weight : 500 ; }
. fee - dialog - summary dd { margin : 0 ; overflow - wrap : anywhere ; color : # 283246 ; font - size : 20 px ; font - weight : 700 ; font - variant - numeric : tabular - nums ; letter - spacing : 0 ; }
. fee - dialog - summary > div : nth - child ( 3 ) dt { color : # 6578 c5 ; }
. fee - dialog - summary > div : nth - child ( 3 ) dd { color : # 405 fd8 ; font - size : 22 px ; }
. fee - dialog - table { margin - top : 16 px ; overflow : hidden ; border - radius : 10 px ; box - shadow : 0 5 px 18 px rgba ( 51 , 65 , 85 , .04 ) ; }
. fee - dialog - table : deep ( . el - table _ _header th . el - table _ _cell ) { height : 42 px ; padding : 9 px 0 ; background : linear - gradient ( 180 deg , # f8f9fc , # f3f5f9 ) ; color : # 697386 ; font - size : 13 px ; font - weight : 650 ; }
. fee - dialog - table : deep ( . el - table _ _body td . el - table _ _cell ) { height : 82 px ; padding : 9 px 0 ; color : # 515 a6c ; font - size : 14 px ; font - variant - numeric : tabular - nums ; }
. fee - dialog - table : deep ( . el - table _ _body td : nth - child ( 7 ) ) , . fee - dialog - table : deep ( . el - table _ _body td : nth - child ( 8 ) ) { color : # 34466 b ; font - weight : 650 ; }
. fee - dialog - table : deep ( . cell ) { line - height : 1.6 ; }
. fee - confirm - notice { display : flex ; align - items : center ; gap : 10 px ; margin - top : 14 px ; padding : 10 px 14 px ; border : 1 px solid # f5dfba ; border - radius : 9 px ; background : linear - gradient ( 90 deg , # fff9ef , # fffaf2 ) ; color : # c6790c ; font - size : 14 px ; font - weight : 500 ; }
. fee - confirm - notice > svg { flex : 0 0 auto ; fill : # eda332 ; color : # fff ; filter : drop - shadow ( 0 2 px 3 px rgba ( 233 , 154 , 37 , .25 ) ) ; }
. fee - confirm - notice . is - confirmed { border - color : # b7dfc2 ; background : # f1faf3 ; color : # 2 d8a46 ; }
. fee - confirm - notice . is - confirmed > svg { fill : # 4 eae67 ; }
. pallet - location - list { margin - top : 9 px ; border - top : 1 px solid var ( -- border ) ; }
. pallet - location - list article { display : grid ; grid - template - columns : auto minmax ( 0 , 1 fr ) auto ; align - items : center ; gap : 11 px ; padding : 12 px 0 ; border - bottom : 1 px solid var ( -- border ) ; }
. pallet - location - list article > svg { color : var ( -- primary ) ; }
@@ -315,7 +312,26 @@ async function confirmFee() {
. inbound - public - remark strong { color : var ( -- navy ) ; font - size : 11 px ; }
. inbound - public - remark p { margin : 5 px 0 0 ; overflow - wrap : anywhere ; color : var ( -- muted ) ; font - size : 11 px ; line - height : 1.55 ; white - space : pre - wrap ; }
: global ( . billing - confirm - dialog ) { max - height : calc ( 100 vh - 40 px ) ; overflow : hidden ; border - radius : 14 px ; box - shadow : 0 28 px 90 px rgba ( 17 , 24 , 39 , .33 ) ; }
: global ( . billing - confirm - dialog . el - dialog _ _header ) { display : flex ; align - items : center ; min - height : 66 px ; margin : 0 ; padding : 16 px 22 px 14 px ; border - bottom : 1 px solid # edf0f5 ; }
: global ( . billing - confirm - dialog . el - dialog _ _title ) { color : # 252 b38 ; font - size : 22 px ; font - weight : 700 ; line - height : 1.4 ; letter - spacing : 0 ; }
: global ( . billing - confirm - dialog . el - dialog _ _headerbtn ) { top : 14 px ; right : 20 px ; width : 36 px ; height : 36 px ; border - radius : 50 % ; background : # f5f6f9 ; }
: global ( . billing - confirm - dialog . el - dialog _ _headerbtn : hover ) { background : # e9edfa ; }
: global ( . billing - confirm - dialog . el - dialog _ _headerbtn . el - dialog _ _close ) { color : # 8 b92a0 ; font - size : 22 px ; }
: global ( . billing - confirm - dialog . el - dialog _ _body ) { max - height : calc ( 100 vh - 174 px ) ; overflow : auto ; padding : 18 px 22 px ; }
: global ( . billing - confirm - dialog . el - dialog _ _footer ) { padding : 14 px 22 px 16 px ; border - top : 1 px solid # edf0f5 ; }
: global ( . billing - confirm - dialog . el - dialog _ _footer . el - button ) { min - height : 40 px ; padding : 0 20 px ; border - radius : 8 px ; font - size : 14 px ; font - weight : 650 ; }
: global ( . billing - confirm - dialog . el - dialog _ _footer . el - button -- primary ) { min - width : 168 px ; border - color : # 526 ee8 ; background : linear - gradient ( 135 deg , # 647 fec , # 526 ee8 ) ; box - shadow : 0 7 px 16 px rgba ( 82 , 110 , 232 , .17 ) ; }
@ media ( max - width : 720 px ) {
. fee - dialog - summary { grid - template - columns : 1 fr ; gap : 8 px ; }
. fee - dialog - summary dd , . fee - dialog - summary > div : nth - child ( 3 ) dd { font - size : 18 px ; }
: global ( . billing - confirm - dialog ) { width : calc ( 100 vw - 16 px ) ! important ; max - height : calc ( 100 vh - 16 px ) ; }
: global ( . billing - confirm - dialog . el - dialog _ _header ) { padding : 14 px 16 px 11 px ; }
: global ( . billing - confirm - dialog . el - dialog _ _title ) { font - size : 19 px ; }
: global ( . billing - confirm - dialog . el - dialog _ _body ) { max - height : calc ( 100 vh - 145 px ) ; padding : 14 px 16 px ; }
: global ( . billing - confirm - dialog . el - dialog _ _footer ) { padding : 12 px 16 px ; }
: global ( . billing - confirm - dialog . el - dialog _ _footer . el - button ) { min - height : 38 px ; padding : 0 14 px ; font - size : 13 px ; }
. inbound - billing - state { grid - template - columns : auto minmax ( 0 , 1 fr ) ; }
. inbound - billing - state . el - button { grid - column : 1 / - 1 ; width : 100 % ; min - height : 44 px ; }
. inbound - overview , . inbound - measurements , . fee - calculation - grid { grid - template - columns : 1 fr ; }