@@ -22,6 +22,8 @@ import {
releaseOceanBooking ,
requestOceanBookingChange ,
updateOceanBooking ,
listWarehouseLogisticsChannels ,
type OceanLogisticsChannel ,
type OceanBookingAction ,
} from '../api/platformOceanBookings'
import type {
@@ -74,24 +76,32 @@ const partners = ref<PlatformPartnerResource[]>([])
const warehouses = ref < PlatformWarehouseResource [ ] > ( [ ] )
const optionsLoading = ref ( false )
const optionsError = ref ( '' )
const channels = ref < OceanLogisticsChannel [ ] > ( [ ] )
const channelsLoading = ref ( false )
const channelsError = ref ( '' )
const selectedChannelName = ref ( '' )
let channelRequestSerial = 0
const selectableCustomers = computed ( ( ) => customers . value . filter ( ( customer ) => (
customer . status === 'ACTIVE' || String ( customer . id ) === String ( form . data . customerId )
) ) )
const shippingCompanies = computed ( ( ) => partners . value . filter ( ( partner ) => partner . types . includes ( 'CARRIER' ) ) )
const bookingAgents = computed ( ( ) => partners . value . filter ( ( partner ) => partner . types . some ( ( type ) => [ 'SUPPLIER' , 'CUSTOMS_BROKER' ] . includes ( type ) ) ) )
const channelUnavailable = computed ( ( ) => Boolean ( form . data . warehouseId ) && ! channelsLoading . value && ! channelsError . value && channels . value . length === 0 )
function blankParties ( ) : OceanBookingParty [ ] {
return partyTypes . map ( ( { value } ) => ( { partyType : value , partyName : '' , contactName : '' , contactPhone : '' , address : '' } ) )
}
function blankData ( ) : OceanBookingDraftData {
return {
customerId : '' , customerName : '' , channelCode : '' , channelName : '' , warehouseId : '' , warehouseName : '' , parties : blankParties ( ) ,
customerId : '' , customerName : '' , channelCode : '' , warehouseId : '' , warehouseName : '' , parties : blankParties ( ) ,
containerRequirements : [ createBlankContainerRequirement ( ) ] ,
}
}
const form = reactive < OceanBookingSaveRequest > ( { expectedVersion : 0 , data : blankData ( ) } )
const rules : FormRules = {
customerId : [ { required : true , message : '请选择客户' , trigger : 'change' } ] ,
warehouseId : [ { required : true , message : '请选择装柜仓库' , trigger : 'change' } ] ,
channelCode : [ { required : true , message : '请选择物流渠道' , trigger : 'change' } ] ,
}
const editable = computed ( ( ) => isNew . value || detail . value ? . status === 'DRAFT' )
const canSave = computed ( ( ) => isNew . value
@@ -115,11 +125,11 @@ async function loadOptions() {
const [ customerResult , partnerResult , warehouseResult ] = await Promise . all ( [
listPlatformTenants ( { page : 1 , size : 200 , status : 'ACTIVE' } ) ,
listPlatformPartners ( { page : 1 , size : 200 , status : 'ACTIVE' } ) ,
listPlatformWarehouses ( { page : 1 , size : 200 , status : 'ACTIVE' } ) ,
listPlatformWarehouses ( { page : 1 , size : 200 , warehouseType : 'DOMESTIC' , status : 'ACTIVE' } ) ,
] )
customers . value = customerResult . records . filter ( ( customer ) => customer . status === 'ACTIVE' )
partners . value = partnerResult . records
warehouses . value = warehouseResult . records
warehouses . value = warehouseResult . records . filter ( ( warehouse ) => warehouse . status === 'ACTIVE' && warehouse . warehouseType === 'DOMESTIC' )
} catch ( cause ) {
optionsError . value = getApiErrorDetails ( cause , '客户及合作单位选项加载失败' ) . message
} finally {
@@ -135,6 +145,29 @@ function selectWarehouse(value: unknown) {
const warehouseId = String ( value || '' )
form . data . warehouseId = warehouseId
form . data . warehouseName = warehouses . value . find ( ( warehouse ) => String ( warehouse . id ) === warehouseId ) ? . warehouseName || ''
form . data . channelCode = ''
selectedChannelName . value = ''
channels . value = [ ]
channelsError . value = ''
if ( warehouseId ) void loadChannels ( warehouseId )
}
async function loadChannels ( warehouseId : string ) {
const serial = ++ channelRequestSerial
channelsLoading . value = true
channelsError . value = ''
try {
const result = await listWarehouseLogisticsChannels ( warehouseId )
if ( serial === channelRequestSerial && warehouseId === form . data . warehouseId ) channels . value = result
} catch ( cause ) {
if ( serial === channelRequestSerial ) channelsError . value = getApiErrorDetails ( cause , '物流渠道加载失败' ) . message
} finally {
if ( serial === channelRequestSerial ) channelsLoading . value = false
}
}
function selectChannel ( channelCode : string ) {
const channel = channels . value . find ( ( item ) => item . channelCode === channelCode )
form . data . channelCode = channelCode
selectedChannelName . value = channel ? . channelName || ''
}
function selectPartner ( kind : 'shippingCompany' | 'bookingAgent' , partnerId : string ) {
const partner = partners . value . find ( ( item ) => String ( item . id ) === partnerId )
@@ -150,7 +183,7 @@ function applyDetail(value: OceanBookingDetail) {
detail . value = value
form . expectedVersion = value . version
form . data = {
customerId : value . customerId || '' , customerName : value . customerName || '' , channelCode : value . channelCode || '' , channelName : value . channelName || '' , warehouseId : value . warehouseId || '' , warehouseName : value . warehouseName || '' , billOfLadingNo : value . billOfLadingNo ,
customerId : value . customerId || '' , customerName : value . customerName || '' , channelCode : value . channelCode || '' , warehouseId : value . warehouseId || '' , warehouseName : value . warehouseName || '' , billOfLadingNo : value . billOfLadingNo ,
shippingCompanyId : value . shippingCompanyId , shippingCompanyName : value . shippingCompanyName ,
bookingAgentId : value . bookingAgentId , bookingAgentName : value . bookingAgentName ,
vesselName : value . vesselName , voyageNo : value . voyageNo ,
@@ -162,6 +195,9 @@ function applyDetail(value: OceanBookingDetail) {
parties : value . parties . length ? value . parties . map ( ( { partyType , partyName , contactName , contactPhone , address } ) => ( { partyType , partyName , contactName , contactPhone , address } ) ) : blankParties ( ) ,
containerRequirements : value . containerRequirements . length ? value . containerRequirements . map ( ( { containerType , containerKind , capacityCbm , maxWeightKg , quantity } ) => ( { containerType , containerKind , capacityCbm : capacityCbm ? ? null , maxWeightKg : maxWeightKg ? ? null , quantity : quantity ? ? null } ) ) : [ createBlankContainerRequirement ( ) ] ,
}
selectedChannelName . value = value . channelName || ''
channels . value = [ ]
if ( form . data . warehouseId ) void loadChannels ( form . data . warehouseId )
}
async function load ( ) {
if ( ! id . value || isNew . value ) return
@@ -182,13 +218,14 @@ async function save() {
saving . value = true
actionError . value = null
try {
const payload = { ... form . data }
if ( isNew . value ) {
const created = await createOceanBooking ( { expectedVersion : 0 , data : form . data } )
const created = await createOceanBooking ( { expectedVersion : 0 , data : payload } )
ElMessage . success ( '订舱已创建' )
await router . replace ( ` /ocean-bookings/ ${ created . id } ` )
applyDetail ( created )
} else {
applyDetail ( await updateOceanBooking ( id . value , { expectedVersion : form . expectedVersion , data : form . data } ) )
applyDetail ( await updateOceanBooking ( id . value , { expectedVersion : form . expectedVersion , data : payload } ) )
ElMessage . success ( '订舱草稿已保存' )
}
} catch ( cause ) { actionError . value = getApiErrorDetails ( cause ) }
@@ -307,27 +344,26 @@ onMounted(() => { void load(); void loadOptions() })
< el-alert v-if = "optionsError" type="warning" :closable="false" show-icon :title="optionsError"><el-button link type="warning" :loading="optionsLoading" @click="loadOptions" > 重新加载选项 < / el -button > < / el-alert >
< el-form ref = "formRef" :model = "form.data" :rules = "rules" label -position = " top " :disabled = "!editable" class = "booking-groups" >
< section class = "booking-group" aria -label = " 基本信息 " >
< h3 > 基本信息 < / h3 > < div class = "booking-group__body" >
< h3 > 基本信息 < / h3 > < div class = "booking-group__body booking-group__body--fields " >
< el-form-item label = "订舱号" > < el-input : model -value = " detail ? .bookingNo | | ' 保存后生成 ' " disabled / > < / el-form-item >
< el-form-item label = "客户" prop = "customerId" > < el-select :model-value = "form.data.customerId" filterable placeholder = "请选择客户" :loading = "optionsLoading" :disabled = "!isNew" style = "width:100%" @ update : model -value = " selectCustomer ( String ( $ event | | ' ' ) ) " > < el-option v-if = "form.data.customerId && !selectableCustomers.some((customer) => String(customer.id) === String(form.data.customerId))" :label="form.data.customerName || '客户名称缺失'" :value="String(form.data.customerId)" /><el-option v-for="customer in selectableCustomers" :key="String(customer.id)" :label="customer.tenantName" :value="String(customer.id)" / > < / el-select > < / el-form-item >
< el-form-item label = "状态" > < el-input : model -value = " detail ? statusLabel ( detail.status ) : ' 待创建 ' " disabled / > < / el-form-item >
< el-form-item label = "渠道编码 " prop = "channelCode" > < el-input v-model = "form.data.channelCode" placeholder="请输入渠道编码" / > < / el-form-item >
< el-form-item label = "渠道名称 " prop = "channelName" > < el-input v-model = "form.data.channelName" placeholder="请输入渠道名称" / > < / el-form-item >
< el-form-item label = "装柜仓库" prop = "warehouseId" > < el-select :model-value = "form.data.warehouseId" filterable placeholder = "请选择装柜仓库" style = "width:100%" @ update :model-value = "selectWarehouse" > < el-option v-for = "warehouse in warehouses" :key="String(warehouse.id)" :label="warehouse.warehouseName" :value="String(warehouse.id)" / > < / el-select > < / el-form-item >
< el-form-item label = "装柜仓库 " prop = "warehouseId" > < el-select :model-value = "form.data.warehouseId" filterable placeholder = "请选择装柜仓库" :loading = "optionsLoading" style = "width:100%" @ update :model-value = "selectWarehouse" > < el-option v-for = "warehouse in warehouses" :key="String(warehouse.id)" :label="warehouse.warehouseName" :value="String(warehouse.id)" / > < / el-select > < / el-form-item >
< el-form-item label = "物流 渠道" prop = "channelCode" > < el-select :model-value = "form.data.channelCode" filterable : disabled = "!form.data.warehouseId || channelsLoading || !!channelsError || channelUnavailable" :loading = "channelsLoading" : placeholder = "form.data.warehouseId ? '请选择物流渠道' : '请先选择装柜仓库'" no -data -text = " 该仓库暂无有效物流渠道 " style = "width:100%" @ update : model -value = " selectChannel ( String ( $ event | | ' ' ) ) " > < el-option v-if = "form.data.channelCode && !channels.some((channel) => channel.channelCode === form.data.channelCode)" :label="selectedChannelName || form.data.channelCode" :value="form.data.channelCode" /><el-option v-for="channel in channels" :key="channel.channelCode" :label="channel.channelName" :value="channel.channelCode"><span>{{ channel.channelName }}</span><small class="channel-code">{{ channel.channelCode }}</small></el-option></el-select><div v-if="channelsError" class="field-error"><span>{{ channelsError }}</span><el-button link type="primary" :loading="channelsLoading" @click="loadChannels(form.data.warehouseId)">重新加载</el-button></div><div v-else-if="channelUnavailable" class="field-hint" > 该仓库暂无有效物流渠道 , 请更换仓库或联系管理员 。 < / div > < / el -form -item >
< el-form-item label = "提单号" > < el-input v-model = "form.data.billOfLadingNo" placeholder="请输入提单号(可选)" / > < / el-form-item >
< el-form-item label = "船公司" > < el-select :model-value = "form.data.shippingCompanyId" filterable clearable placeholder = "请选择船公司" :loading = "optionsLoading" style = "width:100%" @ update : model -value = " selectPartner ( ' shippingCompany ' , String ( $ event | | ' ' ) ) " > < el-option v-if = "form.data.shippingCompanyId && !shippingCompanies.some((partner) => String(partner.id) === String(form.data.shippingCompanyId))" :label="form.data.shippingCompanyName || '船公司名称缺失'" :value="String(form.data.shippingCompanyId)" /><el-option v-for="partner in shippingCompanies" :key="String(partner.id)" :label="partner.partnerName" :value="String(partner.id)" / > < / el-select > < / el-form-item >
< el-form-item label = "订舱代理" > < el-select :model-value = "form.data.bookingAgentId" filterable clearable placeholder = "请选择订舱代理" :loading = "optionsLoading" style = "width:100%" @ update : model -value = " selectPartner ( ' bookingAgent ' , String ( $ event | | ' ' ) ) " > < el-option v-if = "form.data.bookingAgentId && !bookingAgents.some((partner) => String(partner.id) === String(form.data.bookingAgentId))" :label="form.data.bookingAgentName || '订舱代理名称缺失'" :value="String(form.data.bookingAgentId)" /><el-option v-for="partner in bookingAgents" :key="String(partner.id)" :label="partner.partnerName" :value="String(partner.id)" / > < / el-select > < / el-form-item >
< / div >
< / section >
< section class = "booking-group" aria -label = " 航线船期 " >
< h3 > 航线船期 < / h3 > < div class = "booking-group__body" >
< h3 > 航线船期 < / h3 > < div class = "booking-group__body booking-group__body--fields " >
< el-form-item label = "船名" > < el-input v-model = "form.data.vesselName" placeholder="请输入船名" / > < / el-form-item >
< el-form-item label = "航次" > < el-input v-model = "form.data.voyageNo" placeholder="请输入航次" / > < / el-form-item >
< el-form-item label = "起运港代码" > < el-input v-model = "form.data.departurePortCode" placeholder="例如:CNNGB" / > < / el-form-item >
< el-form-item label = "起运港" > < el-input v-model = "form.data.departurePortName" placeholder="例如:宁波港" / > < / el-form-item >
< el-form-item label = "目的港代码" > < el-input v-model = "form.data.destinationPortCode" placeholder="例如:USLAX" / > < / el-form-item >
< el-form-item label = "目的港" > < el-input v-model = "form.data.destinationPortName" placeholder="例如:洛杉矶港" / > < / el-form-item >
< el-form-item label = "交货地点" > < el-input v-model = "form.data.placeOfDelivery" placeholder="请输入最终交货地点" / > < / el-form-item >
< el-form-item class = "booking-field--wide" label = "交货地点" > < el-input v-model = "form.data.placeOfDelivery" placeholder="请输入最终交货地点" / > < / el-form-item >
< el-form-item label = "预计开船" > < el-date-picker v-model = "form.data.estimatedSailingAt" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" placeholder="请选择预计开船时间" style="width:100%" / > < / el-form-item >
< el-form-item label = "预计到港" > < el-date-picker v-model = "form.data.estimatedArrivalAt" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" placeholder="请选择预计到港时间" style="width:100%" / > < / el-form-item >
< / div >
@@ -336,15 +372,27 @@ onMounted(() => { void load(); void loadOptions() })
< h3 > 条款与柜量 < / h3 > < div class = "booking-group__body" >
< el-form-item label = "服务条款" > < el-input v-model = "form.data.serviceTerm" placeholder="例如:CY-CY" / > < / el-form-item >
< el-form-item label = "运费条款" > < el-input v-model = "form.data.freightTerm" placeholder="例如:PREPAID" / > < / el-form-item >
< div v-for = "( container, index) in form.data.containerRequirements" :key="index" class="container-row" >
< el -input v-model = "container.containerType" :disabled="!editable" placeholder="箱型,如 40HC" / >
< el-input v-model = "container.containerKind" :disabled="!editable" placeholder="类型,如 FCL" / >
< el-input-number v-model = "container.capacityCbm" :disabled="!editable" :min="0.01" :precision="2" placeholder="体积 m³" / >
< el-input-number v-model = "container.maxWeightKg" :disabled="!editable" :min="0.01" :precision="2" placeholder="限重 kg" / >
< el-input-number v-model = "container.quantity" :disabled="!editable" :min="1" :max="999" / >
< el-button v-if = "editable" type="danger" plain :disabled ="form.data.containerRequirements.length === 1" @click="removeContainer(index)"><Trash2 :size="15" / > 删除 < / el-button >
< div class = "container-table-wrap" aria -label = " 箱型箱量 " >
< table class = "container-table" >
< thead > < tr > < th scope = "col" > 操作 < / th > < th scope = "col" > 箱型 < / th > < th scope = "col" > 箱种 < / th > < th scope = "col" > 容量 ( m³ ) < / th > < th scope = "col" > 限重 ( kg ) < / th > < th scope = "col" > 数量 < / th > < / tr > < / thead >
< tbody >
< tr v-for = "( container, index) in form.data.containerRequirements" :key="index" >
< td class = "container-table__action" >
< el-tooltip v-if = "editable" :content ="form.data.containerRequirements.length === 1 ? '至少保留一条箱型' : '删除该箱型'" placement="top" >
< span > < el-button circle plain size = "small" type = "danger" : aria -label = " ` 删除箱型 $ { index + 1 } ` " : disabled = "form.data.containerRequirements.length === 1" @click ="removeContainer(index)" > < Trash2 :size = "14" / > < / el-button > < / span >
< / el-tooltip >
< span v-else aria -hidden = " true " > — < / span >
< / td >
< td > < el-input v-model = "container.containerType" :disabled="!editable" placeholder="如 40HC" / > < / td >
< td > < el-input v-model = "container.containerKind" :disabled="!editable" placeholder="如 FCL" / > < / td >
< td > < el-input-number v-model = "container.capacityCbm" :disabled="!editable" :min="0.01" :precision="2" :controls="false" placeholder="请输入容量" / > < / td >
< td > < el-input-number v-model = "container.maxWeightKg" :disabled="!editable" :min="0.01" :precision="2" :controls="false" placeholder="请输入限重" / > < / td >
< td > < el-input-number v-model = "container.quantity" :disabled="!editable" :min="1" :max="999" :controls="false" placeholder="请输入数量" / > < / td >
< / tr >
< / tbody >
< / table >
< / div >
< el-button v-if = "editable" class="add-container" @click="addContainer"><Plus :size="16 " / > 新增箱型 < / el-button >
< el-button v-if = "editable" class="add-container" size="small" @click="addContainer"><Plus :size="15 " / > 新增箱型 < / el-button >
< el-form-item label = "备注" > < el-input v-model = "form.data.remark" type="textarea" :rows="3" placeholder="请输入订舱备注(可选)" / > < / el-form-item >
< / div >
< / section >
@@ -396,5 +444,6 @@ onMounted(() => { void load(); void loadOptions() })
< / template >
< style scoped >
. booking - detail { min - width : 0 } . detail - heading { display : flex ; min - width : 0 ; align - items : flex - start ; gap : 16 px } . booking - page - toolbar { min - width : 0 ; flex : 1 } . section - title p , . history - panel p { margin : 5 px 0 0 ; color : var ( -- cc - muted ) ; font - size : 13 px } . heading - status { display : flex ; align - items : center ; gap : 8 px } . surface - panel { padding : 20 px } . surface - panel h2 { margin : 0 ; font - size : 16 px } . section - title { display : flex ; justify - content : space - between ; gap : 12 px ; align - items : flex - start ; margin - bottom : 18 px } . actions { display : flex ; flex - wrap : wrap ; gap : 8 px } . booking - groups { display : grid ; grid - template - columns : minmax ( 0 , 1.4 fr ) repeat ( 2 , minmax ( 0 , 1 fr ) ) ; gap : 16 px } . booking - group { min - width : 0 ; overflow : hidden ; border : 1 px solid # e8edf3 ; border - radius : 8 px ; background : # fff } . booking - group > h3 { margin : 0 ; padding : 14 px 16 px ; border - bottom : 1 px solid # eef2f6 ; color : # 1 f2937 ; font - size : 14 px } . booking - group _ _body { padding : 16 px } . party - grid { display : grid ; grid - template - columns : repeat ( 3 , minmax ( 0 , 1 fr ) ) ; gap : 12 px ; margin - top : 16 px } . subsection { display : grid ; gap : 10 px ; padding : 14 px ; border : 1 px solid var ( -- cc - border ) ; border - radius : 6 px } . subsection h3 { margin : 0 ; font - size : 14 px } . container - row { display : grid ; grid - template - columns : minmax ( 0 , 1 fr ) minmax ( 0 , 1 fr ) 110 px auto ; gap : 8 px ; margin - bottom : 10 px } . add - container { width : 100 % ; margin - bottom : 18 px } . history - panel strong { font - size : 14 px } @ media ( max - width : 1199 px ) { . booking - groups { grid - template - columns : repeat ( 2 , minmax ( 0 , 1 fr ) ) } . booking - group : last - child { grid - column : 1 / - 1 } } @ media ( max - width : 720 px ) { . booking - groups , . party - grid { grid - template - columns : 1 fr } . booking - group : last - child { grid - column : auto } . container - row { grid - template - columns : 1 fr 1 fr } . detail - heading { flex - direction : column } . booking - page - toolbar { width : 100 % } . section - title { flex - direction : column } . actions { width : 100 % } } @ media ( max - width : 420 px ) { . surface - panel { padding : 12 px } . booking - group _ _body { padding : 14 px } . container - row { grid - template - columns : 1 fr } . actions : deep ( . el - button ) { min - height : 44 px } }
. channel - code { display : block ; margin - left : 8 px ; color : var ( -- cc - muted ) ; font - size : 11 px } . field - error , . field - hint { display : flex ; align - items : center ; justify - content : space - between ; gap : 8 px ; margin - top : 5 px ; color : var ( -- cc - muted ) ; font - size : 12 px ; line - height : 20 px } . field - error { color : var ( -- el - color - danger ) }
. booking - detail { min - width : 0 } . detail - heading { display : flex ; min - width : 0 ; align - items : flex - start ; gap : 16 px } . booking - page - toolbar { min - width : 0 ; flex : 1 } . section - title p , . history - panel p { margin : 5 px 0 0 ; color : var ( -- cc - muted ) ; font - size : 13 px } . heading - status { display : flex ; align - items : center ; gap : 8 px } . surface - panel { padding : 20 px } . surface - panel h2 { margin : 0 ; font - size : 16 px } . section - title { display : flex ; justify - content : space - between ; gap : 12 px ; align - items : flex - start ; margin - bottom : 18 px } . actions { display : flex ; flex - wrap : wrap ; gap : 8 px } . booking - groups { display : grid ; grid - template - columns : minmax ( 0 , 1.4 fr ) repeat ( 2 , minmax ( 0 , 1 fr ) ) ; gap : 16 px } . booking - group { min - width : 0 ; overflow : hidden ; border : 1 px solid # e8edf3 ; border - radius : 8 px ; background : # fff } . booking - group > h3 { margin : 0 ; padding : 14 px 16 px ; border - bottom : 1 px solid # eef2f6 ; color : # 1 f2937 ; font - size : 14 px } . booking - group _ _body { padding : 16 px } . booking - group _ _body -- fields { display : grid ; grid - template - columns : repeat ( 2 , minmax ( 0 , 1 fr ) ) ; column - gap : 12 px } . booking - field -- wide { grid - column : 1 / - 1 } . party - grid { display : grid ; grid - template - columns : repeat ( 3 , minmax ( 0 , 1 fr ) ) ; gap : 12 px ; margin - top : 16 px } . subsection { display : grid ; gap : 10 px ; padding : 14 px ; border : 1 px solid var ( -- cc - border ) ; border - radius : 6 px } . subsection h3 { margin : 0 ; font - size : 14 px } . container - table - wrap { overflow - x : auto ; margin - bottom : 10 px } . container - table { width : 100 % ; min - width : 580 px ; table - layout : fixed ; border - collapse : collapse ; font - size : 12 px } . container - table th , . container - table td { padding : 7 px 6 px ; border - bottom : 1 px solid # eef2f6 ; text - align : left ; vertical - align : middle } . container - table th { background : # fafafa ; color : var ( -- cc - muted ) ; font - weight : 650 ; white - space : nowrap } . container - table th : first - child , . container - table td : first - child { width : 56 px } . container - table th : nth - child ( 2 ) , . container - table td : nth - child ( 2 ) { width : 112 px } . container - table th : nth - child ( 3 ) , . container - table td : nth - child ( 3 ) { width : 88 px } . container - table th : nth - child ( 4 ) , . container - table td : nth - child ( 4 ) , . container - table th : nth - child ( 5 ) , . container - table td : nth - child ( 5 ) { width : 118 px } . container - table th : nth - child ( 6 ) , . container - table td : nth - child ( 6 ) { width : 78 px } . container - table td : deep ( . el - input ) , . container - table td : deep ( . el - input - number ) { width : 100 % ; min - width : 0 } . container - table _ _action { text - align : center ! important } . container - table _ _action : deep ( . el - button ) { width : 28 px ; height : 28 px } . add - container { margin - bottom : 18 px } . history - panel strong { font - size : 14 px } @ media ( max - width : 1599 px ) { . booking - groups { grid - template - columns : repeat ( 2 , minmax ( 0 , 1 fr ) ) } . booking - group : last - child { grid - column : 1 / - 1 } } @ media ( max - width : 720 px ) { . booking - groups , . party - grid { grid - template - columns : 1 fr } . booking - group : last - child { grid - column : auto } . detail - heading { flex - direction : column } . booking - page - toolbar { width : 100 % } . section - title { flex - direction : column } . actions { width : 100 % } } @ media ( max - width : 520 px ) { . booking - group _ _body -- fields { grid - template - columns : 1 fr } . booking - field -- wide { grid - column : auto } } @ media ( max - width : 420 px ) { . surface - panel { padding : 12 px } . booking - group _ _body { padding : 14 px } . actions : deep ( . el - button ) { min - height : 44 px } }
< / style >