调整业务模块

This commit is contained in:
2026-09-04 05:23:34 +08:00
parent c63c7c3e33
commit e789f1647a
10 changed files with 2082 additions and 591 deletions
@@ -1703,7 +1703,7 @@
<div
class="transport-plan-page__dispatch-item-grid transport-plan-page__dispatch-item-grid--full"
>
<template v-for="(group, index) in dispatchItemFreightGroups" :key="group.key">
<template v-for="group in dispatchItemFreightGroups" :key="group.key">
<el-form-item label="单价">
<el-input
:model-value="dispatchFreightGroupUnitPrice(group)"
@@ -1728,11 +1728,15 @@
</el-form-item>
<el-form-item label="数量合计"
><el-input :model-value="dispatchFreightGroupQuantity(group)" disabled
><template #append>{{ group.quantityUnit || '吨' }}</template></el-input
><template #append>{{ fixedQuantityUnit }}</template></el-input
></el-form-item
>
<el-form-item label="运费"
><el-input :model-value="dispatchFreightGroupAmount(group)" disabled
><el-input
:model-value="dispatchFreightGroupAmount(group)"
placeholder="请输入运费"
@input="value => handleDispatchFreightGroupAmountInput(group, value)"
@clear="() => handleDispatchFreightGroupAmountInput(group, '')"
><template #suffix>{{ dispatchItemFreightCurrencyLabel }}</template></el-input
></el-form-item
>
@@ -1886,6 +1890,7 @@
<el-select
v-model="dispatchItemForm.quantityUnit"
class="transport-plan-page__dispatch-unit-select"
clearable
>
<el-option
v-for="item in quantityUnitOptions"
@@ -1954,6 +1959,15 @@
</template>
</el-input>
</el-form-item>
<el-form-item label="运费">
<el-input
v-model="dispatchItemForm.freightAmount"
placeholder="请输入运费"
@input="value => handleDispatchNumberInput('freightAmount', value)"
>
<template #suffix>{{ dispatchItemFreightCurrencyLabel }}</template>
</el-input>
</el-form-item>
<el-form-item label="其他费用合计">
<el-input v-model="dispatchItemForm.otherFeeTotal" placeholder="请输入">
<template #suffix>{{ dispatchItemFreightCurrencyLabel }}</template>
@@ -2857,6 +2871,8 @@ const transportPlanImportColumns = [
['备注', 'remark'],
];
const TRANSPORT_PLAN_QUANTITY_UNIT = '吨';
const defaultTransportCargo = () => ({
cargoName: '',
cargoType: '',
@@ -2908,6 +2924,7 @@ const defaultDispatchRow = () => ({
materialCode: '',
unitPrice: '',
priceUnit: '元/吨',
freightAmount: '',
otherFeeTotal: '',
freightCurrency: 'RMB',
freightJson: '',
@@ -3327,7 +3344,7 @@ export default {
dispatchSummaryItems() {
const summaryMap = new Map();
const addQuantity = (unit, field, quantity) => {
const normalizedUnit = unit || '吨';
const normalizedUnit = unit || TRANSPORT_PLAN_QUANTITY_UNIT;
if (!summaryMap.has(normalizedUnit)) {
summaryMap.set(normalizedUnit, { unit: normalizedUnit, total: 0, assigned: 0 });
}
@@ -3413,6 +3430,9 @@ export default {
dispatchTransportMode() {
return this.resolveTransportMode(this.dispatchItemForm.transportType);
},
fixedQuantityUnit() {
return TRANSPORT_PLAN_QUANTITY_UNIT;
},
dispatchIsRoadTransport() {
return this.dispatchTransportMode === 'road';
},
@@ -3461,27 +3481,30 @@ export default {
},
dispatchItemFreightTotal() {
if (this.dispatchItemForm.taskEntryMode !== 'full') {
const quantity = Number(this.dispatchItemForm.quantity || 0);
const unitPrice = Number(this.dispatchItemForm.unitPrice || 0);
const otherFeeTotal = Number(this.dispatchItemForm.otherFeeTotal || 0);
const hasFreight = this.dispatchItemForm.unitPrice !== '' && quantity > 0;
const freight = this.dispatchItemFreightSubtotal;
const hasFreight = freight !== '';
const hasOtherFee = this.dispatchItemForm.otherFeeTotal !== '';
if (!hasFreight && !hasOtherFee) return '';
const total = (hasFreight ? quantity * unitPrice : 0) + (hasOtherFee ? otherFeeTotal : 0);
const total = (hasFreight ? Number(freight) : 0) + (hasOtherFee ? otherFeeTotal : 0);
return Number.isInteger(total) ? String(total) : String(Number(total.toFixed(2)));
}
const otherFeeTotal = Number(this.dispatchItemForm.otherFeeTotal || 0);
const freightTotal = this.dispatchItemFreightGroups.reduce(
(total, group) => total + Number(this.dispatchFreightGroupAmount(group) || 0),
0
);
const freightSubtotal = this.dispatchItemFreightSubtotal;
const hasOtherFee = this.dispatchItemForm.otherFeeTotal !== '';
if (!freightTotal && !hasOtherFee) return '';
const total = freightTotal + (hasOtherFee ? otherFeeTotal : 0);
if (freightSubtotal === '' && !hasOtherFee) return '';
const total = Number(freightSubtotal || 0) + (hasOtherFee ? otherFeeTotal : 0);
return Number.isInteger(total) ? String(total) : String(Number(total.toFixed(2)));
},
dispatchItemFreightSubtotal() {
if (this.dispatchItemForm.taskEntryMode !== 'full') {
if (
this.dispatchItemForm.freightAmount !== undefined &&
this.dispatchItemForm.freightAmount !== null &&
String(this.dispatchItemForm.freightAmount).trim() !== ''
) {
return this.formatDispatchAmount(this.dispatchItemForm.freightAmount);
}
const quantity = Number(this.dispatchItemForm.quantity || 0);
const unitPrice = Number(this.dispatchItemForm.unitPrice || 0);
if (!quantity || !unitPrice) return '';
@@ -3492,27 +3515,25 @@ export default {
(sum, group) => sum + Number(this.dispatchFreightGroupAmount(group) || 0),
0
);
return total
? Number.isInteger(total)
? String(total)
: String(Number(total.toFixed(2)))
: '';
const hasEnteredAmount = this.dispatchItemFreightGroups.some(group =>
(group.rows || []).some(
cargo =>
cargo.freightAmount !== undefined &&
cargo.freightAmount !== null &&
String(cargo.freightAmount).trim() !== ''
)
);
if (!total && !hasEnteredAmount) return '';
return Number.isInteger(total) ? String(total) : String(Number(total.toFixed(2)));
},
dispatchItemFreightGroups() {
const groups = [];
const groupMap = new Map();
(this.dispatchItemCargoRows || []).forEach((cargo, index) => {
const quantityUnit = String(cargo.quantityUnit || '').trim();
const key = quantityUnit || `__empty_${index}`;
let group = groupMap.get(key);
if (!group) {
group = { key, quantityUnit, rows: [] };
groupMap.set(key, group);
groups.push(group);
}
group.rows.push(cargo);
});
return groups;
return [
{
key: '__all__',
quantityUnit: TRANSPORT_PLAN_QUANTITY_UNIT,
rows: this.dispatchItemCargoRows || [],
},
];
},
dispatchItemFreightCurrencyLabel() {
const value = this.dispatchItemForm.freightCurrency || 'RMB';
@@ -4447,7 +4468,7 @@ export default {
return Number.isFinite(number) ? number : 0;
},
getDispatchQuantityUnit(row = {}) {
return row.quantityUnit || row.goodsQuantityUnit || row.unit || '吨';
return row.quantityUnit || row.goodsQuantityUnit || row.unit || TRANSPORT_PLAN_QUANTITY_UNIT;
},
getDispatchVehicleIdentifier(row = {}) {
return (
@@ -4907,7 +4928,7 @@ export default {
specification: row.specification || row.spec || '',
freightAmount: row.freightAmount ?? row.amount ?? row.totalAmount ?? '',
};
['quantity', 'mileage', 'unitPrice'].forEach(prop => {
['quantity', 'mileage', 'unitPrice', 'freightAmount'].forEach(prop => {
if (Number(cargo[prop]) === -1) cargo[prop] = '';
});
return cargo;
@@ -6908,7 +6929,7 @@ export default {
item.quantityUnit ||
item.goodsQuantityUnit ||
item.unit ||
'吨',
TRANSPORT_PLAN_QUANTITY_UNIT,
specification:
item.specification || item.spec || itemGoods.specification || itemGoods.spec || '',
model: item.model || itemGoods.model || '',
@@ -6968,17 +6989,16 @@ export default {
0
);
const calculatedFreight = unitPrice !== '' && quantity ? Number(unitPrice) * quantity : '';
const freight =
calculatedFreight !== ''
? calculatedFreight
: item.freight ??
item.freightAmount ??
item.transportFee ??
plan.freight ??
plan.freightAmount ??
freightInfo.freightAmount ??
freightInfo.transportFee ??
'';
const explicitFreight = [
item.freight,
item.freightAmount,
item.transportFee,
freightInfo.freightAmount,
freightInfo.transportFee,
plan.freight,
plan.freightAmount,
].find(value => value !== undefined && value !== null && String(value).trim() !== '');
const freight = explicitFreight ?? calculatedFreight;
const freightTotal =
freight !== '' || otherFeeTotal !== ''
? Number(freight || 0) + Number(otherFeeTotal || 0)
@@ -6989,7 +7009,7 @@ export default {
freightInfo.totalFreightAmount ??
freightInfo.freightTotal ??
'';
return { unitPrice, freight, otherFeeTotal, freightTotal };
return { unitPrice, freight, freightAmount: freight, otherFeeTotal, freightTotal };
},
getDispatchWaybillFallback(plan = {}, item = {}, index = 0) {
const sources = [
@@ -7264,6 +7284,8 @@ export default {
...cargo,
unitPrice: cargo.unitPrice || freightInfo.freightItems[itemIndex]?.unitPrice || '',
priceUnit: cargo.priceUnit || freightInfo.freightItems[itemIndex]?.priceUnit || '元/吨',
freightAmount:
cargo.freightAmount || freightInfo.freightItems[itemIndex]?.freightAmount || '',
}));
}
this.dispatchItemAttachmentRows = this.parseJsonArray(
@@ -7480,12 +7502,24 @@ export default {
}
},
dispatchCargoFreightAmount(cargo = {}) {
if (cargo.freightAmount !== undefined && cargo.freightAmount !== null) {
const enteredAmount = String(cargo.freightAmount).trim();
if (enteredAmount !== '' && Number.isFinite(Number(enteredAmount))) {
const amount = Number(enteredAmount);
return Number.isInteger(amount) ? String(amount) : String(Number(amount.toFixed(2)));
}
}
const quantity = Number(cargo.quantity || 0);
const unitPrice = Number(cargo.unitPrice || 0);
if (!quantity || !unitPrice) return '';
const amount = quantity * unitPrice;
return Number.isInteger(amount) ? String(amount) : String(Number(amount.toFixed(2)));
},
formatDispatchAmount(value) {
const amount = Number(value || 0);
if (!Number.isFinite(amount)) return '';
return Number(amount.toFixed(2)).toString();
},
dispatchFreightGroupQuantity(group = {}) {
const quantity = (group.rows || []).reduce(
(sum, cargo) => sum + Number(cargo.quantity || 0),
@@ -7515,6 +7549,7 @@ export default {
const unitPrice = group.rows?.[0]?.unitPrice || '';
(group.rows || []).forEach(cargo => {
cargo.unitPrice = unitPrice;
cargo.freightAmount = '';
});
},
handleDispatchFreightGroupPriceUnitChange(group, value) {
@@ -7522,6 +7557,31 @@ export default {
cargo.priceUnit = value || '';
});
},
handleDispatchFreightGroupAmountInput(group, value) {
const text = String(value || '').replace(/[^\d.]/g, '');
const parts = text.split('.');
const normalized =
parts.length > 1 ? `${parts[0]}.${parts.slice(1).join('').slice(0, 2)}` : parts[0];
const rows = group.rows || [];
const total = Number(normalized || 0);
const quantities = rows.map(cargo => Math.max(0, Number(cargo.quantity || 0)));
const quantityTotal = quantities.reduce((sum, quantity) => sum + quantity, 0);
let allocated = 0;
rows.forEach((cargo, index) => {
if (index === rows.length - 1) {
cargo.freightAmount = this.formatDispatchAmount(total - allocated);
return;
}
let amount = 0;
if (quantityTotal) {
amount = Number((total * (quantities[index] / quantityTotal)).toFixed(2));
} else if (index === 0) {
amount = total;
}
allocated += amount;
cargo.freightAmount = this.formatDispatchAmount(amount);
});
},
dispatchItemRemainingQuantity(row = {}) {
const unit = this.getDispatchQuantityUnit(row);
const hasCargoIdentity = Boolean(
@@ -7718,6 +7778,11 @@ export default {
detailPrefix ? `${goodsPrefix}单价不能小于0` : `${goodsPrefix}单价不能小于0`
);
}
if (!this.isBillingFieldEmpty(goods.freightAmount) && Number(goods.freightAmount) < 0) {
return warn(
detailPrefix ? `${goodsPrefix}运费不能小于0` : `${goodsPrefix}运费不能小于0`
);
}
}
const invalidPhoneField = [
@@ -7854,7 +7919,7 @@ export default {
attachmentsJson: JSON.stringify(this.dispatchItemAttachmentRows),
};
nextRow.cargoInfo = this.formatDispatchCargoInfo({}, nextRow);
nextRow.freight = this.getDispatchFeeFields({}, nextRow).freight;
nextRow.freight = this.dispatchItemFreightSubtotal;
nextRow.otherFeeTotal = this.dispatchItemForm.otherFeeTotal || '';
const quantityUnit = this.getDispatchQuantityUnit(nextRow);
const otherDispatchedQuantity = this.dispatchRows.reduce((total, row, index) => {
@@ -8093,6 +8158,7 @@ export default {
:deep(.el-form-item__content > .el-input),
:deep(.el-form-item__content > .el-select),
:deep(.el-form-item__content > .el-cascader),
:deep(.el-form-item__content > .el-autocomplete),
:deep(.el-form-item__content > .el-input-number),
:deep(.el-form-item__content > .el-date-editor) {
width: 250px;
@@ -8134,7 +8200,9 @@ export default {
&__shipping-title,
&__goods-title {
box-sizing: border-box;
min-width: 100%;
max-width: 100%;
}
&__shipping-title,
@@ -8215,7 +8283,7 @@ export default {
}
&__dispatch-shipping-form &__route-address-row {
grid-template-columns: 260px minmax(280px, 1fr) 58px minmax(160px, 220px) 72px minmax(
grid-template-columns: 260px minmax(280px, 360px) 58px minmax(160px, 220px) 72px minmax(
160px,
220px
);
@@ -8248,8 +8316,10 @@ export default {
&__cargo-wrap {
display: block;
box-sizing: border-box;
width: 100%;
min-width: 0;
max-width: 100%;
overflow: hidden;
}
@@ -8707,13 +8777,21 @@ export default {
}
&__dispatch-item-dialog {
width: calc(100% - 32px) !important;
max-width: 1400px;
:deep(.el-dialog__body) {
min-width: 0;
padding-top: 20px;
overflow-x: hidden;
}
}
&__dispatch-item-form {
box-sizing: border-box;
width: 100%;
min-width: 0;
max-width: 100%;
padding: 16px;
border: 1px solid #ebeef5;
background: #fff;
@@ -8810,7 +8888,10 @@ export default {
}
&__attachment {
box-sizing: border-box;
width: 100%;
min-width: 0;
max-width: 100%;
}
&__attachment-description {
@@ -8832,8 +8913,12 @@ export default {
&__attachment-head {
display: flex;
box-sizing: border-box;
align-items: center;
justify-content: flex-end;
width: 100%;
min-width: 0;
max-width: 100%;
margin-bottom: 16px;
}
@@ -9204,6 +9289,13 @@ export default {
grid-template-columns: 240px minmax(240px, 1fr) 40px 58px minmax(140px, 1fr);
}
&__dispatch-shipping-form &__route-address-row {
grid-template-columns: 240px minmax(240px, 300px) 58px minmax(140px, 180px) 72px minmax(
140px,
180px
);
}
&__route-address-row &__route-label:nth-of-type(2),
&__route-address-row .el-input:last-child {
grid-column: auto;
@@ -9215,6 +9307,10 @@ export default {
grid-template-columns: 1fr;
}
&__dispatch-shipping-form &__route-address-row {
grid-template-columns: 1fr;
}
&__route-label {
text-align: left;
}