fix bug
This commit is contained in:
@@ -32,6 +32,23 @@ const parseJsonArray = value => {
|
||||
}
|
||||
};
|
||||
|
||||
const hasProcessConfig = value => {
|
||||
if (isEmpty(value)) return false;
|
||||
if (typeof value !== 'string') {
|
||||
return Array.isArray(value) ? value.length > 0 : typeof value === 'object';
|
||||
}
|
||||
const text = value.trim();
|
||||
if (!text) return false;
|
||||
try {
|
||||
const result = JSON.parse(text);
|
||||
return Array.isArray(result)
|
||||
? result.length > 0
|
||||
: Boolean(result && Object.keys(result).length);
|
||||
} catch (error) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
const getFirstValue = (row, props) => {
|
||||
const prop = props.find(item => !isEmpty(row[item]));
|
||||
return prop ? row[prop] : '';
|
||||
@@ -96,6 +113,11 @@ export const config = {
|
||||
exportUrl: '/blade-transport/waybill-manage/export-waybill-manage',
|
||||
exportName: '运单管理',
|
||||
importUrl: '/blade-transport/waybill-manage/import-waybill-manage',
|
||||
defaultForm: {
|
||||
carrierType: '承运商',
|
||||
quantityUnit: '吨',
|
||||
priceUnit: '元/吨',
|
||||
},
|
||||
enableAllDept: false,
|
||||
enableProjectSelect: true,
|
||||
templateCreateTarget: 'waybill-manage',
|
||||
@@ -103,6 +125,13 @@ export const config = {
|
||||
enableShippingPlanSelect: true,
|
||||
enableShippingInfoForm: true,
|
||||
enableTaskInfoForm: true,
|
||||
enableWaybillFooterFreightSummary: true,
|
||||
enableDraftSave: true,
|
||||
saveAsDraft: true,
|
||||
skipDraftValidation: true,
|
||||
draftStatusProp: 'businessStatus',
|
||||
draftStatus: 'draft',
|
||||
draftSaveText: '暂存',
|
||||
batchDelete: false,
|
||||
actionButtonLikeSearch: true,
|
||||
createText: '新建运单',
|
||||
@@ -118,6 +147,16 @@ export const config = {
|
||||
actions: ['copy', 'cancel', 'reassign', 'complete', 'batchComplete'],
|
||||
statusProp: 'businessStatus',
|
||||
statusTextProp: 'businessStatusName',
|
||||
formatStatus(row, prop, defaultText) {
|
||||
if (
|
||||
prop === 'businessStatus' &&
|
||||
row.businessStatus === 'pending' &&
|
||||
!hasProcessConfig(row.processJson)
|
||||
) {
|
||||
return '进行中';
|
||||
}
|
||||
return defaultText;
|
||||
},
|
||||
deleteStatus: ['draft'],
|
||||
editStatus: ['draft', 'pending'],
|
||||
};
|
||||
|
||||
@@ -368,19 +368,19 @@
|
||||
</template>
|
||||
|
||||
<template #taskInfoTitle-form>
|
||||
<div class="dialog-section-title">任务信息</div>
|
||||
<div class="dialog-section-title dialog-section-title--action">
|
||||
<span>任务信息</span>
|
||||
<el-segmented
|
||||
v-model="form.taskEntryMode"
|
||||
:options="taskEntryModeOptions"
|
||||
:disabled="dialogReadonly"
|
||||
@change="handleTaskEntryModeChange"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #taskInfoForm-form>
|
||||
<div class="business-crud-page__task">
|
||||
<div class="business-crud-page__task-toolbar">
|
||||
<el-segmented
|
||||
v-model="form.taskEntryMode"
|
||||
:options="taskEntryModeOptions"
|
||||
:disabled="dialogReadonly"
|
||||
@change="handleTaskEntryModeChange"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="isTaskFullMode" class="business-crud-page__task-full">
|
||||
<div class="business-crud-page__subsection">
|
||||
<div
|
||||
@@ -663,6 +663,7 @@
|
||||
v-model="form.driverPhone"
|
||||
placeholder="请输入"
|
||||
clearable
|
||||
maxlength="20"
|
||||
:disabled="dialogReadonly"
|
||||
/>
|
||||
</el-form-item>
|
||||
@@ -671,21 +672,67 @@
|
||||
v-model="form.vehicleNo"
|
||||
placeholder="请输入"
|
||||
clearable
|
||||
maxlength="30"
|
||||
:disabled="dialogReadonly"
|
||||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="business-crud-page__task-row">
|
||||
<el-form-item
|
||||
v-if="isRoadTransport"
|
||||
label="挂车车牌号"
|
||||
class="business-crud-page__task-span-1"
|
||||
>
|
||||
<el-input
|
||||
v-model="form.trailerVehicleNo"
|
||||
placeholder="请输入"
|
||||
clearable
|
||||
maxlength="30"
|
||||
:disabled="dialogReadonly"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="isRoadTransport"
|
||||
label="押运人"
|
||||
class="business-crud-page__task-span-1"
|
||||
>
|
||||
<el-input
|
||||
v-model="form.escortName"
|
||||
placeholder="请输入"
|
||||
clearable
|
||||
maxlength="20"
|
||||
:disabled="dialogReadonly"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="isRoadTransport"
|
||||
label="押运人手机号"
|
||||
class="business-crud-page__task-span-1"
|
||||
>
|
||||
<el-input
|
||||
v-model="form.escortPhone"
|
||||
placeholder="请输入"
|
||||
clearable
|
||||
maxlength="20"
|
||||
:disabled="dialogReadonly"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="里程(km)" class="business-crud-page__task-span-1">
|
||||
<el-input
|
||||
v-model="form.mileage"
|
||||
placeholder="请输入"
|
||||
clearable
|
||||
maxlength="10"
|
||||
:disabled="dialogReadonly"
|
||||
@input="value => handleTaskNumberInput('mileage', value)"
|
||||
@input="handleTaskMileageInput"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="预计发货日期" class="business-crud-page__task-span-1">
|
||||
</div>
|
||||
<div class="business-crud-page__task-row">
|
||||
<el-form-item
|
||||
:label="isRoadTransport ? '计划发货日期' : '预计发货日期'"
|
||||
class="business-crud-page__task-span-1"
|
||||
>
|
||||
<el-date-picker
|
||||
v-model="form.estimatedStartTime"
|
||||
type="date"
|
||||
@@ -695,7 +742,10 @@
|
||||
:disabled="dialogReadonly"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="预计完成日期" class="business-crud-page__task-span-1">
|
||||
<el-form-item
|
||||
:label="isRoadTransport ? '计划完成日期' : '预计完成日期'"
|
||||
class="business-crud-page__task-span-1"
|
||||
>
|
||||
<el-date-picker
|
||||
v-model="form.estimatedEndTime"
|
||||
type="date"
|
||||
@@ -724,7 +774,11 @@
|
||||
</div>
|
||||
<template v-else>
|
||||
<div class="business-crud-page__task-row">
|
||||
<el-form-item label="司机" class="business-crud-page__task-span-1">
|
||||
<el-form-item
|
||||
label="司机"
|
||||
:required="isRoadTransport"
|
||||
class="business-crud-page__task-span-1"
|
||||
>
|
||||
<el-select
|
||||
v-model="form.driverName"
|
||||
placeholder="请输入"
|
||||
@@ -746,11 +800,12 @@
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="司机手机号" required class="business-crud-page__task-span-1">
|
||||
<el-form-item label="手机号" required class="business-crud-page__task-span-1">
|
||||
<el-input
|
||||
v-model="form.driverPhone"
|
||||
placeholder="请输入"
|
||||
clearable
|
||||
maxlength="20"
|
||||
:disabled="dialogReadonly"
|
||||
/>
|
||||
</el-form-item>
|
||||
@@ -759,6 +814,7 @@
|
||||
v-model="form.vehicleNo"
|
||||
placeholder="请输入"
|
||||
clearable
|
||||
maxlength="30"
|
||||
:disabled="dialogReadonly"
|
||||
/>
|
||||
</el-form-item>
|
||||
@@ -767,6 +823,7 @@
|
||||
v-model="form.trailerVehicleNo"
|
||||
placeholder="请输入"
|
||||
clearable
|
||||
maxlength="30"
|
||||
:disabled="dialogReadonly"
|
||||
/>
|
||||
</el-form-item>
|
||||
@@ -777,6 +834,7 @@
|
||||
v-model="form.escortName"
|
||||
placeholder="请输入"
|
||||
clearable
|
||||
maxlength="20"
|
||||
:disabled="dialogReadonly"
|
||||
/>
|
||||
</el-form-item>
|
||||
@@ -785,6 +843,7 @@
|
||||
v-model="form.escortPhone"
|
||||
placeholder="请输入"
|
||||
clearable
|
||||
maxlength="20"
|
||||
:disabled="dialogReadonly"
|
||||
/>
|
||||
</el-form-item>
|
||||
@@ -793,13 +852,17 @@
|
||||
v-model="form.mileage"
|
||||
placeholder="请输入"
|
||||
clearable
|
||||
maxlength="10"
|
||||
:disabled="dialogReadonly"
|
||||
@input="value => handleTaskNumberInput('mileage', value)"
|
||||
@input="handleTaskMileageInput"
|
||||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="business-crud-page__task-row">
|
||||
<el-form-item label="预计发货日期" class="business-crud-page__task-span-1">
|
||||
<el-form-item
|
||||
:label="isRoadTransport ? '计划发货日期' : '预计发货日期'"
|
||||
class="business-crud-page__task-span-1"
|
||||
>
|
||||
<el-date-picker
|
||||
v-model="form.estimatedStartTime"
|
||||
type="date"
|
||||
@@ -809,7 +872,10 @@
|
||||
:disabled="dialogReadonly"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="预计完成日期" class="business-crud-page__task-span-1">
|
||||
<el-form-item
|
||||
:label="isRoadTransport ? '计划完成日期' : '预计完成日期'"
|
||||
class="business-crud-page__task-span-1"
|
||||
>
|
||||
<el-date-picker
|
||||
v-model="form.estimatedEndTime"
|
||||
type="date"
|
||||
@@ -966,7 +1032,7 @@
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="司机">
|
||||
<el-form-item label="司机" :required="isRoadTransport && form.carrierType === '自运'">
|
||||
<el-select
|
||||
v-model="form.driverName"
|
||||
placeholder="请选择或输入司机"
|
||||
@@ -992,6 +1058,7 @@
|
||||
v-model="form.driverPhone"
|
||||
placeholder="请输入手机号"
|
||||
clearable
|
||||
maxlength="20"
|
||||
:disabled="dialogReadonly"
|
||||
/>
|
||||
</el-form-item>
|
||||
@@ -1000,6 +1067,34 @@
|
||||
v-model="form.vehicleNo"
|
||||
placeholder="请输入车牌号"
|
||||
clearable
|
||||
maxlength="30"
|
||||
:disabled="dialogReadonly"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="isRoadTransport" label="挂车车牌号">
|
||||
<el-input
|
||||
v-model="form.trailerVehicleNo"
|
||||
placeholder="请输入挂车车牌号"
|
||||
clearable
|
||||
maxlength="30"
|
||||
:disabled="dialogReadonly"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="isRoadTransport" label="押运人">
|
||||
<el-input
|
||||
v-model="form.escortName"
|
||||
placeholder="请输入押运人"
|
||||
clearable
|
||||
maxlength="20"
|
||||
:disabled="dialogReadonly"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="isRoadTransport" label="押运人手机号">
|
||||
<el-input
|
||||
v-model="form.escortPhone"
|
||||
placeholder="请输入押运人手机号"
|
||||
clearable
|
||||
maxlength="20"
|
||||
:disabled="dialogReadonly"
|
||||
/>
|
||||
</el-form-item>
|
||||
@@ -1078,16 +1173,17 @@
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="里程(公里)">
|
||||
<el-form-item label="里程(km)">
|
||||
<el-input
|
||||
v-model="form.mileage"
|
||||
placeholder="请输入里程"
|
||||
clearable
|
||||
maxlength="10"
|
||||
:disabled="dialogReadonly"
|
||||
@input="value => handleTaskNumberInput('mileage', value)"
|
||||
@input="handleTaskMileageInput"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="预计发货日期">
|
||||
<el-form-item :label="isRoadTransport ? '计划发货日期' : '预计发货日期'">
|
||||
<el-date-picker
|
||||
v-model="form.estimatedStartTime"
|
||||
type="date"
|
||||
@@ -1097,7 +1193,7 @@
|
||||
:disabled="dialogReadonly"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="预计完成日期">
|
||||
<el-form-item :label="isRoadTransport ? '计划完成日期' : '预计完成日期'">
|
||||
<el-date-picker
|
||||
v-model="form.estimatedEndTime"
|
||||
type="date"
|
||||
@@ -1851,11 +1947,11 @@
|
||||
|
||||
<template #menu-form-before>
|
||||
<div
|
||||
v-if="config.enableShippingTemplateFreight && !dialogReadonly"
|
||||
v-if="showFooterFreightSummary && !dialogReadonly"
|
||||
class="business-crud-page__shipping-template-footer-summary"
|
||||
>
|
||||
<span>
|
||||
运费合计:<strong>¥{{ formatShippingTemplateFooterFreightTotal }}</strong>
|
||||
运费合计:<strong>¥{{ formatFooterFreightTotal }}</strong>
|
||||
</span>
|
||||
<el-link
|
||||
type="primary"
|
||||
@@ -1872,7 +1968,7 @@
|
||||
:loading="draftSaveLoading"
|
||||
@click="handleDraftSave"
|
||||
>
|
||||
保存
|
||||
{{ config.draftSaveText || '保存' }}
|
||||
</el-button>
|
||||
</template>
|
||||
|
||||
@@ -2420,18 +2516,21 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section-card title="待调度列表">
|
||||
<section-card>
|
||||
<template #title>
|
||||
<span>待调度列表</span>
|
||||
<span class="business-crud-page__dispatch-list-summary">
|
||||
{{ dispatchSummaryText }}
|
||||
</span>
|
||||
</template>
|
||||
<template #extra>
|
||||
<el-button
|
||||
type="primary"
|
||||
:disabled="dispatchSummaryRemainingQuantity <= 0"
|
||||
:disabled="!dispatchHasRemainingQuantity"
|
||||
@click="handleDispatchAddRow"
|
||||
>
|
||||
新增
|
||||
</el-button>
|
||||
<span class="business-crud-page__dispatch-list-summary">
|
||||
{{ dispatchSummaryText }}
|
||||
</span>
|
||||
</template>
|
||||
<el-table
|
||||
:data="dispatchRows"
|
||||
@@ -4408,6 +4507,9 @@ export default {
|
||||
isTransportPlanPage() {
|
||||
return this.config.permission === 'transport_plan';
|
||||
},
|
||||
isRoadTransport() {
|
||||
return this.config.permission === 'waybill_manage' && this.transportMode === 'road';
|
||||
},
|
||||
transportPlanImportDuplicateCount() {
|
||||
return this.transportPlanImportRows.filter(row => row._duplicate).length;
|
||||
},
|
||||
@@ -4479,50 +4581,50 @@ export default {
|
||||
.join('; ');
|
||||
return cargoInfo || this.dispatchRow.goodsInfo || '';
|
||||
},
|
||||
dispatchSummaryTotalQuantity() {
|
||||
const goodsQuantity = this.dispatchPlanGoodsRows.reduce(
|
||||
(total, row) =>
|
||||
total +
|
||||
this.parseDispatchQuantity(row.quantity || row.cargoQuantity || row.goodsQuantity),
|
||||
0
|
||||
);
|
||||
if (goodsQuantity > 0) return goodsQuantity;
|
||||
return this.parseDispatchQuantity(
|
||||
this.dispatchRow.totalQuantity ||
|
||||
this.dispatchRow.totalCargoQuantity ||
|
||||
this.dispatchRow.quantity
|
||||
);
|
||||
dispatchSummaryItems() {
|
||||
const summaryMap = new Map();
|
||||
const addQuantity = (unit, field, quantity) => {
|
||||
const normalizedUnit = unit || '吨';
|
||||
if (!summaryMap.has(normalizedUnit)) {
|
||||
summaryMap.set(normalizedUnit, { unit: normalizedUnit, total: 0, assigned: 0 });
|
||||
}
|
||||
summaryMap.get(normalizedUnit)[field] += this.parseDispatchQuantity(quantity);
|
||||
};
|
||||
const goodsRows = this.dispatchPlanGoodsRows.length
|
||||
? this.dispatchPlanGoodsRows
|
||||
: [this.dispatchRow];
|
||||
|
||||
goodsRows.forEach(row => {
|
||||
addQuantity(
|
||||
this.getDispatchQuantityUnit(row),
|
||||
'total',
|
||||
row.quantity ||
|
||||
row.cargoQuantity ||
|
||||
row.goodsQuantity ||
|
||||
row.totalQuantity ||
|
||||
row.totalCargoQuantity
|
||||
);
|
||||
});
|
||||
this.dispatchRows.forEach(row => {
|
||||
addQuantity(this.getDispatchQuantityUnit(row), 'assigned', row.quantity);
|
||||
});
|
||||
|
||||
return Array.from(summaryMap.values()).map(item => ({
|
||||
...item,
|
||||
remaining: Math.max(item.total - item.assigned, 0),
|
||||
}));
|
||||
},
|
||||
dispatchSummaryAssignedQuantity() {
|
||||
return this.dispatchRows.reduce(
|
||||
(total, row) => total + this.parseDispatchQuantity(row.quantity),
|
||||
0
|
||||
);
|
||||
},
|
||||
dispatchSummaryRemainingQuantity() {
|
||||
const total = this.dispatchSummaryTotalQuantity;
|
||||
const assigned = this.dispatchSummaryAssignedQuantity;
|
||||
const remain = total - assigned;
|
||||
return remain > 0 ? remain : 0;
|
||||
},
|
||||
dispatchSummaryUnit() {
|
||||
const unitRow = this.dispatchPlanGoodsRows.find(
|
||||
row => row.quantityUnit || row.goodsQuantityUnit || row.unit
|
||||
);
|
||||
return (
|
||||
unitRow?.quantityUnit ||
|
||||
unitRow?.goodsQuantityUnit ||
|
||||
unitRow?.unit ||
|
||||
this.dispatchRow.quantityUnit ||
|
||||
this.dispatchRows.find(row => row.quantityUnit)?.quantityUnit ||
|
||||
'吨'
|
||||
);
|
||||
dispatchHasRemainingQuantity() {
|
||||
return this.dispatchSummaryItems.some(item => item.remaining > 0);
|
||||
},
|
||||
dispatchSummaryText() {
|
||||
const total = this.formatDispatchQuantity(this.dispatchSummaryTotalQuantity);
|
||||
const assigned = this.formatDispatchQuantity(this.dispatchSummaryAssignedQuantity);
|
||||
const remain = this.formatDispatchQuantity(this.dispatchSummaryRemainingQuantity);
|
||||
return `共${total}${this.dispatchSummaryUnit} | 已调度 ${assigned}${this.dispatchSummaryUnit},剩余${remain}${this.dispatchSummaryUnit}`;
|
||||
const formatSummary = field =>
|
||||
this.dispatchSummaryItems
|
||||
.map(item => `${this.formatDispatchQuantity(item[field])}${item.unit}`)
|
||||
.join('、');
|
||||
return `共${formatSummary('total')} | 已调度 ${formatSummary('assigned')},剩余${formatSummary(
|
||||
'remaining'
|
||||
)}`;
|
||||
},
|
||||
dispatchAttachmentRows() {
|
||||
return this.parseJsonArray(this.dispatchRow.attachmentsJson);
|
||||
@@ -4738,8 +4840,22 @@ export default {
|
||||
: Number(this.shippingTemplateFreight.freightAmount || 0);
|
||||
return freightAmount + Number(this.shippingTemplateFreight.otherFreightAmount || 0);
|
||||
},
|
||||
formatShippingTemplateFooterFreightTotal() {
|
||||
return this.shippingTemplateFooterFreightTotal.toLocaleString('zh-CN', {
|
||||
waybillFooterFreightTotal() {
|
||||
return Number(this.taskFreightAmount || 0) + Number(this.form.otherFeeTotal || 0);
|
||||
},
|
||||
showFooterFreightSummary() {
|
||||
return (
|
||||
this.config.enableShippingTemplateFreight === true ||
|
||||
this.config.enableWaybillFooterFreightSummary === true
|
||||
);
|
||||
},
|
||||
footerFreightTotal() {
|
||||
return this.config.enableShippingTemplateFreight === true
|
||||
? this.shippingTemplateFooterFreightTotal
|
||||
: this.waybillFooterFreightTotal;
|
||||
},
|
||||
formatFooterFreightTotal() {
|
||||
return this.footerFreightTotal.toLocaleString('zh-CN', {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
});
|
||||
@@ -5053,13 +5169,15 @@ export default {
|
||||
});
|
||||
},
|
||||
displayStatus(row, prop) {
|
||||
const formatStatus = this.config.formatStatus;
|
||||
const textProp = prop === this.config.statusProp ? this.config.statusTextProp : '';
|
||||
if (textProp && row[textProp]) {
|
||||
return row[textProp];
|
||||
}
|
||||
const column = this.findColumn(this.option.column, prop);
|
||||
const item = column && (column.dicData || []).find(dic => dic.value === row[prop]);
|
||||
return item ? item.label : row[prop] || '未知';
|
||||
const defaultText =
|
||||
textProp && row[textProp] ? row[textProp] : item ? item.label : row[prop] || '未知';
|
||||
return typeof formatStatus === 'function'
|
||||
? formatStatus(row, prop, defaultText)
|
||||
: defaultText;
|
||||
},
|
||||
syncContractNoDisabled(type) {
|
||||
if (!this.config.enableContractForm) return;
|
||||
@@ -5223,16 +5341,17 @@ export default {
|
||||
},
|
||||
normalizeRow(row, saveAsDraft = false) {
|
||||
const submitRow = { ...row };
|
||||
const skipValidation = saveAsDraft && this.config.skipDraftValidation === true;
|
||||
if (this.config.enableTransportPlanForm) {
|
||||
if (!this.validateTransportPlanForm(submitRow)) return false;
|
||||
if (!skipValidation && !this.validateTransportPlanForm(submitRow)) return false;
|
||||
submitRow.goodsJson = JSON.stringify(this.transportCargoRows);
|
||||
if (this.config.enableShippingTemplateFreight) {
|
||||
if (!this.validateShippingTemplateFreight()) return false;
|
||||
if (!skipValidation && !this.validateShippingTemplateFreight()) return false;
|
||||
submitRow.freightJson = this.serializeShippingTemplateFreight();
|
||||
}
|
||||
}
|
||||
if (this.taskInfoFormEnabled) {
|
||||
if (!this.validateTaskInfoForm(submitRow)) return false;
|
||||
if (!skipValidation && !this.validateTaskInfoForm(submitRow)) return false;
|
||||
this.syncTaskInfoToRow(submitRow);
|
||||
}
|
||||
if (this.config.enableAttachmentTable) {
|
||||
@@ -5245,7 +5364,9 @@ export default {
|
||||
submitRow.billingPlanJson = JSON.stringify(this.billingPlanRows);
|
||||
}
|
||||
if (this.config.enableSettlementRule) {
|
||||
if (this.settlementRuleEnabled && !this.validateSettlementRule()) return false;
|
||||
if (!skipValidation && this.settlementRuleEnabled && !this.validateSettlementRule()) {
|
||||
return false;
|
||||
}
|
||||
submitRow.settlementRuleJson = JSON.stringify(this.normalizeSettlementRule());
|
||||
}
|
||||
if (this.config.enableReconciliation) {
|
||||
@@ -5255,7 +5376,7 @@ export default {
|
||||
submitRow.changeRecordJson = JSON.stringify(this.changeRecordRows);
|
||||
}
|
||||
if (this.config.saveAsDraft && saveAsDraft) {
|
||||
submitRow.approvalStatus = 'draft';
|
||||
submitRow[this.config.draftStatusProp || 'approvalStatus'] = this.config.draftStatus || 'draft';
|
||||
}
|
||||
delete submitRow.basicInfoTitle;
|
||||
delete submitRow.templateInfoTitle;
|
||||
@@ -5619,7 +5740,7 @@ export default {
|
||||
this.draftSaveLoading = true;
|
||||
request(submitRow)
|
||||
.then(() => {
|
||||
this.$message.success('保存成功');
|
||||
this.$message.success(`${this.config.draftSaveText || '保存'}成功`);
|
||||
this.onLoad(this.page, this.query);
|
||||
this.closeCrudDialog();
|
||||
})
|
||||
@@ -5798,6 +5919,15 @@ export default {
|
||||
const number = Number(match[0]);
|
||||
return Number.isFinite(number) ? number : 0;
|
||||
},
|
||||
getDispatchQuantityUnit(row = {}) {
|
||||
return row.quantityUnit || row.goodsQuantityUnit || row.unit || '吨';
|
||||
},
|
||||
getDispatchSummaryItem(unit) {
|
||||
return this.dispatchSummaryItems.find(item => item.unit === unit);
|
||||
},
|
||||
getDispatchRemainingQuantity(unit) {
|
||||
return this.getDispatchSummaryItem(unit)?.remaining || 0;
|
||||
},
|
||||
formatDispatchQuantity(value) {
|
||||
const number = Number(value || 0);
|
||||
if (!Number.isFinite(number)) return '0';
|
||||
@@ -6060,10 +6190,10 @@ export default {
|
||||
this.form.model = this.form.model || taskInfo.model || goodsInfo.model || '';
|
||||
this.form.quantity = this.form.quantity || taskInfo.quantity || goodsInfo.quantity || '';
|
||||
this.form.quantityUnit =
|
||||
this.form.quantityUnit || taskInfo.quantityUnit || goodsInfo.quantityUnit || '';
|
||||
this.form.quantityUnit || taskInfo.quantityUnit || goodsInfo.quantityUnit || '吨';
|
||||
this.form.mileage = this.form.mileage || taskInfo.mileage || goodsInfo.mileage || '';
|
||||
this.form.unitPrice = this.form.unitPrice || taskInfo.unitPrice || goodsInfo.unitPrice || '';
|
||||
this.form.priceUnit = this.form.priceUnit || taskInfo.priceUnit || goodsInfo.priceUnit || '';
|
||||
this.form.priceUnit = this.form.priceUnit || taskInfo.priceUnit || goodsInfo.priceUnit || '元/吨';
|
||||
this.form.otherFeeTotal =
|
||||
this.form.otherFeeTotal || taskInfo.otherFeeTotal || goodsInfo.otherFeeTotal || '';
|
||||
this.form.estimatedStartTime =
|
||||
@@ -6111,9 +6241,9 @@ export default {
|
||||
loadTaskCarrierOptions() {
|
||||
if (!this.taskInfoFormEnabled || this.taskCarrierLoading) return Promise.resolve([]);
|
||||
this.taskCarrierLoading = true;
|
||||
return getCarrierCustomerList(1, 9999, { customerType: '承运商' })
|
||||
return getCarrierCustomerList(1, 9999, { customerType: '承运商', status: 1 })
|
||||
.then(res => {
|
||||
this.taskCarrierOptions = extractRecords(res);
|
||||
this.taskCarrierOptions = extractRecords(res).filter(item => Number(item.status) === 1);
|
||||
return this.taskCarrierOptions;
|
||||
})
|
||||
.finally(() => {
|
||||
@@ -6307,6 +6437,11 @@ export default {
|
||||
handleTaskNumberInput(prop, value) {
|
||||
this.form[prop] = this.normalizeTaskNumber(value);
|
||||
},
|
||||
handleTaskMileageInput(value) {
|
||||
this.form.mileage = this.isRoadTransport
|
||||
? String(value || '').replace(/\D/g, '').slice(0, 10)
|
||||
: this.normalizeTaskNumber(value);
|
||||
},
|
||||
normalizeTaskNumber(value) {
|
||||
const text = String(value || '').replace(/[^\d.]/g, '');
|
||||
const parts = text.split('.');
|
||||
@@ -6352,6 +6487,9 @@ export default {
|
||||
requiredFields.push(['carrierName', '承运商']);
|
||||
}
|
||||
if (row.carrierType === '自运') {
|
||||
if (this.isRoadTransport) {
|
||||
requiredFields.push(['driverName', '司机']);
|
||||
}
|
||||
requiredFields.push(['driverPhone', '手机号']);
|
||||
}
|
||||
const emptyField = requiredFields.find(([prop]) => this.isBillingFieldEmpty(row[prop]));
|
||||
@@ -6363,8 +6501,10 @@ export default {
|
||||
['quantity', '数量'],
|
||||
['mileage', '里程'],
|
||||
['unitPrice', '单价'],
|
||||
['otherFeeTotal', '其他运费合计'],
|
||||
];
|
||||
if (this.isTaskFullMode) {
|
||||
numberFields.push(['otherFeeTotal', '其他运费合计']);
|
||||
}
|
||||
const invalidField = numberFields.find(([prop]) => {
|
||||
const value = row[prop];
|
||||
return value !== undefined && value !== null && value !== '' && Number(value) < 0;
|
||||
@@ -6373,6 +6513,27 @@ export default {
|
||||
this.$message.warning(`${invalidField[1]}不能小于0`);
|
||||
return false;
|
||||
}
|
||||
if (this.isRoadTransport) {
|
||||
const invalidLengthField = [
|
||||
['driverName', '司机', 20],
|
||||
['driverPhone', '手机号', 20],
|
||||
['vehicleNo', '车牌号', 30],
|
||||
['trailerVehicleNo', '挂车车牌号', 30],
|
||||
['escortName', '押运人', 20],
|
||||
['escortPhone', '押运人手机号', 20],
|
||||
].find(([prop, , max]) => String(row[prop] || '').length > max);
|
||||
if (invalidLengthField) {
|
||||
this.$message.warning(`${invalidLengthField[1]}不能超过${invalidLengthField[2]}个字符`);
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
row.mileage &&
|
||||
(!/^\d{1,10}$/.test(String(row.mileage)) || Number(row.mileage) <= 0)
|
||||
) {
|
||||
this.$message.warning('里程必须为不超过10位的正整数');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (
|
||||
row.estimatedStartTime &&
|
||||
row.estimatedEndTime &&
|
||||
@@ -8886,17 +9047,51 @@ export default {
|
||||
};
|
||||
},
|
||||
formatDispatchCargoInfo(plan = {}, item = {}) {
|
||||
const cargoName = item.cargoName || item.goodsName || plan.cargoName || '';
|
||||
const cargoType = item.cargoType || item.goodsType || plan.cargoType || '';
|
||||
const quantity = item.quantity || item.cargoQuantity || item.goodsQuantity || '';
|
||||
const unit = item.quantityUnit || item.goodsQuantityUnit || item.unit || '';
|
||||
const quantityText = quantity ? `${quantity}${unit}` : '';
|
||||
return (
|
||||
[cargoName, cargoType, quantityText].filter(Boolean).join(' - ') || plan.goodsInfo || ''
|
||||
);
|
||||
const goodsRows = this.parseJsonArray(plan.goodsJson);
|
||||
const sourceRows = goodsRows.length ? goodsRows : [item];
|
||||
const groups = sourceRows.reduce((result, goods = {}) => {
|
||||
const cargoType =
|
||||
goods.cargoType ||
|
||||
goods.secondCargoTypeName ||
|
||||
goods.secondCargoType ||
|
||||
goods.goodsType ||
|
||||
goods.type ||
|
||||
plan.cargoType ||
|
||||
'货物';
|
||||
const unit = this.getDispatchQuantityUnit(goods);
|
||||
if (!result[unit]) {
|
||||
result[unit] = {
|
||||
cargoType,
|
||||
count: 0,
|
||||
quantity: 0,
|
||||
unit,
|
||||
};
|
||||
}
|
||||
result[unit].count += 1;
|
||||
result[unit].quantity += this.parseDispatchQuantity(
|
||||
goods.quantity || goods.cargoQuantity || goods.goodsQuantity
|
||||
);
|
||||
return result;
|
||||
}, {});
|
||||
|
||||
const cargoInfo = Object.values(groups)
|
||||
.map(
|
||||
group =>
|
||||
`${group.cargoType}等${group.count}种货物 | ${this.formatDispatchQuantity(
|
||||
group.quantity
|
||||
)}${group.unit || ''}`
|
||||
)
|
||||
.join(';');
|
||||
return cargoInfo || plan.goodsInfo || '';
|
||||
},
|
||||
openDispatchItemDialog(index = -1, row = defaultDispatchRow()) {
|
||||
const defaultGoods = this.dispatchPlanGoodsRows[0] || {};
|
||||
const defaultSummaryItem =
|
||||
this.dispatchSummaryItems.find(item => item.remaining > 0) || this.dispatchSummaryItems[0];
|
||||
const defaultGoods =
|
||||
this.dispatchPlanGoodsRows.find(
|
||||
item => this.getDispatchQuantityUnit(item) === defaultSummaryItem?.unit
|
||||
) || this.dispatchPlanGoodsRows[0] || {};
|
||||
const defaultUnit = defaultSummaryItem?.unit || this.getDispatchQuantityUnit(defaultGoods);
|
||||
const baseRow = {
|
||||
...defaultDispatchRow(),
|
||||
transportType: this.dispatchRow.transportType || '',
|
||||
@@ -8910,8 +9105,8 @@ export default {
|
||||
quantity:
|
||||
index >= 0
|
||||
? defaultGoods.quantity || ''
|
||||
: this.formatDispatchQuantity(this.dispatchSummaryRemainingQuantity),
|
||||
quantityUnit: defaultGoods.quantityUnit || '吨',
|
||||
: this.formatDispatchQuantity(this.getDispatchRemainingQuantity(defaultUnit)),
|
||||
quantityUnit: defaultUnit,
|
||||
specification: defaultGoods.specification || '',
|
||||
model: defaultGoods.model || '',
|
||||
packageType: defaultGoods.packageType || '',
|
||||
@@ -9000,17 +9195,18 @@ export default {
|
||||
...this.dispatchItemForm,
|
||||
attachmentsJson: JSON.stringify(this.dispatchItemAttachmentRows),
|
||||
};
|
||||
const quantityUnit = this.getDispatchQuantityUnit(nextRow);
|
||||
const otherDispatchedQuantity = this.dispatchRows.reduce((total, row, index) => {
|
||||
if (index === this.dispatchItemIndex) return total;
|
||||
if (index === this.dispatchItemIndex || this.getDispatchQuantityUnit(row) !== quantityUnit) {
|
||||
return total;
|
||||
}
|
||||
return total + this.parseDispatchQuantity(row.quantity);
|
||||
}, 0);
|
||||
const currentQuantity = this.parseDispatchQuantity(nextRow.quantity);
|
||||
const totalQuantity = this.dispatchSummaryTotalQuantity;
|
||||
const totalQuantity = this.getDispatchSummaryItem(quantityUnit)?.total || 0;
|
||||
if (totalQuantity > 0 && otherDispatchedQuantity + currentQuantity > totalQuantity) {
|
||||
this.$message.warning(
|
||||
`已调度数量合计不能超过总数量${this.formatDispatchQuantity(totalQuantity)}${
|
||||
this.dispatchSummaryUnit
|
||||
}`
|
||||
`已调度${quantityUnit}合计不能超过总数量${this.formatDispatchQuantity(totalQuantity)}${quantityUnit}`
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -9039,7 +9235,7 @@ export default {
|
||||
});
|
||||
},
|
||||
handleDispatchAddRow() {
|
||||
if (this.dispatchSummaryRemainingQuantity <= 0) {
|
||||
if (!this.dispatchHasRemainingQuantity) {
|
||||
this.$message.warning('剩余数量为0,不能新增调度明细');
|
||||
return;
|
||||
}
|
||||
@@ -9141,7 +9337,7 @@ export default {
|
||||
},
|
||||
submitDispatch(mode) {
|
||||
this.dispatchSaving = mode;
|
||||
const shouldCompletePlan = mode === 'submit' && this.dispatchSummaryRemainingQuantity <= 0;
|
||||
const shouldCompletePlan = mode === 'submit' && !this.dispatchHasRemainingQuantity;
|
||||
this.api
|
||||
.dispatch(this.buildDispatchPayload(mode))
|
||||
.then(() => {
|
||||
@@ -9329,12 +9525,6 @@ export default {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&__task-toolbar {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
&__task-form {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
|
||||
Reference in New Issue
Block a user