修复业务模块bug

This commit is contained in:
2026-08-13 14:07:04 +08:00
parent 6554ad80dd
commit f62e36e846
15 changed files with 941 additions and 186 deletions
@@ -41,13 +41,13 @@
<div>
<el-checkbox v-model="route.selected" :label="`${route.segmentNo}${route.departureName} → ${route.arrivalName}`" />
</div>
<div>总量 {{ formatQuantity(totalQuantity) }}已调度 <em>{{ formatQuantity(route.dispatchedQuantity) }}</em>剩余 <em>{{ formatQuantity(remaining(route)) }}</em></div>
<div>总量 {{ formatQuantity(totalQuantity) }}已调度 <em>{{ formatQuantity(dispatchedQuantity(route)) }}</em>剩余 <em>{{ formatQuantity(remaining(route)) }}</em></div>
</header>
<div v-show="route.selected" class="segment-content">
<el-form :model="route" label-position="right" label-width="auto" class="dispatch-form">
<el-row :gutter="16">
<el-col :span="24">
<el-form-item label="运输类型" required class="transport-type-field"><el-input :model-value="route.transportType" readonly /></el-form-item>
<el-form-item label="运输方式" required class="transport-type-field"><el-input :model-value="route.transportType" readonly /></el-form-item>
</el-col>
<el-col v-if="isRoad(route)" :span="8">
<el-form-item label="单据类型" required>
@@ -74,10 +74,10 @@
<div class="goods-heading"><h3>货物信息</h3><div><el-link type="primary" @click="addGoods(route)">新增货物</el-link></div></div>
<el-table :data="route.goods" border class="goods-table">
<el-table-column type="index" label="序号" width="64" />
<el-table-column label="货物名称" min-width="180"><template #default="{ row }"><el-select v-model="row.sourceIndex" placeholder="请选择总单货物" @change="selectGoods(route, row)"><el-option v-for="item in masterGoods" :key="item.sourceIndex" :label="item.label" :value="item.sourceIndex" /></el-select></template></el-table-column>
<el-table-column label="货物类型" min-width="130"><template #default="{ row }"><el-input :model-value="row.cargoType" readonly /></template></el-table-column>
<el-table-column label="剩余数量" width="120"><template #default="{ row }">{{ formatQuantity(goodsRemainingQuantity(route, row)) }}</template></el-table-column>
<el-table-column label="本次数量" width="160"><template #default="{ row }"><el-input :model-value="row.dispatchQuantity" inputmode="decimal" placeholder="请输入" @input="value => handleDispatchQuantityInput(route, row, value)" /></template></el-table-column>
<el-table-column label="货物类型" min-width="180"><template #default="{ row }"><el-cascader v-model="row.cargoTypePath" :options="cargoTypeOptions" :props="cargoTypeCascaderProps" placeholder="请选择货物类型" clearable filterable @change="value => handleCargoTypeChange(route, row, value)" /></template></el-table-column>
<el-table-column label="货物名称" min-width="180"><template #default="{ row }"><el-select v-model="row.sourceIndex" placeholder="请选择总单货物" @change="selectGoods(route, row)"><el-option v-for="item in masterGoodsByCargoType(row)" :key="item.sourceIndex" :label="item.cargoName" :value="item.sourceIndex" /></el-select></template></el-table-column>
<el-table-column prop="remainingQuantity" column-key="remainingQuantity" label="剩余数量" width="150" class-name="goods-table__remaining"><template #default="{ row }">{{ formatQuantity(goodsRemainingQuantity(route, row)) }}</template></el-table-column>
<el-table-column prop="dispatchQuantity" column-key="dispatchQuantity" label="本次数量" width="200" class-name="goods-table__dispatch"><template #default="{ row }"><el-input :model-value="row.dispatchQuantity" inputmode="decimal" placeholder="请输入" @input="value => handleDispatchQuantityInput(route, row, value)" /></template></el-table-column>
<el-table-column prop="quantityUnit" label="数量单位" width="110" />
<el-table-column prop="packageType" label="包装" min-width="110" />
<el-table-column prop="brand" label="品牌" min-width="110" />
@@ -89,11 +89,31 @@
<div class="freight-heading"><h3>运费信息</h3></div>
<el-form :model="route" label-position="right" label-width="auto" class="dispatch-form freight-form">
<el-row :gutter="16">
<el-col :span="6"><el-form-item label="单价"><el-input :model-value="route.unitPrice" inputmode="decimal" placeholder="请输入" @input="value => handleUnitPriceInput(route, value)" /></el-form-item></el-col>
<el-col :span="6"><el-form-item label="计价单位"><el-select v-model="route.priceUnit"><el-option label="元/吨" value="元/吨" /><el-option label="元/件" value="元/件" /></el-select></el-form-item></el-col>
<el-col :span="6"><el-form-item label="重量合计"><el-input :model-value="formatQuantity(dispatchWeight(route))" readonly><template #append></template></el-input></el-form-item></el-col>
<el-col :span="6"><el-form-item label="运费"><el-input :model-value="formatAmount(freightAmount(route))" readonly><template #append></template></el-input></el-form-item></el-col>
<el-row v-for="(item, index) in route.freightItems" :key="item.sourceIndex" :gutter="16">
<el-col :span="6">
<el-form-item :label="`单价${index + 1}`" required>
<el-input :model-value="item.unitPrice" inputmode="decimal" placeholder="请输入" @input="value => handleFreightUnitPriceInput(item, value)">
<template #append><el-select v-model="item.priceUnit" class="freight-unit-select"><el-option label="元/吨" value="元/吨" /><el-option label="元/件" value="元/件" /><el-option label="元/方" value="元/方" /></el-select></template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item :label="`数量${index + 1}`" required>
<el-input :model-value="formatQuantity(item.quantity)" readonly>
<template #append><el-select v-model="item.quantityUnit" class="freight-unit-select" @change="value => handleFreightQuantityUnitChange(route, item, value)"><el-option v-for="unit in quantityUnitOptions" :key="unit" :label="unit" :value="unit" /></el-select></template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item :label="`运费${index + 1}`">
<el-input :model-value="formatAmount(freightAmount(item))" readonly><template #suffix>{{ currencyLabel(route.currency) }}</template></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row v-if="route.freightItems.length" :gutter="16">
<el-col :span="6"><el-form-item label="运费合计"><el-input :model-value="formatAmount(freightTotal(route))" readonly><template #suffix>{{ currencyLabel(route.currency) }}</template></el-input></el-form-item></el-col>
<el-col :span="6"><el-form-item label="其他费用合计"><el-input :model-value="route.otherFeeTotal" inputmode="decimal" placeholder="请输入" @input="value => handleOtherFeeTotalInput(route, value)" /></el-form-item></el-col>
<el-col :span="6"><el-form-item label="币种"><el-select v-model="route.currency"><el-option label="人民币" value="CNY" /><el-option label="美元" value="USD" /><el-option label="欧元" value="EUR" /></el-select></el-form-item></el-col>
</el-row>
</el-form>
@@ -142,6 +162,7 @@
import * as api from '@/api/business/master-order';
import { getList as getCustomerList } from '@/api/vehicle/customer-archive';
import { getList as getDriverList } from '@/api/transportCapacity/driver';
import { isMobile } from '@/utils/validate';
const unwrapRecords = res => {
const data = res?.data || res;
@@ -156,7 +177,7 @@ export default {
props: { id: [String, Number] },
emits: ['back'],
data() {
return { loading: false, submitting: false, master: null, routes: [], pending: [], pendingExpanded: false, editingId: null, driverInputs: {}, carrierOptions: [], driverOptions: [], carrierLoading: false, driverLoading: false };
return { loading: false, submitting: false, master: null, routes: [], pending: [], pendingExpanded: false, editingId: null, driverInputs: {}, carrierOptions: [], driverOptions: [], carrierLoading: false, driverLoading: false, cargoTypeOptions: [], cargoTypeCascaderProps: { label: 'cargoName', value: 'id', children: 'children', emitPath: true }, quantityUnitOptions: ['吨', '千克', '立方米', '件', '车', '箱', '托盘'] };
},
computed: {
totalQuantity() { return (this.master?.goods || []).reduce((sum, item) => sum + Number(item.quantity || 0), 0); },
@@ -186,6 +207,7 @@ export default {
try {
const res = await api.getDetail(this.id);
this.master = res.data?.data || res.data || res;
this.cargoTypeOptions = this.buildMasterCargoTypeOptions(this.master.goods || []);
this.routes = (this.master.routes || []).map((node, index) => this.createRoute(node, index));
} finally { this.loading = false; }
},
@@ -196,26 +218,88 @@ export default {
selected: false,
documentType: '运单',
carrierType: '承运商',
unitPrice: undefined,
priceUnit: '元/吨',
currency: 'CNY',
otherFeeTotal: '',
freightItems: [],
departureName: previous.departureName || '', departureAddress: previous.departureAddress || '', departureContact: previous.departureContact || '', departurePhone: previous.departurePhone || '',
arrivalName: node.departureName || this.master.arrivalName || '', arrivalAddress: node.departureAddress || this.master.arrivalAddress || '', arrivalContact: node.departureContact || '', arrivalPhone: node.departurePhone || '',
goods: [],
};
},
buildMasterCargoTypeOptions(goods = []) {
return [...new Set(goods.map(item => item.cargoType).filter(Boolean))].map(cargoType => ({
id: cargoType,
cargoName: cargoType,
}));
},
masterGoodsByCargoType(row = {}) {
return this.masterGoods.filter(item => !row.cargoType || item.cargoType === row.cargoType);
},
findCargoTypeByPath(path = []) {
let options = this.cargoTypeOptions;
let selected;
(path || []).forEach(id => {
selected = (options || []).find(item => String(item.id) === String(id));
options = selected?.children || [];
});
return selected;
},
findCargoTypePath(cargoType, options = this.cargoTypeOptions, parentPath = []) {
for (const option of options || []) {
const path = [...parentPath, option.id];
if (option.cargoName === cargoType) return path;
const result = this.findCargoTypePath(cargoType, option.children, path);
if (result.length) return result;
}
return [];
},
handleCargoTypeChange(route, row, value) {
const path = Array.isArray(value) ? value : [];
const cargoType = this.findCargoTypeByPath(path);
row.cargoTypePath = path;
row.cargoType = cargoType?.cargoName || '';
const firstGoods = this.masterGoodsByCargoType(row)[0];
if (firstGoods) {
row.sourceIndex = firstGoods.sourceIndex;
this.selectGoods(route, row);
}
else Object.assign(row, { sourceIndex: undefined, cargoName: '', quantity: '', quantityUnit: '' });
this.syncFreightItems(route);
},
isRoad(route) { return String(route.transportType || '').includes('公路'); },
dispatchedQuantity(route) {
return this.quantityNumber(route.dispatchedQuantity) + this.pendingSegmentQuantity(route);
},
remaining(route) {
return Math.max(
0,
this.totalQuantity -
Number(route.dispatchedQuantity || 0) -
this.pendingSegmentQuantity(route)
this.dispatchedQuantity(route)
);
},
formatQuantity(value) { const number = Number(value || 0); return Number.isInteger(number) ? number : number.toFixed(3).replace(/\.?0+$/, ''); },
formatAmount(value) { return Number(value || 0).toFixed(2); },
dispatchWeight(route) { return (route.goods || []).reduce((sum, item) => sum + Number(item.dispatchQuantity || 0), 0); },
freightAmount(route) { return Number(route.unitPrice || 0) * this.dispatchWeight(route); },
freightAmount(item = {}) { return Number(item.unitPrice || 0) * Number(item.quantity || 0); },
freightTotal(route) {
const goodsFreight = (route.freightItems || []).reduce(
(sum, item) => sum + this.freightAmount(item),
0
);
return goodsFreight + Number(route.otherFeeTotal || 0);
},
buildFreightJson(route) {
return JSON.stringify({
currency: route.currency || 'CNY',
totalFreightAmount: this.freightTotal(route),
otherFreightAmount: route.otherFeeTotal || '',
freightItems: (route.freightItems || []).map(item => ({
...item,
freightAmount: this.freightAmount(item),
})),
});
},
currencyLabel(value) { return ({ CNY: '人民币', USD: '美元', EUR: '欧元' })[value] || value || '人民币'; },
quantityNumber(value) { return Number(value || 0); },
goodsKey(goods = {}, includeUnit = true) {
return [
@@ -224,8 +308,20 @@ export default {
includeUnit ? goods.quantityUnit || '' : '',
].join('\u0000');
},
masterGoodsIndex(goods = {}) {
if (goods.sourceIndex !== undefined && goods.sourceIndex !== null && goods.sourceIndex !== '') {
return Number(goods.sourceIndex);
}
return (this.master?.goods || []).findIndex(item =>
item.cargoName === goods.cargoName &&
item.cargoType === goods.cargoType &&
(!goods.quantityUnit || !item.quantityUnit || item.quantityUnit === goods.quantityUnit)
);
},
isSameGoods(left = {}, right = {}) {
if (left.sourceIndex !== undefined && right.sourceIndex !== undefined) return Number(left.sourceIndex) === Number(right.sourceIndex);
const leftIndex = this.masterGoodsIndex(left);
const rightIndex = this.masterGoodsIndex(right);
if (leftIndex >= 0 && rightIndex >= 0) return leftIndex === rightIndex;
return left.cargoName === right.cargoName && left.cargoType === right.cargoType && left.quantityUnit === right.quantityUnit;
},
dispatchedGoodsQuantity(route, row) {
@@ -239,16 +335,29 @@ export default {
},
pendingSegmentQuantity(route) {
return this.pending.reduce((sum, item) => {
if (item.segmentNo !== route.segmentNo) return sum;
if (!this.isSameRouteSegment(route, item)) return sum;
return sum + this.quantityNumber(item.quantity);
}, 0);
},
pendingGoodsQuantity(route, row) {
const goodsIndex = this.masterGoodsIndex(row);
return this.pending.reduce((sum, item) => {
if (item.segmentNo !== route.segmentNo || !this.isSameGoods(item, row)) return sum;
if (!this.isSameRouteSegment(route, item)) return sum;
const pendingGoodsIndex = this.masterGoodsIndex(item);
if (
(goodsIndex >= 0 && pendingGoodsIndex >= 0 && pendingGoodsIndex !== goodsIndex) ||
(goodsIndex < 0 && !this.isSameGoods(item, row))
) {
return sum;
}
return sum + this.quantityNumber(item.quantity);
}, 0);
},
isSameRouteSegment(route = {}, item = {}) {
const routeSegment = route.segmentNo || route.relationNo || '';
const itemSegment = item.segmentNo || item.relationNo || '';
return String(routeSegment) === String(itemSegment);
},
editingGoodsQuantity(route, row) {
return (route.goods || []).reduce((sum, item) => {
if (item === row || !this.isSameGoods(item, row)) return sum;
@@ -270,14 +379,42 @@ export default {
const availableQuantity = this.availableDispatchQuantity(route, row);
if (Number(nextValue || 0) > availableQuantity) {
row.dispatchQuantity = this.formatQuantity(availableQuantity);
this.syncFreightItems(route);
this.$message.warning('本次数量不能超过剩余数量');
return;
}
row.dispatchQuantity = nextValue;
this.syncFreightItems(route);
},
handleUnitPriceInput(route, value) {
handleFreightUnitPriceInput(item, value) {
const [integer = '', decimal = ''] = String(value || '').replace(/[^\d.]/g, '').split('.');
route.unitPrice = decimal || String(value || '').includes('.') ? `${integer}.${decimal.slice(0, 2)}` : integer;
item.unitPrice = decimal || String(value || '').includes('.') ? `${integer}.${decimal.slice(0, 2)}` : integer;
},
handleOtherFeeTotalInput(route, value) {
const [integer = '', decimal = ''] = String(value || '').replace(/[^\d.]/g, '').split('.');
route.otherFeeTotal = decimal || String(value || '').includes('.') ? `${integer}.${decimal.slice(0, 2)}` : integer;
},
validateFreightItems(route) {
for (const [index, item] of (route.freightItems || []).entries()) {
const fields = [
['unitPrice', '单价'],
['priceUnit', '单价单位'],
['quantity', '数量'],
['quantityUnit', '数量单位'],
];
const emptyField = fields.find(
([prop]) => item[prop] === undefined || item[prop] === null || item[prop] === ''
);
if (emptyField) {
this.$message.warning(`${index + 1}条货物的${emptyField[1]}不能为空`);
return false;
}
}
return true;
},
handleFreightQuantityUnitChange(route, freightItem, value) {
const goods = (route.goods || []).find(item => String(item.sourceIndex) === String(freightItem.sourceIndex));
if (goods) goods.quantityUnit = value;
},
handleMileageInput(route, value) {
const [integer = '', decimal = ''] = String(value || '').replace(/[^\d.]/g, '').split('.');
@@ -291,16 +428,46 @@ export default {
return {
...goods,
sourceIndex,
cargoTypePath:
Array.isArray(goods.cargoTypePath) && goods.cargoTypePath.length
? goods.cargoTypePath
: this.findCargoTypePath(goods.cargoType),
dispatchQuantity: undefined,
};
},
addGoods(route) { route.goods.push(this.createGoodsRow()); },
addGoods(route) {
const firstGoods = this.masterGoods[0];
route.goods.push(
firstGoods
? this.createGoodsRow(firstGoods, firstGoods.sourceIndex)
: this.createGoodsRow()
);
this.syncFreightItems(route);
},
selectGoods(route, row) {
const source = (this.master.goods || [])[Number(row.sourceIndex)];
if (!source) return;
Object.assign(row, this.createGoodsRow(source, Number(row.sourceIndex)));
this.syncFreightItems(route);
},
removeGoods(route, index) { route.goods.splice(index, 1); this.syncFreightItems(route); },
syncFreightItems(route) {
const oldItems = route.freightItems || [];
route.freightItems = (route.goods || [])
.filter(item => item.sourceIndex !== undefined && item.sourceIndex !== '')
.map(item => {
const old = oldItems.find(entry => String(entry.sourceIndex) === String(item.sourceIndex)) || {};
return {
...old,
sourceIndex: item.sourceIndex,
cargoName: item.cargoName || '',
quantity: item.dispatchQuantity || '',
quantityUnit: item.quantityUnit || '',
unitPrice: old.unitPrice || '',
priceUnit: old.priceUnit || `元/${item.quantityUnit || '吨'}`,
};
});
},
removeGoods(route, index) { route.goods.splice(index, 1); },
handleCarrierTypeChange(route, value) {
route.carrierType = value;
if (value === '承运商') {
@@ -356,8 +523,11 @@ export default {
const goods = route.goods.filter(item => Number(item.dispatchQuantity) > 0);
if (!goods.length) return this.$message.warning('请填写本次数量');
if (goods.some(item => Number(item.dispatchQuantity) > this.availableDispatchQuantity(route, item))) return this.$message.warning('本次数量不能超过剩余数量');
this.syncFreightItems(route);
if (!this.validateFreightItems(route)) return;
if (!route.estimatedStartTime) return this.$message.warning(`请选择${this.dateStartLabel(route)}`);
if (!route.estimatedEndTime) return this.$message.warning(`请选择${this.dateEndLabel(route)}`);
if (!this.validateRoutePhones(route)) return;
if (route.documentType === '运单') {
if (route.carrierType === '承运商' && (!route.carrierName || !route.vehicleNo)) return this.$message.warning('请填写承运商和车牌号');
if (route.carrierType !== '承运商' && (!route.driverName || !route.driverPhone || !route.vehicleNo || !route.trailerVehicleNo || !route.escortName || !route.escortPhone || route.mileage === undefined || route.mileage === null || route.mileage === '')) return this.$message.warning('请补全自运或网货平台的车辆与人员信息');
@@ -367,11 +537,11 @@ export default {
id: `${route.segmentNo}-${item.cargoName}-${Date.now()}-${Math.random()}`,
batchNo,
segmentNo: route.segmentNo, relationNo: route.segmentNo, documentType: route.documentType, transportType: route.transportType, carrierType: route.carrierType,
carrierName: route.carrierName, driverName: route.driverName, driverPhone: route.driverPhone, vehicleNo: route.vehicleNo, trailerVehicleNo: route.trailerVehicleNo, escortName: route.escortName, escortPhone: route.escortPhone, mileage: route.mileage, unitPrice: route.unitPrice, priceUnit: route.priceUnit, remark: route.remark,
carrierName: route.carrierName, driverName: route.driverName, driverPhone: route.driverPhone, vehicleNo: route.vehicleNo, trailerVehicleNo: route.trailerVehicleNo, escortName: route.escortName, escortPhone: route.escortPhone, mileage: route.mileage, unitPrice: this.freightItemsForGoods(route, item).unitPrice || '', priceUnit: this.freightItemsForGoods(route, item).priceUnit || '', currency: route.currency || 'CNY', freightAmount: this.freightAmount(this.freightItemsForGoods(route, item)), freightTotal: this.freightTotal(route), otherFeeTotal: route.otherFeeTotal || '', freightJson: this.buildFreightJson(route), remark: route.remark,
departureName: route.departureName, departureAddress: route.departureAddress, departureContact: route.departureContact, departurePhone: route.departurePhone,
arrivalName: route.arrivalName, arrivalAddress: route.arrivalAddress, arrivalContact: route.arrivalContact, arrivalPhone: route.arrivalPhone,
estimatedStartTime: route.estimatedStartTime, estimatedEndTime: route.estimatedEndTime,
sourceIndex: item.sourceIndex, cargoName: item.cargoName, cargoType: item.cargoType, quantity: item.dispatchQuantity, quantityUnit: item.quantityUnit, packageType: item.packageType, brand: item.brand, specification: item.specification, model: item.model, materialCode: item.materialCode,
sourceIndex: this.masterGoodsIndex(item), cargoName: item.cargoName, cargoType: item.cargoType, quantity: item.dispatchQuantity, quantityUnit: item.quantityUnit, packageType: item.packageType, brand: item.brand, specification: item.specification, model: item.model, materialCode: item.materialCode,
}));
this.editingId = null;
this.pendingExpanded = true;
@@ -393,13 +563,31 @@ export default {
}
if (goods) goods.dispatchQuantity = item.quantity;
Object.assign(route, item);
this.syncFreightItems(route);
const freightItem = this.freightItemsForGoods(route, goods);
if (freightItem) { freightItem.unitPrice = item.unitPrice || ''; freightItem.priceUnit = item.priceUnit || freightItem.priceUnit; }
this.editingId = item.id;
this.removePending(item.id);
this.$nextTick(() => document.querySelector(`[data-segment="${item.segmentNo}"]`)?.scrollIntoView({ behavior: 'smooth', block: 'start' }));
},
freightItemsForGoods(route, goods) {
return (route.freightItems || []).find(item => String(item.sourceIndex) === String(goods?.sourceIndex)) || {};
},
removePending(id) { this.pending = this.pending.filter(item => item.id !== id); if (this.editingId === id) this.editingId = null; },
validateRoutePhones(route = {}) {
const invalidPhone = [
[route.departurePhone, '发货联系方式'],
[route.arrivalPhone, '收货联系方式'],
[route.driverPhone, '手机号'],
[route.escortPhone, '押运人手机号'],
].find(([value]) => String(value || '').trim() && !isMobile(value));
if (!invalidPhone) return true;
this.$message.warning(`${invalidPhone[1]}格式不正确`);
return false;
},
async submit() {
if (!this.pending.length) return this.$message.warning('请加入待提交调度清单');
if (this.pending.some(item => !this.validateRoutePhones(item))) return;
this.submitting = true;
try { await api.dispatch({ id: this.master.id, dispatches: this.pending.map(({ id, ...item }) => item) }); this.$message.success('调度成功'); this.$emit('back'); } finally { this.submitting = false; }
},
@@ -426,7 +614,8 @@ export default {
.transport-type-field :deep(.el-input) { width: 240px; }
.goods-heading { display: flex; align-items: center; justify-content: space-between; margin: 0 -24px 12px; padding: 14px 24px; border-top: 1px solid #eff1f7; border-bottom: 1px solid #eff1f7; h3 { margin: 0; padding-left: 12px; border-left: 4px solid #409eff; font-size: 16px; } span { color: #909399; font-size: 13px; } }
.freight-heading { margin: 16px 0 12px; h3 { margin: 0; padding-left: 12px; border-left: 4px solid #409eff; font-size: 16px; } }
.goods-table { :deep(th.el-table__cell), :deep(td.el-table__cell) { border-color: #eff1f7; } :deep(.el-table__row--striped td.el-table__cell) { background: #fafafa; } }
.goods-table { :deep(th.el-table__cell), :deep(td.el-table__cell) { border-color: #eff1f7; } :deep(.el-table__row--striped td.el-table__cell) { background: #fafafa; } :deep(.goods-table__remaining .cell) { white-space: nowrap; } :deep(.goods-table__dispatch .el-input) { width: 100%; min-width: 0; } }
.freight-form { :deep(.freight-unit-select) { width: 92px; } }
.carrier-type-form { margin-top: 16px; }
.carrier-form { padding-top: 8px; }
.segment-actions { display: flex; justify-content: flex-end; gap: 12px; padding-top: 4px; }