1、调整凭证
2、调整对账 3、解决正式结算冲突bug
This commit is contained in:
@@ -35,3 +35,27 @@ export const importTransportPlan = ({
|
||||
timeout: 60000,
|
||||
});
|
||||
};
|
||||
|
||||
export const validateTransportPlan = ({
|
||||
file,
|
||||
projectId,
|
||||
projectName,
|
||||
customerName,
|
||||
contractId,
|
||||
contractName,
|
||||
}) => {
|
||||
const data = new FormData();
|
||||
data.append('file', file);
|
||||
data.append('projectId', projectId || '');
|
||||
data.append('projectName', projectName || '');
|
||||
data.append('customerName', customerName || '');
|
||||
data.append('contractId', contractId || '');
|
||||
data.append('contractName', contractName || '');
|
||||
return request({
|
||||
url: `${baseUrl}/validate-transport-plan`,
|
||||
method: 'post',
|
||||
data,
|
||||
responseType: 'blob',
|
||||
timeout: 60000,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -16,6 +16,13 @@ export const replaceFolder = (voucherId, plateNo, file) => {
|
||||
data.append('file', file);
|
||||
return request({ url: `${baseUrl}/folder-replace`, method: 'post', data });
|
||||
};
|
||||
export const replaceFolderByObject = (voucherId, plateNo, fileInfo) =>
|
||||
request({
|
||||
url: `${baseUrl}/folder-replace-object`,
|
||||
method: 'post',
|
||||
params: { voucherId, plateNo, ...fileInfo },
|
||||
timeout: 120000,
|
||||
});
|
||||
export const removeFolder = (voucherId, plateNo) =>
|
||||
request({ url: `${baseUrl}/folder-remove`, method: 'post', params: { voucherId, plateNo } });
|
||||
export const submit = data => request({ url: `${baseUrl}/submit`, method: 'post', data });
|
||||
|
||||
@@ -41,4 +41,5 @@ export const removeImportBatches = ids => request({ url: `${baseUrl}/import-batc
|
||||
export const getImportOptions = () => request({ url: `${baseUrl}/import-batch/options`, method: 'get' });
|
||||
export const exportImportTemplate = () => request({ url: `${baseUrl}/import-batch/export-template`, method: 'get', responseType: 'blob' });
|
||||
export const saveImportDraft = data => request({ url: `${baseUrl}/import-batch/draft`, method: 'post', data });
|
||||
export const validateImport = data => request({ url: `${baseUrl}/import-batch/validate`, method: 'post', data, responseType: 'blob' });
|
||||
export const confirmImport = data => request({ url: `${baseUrl}/import-batch/confirm`, method: 'post', data });
|
||||
|
||||
@@ -23,8 +23,8 @@ export const manualMatch = data =>
|
||||
export const unmatch = internalId =>
|
||||
request({ url: `${baseUrl}/unmatch`, method: 'post', params: { internalId } });
|
||||
export const adjust = data => request({ url: `${baseUrl}/adjust`, method: 'post', data });
|
||||
export const updateByMatch = id =>
|
||||
request({ url: `${baseUrl}/update-by-match`, method: 'post', params: { id } });
|
||||
export const updateByMatch = (id, data) =>
|
||||
request({ url: `${baseUrl}/update-by-match`, method: 'post', params: { id }, data });
|
||||
export const complete = id =>
|
||||
request({ url: `${baseUrl}/complete`, method: 'post', params: { id } });
|
||||
export const completeWithData = data =>
|
||||
|
||||
@@ -7234,6 +7234,7 @@ export default {
|
||||
.then(res => {
|
||||
const detail = res?.data?.data || res?.data || row;
|
||||
this.detailRow = detail;
|
||||
this.loadWaybillVoucherImages();
|
||||
this.ensureTransportPlanDetailTransportTypeName(detail);
|
||||
if (this.isWaybillDetailLayout && detail.contractId) {
|
||||
return getContractDetail(detail.contractId)
|
||||
@@ -7296,7 +7297,8 @@ export default {
|
||||
if (!config?.id) return [];
|
||||
return getProcessConfigDetail(config.id, this.detailRow.id).then(detailRes => {
|
||||
const detail = detailRes?.data?.data || detailRes?.data || config;
|
||||
this.waybillHasRelatedVoucher = Boolean(detail.hasRelatedVoucher);
|
||||
this.waybillHasRelatedVoucher =
|
||||
this.waybillHasRelatedVoucher || Boolean(detail.hasRelatedVoucher);
|
||||
return this.getProcessConfigEnabledNodes(detail);
|
||||
});
|
||||
})
|
||||
@@ -7320,6 +7322,7 @@ export default {
|
||||
getProcessConfigVoucherImages(this.detailRow.id)
|
||||
.then(res => {
|
||||
this.waybillVoucherImages = extractRecords(res);
|
||||
if (this.waybillVoucherImages.length) this.waybillHasRelatedVoucher = true;
|
||||
this.waybillVoucherImagesLoaded = true;
|
||||
})
|
||||
.finally(() => {
|
||||
|
||||
@@ -1095,7 +1095,8 @@ const fileChange = async (file, list) => {
|
||||
return text.slice(0, 10);
|
||||
};
|
||||
const count = new Map();
|
||||
rows.value = source.map((item, index) => {
|
||||
// 先解析数据,但不填充到 rows.value
|
||||
const parsedRows = source.map((item, index) => {
|
||||
const row = { _key: `${Date.now()}-${index}`, ...item, batchNo: form.batchNo };
|
||||
Object.entries(keyMap).forEach(([key, labels]) => {
|
||||
row[key] =
|
||||
@@ -1112,14 +1113,88 @@ const fileChange = async (file, list) => {
|
||||
row._duplicateKey = duplicateKey;
|
||||
return row;
|
||||
});
|
||||
rows.value.forEach(row => {
|
||||
parsedRows.forEach(row => {
|
||||
row._duplicate = count.get(row._duplicateKey) > 1;
|
||||
});
|
||||
|
||||
// 调用后端校验接口,校验通过才填充表格
|
||||
const isValid = await performValidation(parsedRows);
|
||||
|
||||
if (isValid) {
|
||||
// 校验通过,填充表格数据
|
||||
rows.value = parsedRows;
|
||||
} else {
|
||||
// 校验失败,清空数据
|
||||
rows.value = [];
|
||||
files.value = [];
|
||||
form.file = null;
|
||||
}
|
||||
};
|
||||
const fileRemove = () => {
|
||||
files.value = [];
|
||||
form.file = null;
|
||||
};
|
||||
|
||||
const performValidation = async (parsedRows) => {
|
||||
if (!parsedRows || !parsedRows.length) return false;
|
||||
|
||||
try {
|
||||
// 构建校验请求参数
|
||||
const payload = {
|
||||
...form,
|
||||
rows: parsedRows.map(row => {
|
||||
const { _key, _duplicate, _duplicateKey, _editing, _editSnapshot, ...data } = row;
|
||||
return data;
|
||||
})
|
||||
};
|
||||
|
||||
// 调用后端校验接口
|
||||
const response = await api.validateImport(payload);
|
||||
|
||||
// 检查响应类型
|
||||
const blob = response.data || response;
|
||||
|
||||
// 如果是 Blob,需要检查其 MIME 类型
|
||||
if (blob instanceof Blob) {
|
||||
// Excel 文件的 MIME 类型
|
||||
if (blob.type.includes('application/vnd.ms-excel') ||
|
||||
blob.type.includes('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')) {
|
||||
// 校验失败,下载错误明细
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const link = document.createElement('a');
|
||||
link.href = url;
|
||||
link.download = `运单导入失败明细_${dayjs().format('YYYYMMDDHHmmss')}.xlsx`;
|
||||
link.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
ElMessage.warning('数据校验失败,已自动下载错误明细表,请修正后重新上传');
|
||||
return false;
|
||||
} else if (blob.type.includes('application/json')) {
|
||||
// 可能是 JSON 响应被当作 Blob,需要解析
|
||||
const text = await blob.text();
|
||||
const json = JSON.parse(text);
|
||||
if (json.success) {
|
||||
ElMessage.success('数据校验通过');
|
||||
return true;
|
||||
} else {
|
||||
ElMessage.error(json.msg || '校验失败');
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// 其他类型,默认认为是校验通过
|
||||
ElMessage.success('数据校验通过');
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// 不是 Blob,直接判断
|
||||
ElMessage.success('数据校验通过');
|
||||
return true;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('校验失败:', error);
|
||||
ElMessage.error('校验接口调用失败');
|
||||
return false;
|
||||
}
|
||||
};
|
||||
const formatCell = (row, column) => row[column.prop] || '';
|
||||
const updateEditorValue = (column, row, value) => {
|
||||
if (column.editor === 'number') {
|
||||
|
||||
@@ -4127,6 +4127,7 @@ export default {
|
||||
.then(res => {
|
||||
const detail = res?.data?.data || res?.data || row;
|
||||
this.detailRow = detail;
|
||||
this.loadWaybillVoucherImages();
|
||||
if (detail.contractId) {
|
||||
return getContractDetail(detail.contractId)
|
||||
.then(contractRes => {
|
||||
@@ -4196,7 +4197,8 @@ export default {
|
||||
if (!config?.id) return [];
|
||||
return getProcessConfigDetail(config.id, this.detailRow.id).then(detailRes => {
|
||||
const detail = detailRes?.data?.data || detailRes?.data || config;
|
||||
this.waybillHasRelatedVoucher = Boolean(detail.hasRelatedVoucher);
|
||||
this.waybillHasRelatedVoucher =
|
||||
this.waybillHasRelatedVoucher || Boolean(detail.hasRelatedVoucher);
|
||||
return this.getProcessConfigEnabledNodes(detail);
|
||||
});
|
||||
})
|
||||
@@ -4220,6 +4222,7 @@ export default {
|
||||
getProcessConfigVoucherImages(this.detailRow.id)
|
||||
.then(res => {
|
||||
this.waybillVoucherImages = extractRecords(res);
|
||||
if (this.waybillVoucherImages.length) this.waybillHasRelatedVoucher = true;
|
||||
this.waybillVoucherImagesLoaded = true;
|
||||
})
|
||||
.finally(() => {
|
||||
|
||||
@@ -163,9 +163,10 @@
|
||||
import { exportBlob } from '@/api/common';
|
||||
import { getList as getContractList } from '@/api/business/contract-manage';
|
||||
import { getList as getProjectList } from '@/api/business/project-apply';
|
||||
import { importTransportPlan } from '@/api/business/transport-plan';
|
||||
import { importTransportPlan, validateTransportPlan } from '@/api/business/transport-plan';
|
||||
import { config } from '@/option/business/transport-plan';
|
||||
import { downloadXls } from '@/utils/util';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
const importColumns = [
|
||||
['计划名称', 'planName'],
|
||||
@@ -362,6 +363,9 @@ export default {
|
||||
this.markDuplicates();
|
||||
this.$refs.importFormRef?.validateField('file');
|
||||
this.$message.success(`已读取${rows.length}条计划明细`);
|
||||
|
||||
// 调用后端校验接口
|
||||
await this.performValidation();
|
||||
} catch (error) {
|
||||
this.handleFileRemove();
|
||||
this.$message.error('计划明细表读取失败,请检查文件格式');
|
||||
@@ -376,6 +380,63 @@ export default {
|
||||
this.editingKey = '';
|
||||
this.editSnapshot = null;
|
||||
},
|
||||
async performValidation() {
|
||||
if (!this.rows.length || !this.form.file) return;
|
||||
|
||||
try {
|
||||
// 校验表单必填项
|
||||
await this.$refs.importFormRef?.validate();
|
||||
|
||||
const response = await validateTransportPlan({
|
||||
file: this.form.file,
|
||||
projectId: this.form.projectId,
|
||||
projectName: this.form.projectName,
|
||||
customerName: this.form.customerName,
|
||||
contractId: this.form.contractId,
|
||||
contractName: this.form.contractName,
|
||||
});
|
||||
|
||||
// 检查响应类型
|
||||
const blob = response.data || response;
|
||||
|
||||
// 如果是 Blob,需要检查其 MIME 类型
|
||||
if (blob instanceof Blob) {
|
||||
// Excel 文件的 MIME 类型
|
||||
if (blob.type.includes('application/vnd.ms-excel') ||
|
||||
blob.type.includes('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')) {
|
||||
// 校验失败,下载错误明细
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const link = document.createElement('a');
|
||||
link.href = url;
|
||||
link.download = `运输计划导入失败明细_${dayjs().format('YYYYMMDDHHmmss')}.xlsx`;
|
||||
link.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
this.$message.warning('数据校验失败,已自动下载错误明细表,请修正后重新上传');
|
||||
} else if (blob.type.includes('application/json')) {
|
||||
// 可能是 JSON 响应被当作 Blob,需要解析
|
||||
const text = await blob.text();
|
||||
const json = JSON.parse(text);
|
||||
if (json.success) {
|
||||
this.$message.success('数据校验通过');
|
||||
} else {
|
||||
this.$message.error(json.msg || '校验失败');
|
||||
}
|
||||
} else {
|
||||
// 其他类型,默认认为是校验通过
|
||||
this.$message.success('数据校验通过');
|
||||
}
|
||||
} else {
|
||||
// 不是 Blob,直接判断
|
||||
this.$message.success('数据校验通过');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('校验失败:', error);
|
||||
// 表单校验失败时不提示错误,让表单自己显示错误信息
|
||||
if (error && error.message && !error.message.includes('validate')) {
|
||||
this.$message.error('校验接口调用失败');
|
||||
}
|
||||
}
|
||||
},
|
||||
duplicateKey(row) {
|
||||
return importColumns.map(([, prop]) => String(row[prop] || '').trim()).join('\u0001');
|
||||
},
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="replaceVisible" title="重新上传" width="680px" destroy-on-close>
|
||||
<div class="voucher-folder-page__replace"><el-upload action="#" :auto-upload="false" :limit="1" accept=".jpg,.jpeg,.png,.bmp,.webp,.zip" :on-change="selectReplace" :on-remove="clearReplace"><el-button type="primary">上传</el-button></el-upload><p>重新上传替换当前未匹配的凭证,支持图片或压缩包,大小不超过50M</p></div>
|
||||
<div class="voucher-folder-page__replace"><el-upload action="#" :auto-upload="false" :limit="1" accept=".jpg,.jpeg,.png,.bmp,.webp,.zip" :on-change="selectReplace" :on-remove="clearReplace"><el-button type="primary">选择文件</el-button></el-upload><el-progress v-if="replacing" class="voucher-folder-page__replace-progress" :percentage="replaceProgress" :status="replaceProgressStatus" :text-inside="false" /><p>{{ replaceProgress >= 100 ? '文件上传完成,正在处理凭证...' : '重新上传替换当前未匹配的凭证,支持图片或压缩包,大小不超过50M' }}</p></div>
|
||||
<template #footer><el-button @click="replaceVisible = false">关闭</el-button><el-button type="primary" :loading="replacing" @click="confirmReplace">确认</el-button></template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
@@ -42,6 +42,7 @@
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import md5 from 'js-md5';
|
||||
import * as api from '@/api/business/voucher-manage';
|
||||
|
||||
const route = useRoute();
|
||||
@@ -51,7 +52,7 @@ const loading = ref(false), rows = ref([]), voucher = ref({ voucherBatchNo: rout
|
||||
const page = reactive({ current: 1, size: 10, total: 0 });
|
||||
const query = reactive({ plateNo: '', matched: undefined });
|
||||
const viewerVisible = ref(false), viewerLoading = ref(false), viewer = ref({}), viewerFiles = ref([]);
|
||||
const replaceVisible = ref(false), replacing = ref(false), replaceRow = ref(), replaceFile = ref();
|
||||
const replaceVisible = ref(false), replacing = ref(false), replaceRow = ref(), replaceFile = ref(), replaceProgress = ref(0), replaceProgressStatus = ref('');
|
||||
const load = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
@@ -68,14 +69,58 @@ const openViewer = async row => {
|
||||
viewerVisible.value = true; viewerLoading.value = true; viewer.value = row; viewerFiles.value = [];
|
||||
try { const res = await api.getFolderDetail(voucherId, row.plateNo); viewer.value = res.data?.data || row; viewerFiles.value = viewer.value.files || []; } catch (error) { ElMessage.error(error.message || '获取凭证详情失败'); } finally { viewerLoading.value = false; }
|
||||
};
|
||||
const openReplace = row => { replaceRow.value = row; replaceFile.value = undefined; replaceVisible.value = true; };
|
||||
const openReplace = row => { replaceRow.value = row; replaceFile.value = undefined; replaceProgress.value = 0; replaceProgressStatus.value = ''; replaceVisible.value = true; };
|
||||
const selectReplace = upload => { replaceFile.value = upload.raw; };
|
||||
const clearReplace = () => { replaceFile.value = undefined; };
|
||||
const clearReplace = () => { replaceFile.value = undefined; replaceProgress.value = 0; replaceProgressStatus.value = ''; };
|
||||
const uploadReplaceFile = async file => {
|
||||
const chunkSize = 2 * 1024 * 1024;
|
||||
const digest = md5.base64(await file.arrayBuffer());
|
||||
const taskRes = await api.createFileTask({
|
||||
md5: digest,
|
||||
attachmentName: file.name,
|
||||
size: file.size,
|
||||
chunkSize,
|
||||
chunkTotal: Math.ceil(file.size / chunkSize),
|
||||
force: true,
|
||||
businessType: 'voucher-replace',
|
||||
businessId: `${voucherId}:${replaceRow.value.plateNo}`,
|
||||
});
|
||||
const task = taskRes.data?.data;
|
||||
if (!task?.id || !task.objectKey) throw new Error('创建分片上传任务失败');
|
||||
replaceProgress.value = 0;
|
||||
for (let partNumber = 1; partNumber <= task.chunkTotal; partNumber += 1) {
|
||||
const urlRes = await api.getPartUploadUrl(task.id, partNumber);
|
||||
const part = file.slice((partNumber - 1) * chunkSize, Math.min(partNumber * chunkSize, file.size));
|
||||
const response = await fetch(urlRes.data?.data, { method: 'PUT', body: part });
|
||||
if (!response.ok) throw new Error(`分片${partNumber}上传失败`);
|
||||
const etag = String(response.headers.get('etag') || '').replaceAll('"', '');
|
||||
if (!etag) throw new Error('未获取到分片 ETag');
|
||||
await api.updateFileTask({ id: task.id, partNumber, etag });
|
||||
replaceProgress.value = Math.round((partNumber / task.chunkTotal) * 100);
|
||||
}
|
||||
const completedRes = await api.getFileTask(task.id);
|
||||
const completedTask = completedRes.data?.data;
|
||||
if (!completedTask || completedTask.status !== 'completed') throw new Error('文件分片合并未完成');
|
||||
return completedTask;
|
||||
};
|
||||
const confirmReplace = async () => {
|
||||
if (!replaceFile.value) return ElMessage.warning('请选择凭证文件');
|
||||
if (replaceFile.value.size > 50 * 1024 * 1024) return ElMessage.warning('凭证文件大小不能超过50M');
|
||||
replacing.value = true;
|
||||
try { await api.replaceFolder(voucherId, replaceRow.value.plateNo, replaceFile.value); ElMessage.success('上传成功,已重新匹配运单'); replaceVisible.value = false; await load(); } catch (error) { ElMessage.error(error.message || '上传失败'); } finally { replacing.value = false; }
|
||||
replaceProgress.value = 0;
|
||||
replaceProgressStatus.value = '';
|
||||
try {
|
||||
const task = await uploadReplaceFile(replaceFile.value);
|
||||
await api.replaceFolderByObject(voucherId, replaceRow.value.plateNo, {
|
||||
objectKey: task.objectKey,
|
||||
fileName: task.attachmentName || replaceFile.value.name,
|
||||
size: replaceFile.value.size,
|
||||
contentType: replaceFile.value.type,
|
||||
});
|
||||
ElMessage.success('上传成功,已重新匹配运单');
|
||||
replaceVisible.value = false;
|
||||
await load();
|
||||
} catch (error) { replaceProgressStatus.value = 'exception'; ElMessage.error(error.message || '上传失败'); } finally { replacing.value = false; }
|
||||
};
|
||||
const removeFolder = row => ElMessageBox.confirm(`确认删除车牌”${row.plateNo}”的凭证吗?`, '提示', { type: 'warning' }).then(async () => { await api.removeFolder(voucherId, row.plateNo); ElMessage.success('删除成功'); load(); });
|
||||
const goToLoading = loadingNo => { router.push({ path: '/business/loading-manage', query: { loadingNo } }); };
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
width="120"
|
||||
fixed="right"
|
||||
align="center"
|
||||
/><el-table-column label="操作" width="200" fixed="right" align="left"
|
||||
/><el-table-column label="操作" width="320" fixed="right" align="left"
|
||||
><template #default="{ row }"
|
||||
><div class="voucher-manage-page__actions">
|
||||
<el-link
|
||||
@@ -120,6 +120,16 @@
|
||||
type="primary"
|
||||
@click="download(row)"
|
||||
>下载</el-link
|
||||
><el-link
|
||||
v-if="row.auditStatus === '审核驳回'"
|
||||
type="primary"
|
||||
@click="openUpload(row, 'reupload')"
|
||||
>重新上传</el-link
|
||||
><el-link
|
||||
v-if="row.auditStatus === '审核驳回'"
|
||||
type="primary"
|
||||
@click="openUpload(row, 'changeBatch')"
|
||||
>更换运单批次</el-link
|
||||
><el-link
|
||||
v-if="row.processStatus !== '处理完成' || row.auditStatus === '待审核'"
|
||||
type="primary"
|
||||
@@ -207,7 +217,7 @@
|
||||
|
||||
<el-dialog
|
||||
v-model="uploadVisible"
|
||||
:title="editing.id ? '更换运单批次' : '批量导入凭证'"
|
||||
:title="editing.id ? (uploadMode === 'reupload' ? '重新上传' : '更换运单批次') : '批量导入凭证'"
|
||||
width="1200px"
|
||||
destroy-on-close
|
||||
:before-close="beforeUploadDialogClose"
|
||||
@@ -525,7 +535,8 @@ const loading = ref(false),
|
||||
cancelledTaskIds = ref(new Set()),
|
||||
uploadCancelled = ref(false),
|
||||
activeUploadTaskId = ref(),
|
||||
selectedVoucherFile = ref();
|
||||
selectedVoucherFile = ref(),
|
||||
uploadMode = ref('');
|
||||
const query = reactive({
|
||||
voucherBatchNo: '',
|
||||
auditStatus: '',
|
||||
@@ -597,9 +608,10 @@ const loadProjects = async () => {
|
||||
const changeProject = projectId => {
|
||||
editing.projectName = projectOptions.value.find(item => item.id === projectId)?.projectName || '';
|
||||
};
|
||||
const openUpload = async row => {
|
||||
const openUpload = async (row, mode = '') => {
|
||||
await loadProjects();
|
||||
selectedVoucherFile.value = undefined;
|
||||
uploadMode.value = mode;
|
||||
Object.assign(editing, {
|
||||
id: row?.id || '',
|
||||
voucherBatchNo: row?.voucherBatchNo || '',
|
||||
@@ -610,6 +622,7 @@ const openUpload = async row => {
|
||||
fileTaskId: row?.fileTaskId || '',
|
||||
waybillImportBatchIds: [],
|
||||
});
|
||||
if (mode === 'reupload') Object.assign(editing, { fileName: '', fileUrl: '', fileTaskId: '' });
|
||||
uploadPercent.value = 0;
|
||||
selectedBatches.value = [];
|
||||
uploadVisible.value = true;
|
||||
|
||||
@@ -2371,6 +2371,7 @@ export default {
|
||||
buildSavePayload() {
|
||||
return {
|
||||
id: this.form.id,
|
||||
formalSettlementNo: this.form.formalSettlementNo,
|
||||
contractId: this.form.contractId,
|
||||
settlementType: this.form.settlementType,
|
||||
sourcePreSettlementIds: this.form.sourcePreSettlementIds,
|
||||
@@ -2444,7 +2445,7 @@ export default {
|
||||
}
|
||||
if (!this.validateInvoices()) return;
|
||||
// 附件类型仅做提示,不阻断正式结算单新增/保存提交。
|
||||
this.validateAttachments();
|
||||
// this.validateAttachments();
|
||||
this.saving = true;
|
||||
try {
|
||||
await save(this.buildSavePayload());
|
||||
|
||||
@@ -1181,12 +1181,17 @@ export default {
|
||||
}
|
||||
},
|
||||
async handleUpdate() {
|
||||
await this.$confirm('将以外部账单匹配金额更新内部结算明细,是否继续?', '更新账单', {
|
||||
await this.$confirm('将以外部账单数据更新运单及内部结算明细,是否继续?', '更新账单', {
|
||||
type: 'warning',
|
||||
});
|
||||
this.actionLoading = true;
|
||||
try {
|
||||
await api.updateByMatch(this.currentId);
|
||||
await api.updateByMatch(this.currentId, {
|
||||
id: this.currentId,
|
||||
reconciliationMode: this.form.reconciliationMode,
|
||||
internalDetails: this.serializeInternalRows(),
|
||||
externalDetails: this.serializeExternalRows(),
|
||||
});
|
||||
await this.loadDetail();
|
||||
this.$message.success('账单更新完成');
|
||||
} finally {
|
||||
|
||||
Reference in New Issue
Block a user