✨ 完善付款申请多结算行、结算导入编辑与计费规则展示
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -208,12 +208,13 @@
|
||||
:prop="column.prop"
|
||||
:label="column.label"
|
||||
:min-width="column.minWidth || 120"
|
||||
show-overflow-tooltip
|
||||
:show-overflow-tooltip="readonly || !column.editor || column.readonly"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<template v-if="row._editing && column.editor && !column.readonly">
|
||||
<template v-if="!readonly && column.editor && !column.readonly">
|
||||
<el-date-picker
|
||||
v-if="column.editor === 'date'"
|
||||
:key="`${row._key}-${column.prop}`"
|
||||
v-model="row[column.prop]"
|
||||
type="date"
|
||||
format="YYYY-MM-DD"
|
||||
@@ -222,6 +223,7 @@
|
||||
/>
|
||||
<el-select
|
||||
v-else-if="column.editor === 'select' && column.prop === 'transportType'"
|
||||
:key="`${row._key}-${column.prop}`"
|
||||
v-model="row[column.prop]"
|
||||
clearable
|
||||
filterable
|
||||
@@ -244,8 +246,21 @@
|
||||
选择
|
||||
</el-link>
|
||||
</div>
|
||||
<el-cascader
|
||||
v-else-if="column.editor === 'cargoType'"
|
||||
:key="`${row._key}-${column.prop}`"
|
||||
:model-value="resolveCargoTypePath(row)"
|
||||
:options="cargoTypeSelectOptions(row)"
|
||||
:props="cargoTypeCascaderProps"
|
||||
clearable
|
||||
filterable
|
||||
placeholder="请选择货物类型"
|
||||
style="width: 100%"
|
||||
@change="value => handleCargoTypeChange(row, value)"
|
||||
/>
|
||||
<el-input
|
||||
v-else-if="column.editor === 'number' || column.editor === 'optionalNumber'"
|
||||
:key="`${row._key}-${column.prop}`"
|
||||
:model-value="resolveCellValue(row, column)"
|
||||
inputmode="decimal"
|
||||
:placeholder="`请输入${column.label}`"
|
||||
@@ -253,8 +268,10 @@
|
||||
/>
|
||||
<el-input
|
||||
v-else
|
||||
:key="`${row._key}-${column.prop}`"
|
||||
v-model="row[column.prop]"
|
||||
:placeholder="`请输入${column.label}`"
|
||||
@update:model-value="value => syncEditedText(row, column, value)"
|
||||
/>
|
||||
</template>
|
||||
<template v-else-if="column.editor === 'waybillSelect' && !readonly">
|
||||
@@ -268,20 +285,13 @@
|
||||
<span v-else>{{ formatCell(row, column) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="!readonly" label="操作" width="180" fixed="right">
|
||||
<el-table-column v-if="!readonly" label="操作" width="120" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<div class="settlement-import-create__row-actions">
|
||||
<template v-if="row._editing">
|
||||
<el-link type="primary" @click="saveRow(row)">保存</el-link>
|
||||
<el-link type="primary" @click="cancelRow(row)">取消</el-link>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-link v-if="row._duplicate" type="primary" @click="confirmDuplicateRow(row)">
|
||||
确认
|
||||
</el-link>
|
||||
<el-link type="primary" @click="editRow(row)">编辑</el-link>
|
||||
<el-link type="danger" @click="deleteRow(row)">删除</el-link>
|
||||
</template>
|
||||
<el-link v-if="row._duplicate" type="primary" @click="confirmDuplicateRow(row)">
|
||||
确认
|
||||
</el-link>
|
||||
<el-link type="danger" @click="deleteRow(row)">删除</el-link>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -345,6 +355,7 @@ import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import { QuestionFilled } from '@element-plus/icons-vue';
|
||||
import dayjs from 'dayjs';
|
||||
import * as api from '@/api/settlement/settlementImport';
|
||||
import { getList as getCargoTypeList } from '@/api/base/cargo-type';
|
||||
import { getList as getContractList } from '@/api/business/contract-manage';
|
||||
import { getDictionary } from '@/api/system/dictbiz';
|
||||
import { formatContractOptionLabel } from '@/utils/contract';
|
||||
@@ -363,6 +374,7 @@ const parseLoading = ref(false);
|
||||
const rowSelection = ref([]);
|
||||
const previewTab = ref('all');
|
||||
const feeItemNames = ref([]);
|
||||
const parsedHeaders = ref([]);
|
||||
const projects = ref([]);
|
||||
const customerContracts = ref([]);
|
||||
const carrierContracts = ref([]);
|
||||
@@ -370,6 +382,14 @@ const draftLoading = ref(false);
|
||||
const confirmLoading = ref(false);
|
||||
const readonly = ref(false);
|
||||
const transportTypeOptions = ref([]);
|
||||
const cargoTypeOptions = ref([]);
|
||||
const cargoTypeFlatOptions = ref([]);
|
||||
const cargoTypeCascaderProps = {
|
||||
label: 'cargoName',
|
||||
value: 'id',
|
||||
children: 'children',
|
||||
emitPath: true,
|
||||
};
|
||||
const historyWaybillVisible = ref(false);
|
||||
const historyWaybillLoading = ref(false);
|
||||
const historyWaybillRows = ref([]);
|
||||
@@ -478,18 +498,18 @@ const loadContractsByProject = async (projectId, projectName = '') => {
|
||||
.filter(Boolean);
|
||||
};
|
||||
|
||||
const fixedDetailColumns = [
|
||||
{ prop: 'loadingIdentifier', label: '配载标识号', editor: 'input', minWidth: 140 },
|
||||
const columnsBeforeFee = [
|
||||
{ prop: 'originalNo', label: '原始单号', editor: 'input', minWidth: 130 },
|
||||
{ prop: 'loadingIdentifier', label: '配载标识号', editor: 'input', minWidth: 140 },
|
||||
{
|
||||
prop: 'vehicleNo',
|
||||
label: '车牌号/航班号/船号/班列号',
|
||||
editor: 'input',
|
||||
minWidth: 190,
|
||||
},
|
||||
{ prop: 'transportType', label: '运输方式', editor: 'select', minWidth: 120 },
|
||||
{ prop: 'driverName', label: '司机/船长姓名', editor: 'input', minWidth: 120 },
|
||||
{ prop: 'driverPhone', label: '司机/船长手机号', editor: 'input', minWidth: 140 },
|
||||
{ prop: 'transportType', label: '运输方式', editor: 'select', minWidth: 140 },
|
||||
{ prop: 'driverName', label: '司机/船长姓名', editor: 'input', minWidth: 130 },
|
||||
{ prop: 'driverPhone', label: '司机/船长手机号', editor: 'input', minWidth: 150 },
|
||||
{ prop: 'departureAddress', label: '发货地址', editor: 'input', minWidth: 160 },
|
||||
{ prop: 'departureContact', label: '发货联系人', editor: 'input', minWidth: 120 },
|
||||
{ prop: 'departurePhone', label: '发货联系人电话', editor: 'input', minWidth: 140 },
|
||||
@@ -497,30 +517,97 @@ const fixedDetailColumns = [
|
||||
{ prop: 'arrivalContact', label: '收货联系人', editor: 'input', minWidth: 120 },
|
||||
{ prop: 'arrivalPhone', label: '收货联系人电话', editor: 'input', minWidth: 140 },
|
||||
{ prop: 'cargoName', label: '货物名称', editor: 'input', minWidth: 140 },
|
||||
{ prop: 'cargoType', label: '货物类型', editor: 'input', minWidth: 120 },
|
||||
{ prop: 'cargoType', label: '货物类型', editor: 'cargoType', minWidth: 200 },
|
||||
{ prop: 'packageType', label: '包装', editor: 'input', minWidth: 100 },
|
||||
{ prop: 'quantity', label: '数量', editor: 'number', minWidth: 100 },
|
||||
{ prop: 'quantityUnit', label: '数量单位', editor: 'input', minWidth: 100 },
|
||||
{ prop: 'quantityUnit', label: '数量单位', editor: 'input', minWidth: 110 },
|
||||
{ prop: 'specification', label: '规格', editor: 'input', minWidth: 110 },
|
||||
{ prop: 'model', label: '型号', editor: 'input', minWidth: 110 },
|
||||
{ prop: 'mileage', label: '里程(km)', editor: 'optionalNumber', minWidth: 110 },
|
||||
{ prop: 'unitPrice', label: '运输单价', editor: 'optionalNumber', minWidth: 100 },
|
||||
{ prop: 'transportFee', label: '运输费', editor: 'number', minWidth: 100 },
|
||||
{ prop: 'actualStartDate', label: '实际发货时间', editor: 'date', minWidth: 140 },
|
||||
{ prop: 'actualEndDate', label: '实际完成时间', editor: 'date', minWidth: 140 },
|
||||
{ prop: 'planStartDate', label: '预计发货时间', editor: 'date', minWidth: 140 },
|
||||
{ prop: 'planEndDate', label: '预计完成时间', editor: 'date', minWidth: 140 },
|
||||
{ prop: 'waybillIdentifier', label: '同一运单标识号', editor: 'input', minWidth: 140 },
|
||||
{ prop: 'unitPrice', label: '运输单价', editor: 'optionalNumber', minWidth: 110 },
|
||||
{ prop: 'transportFee', label: '运输费', editor: 'number', minWidth: 110 },
|
||||
];
|
||||
const columnsAfterFee = [
|
||||
{ prop: 'actualStartDate', label: '实际发货时间', editor: 'date', minWidth: 150 },
|
||||
{ prop: 'actualEndDate', label: '实际完成时间', editor: 'date', minWidth: 150 },
|
||||
{ prop: 'planStartDate', label: '预计发货时间', editor: 'date', minWidth: 150 },
|
||||
{ prop: 'planEndDate', label: '预计完成时间', editor: 'date', minWidth: 150 },
|
||||
{ prop: 'remark', label: '备注', editor: 'input', minWidth: 160 },
|
||||
{ prop: 'waybillIdentifier', label: '同一运单标识号', editor: 'input', minWidth: 150 },
|
||||
];
|
||||
|
||||
const detailColumns = computed(() => {
|
||||
const feeColumns = feeItemNames.value.map(name => ({
|
||||
const headerColumnMap = {};
|
||||
[...columnsBeforeFee, ...columnsAfterFee].forEach(column => {
|
||||
headerColumnMap[column.label] = column;
|
||||
headerColumnMap[`*${column.label}`] = column;
|
||||
});
|
||||
headerColumnMap['结算金额'] = {
|
||||
prop: 'settlementAmount',
|
||||
label: '结算金额',
|
||||
editor: 'number',
|
||||
minWidth: 120,
|
||||
};
|
||||
headerColumnMap['里程'] = headerColumnMap['里程(km)'];
|
||||
headerColumnMap['单价'] = headerColumnMap['运输单价'];
|
||||
headerColumnMap['运输类型'] = headerColumnMap['运输方式'];
|
||||
headerColumnMap['*运输类型'] = headerColumnMap['运输方式'];
|
||||
|
||||
const VEHICLE_ALIAS_KEYS = [
|
||||
'*车牌号/航班号/船号/班列号',
|
||||
'车牌号/航班号/船号/班列号',
|
||||
'*车牌号/船班号/船次号/班次号',
|
||||
'车牌号/船班号/船次号/班次号',
|
||||
'车号',
|
||||
];
|
||||
|
||||
const readFilledText = value => {
|
||||
const text = String(value ?? '').trim();
|
||||
return text;
|
||||
};
|
||||
|
||||
const applyVehicleNo = (row, value) => {
|
||||
const vehicleNo = readFilledText(value);
|
||||
row.vehicleNo = vehicleNo;
|
||||
VEHICLE_ALIAS_KEYS.forEach(key => {
|
||||
row[key] = vehicleNo;
|
||||
});
|
||||
};
|
||||
|
||||
const syncEditedText = (row, column, value) => {
|
||||
if (column.prop !== 'vehicleNo') return;
|
||||
applyVehicleNo(row, value);
|
||||
};
|
||||
prop: name,
|
||||
label: name,
|
||||
editor: 'number',
|
||||
minWidth: 110,
|
||||
isFeeItem: true,
|
||||
});
|
||||
|
||||
const columnFromHeader = header => {
|
||||
const name = String(header || '').trim();
|
||||
if (!name || name === '序号') return null;
|
||||
if (feeItemNames.value.includes(name)) return feeColumn(name);
|
||||
const mapped = headerColumnMap[name];
|
||||
if (mapped) return { ...mapped, label: mapped.label || name.replace(/^\*/, '') };
|
||||
return {
|
||||
prop: name,
|
||||
label: name,
|
||||
editor: 'number',
|
||||
minWidth: 110,
|
||||
isFeeItem: true,
|
||||
}));
|
||||
label: name.replace(/^\*/, ''),
|
||||
editor: 'input',
|
||||
minWidth: 140,
|
||||
};
|
||||
};
|
||||
|
||||
const dedupeColumns = columns => {
|
||||
const seen = new Set();
|
||||
return columns.filter(column => {
|
||||
if (!column?.prop || seen.has(column.prop)) return false;
|
||||
seen.add(column.prop);
|
||||
return true;
|
||||
});
|
||||
};
|
||||
|
||||
const detailColumns = computed(() => {
|
||||
const historyColumns =
|
||||
form.waybillMode === 'history'
|
||||
? [
|
||||
@@ -532,19 +619,20 @@ const detailColumns = computed(() => {
|
||||
},
|
||||
]
|
||||
: [];
|
||||
return [
|
||||
...historyColumns,
|
||||
...fixedDetailColumns,
|
||||
...feeColumns,
|
||||
const fallback = [
|
||||
...columnsBeforeFee,
|
||||
...feeItemNames.value.map(name => feeColumn(name)),
|
||||
{
|
||||
prop: 'settlementAmount',
|
||||
label: '结算金额',
|
||||
editor: 'number',
|
||||
readonly: true,
|
||||
minWidth: 120,
|
||||
},
|
||||
{ prop: 'remark', label: '备注', editor: 'input', minWidth: 140 },
|
||||
...columnsAfterFee,
|
||||
];
|
||||
const uploaded = parsedHeaders.value.map(columnFromHeader).filter(Boolean);
|
||||
const columns = dedupeColumns(uploaded.length ? uploaded : fallback);
|
||||
return [...historyColumns, ...columns];
|
||||
});
|
||||
|
||||
const duplicateRows = computed(() => rows.value.filter(row => row._duplicate));
|
||||
@@ -664,6 +752,11 @@ const updateNumberCell = (row, column, value) => {
|
||||
if (column.prop === 'transportFee') row.freight = '';
|
||||
if (column.prop === 'unitPrice') row.transportUnitPrice = '';
|
||||
}
|
||||
if (column.prop === 'settlementAmount') {
|
||||
row.settlementAmount = '';
|
||||
row.freightTotal = '';
|
||||
return;
|
||||
}
|
||||
recalcSettlementAmount(row);
|
||||
return;
|
||||
}
|
||||
@@ -682,6 +775,11 @@ const updateNumberCell = (row, column, value) => {
|
||||
if (column.prop === 'unitPrice') {
|
||||
row.transportUnitPrice = normalized;
|
||||
}
|
||||
if (column.prop === 'settlementAmount') {
|
||||
row.freightTotal = normalized;
|
||||
row['运费合计'] = normalized;
|
||||
return;
|
||||
}
|
||||
}
|
||||
recalcSettlementAmount(row);
|
||||
};
|
||||
@@ -748,11 +846,22 @@ const normalizeParsedRow = (item, index) => {
|
||||
model: item.model ?? item['型号'] ?? '',
|
||||
specification: item.specification ?? item['规格'] ?? '',
|
||||
cargoType: item.cargoType ?? item['*货物类型'] ?? item['货物类型'] ?? '',
|
||||
settlementAmount:
|
||||
item.settlementAmount ?? item['结算金额'] ?? '',
|
||||
feeItems,
|
||||
};
|
||||
const vehicleNo =
|
||||
item.vehicleNo !== undefined && item.vehicleNo !== null
|
||||
? readFilledText(item.vehicleNo)
|
||||
: readFilledText(VEHICLE_ALIAS_KEYS.map(key => item[key]).find(value => readFilledText(value)));
|
||||
applyVehicleNo(row, vehicleNo);
|
||||
row.transportUnitPrice = row.unitPrice;
|
||||
row.freight = row.transportFee;
|
||||
recalcSettlementAmount(row);
|
||||
if (row.settlementAmount === '' || row.settlementAmount === null || row.settlementAmount === undefined) {
|
||||
recalcSettlementAmount(row);
|
||||
} else {
|
||||
row.freightTotal = row.settlementAmount;
|
||||
}
|
||||
return row;
|
||||
};
|
||||
|
||||
@@ -863,6 +972,7 @@ const resetUploadState = () => {
|
||||
form.file = null;
|
||||
rows.value = [];
|
||||
feeItemNames.value = [];
|
||||
parsedHeaders.value = [];
|
||||
rowSelection.value = [];
|
||||
};
|
||||
|
||||
@@ -918,6 +1028,7 @@ const parseSelectedFile = async (raw, displayName = '') => {
|
||||
const response = await api.parseFile(raw);
|
||||
const data = unwrapData(response) || {};
|
||||
feeItemNames.value = Array.isArray(data.feeItemNames) ? data.feeItemNames : [];
|
||||
parsedHeaders.value = Array.isArray(data.headers) ? data.headers : [];
|
||||
const parsedRows = Array.isArray(data.rows) ? data.rows : [];
|
||||
rows.value = parsedRows.map((item, index) => normalizeParsedRow(item, index));
|
||||
refreshDuplicateFlags();
|
||||
@@ -938,22 +1049,115 @@ const parseSelectedFile = async (raw, displayName = '') => {
|
||||
}
|
||||
};
|
||||
|
||||
const editRow = row => {
|
||||
row._editSnapshot = JSON.parse(JSON.stringify(row));
|
||||
row._editing = true;
|
||||
const formatCargoTypeLabel = item =>
|
||||
item?.cargoName || item?.name || item?.typeName || item?.label || '';
|
||||
|
||||
const buildCargoTypeTree = cargoTypes => {
|
||||
const flatCargoTypes = [];
|
||||
const collectCargoTypes = list => {
|
||||
(list || []).forEach(item => {
|
||||
flatCargoTypes.push({ ...item, children: undefined });
|
||||
if (item.children?.length) collectCargoTypes(item.children);
|
||||
});
|
||||
};
|
||||
collectCargoTypes(cargoTypes);
|
||||
const nodeMap = new Map();
|
||||
const codeMap = new Map();
|
||||
flatCargoTypes.forEach(item => {
|
||||
const id = item.id ?? item.cargoCode ?? item.code;
|
||||
if (id === undefined || id === null) return;
|
||||
const node = {
|
||||
...item,
|
||||
id: String(id),
|
||||
cargoName: formatCargoTypeLabel(item),
|
||||
cargoCode: item.cargoCode || item.code || '',
|
||||
parentId: item.parentId === undefined || item.parentId === null ? '' : String(item.parentId),
|
||||
parentCargoCode: item.parentCargoCode || item.parentCode || '',
|
||||
children: [],
|
||||
};
|
||||
nodeMap.set(node.id, node);
|
||||
if (node.cargoCode) codeMap.set(String(node.cargoCode), node);
|
||||
});
|
||||
const rootNodes = [];
|
||||
nodeMap.forEach(node => {
|
||||
const parent =
|
||||
nodeMap.get(node.parentId) ||
|
||||
codeMap.get(String(node.parentCargoCode || '')) ||
|
||||
codeMap.get(String(node.parentId || ''));
|
||||
if (parent && parent !== node && Number(node.typeLevel) !== 1) parent.children.push(node);
|
||||
else rootNodes.push(node);
|
||||
});
|
||||
const normalize = (cargoType, level = 1, parentPath = []) => {
|
||||
if (level > 2) return null;
|
||||
const id = String(cargoType.id);
|
||||
const path = [...parentPath, id];
|
||||
const children =
|
||||
level === 1
|
||||
? (cargoType.children || []).map(item => normalize(item, level + 1, path)).filter(Boolean)
|
||||
: [];
|
||||
return {
|
||||
...cargoType,
|
||||
id,
|
||||
cargoName: formatCargoTypeLabel(cargoType),
|
||||
path,
|
||||
leaf: level === 2,
|
||||
children: children.length ? children : undefined,
|
||||
};
|
||||
};
|
||||
return rootNodes.map(item => normalize(item, 1)).filter(Boolean);
|
||||
};
|
||||
|
||||
const saveRow = row => {
|
||||
recalcSettlementAmount(row);
|
||||
row._editing = false;
|
||||
delete row._editSnapshot;
|
||||
refreshDuplicateFlags();
|
||||
const flattenCargoTypeOptions = options => {
|
||||
const result = [];
|
||||
const collect = list =>
|
||||
(list || []).forEach(item => {
|
||||
result.push(item);
|
||||
if (item.children?.length) collect(item.children);
|
||||
});
|
||||
collect(options);
|
||||
return result;
|
||||
};
|
||||
|
||||
const cancelRow = row => {
|
||||
if (row._editSnapshot) Object.assign(row, row._editSnapshot);
|
||||
row._editing = false;
|
||||
delete row._editSnapshot;
|
||||
const resolveCargoTypePath = row => {
|
||||
if (Array.isArray(row.cargoTypePath) && row.cargoTypePath.length) return row.cargoTypePath;
|
||||
const current = String(row.cargoType || row.cargoTypeCode || '').trim();
|
||||
if (!current) return [];
|
||||
const matched = cargoTypeFlatOptions.value.find(item =>
|
||||
[item.cargoName, item.name, item.typeName, item.cargoCode, item.code].some(
|
||||
value => String(value || '').trim() === current
|
||||
)
|
||||
);
|
||||
if (matched?.path?.length) return matched.path;
|
||||
return [`custom:${current}`];
|
||||
};
|
||||
|
||||
const cargoTypeSelectOptions = row => {
|
||||
const path = resolveCargoTypePath(row);
|
||||
const customId = path.find(value => String(value).startsWith('custom:'));
|
||||
if (!customId) return cargoTypeOptions.value;
|
||||
const name = String(customId).slice('custom:'.length);
|
||||
return [{ id: customId, cargoName: name, leaf: true }, ...cargoTypeOptions.value];
|
||||
};
|
||||
|
||||
const handleCargoTypeChange = (row, value) => {
|
||||
const path = Array.isArray(value) ? value : [];
|
||||
const leafId = path.length ? String(path[path.length - 1]) : '';
|
||||
if (!leafId) {
|
||||
row.cargoTypePath = [];
|
||||
row.cargoType = '';
|
||||
row.cargoTypeCode = '';
|
||||
return;
|
||||
}
|
||||
if (leafId.startsWith('custom:')) {
|
||||
row.cargoTypePath = path;
|
||||
row.cargoType = leafId.slice('custom:'.length);
|
||||
row.cargoTypeCode = '';
|
||||
return;
|
||||
}
|
||||
const cargoType = cargoTypeFlatOptions.value.find(item => String(item.id) === leafId);
|
||||
row.cargoTypePath = cargoType?.path || path;
|
||||
row.cargoType = cargoType?.cargoName || '';
|
||||
row.cargoTypeCode = cargoType?.cargoCode || cargoType?.code || '';
|
||||
};
|
||||
|
||||
const deleteRow = row => {
|
||||
@@ -1159,11 +1363,24 @@ const loadTransportTypeOptions = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
const loadCargoTypeOptions = async () => {
|
||||
try {
|
||||
const response = await getCargoTypeList(1, 9999);
|
||||
const body = unwrapData(response) || {};
|
||||
const records = Array.isArray(body) ? body : body.records || body.data || [];
|
||||
cargoTypeOptions.value = buildCargoTypeTree(records);
|
||||
cargoTypeFlatOptions.value = flattenCargoTypeOptions(cargoTypeOptions.value);
|
||||
} catch (error) {
|
||||
cargoTypeOptions.value = [];
|
||||
cargoTypeFlatOptions.value = [];
|
||||
}
|
||||
};
|
||||
|
||||
const loadOptions = async () => {
|
||||
const response = await api.getOptions();
|
||||
const options = unwrapData(response) || {};
|
||||
projects.value = (options.projects || []).map(normalizeProject).filter(Boolean);
|
||||
await loadTransportTypeOptions();
|
||||
await Promise.all([loadTransportTypeOptions(), loadCargoTypeOptions()]);
|
||||
};
|
||||
|
||||
const loadDetail = async id => {
|
||||
@@ -1190,6 +1407,7 @@ const loadDetail = async id => {
|
||||
await loadContractsByProject(detail.projectId, detail.projectName || '');
|
||||
}
|
||||
feeItemNames.value = Array.isArray(detail.feeItemNames) ? detail.feeItemNames : [];
|
||||
parsedHeaders.value = [];
|
||||
const detailRows = Array.isArray(detail.rows) ? detail.rows : [];
|
||||
rows.value = detailRows.map((item, index) => normalizeParsedRow(item, index));
|
||||
refreshDuplicateFlags();
|
||||
|
||||
Reference in New Issue
Block a user