1、调整凭证

2、调整运单
This commit is contained in:
2026-09-08 17:50:34 +08:00
parent a7315b4491
commit cba2ad3b3b
43 changed files with 5730 additions and 1119 deletions
@@ -119,18 +119,22 @@
label="运单批次号"
min-width="140"
/><el-table-column prop="originalNo" label="原始单号" min-width="130" /><el-table-column
prop="loadingIdentifier"
label="配载标识号"
min-width="130"
/><el-table-column
prop="vehicleNo"
label="车牌号/航班号/船号/班列号"
min-width="190"
/><el-table-column prop="driverName" label="司机/船长" min-width="120" /><el-table-column
prop="transportType"
label="运输方式"
width="110"
/><el-table-column prop="cargoName" label="货物名称" width="130" /><el-table-column
prop="cargoType"
label="货物类型"
width="120"
/><el-table-column prop="quantity" label="重量" width="90" /><el-table-column
/><el-table-column prop="transportType" label="运输方式" width="110" /><el-table-column
prop="driverName"
label="司机/船长姓名"
min-width="120"
/><el-table-column
prop="driverPhone"
label="司机/船长手机号"
width="140"
/><el-table-column
prop="departureAddress"
label="发货地址"
min-width="220"
@@ -148,11 +152,22 @@
prop="arrivalPhone"
label="收货联系人电话"
width="140"
/><el-table-column prop="startDate" label="开始时间" width="160" sortable /><el-table-column
prop="endDate"
label="结束时间"
width="160"
sortable
/><el-table-column prop="cargoName" label="货物名称" width="130" /><el-table-column
prop="cargoType"
label="货物类型"
width="120"
/><el-table-column prop="packageType" label="包装" width="100" /><el-table-column
prop="quantity"
label="数量"
width="90"
/><el-table-column prop="quantityUnit" label="数量单位" width="100" /><el-table-column
prop="specification"
label="规格"
width="120"
/><el-table-column prop="model" label="型号" width="120" /><el-table-column
prop="mileage"
label="里程(km)"
width="100"
/><el-table-column prop="unitPrice" label="单价" width="90" /><el-table-column
prop="freight"
label="运费"
@@ -161,11 +176,31 @@
prop="freightTotal"
label="运费合计"
width="100"
/><el-table-column
prop="actualStartDate"
label="实际发货时间"
width="160"
sortable
/><el-table-column
prop="actualEndDate"
label="实际完成时间"
width="160"
sortable
/><el-table-column
prop="planStartDate"
label="预计发货时间"
width="160"
sortable
/><el-table-column
prop="planEndDate"
label="预计完成时间"
width="160"
sortable
/><el-table-column prop="remark" label="备注" min-width="160" /><el-table-column
label="操作"
width="80"
>-</el-table-column
></el-table
prop="waybillIdentifier"
label="同一运单标识号"
min-width="140"
/><el-table-column label="操作" width="80">-</el-table-column></el-table
>
<el-pagination
v-model:current-page="detailPage.current"
@@ -441,7 +476,6 @@
</section>
<div v-if="createPage" class="waybill-import-create__footer">
<el-button @click="closeCreate">取消</el-button>
<el-button @click="saveDraft">保存草稿</el-button>
<el-button type="primary" @click="confirmImport">确认导入</el-button>
</div>
</component>
@@ -496,7 +530,7 @@ const createDefaultForm = () => ({
const form = reactive(createDefaultForm());
// 批量导入状态仅保留草稿与导入完成两种,与后端 importStatus 取值一致。
const importStatusOptions = [
{ label: '草稿', value: 'draft' },
{ label: '进行中', value: 'draft' },
{ label: '导入完成', value: 'completed' },
];
// 编辑草稿时明细已入库,此时不再强制重新上传附件。
@@ -541,7 +575,7 @@ const previewRows = computed(() =>
);
const carrierContractsLoaded = ref(false),
hasCarrierContracts = ref(null);
const carrierTypes = ['承运商', '自运', '网货平台'];
const carrierTypes = ['承运商', '自运'];
const isSelfOperated = computed(() => form.carrierType === '自运');
// 项目下没有承运商合同时只允许自运,与运单管理的承运类型收窄规则一致。
const carrierTypeOptions = computed(() =>
@@ -570,19 +604,47 @@ const resetCreateForm = () => {
const detailColumns = [
{ prop: 'batchNo', label: '运单批次号', minWidth: 150 },
{ prop: 'originalNo', label: '原始单号', editor: 'input', minWidth: 150 },
{ prop: 'loadingIdentifier', label: '配载标识号', editor: 'input', minWidth: 150 },
{ prop: 'vehicleNo', label: '车牌号/航班号/船号/班列号', editor: 'input', minWidth: 220 },
{ prop: 'driverName', label: '司机/船长', editor: 'driver', minWidth: 170 },
{ prop: 'transportType', label: '运输类型', editor: 'transportType', minWidth: 150 },
{ prop: 'transportType', label: '运输方式', editor: 'transportType', minWidth: 150 },
{ prop: 'driverName', label: '司机/船长姓名', editor: 'driver', minWidth: 170 },
{ prop: 'driverPhone', label: '司机/船长手机号', editor: 'input', minWidth: 150 },
{ prop: 'departureAddress', label: '发货地址', editor: 'input', minWidth: 220 },
{ prop: 'departureContact', label: '发货联系人', editor: 'input', minWidth: 120 },
{ prop: 'departurePhone', label: '发货联系人电话', editor: 'input', minWidth: 150 },
{ prop: 'arrivalAddress', label: '到货地址', editor: 'input', minWidth: 220 },
{ prop: 'arrivalContact', label: '收货联系人', editor: 'input', minWidth: 120 },
{ prop: 'arrivalPhone', label: '收货联系人电话', editor: 'input', minWidth: 150 },
{ prop: 'cargoName', label: '货物名称', editor: 'cargoName', minWidth: 220 },
{ prop: 'cargoType', label: '货物类型', editor: 'cargoType', minWidth: 220 },
{ prop: 'quantity', label: '重量', editor: 'number', minWidth: 130 },
{ prop: 'packageType', label: '包装', editor: 'input', minWidth: 120 },
{ prop: 'quantity', label: '数量', editor: 'number', minWidth: 130 },
{ prop: 'quantityUnit', label: '数量单位', editor: 'input', minWidth: 120 },
{ prop: 'specification', label: '规格', editor: 'input', minWidth: 150 },
{ prop: 'model', label: '型号', editor: 'input', minWidth: 150 },
{ prop: 'mileage', label: '里程(km)', editor: 'number', minWidth: 120 },
{ prop: 'unitPrice', label: '单价', editor: 'number', minWidth: 120 },
{ prop: 'freight', label: '运费', editor: 'number', minWidth: 120 },
{ prop: 'otherFeeTotal', label: '其他费用合计', editor: 'number', minWidth: 140 },
{ prop: 'freightTotal', label: '运费合计', editor: 'number', minWidth: 120 },
{ prop: 'actualStartDate', label: '实际发货时间', editor: 'date', minWidth: 160 },
{ prop: 'actualEndDate', label: '实际完成时间', editor: 'date', minWidth: 160 },
{ prop: 'planStartDate', label: '预计发货时间', editor: 'date', minWidth: 160 },
{ prop: 'planEndDate', label: '预计完成时间', editor: 'date', minWidth: 160 },
{ prop: 'remark', label: '备注', editor: 'textarea', minWidth: 200 },
{ prop: 'waybillIdentifier', label: '同一运单标识号', editor: 'input', minWidth: 150 },
];
const requiredDetailFields = [
{ prop: 'vehicleNo', label: '车牌号/航班号/船号/班列号' },
{ prop: 'driverName', label: '司机/船长' },
{ prop: 'transportType', label: '运输类型' },
{ prop: 'transportType', label: '运输方式' },
{ prop: 'departureAddress', label: '发货地址' },
{ prop: 'arrivalAddress', label: '到货地址' },
{ prop: 'cargoName', label: '货物名称' },
{ prop: 'cargoType', label: '货物类型' },
{ prop: 'quantity', label: '数量' },
{ prop: 'quantityUnit', label: '数量单位' },
{ prop: 'actualStartDate', label: '实际发货时间' },
{ prop: 'actualEndDate', label: '实际完成时间' },
];
const projectQueryParams = { approvalStatuses: 'approved,change_approved' };
const extractRecords = res => {
@@ -975,6 +1037,12 @@ const carrierChange = value => {
if (!isSelfOperated.value) form.carrierContractId = item.carrierContractId || '';
};
const fileChange = async (file, list) => {
if (file.raw?.size > 50 * 1024 * 1024) {
ElMessage.warning('单个文件大小不能超过50M');
files.value = [];
form.file = null;
return;
}
files.value = list.slice(-1);
form.file = file.raw;
const XLSX = await import('xlsx');
@@ -988,25 +1056,35 @@ const fileChange = async (file, list) => {
);
const keyMap = {
originalNo: ['原始单号'],
loadingIdentifier: ['配载标识号'],
vehicleNo: ['车牌号/航班号/船号/班列号'],
driverName: ['司机/船长'],
transportType: ['运输类型', '运输方式'],
cargoName: ['货物名称'],
cargoType: ['货物类型'],
quantity: ['重量'],
transportType: ['运输方式', '运输类型'],
driverName: ['司机/船长姓名', '司机/船长'],
driverPhone: ['司机/船长手机号'],
departureAddress: ['发货地址'],
departureContact: ['发货联系人'],
departurePhone: ['发货联系人电话'],
arrivalAddress: ['到货地址'],
arrivalContact: ['货联系人', '货联系人'],
arrivalContact: ['货联系人', '货联系人'],
arrivalPhone: ['收货联系人电话'],
startDate: ['开始时间'],
endDate: ['结束时间'],
cargoName: ['货物名称'],
cargoType: ['货物类型'],
packageType: ['包装'],
quantity: ['数量', '重量'],
quantityUnit: ['数量单位'],
specification: ['规格'],
model: ['型号'],
mileage: ['里程(km)', '里程'],
unitPrice: ['单价'],
freight: ['运费'],
otherFeeTotal: ['其他费用合计'],
freightTotal: ['运费合计'],
actualStartDate: ['实际发货时间', '开始时间'],
actualEndDate: ['实际完成时间', '结束时间'],
planStartDate: ['预计发货时间'],
planEndDate: ['预计完成时间'],
remark: ['备注'],
waybillIdentifier: ['同一运单标识号'],
};
const normalizeImportDate = value => {
if (value instanceof Date && !Number.isNaN(value.getTime())) {
@@ -1025,8 +1103,10 @@ const fileChange = async (file, list) => {
item[key] ??
'';
});
row.startDate = normalizeImportDate(row.startDate);
row.endDate = normalizeImportDate(row.endDate);
row.actualStartDate = normalizeImportDate(row.actualStartDate);
row.actualEndDate = normalizeImportDate(row.actualEndDate);
row.planStartDate = normalizeImportDate(row.planStartDate);
row.planEndDate = normalizeImportDate(row.planEndDate);
const duplicateKey = JSON.stringify(Object.keys(keyMap).map(key => row[key]));
count.set(duplicateKey, (count.get(duplicateKey) || 0) + 1);
row._duplicateKey = duplicateKey;
@@ -1143,6 +1223,9 @@ const normalizeImportRow = row => ({
otherFeeTotal: normalizeOptionalImportNumber(
firstNotEmpty(row.otherFeeTotal, row['其他费用合计'])
),
unitPrice: normalizeOptionalImportNumber(firstNotEmpty(row.unitPrice, row['单价'])),
freight: normalizeOptionalImportNumber(firstNotEmpty(row.freight, row['运费'])),
freightTotal: normalizeOptionalImportNumber(firstNotEmpty(row.freightTotal, row['运费合计'])),
transportType: firstNotEmpty(
row.transportType,
row['运输类型'],