1、调整合同
2、调整项目 3、调整付款管理
This commit is contained in:
@@ -123,12 +123,25 @@
|
||||
><el-input v-model="form.payeeName" disabled /></el-form-item
|
||||
></el-col>
|
||||
<el-col :span="6"
|
||||
><el-form-item label="收款账号"
|
||||
><el-input v-model="form.bankAccount" :disabled="readonly" /></el-form-item
|
||||
><el-form-item label="收款账号" prop="receiptAccountId"
|
||||
><el-select
|
||||
v-model="form.receiptAccountId"
|
||||
:disabled="readonly || !form.payeeName"
|
||||
:loading="receiptAccountLoading"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="请选择收款方的收款账号"
|
||||
no-data-text="该收款方未维护可用收款信息"
|
||||
@change="handleReceiptAccountChange"
|
||||
><el-option
|
||||
v-for="item in receiptAccountOptions"
|
||||
:key="item.id"
|
||||
:label="receiptAccountLabel(item)"
|
||||
:value="item.id" /></el-select></el-form-item
|
||||
></el-col>
|
||||
<el-col :span="6"
|
||||
><el-form-item label="开户银行"
|
||||
><el-input v-model="form.bankName" :disabled="readonly" /></el-form-item
|
||||
><el-input v-model="form.bankName" disabled /></el-form-item
|
||||
></el-col>
|
||||
<el-col :span="6"
|
||||
><el-form-item label="申请人"
|
||||
@@ -244,7 +257,24 @@
|
||||
min-width="160"
|
||||
/></el-table>
|
||||
</section-card>
|
||||
<section-card title="附件">
|
||||
<section-card>
|
||||
<template #title>
|
||||
<span>附件</span>
|
||||
<span v-if="missingAttachmentMaterials.length" class="payment-form-page__missing-text">
|
||||
未上传:{{ missingAttachmentMaterials.map(item => item.label).join('、') }}
|
||||
</span>
|
||||
</template>
|
||||
<div v-loading="attachmentRuleLoading" class="payment-form-page__attachment-checklist">
|
||||
<span class="payment-form-page__attachment-checklist-label">材料清单</span>
|
||||
<el-tag
|
||||
v-for="item in requiredAttachmentMaterials"
|
||||
:key="item.key"
|
||||
:type="hasAttachmentMaterial(item) ? 'success' : 'danger'"
|
||||
effect="plain"
|
||||
>
|
||||
{{ item.label }}({{ hasAttachmentMaterial(item) ? '已上传' : '未上传' }})
|
||||
</el-tag>
|
||||
</div>
|
||||
<el-table :data="form.attachments" border
|
||||
><el-table-column type="index" label="序号" width="70" /><el-table-column
|
||||
label="附件类型"
|
||||
@@ -252,8 +282,10 @@
|
||||
><template #default="{ row }"
|
||||
><el-select v-model="row.attachmentType" :disabled="readonly"
|
||||
><el-option label="磅单" value="weighing_slip" /><el-option
|
||||
label="结算单"
|
||||
value="settlement" /><el-option label="合同签章文件" value="contract" /><el-option
|
||||
label="委托单"
|
||||
value="entrust_order" /><el-option label="结算单" value="settlement" /><el-option
|
||||
label="合同签章文件"
|
||||
value="contract" /><el-option
|
||||
label="特批附件"
|
||||
value="special_approval" /><el-option
|
||||
label="其他"
|
||||
@@ -297,7 +329,7 @@
|
||||
</section-card>
|
||||
<div class="payment-form-page__actions">
|
||||
<el-button @click="goBack">返回</el-button
|
||||
><el-button v-if="!readonly && canSave" @click="saveDraft">保存</el-button
|
||||
><el-button v-if="!readonly && canSave" @click="saveDraft(false)">保存</el-button
|
||||
><el-button
|
||||
v-if="!readonly && canSave && hasPermission('payment_application_submit')"
|
||||
type="primary"
|
||||
@@ -347,8 +379,38 @@
|
||||
import { mapGetters } from 'vuex';
|
||||
import * as api from '@/api/payment/paymentApplication';
|
||||
import * as billLedgerApi from '@/api/payment/billLedger';
|
||||
import { getDetail as getContractDetail } from '@/api/business/contract-manage';
|
||||
import * as formalApi from '@/api/settlement/formalSettlement';
|
||||
import * as preApi from '@/api/settlement/preSettlement';
|
||||
import {
|
||||
getDetail as getCustomerArchiveDetail,
|
||||
getList as getCustomerArchiveList,
|
||||
} from '@/api/vehicle/customer-archive';
|
||||
import { readSettlementTransfer, removeSettlementTransfer } from '@/utils/settlement-transfer';
|
||||
|
||||
const ATTACHMENT_MATERIALS = {
|
||||
weighingSlip: { key: 'weighingSlip', label: '磅单', keywords: ['磅单'] },
|
||||
entrustOrder: { key: 'entrustOrder', label: '委托单', keywords: ['委托单'] },
|
||||
settlement: { key: 'settlement', label: '结算单', keywords: ['结算单'] },
|
||||
contract: {
|
||||
key: 'contract',
|
||||
label: '合同签章文件',
|
||||
keywords: ['合同签章文件', '合同签章', '签章'],
|
||||
},
|
||||
specialApproval: {
|
||||
key: 'specialApproval',
|
||||
label: '特批附件',
|
||||
keywords: ['特批附件', '特批'],
|
||||
},
|
||||
};
|
||||
|
||||
const MATERIAL_TYPE_MAP = {
|
||||
weighingSlip: 'weighing_slip',
|
||||
entrustOrder: 'entrust_order',
|
||||
settlement: 'settlement',
|
||||
contract: 'contract',
|
||||
specialApproval: 'special_approval',
|
||||
};
|
||||
|
||||
const emptyForm = () => ({
|
||||
id: null,
|
||||
@@ -356,6 +418,7 @@ const emptyForm = () => ({
|
||||
paymentType: 'project_advance',
|
||||
settlementId: null,
|
||||
preSettlementId: null,
|
||||
preSettlementIds: [],
|
||||
projectId: null,
|
||||
projectName: '',
|
||||
deptId: null,
|
||||
@@ -389,6 +452,8 @@ export default {
|
||||
return {
|
||||
form: emptyForm(),
|
||||
amountSyncing: false,
|
||||
transferPayload: null,
|
||||
referenceRows: [],
|
||||
paymentRecords: [],
|
||||
referenceVisible: false,
|
||||
referenceTab: 'formal',
|
||||
@@ -397,6 +462,11 @@ export default {
|
||||
contractRows: [],
|
||||
billOptions: [],
|
||||
billLoading: false,
|
||||
receiptAccountOptions: [],
|
||||
receiptAccountLoading: false,
|
||||
firstContractPayment: false,
|
||||
payeeCustomerLevel: '',
|
||||
attachmentRuleLoading: false,
|
||||
paymentTypeOptions: api.paymentTypeOptions,
|
||||
paymentMethodOptions: api.paymentMethodOptions,
|
||||
attachmentFileTypes: [
|
||||
@@ -420,6 +490,7 @@ export default {
|
||||
paymentType: [{ required: true, message: '请选择付款类型' }],
|
||||
referenceId: [{ validator: this.validateReference, trigger: 'change' }],
|
||||
paymentMethod: [{ required: true, message: '请选择付款方式' }],
|
||||
receiptAccountId: [{ required: true, message: '请选择收款账号', trigger: 'change' }],
|
||||
billLedgerId: [{ validator: this.validateBillLedger, trigger: 'change' }],
|
||||
appliedAmount: [{ validator: this.validateAppliedAmount, trigger: 'change' }],
|
||||
},
|
||||
@@ -441,9 +512,26 @@ export default {
|
||||
return ['bank_draft', 'commercial_draft'].includes(this.form.paymentMethod);
|
||||
},
|
||||
referenceLabel() {
|
||||
if (this.referenceRows.length) {
|
||||
return this.referenceRows
|
||||
.map(item => item.settlementNo)
|
||||
.filter(Boolean)
|
||||
.join('、');
|
||||
}
|
||||
return this.form.settlementNo || this.form.preSettlementNo || '';
|
||||
},
|
||||
settlementRows() {
|
||||
if (this.referenceRows.length) {
|
||||
return this.referenceRows.map(item => ({
|
||||
...item,
|
||||
paymentRatio: this.form.paymentRatio,
|
||||
appliedAmount: Number(
|
||||
((Number(item.payableAmount || 0) * Number(this.form.paymentRatio || 0)) / 100).toFixed(
|
||||
2
|
||||
)
|
||||
),
|
||||
}));
|
||||
}
|
||||
if (!this.referenceLabel) return [];
|
||||
return [
|
||||
{
|
||||
@@ -455,8 +543,32 @@ export default {
|
||||
},
|
||||
];
|
||||
},
|
||||
highRiskPayee() {
|
||||
const level = String(this.payeeCustomerLevel || '')
|
||||
.trim()
|
||||
.toUpperCase();
|
||||
return ['D', 'D级', 'E', 'E级', 'F', 'F级'].includes(level) || level.includes('高风险');
|
||||
},
|
||||
requiredAttachmentMaterials() {
|
||||
const materials = [ATTACHMENT_MATERIALS.weighingSlip, ATTACHMENT_MATERIALS.settlement];
|
||||
if (this.form.paymentType === 'project_advance') {
|
||||
materials.splice(1, 0, ATTACHMENT_MATERIALS.entrustOrder);
|
||||
}
|
||||
if (this.firstContractPayment) materials.push(ATTACHMENT_MATERIALS.contract);
|
||||
if (this.highRiskPayee) materials.push(ATTACHMENT_MATERIALS.specialApproval);
|
||||
return materials;
|
||||
},
|
||||
missingAttachmentMaterials() {
|
||||
return this.requiredAttachmentMaterials.filter(item => !this.hasAttachmentMaterial(item));
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
'$route.query.transferToken': async function (token, oldToken) {
|
||||
if (!this.recordId && token && token !== oldToken) {
|
||||
this.transferPayload = readSettlementTransfer(token);
|
||||
await this.initialize();
|
||||
}
|
||||
},
|
||||
'form.paymentRatio'(value) {
|
||||
if (this.amountSyncing || !Number(this.form.payableAmount)) return;
|
||||
this.amountSyncing = true;
|
||||
@@ -479,6 +591,7 @@ export default {
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.transferPayload = readSettlementTransfer(this.$route.query.transferToken);
|
||||
this.initialize();
|
||||
},
|
||||
methods: {
|
||||
@@ -486,7 +599,11 @@ export default {
|
||||
return this.permission?.[code] !== false;
|
||||
},
|
||||
validateReference(rule, value, callback) {
|
||||
if (this.form.paymentType === 'progress_advance' && !this.form.preSettlementId) {
|
||||
if (
|
||||
this.form.paymentType === 'progress_advance' &&
|
||||
!this.form.preSettlementId &&
|
||||
!this.form.preSettlementIds?.length
|
||||
) {
|
||||
callback(new Error('请选择预结算单'));
|
||||
return;
|
||||
}
|
||||
@@ -556,17 +673,133 @@ export default {
|
||||
this.form = {
|
||||
...emptyForm(),
|
||||
...data,
|
||||
preSettlementIds: data.preSettlementIds?.length
|
||||
? data.preSettlementIds
|
||||
: data.preSettlementId
|
||||
? [data.preSettlementId]
|
||||
: [],
|
||||
attachments: this.parse(data.attachmentsJson),
|
||||
invoices: data.invoices || [],
|
||||
};
|
||||
const referenceRow = this.createReferenceRow(data);
|
||||
this.referenceRows = referenceRow.settlementNo ? [referenceRow] : [];
|
||||
this.paymentRecords = data.paymentRecords || [];
|
||||
await this.loadReceiptAccountOptions(false);
|
||||
await this.loadAttachmentRuleData(await this.loadCurrentSettlementDetails());
|
||||
if (this.billPayment) await this.loadBillOptions('', data.billLedgerId);
|
||||
} else {
|
||||
this.form = emptyForm();
|
||||
this.referenceRows = [];
|
||||
this.form.applyDate = this.$dayjs().format('YYYY-MM-DD');
|
||||
this.form.applicantName =
|
||||
this.$store.getters.userInfo?.realName || this.$store.getters.userInfo?.userName || '';
|
||||
await this.loadTransferredPreSettlements();
|
||||
}
|
||||
},
|
||||
getTransferredPreSettlementIds() {
|
||||
const payloadIds = (this.transferPayload?.sourcePreSettlements || []).map(
|
||||
item => item.preSettlementId || item.id
|
||||
);
|
||||
const queryIds = String(this.$route.query.preSettlementIds || '')
|
||||
.split(',')
|
||||
.map(item => item.trim())
|
||||
.filter(Boolean);
|
||||
return [...new Set([...payloadIds, ...queryIds].map(String))];
|
||||
},
|
||||
async loadTransferredPreSettlements() {
|
||||
const fallbackRows = this.transferPayload?.sourcePreSettlements || [];
|
||||
const ids = this.getTransferredPreSettlementIds();
|
||||
if (!ids.length) {
|
||||
this.applyTransferredPreSettlements(fallbackRows);
|
||||
await Promise.all([
|
||||
this.loadReceiptAccountOptions(),
|
||||
this.loadAttachmentRuleData(fallbackRows),
|
||||
]);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const responses = await Promise.all(ids.map(id => preApi.getDetail(id)));
|
||||
const rows = responses.map(response => this.unwrapData(response)).filter(item => item?.id);
|
||||
const sourceRows = rows.length ? rows : fallbackRows;
|
||||
this.applyTransferredPreSettlements(sourceRows);
|
||||
await Promise.all([
|
||||
this.loadReceiptAccountOptions(),
|
||||
this.loadAttachmentRuleData(sourceRows),
|
||||
]);
|
||||
} catch (error) {
|
||||
if (fallbackRows.length) {
|
||||
this.applyTransferredPreSettlements(fallbackRows);
|
||||
await Promise.all([
|
||||
this.loadReceiptAccountOptions(),
|
||||
this.loadAttachmentRuleData(fallbackRows),
|
||||
]);
|
||||
return;
|
||||
}
|
||||
this.$message.error('预结算信息加载失败,请返回后重新发起预付申请');
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
createReferenceRow(row) {
|
||||
const settlementAmount = Number(row.settlementAmount || 0);
|
||||
const appliedAmount = Number(row.advanceAppliedAmount || row.appliedPaymentAmount || 0);
|
||||
return {
|
||||
id: row.preSettlementId || row.settlementId || row.id,
|
||||
settlementNo: row.preSettlementNo || row.formalSettlementNo || row.settlementNo || '',
|
||||
settlementAmount,
|
||||
payableAmount:
|
||||
row.payableAmount === undefined || row.payableAmount === null
|
||||
? Math.max(0, settlementAmount - appliedAmount)
|
||||
: Number(row.payableAmount || 0),
|
||||
};
|
||||
},
|
||||
applyTransferredPreSettlements(rows = []) {
|
||||
if (!rows.length) return;
|
||||
const contractIds = new Set(rows.map(item => String(item.contractId || '')));
|
||||
if (contractIds.size > 1 || contractIds.has('')) {
|
||||
this.$message.warning('所选预结算单合同信息不一致,请返回后重新选择');
|
||||
return;
|
||||
}
|
||||
const first = rows[0];
|
||||
this.referenceRows = rows.map(item => this.createReferenceRow(item));
|
||||
const settlementAmount = this.referenceRows.reduce(
|
||||
(total, item) => total + Number(item.settlementAmount || 0),
|
||||
0
|
||||
);
|
||||
const payableAmount = this.referenceRows.reduce(
|
||||
(total, item) => total + Number(item.payableAmount || 0),
|
||||
0
|
||||
);
|
||||
const paymentRatio = Number(this.form.paymentRatio || 0);
|
||||
this.amountSyncing = true;
|
||||
Object.assign(this.form, {
|
||||
paymentType: 'progress_advance',
|
||||
settlementId: null,
|
||||
settlementNo: '',
|
||||
preSettlementId: first.preSettlementId || first.id,
|
||||
preSettlementIds: rows.map(item => item.preSettlementId || item.id),
|
||||
preSettlementNo: this.referenceRows
|
||||
.map(item => item.settlementNo)
|
||||
.filter(Boolean)
|
||||
.join('、'),
|
||||
projectId: first.projectId,
|
||||
projectName: first.projectName,
|
||||
deptId: first.deptId,
|
||||
deptName: first.deptName,
|
||||
contractId: first.contractId,
|
||||
contractNo: first.contractNo,
|
||||
contractName: first.contractName,
|
||||
payerName: first.payerName,
|
||||
payeeName: first.payeeName,
|
||||
settlementAmount: Number(settlementAmount.toFixed(2)),
|
||||
payableAmount: Number(payableAmount.toFixed(2)),
|
||||
billType: '预结算单',
|
||||
appliedAmount: Number(((payableAmount * paymentRatio) / 100).toFixed(2)),
|
||||
});
|
||||
this.$nextTick(() => {
|
||||
this.amountSyncing = false;
|
||||
this.$refs.formRef?.clearValidate();
|
||||
});
|
||||
},
|
||||
parse(value) {
|
||||
if (!value) return [];
|
||||
if (Array.isArray(value)) return value;
|
||||
@@ -576,11 +809,218 @@ export default {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
attachmentFileName(file) {
|
||||
return String(file?.originalName || file?.name || file?.fileName || '').trim();
|
||||
},
|
||||
attachmentFileUrl(file) {
|
||||
return file?.url || file?.link || file?.src || file?.domain || '';
|
||||
},
|
||||
attachmentMatchesMaterial(file, material) {
|
||||
const fileName = this.attachmentFileName(file).toLocaleLowerCase();
|
||||
return (
|
||||
Boolean(this.attachmentFileUrl(file)) &&
|
||||
material.keywords.some(keyword => fileName.includes(keyword.toLocaleLowerCase()))
|
||||
);
|
||||
},
|
||||
hasAttachmentMaterial(material) {
|
||||
return (this.form.attachments || []).some(file =>
|
||||
this.attachmentMatchesMaterial(file, material)
|
||||
);
|
||||
},
|
||||
resolveAttachmentMaterial(file, materials = Object.values(ATTACHMENT_MATERIALS)) {
|
||||
return [...materials]
|
||||
.sort(
|
||||
(a, b) =>
|
||||
Math.max(...b.keywords.map(String.length)) - Math.max(...a.keywords.map(String.length))
|
||||
)
|
||||
.find(material => this.attachmentMatchesMaterial(file, material));
|
||||
},
|
||||
mergeAutomaticAttachments(files, materials, sourceName) {
|
||||
const existingUrls = new Set(
|
||||
(this.form.attachments || []).map(file => this.attachmentFileUrl(file)).filter(Boolean)
|
||||
);
|
||||
const imported = (files || [])
|
||||
.map(file => ({ file, material: this.resolveAttachmentMaterial(file, materials) }))
|
||||
.filter(item => item.material && !existingUrls.has(this.attachmentFileUrl(item.file)))
|
||||
.map(({ file, material }) => {
|
||||
existingUrls.add(this.attachmentFileUrl(file));
|
||||
return {
|
||||
...file,
|
||||
originalName: this.attachmentFileName(file),
|
||||
name: this.attachmentFileName(file),
|
||||
url: this.attachmentFileUrl(file),
|
||||
link: file.link || this.attachmentFileUrl(file),
|
||||
attachmentType: MATERIAL_TYPE_MAP[material.key],
|
||||
description: file.description || `自动取自${sourceName}`,
|
||||
sourceImported: true,
|
||||
};
|
||||
});
|
||||
if (imported.length) this.form.attachments = [...this.form.attachments, ...imported];
|
||||
},
|
||||
async loadCurrentSettlementDetails() {
|
||||
const requests = [];
|
||||
if (this.form.preSettlementId) requests.push(preApi.getDetail(this.form.preSettlementId));
|
||||
if (this.form.settlementId) requests.push(formalApi.getDetail(this.form.settlementId));
|
||||
if (!requests.length) return [];
|
||||
const responses = await Promise.all(requests);
|
||||
return responses.map(response => this.unwrapData(response)).filter(item => item?.id);
|
||||
},
|
||||
async loadAttachmentRuleData(settlementRows = []) {
|
||||
this.attachmentRuleLoading = true;
|
||||
this.firstContractPayment = false;
|
||||
try {
|
||||
const settlementMaterials = [
|
||||
ATTACHMENT_MATERIALS.weighingSlip,
|
||||
ATTACHMENT_MATERIALS.entrustOrder,
|
||||
ATTACHMENT_MATERIALS.settlement,
|
||||
];
|
||||
const settlementFiles = (settlementRows || []).flatMap(row =>
|
||||
this.parse(row.attachmentsJson)
|
||||
);
|
||||
this.mergeAutomaticAttachments(settlementFiles, settlementMaterials, '结算单');
|
||||
if (!this.form.contractId) {
|
||||
this.firstContractPayment = false;
|
||||
return;
|
||||
}
|
||||
const [contractResponse, paymentResponse] = await Promise.all([
|
||||
getContractDetail(this.form.contractId),
|
||||
api.getList(1, 9999, { contractId: this.form.contractId }),
|
||||
]);
|
||||
const contract = this.unwrapData(contractResponse) || {};
|
||||
const payments = this.unwrapData(paymentResponse)?.records || [];
|
||||
this.firstContractPayment = !payments.some(
|
||||
item =>
|
||||
String(item.contractId || '') === String(this.form.contractId) &&
|
||||
String(item.id || '') !== String(this.form.id || '') &&
|
||||
item.approvalStatus !== 'voided'
|
||||
);
|
||||
if (this.firstContractPayment) {
|
||||
this.mergeAutomaticAttachments(
|
||||
this.parse(contract.contractFileJson),
|
||||
[ATTACHMENT_MATERIALS.contract],
|
||||
'合同'
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
this.$message.warning('附件清单来源材料加载失败,请核对后手工补充');
|
||||
} finally {
|
||||
this.attachmentRuleLoading = false;
|
||||
}
|
||||
},
|
||||
validateRequiredAttachments() {
|
||||
if (!this.missingAttachmentMaterials.length) return true;
|
||||
this.$message.warning(
|
||||
`请先上传付款申请所需材料:${this.missingAttachmentMaterials
|
||||
.map(item => item.label)
|
||||
.join('、')}`
|
||||
);
|
||||
return false;
|
||||
},
|
||||
handleTypeChange() {
|
||||
if (this.form.paymentType === 'project_advance') {
|
||||
this.form.settlementId = null;
|
||||
this.form.preSettlementId = null;
|
||||
this.form.preSettlementIds = [];
|
||||
this.form.settlementNo = '';
|
||||
this.form.preSettlementNo = '';
|
||||
this.referenceRows = [];
|
||||
}
|
||||
this.loadAttachmentRuleData([]);
|
||||
},
|
||||
clearReceiptAccount() {
|
||||
Object.assign(this.form, {
|
||||
receiptAccountId: null,
|
||||
receiptAccountName: '',
|
||||
bankName: '',
|
||||
bankAccount: '',
|
||||
});
|
||||
},
|
||||
customerRecords(response) {
|
||||
return this.unwrapData(response)?.records || [];
|
||||
},
|
||||
async loadReceiptAccountOptions(autoSelectDefault = true) {
|
||||
const payeeName = String(this.form.payeeName || '').trim();
|
||||
const preserveCurrentValue = autoSelectDefault === false;
|
||||
this.receiptAccountOptions = [];
|
||||
this.payeeCustomerLevel = '';
|
||||
if (!payeeName) {
|
||||
if (!preserveCurrentValue) this.clearReceiptAccount();
|
||||
return;
|
||||
}
|
||||
this.receiptAccountLoading = true;
|
||||
try {
|
||||
const [fullNameResponse, shortNameResponse] = await Promise.all([
|
||||
getCustomerArchiveList(1, 20, {
|
||||
fullName: payeeName,
|
||||
approvalStatus: 'approved',
|
||||
status: 1,
|
||||
}),
|
||||
getCustomerArchiveList(1, 20, {
|
||||
shortName: payeeName,
|
||||
approvalStatus: 'approved',
|
||||
status: 1,
|
||||
}),
|
||||
]);
|
||||
const customers = [
|
||||
...this.customerRecords(fullNameResponse),
|
||||
...this.customerRecords(shortNameResponse),
|
||||
];
|
||||
const customer = customers.find(
|
||||
item => item.fullName === payeeName || item.shortName === payeeName
|
||||
);
|
||||
if (!customer?.id) {
|
||||
if (!preserveCurrentValue) this.clearReceiptAccount();
|
||||
return;
|
||||
}
|
||||
const detail = this.unwrapData(await getCustomerArchiveDetail(customer.id));
|
||||
this.payeeCustomerLevel = detail.customerLevel || '';
|
||||
this.receiptAccountOptions = (detail.receiptAccounts || []).map(item => ({
|
||||
...item,
|
||||
id: String(item.id),
|
||||
}));
|
||||
const selected = this.receiptAccountOptions.find(
|
||||
item => String(item.id) === String(this.form.receiptAccountId || '')
|
||||
);
|
||||
if (selected) {
|
||||
this.applyReceiptAccount(selected);
|
||||
return;
|
||||
}
|
||||
if (preserveCurrentValue) return;
|
||||
this.clearReceiptAccount();
|
||||
if (autoSelectDefault && !this.readonly) {
|
||||
const defaultAccount =
|
||||
this.receiptAccountOptions.find(item => Number(item.isDefault) === 1) ||
|
||||
(this.receiptAccountOptions.length === 1 ? this.receiptAccountOptions[0] : null);
|
||||
if (defaultAccount) this.applyReceiptAccount(defaultAccount);
|
||||
}
|
||||
} catch (error) {
|
||||
if (!preserveCurrentValue) this.clearReceiptAccount();
|
||||
this.$message.warning('收款方的客商收款信息加载失败,请稍后重试');
|
||||
} finally {
|
||||
this.receiptAccountLoading = false;
|
||||
}
|
||||
},
|
||||
receiptAccountLabel(item) {
|
||||
return [item.accountName || item.accountHolderName, item.bankName, item.bankAccount]
|
||||
.filter(Boolean)
|
||||
.join('|');
|
||||
},
|
||||
applyReceiptAccount(account) {
|
||||
Object.assign(this.form, {
|
||||
receiptAccountId: account.id,
|
||||
receiptAccountName: account.accountName || account.accountHolderName || '',
|
||||
bankName: account.bankName || '',
|
||||
bankAccount: account.bankAccount || '',
|
||||
});
|
||||
this.$nextTick(() => this.$refs.formRef?.validateField('receiptAccountId').catch(() => {}));
|
||||
},
|
||||
handleReceiptAccountChange(id) {
|
||||
const account = this.receiptAccountOptions.find(item => String(item.id) === String(id || ''));
|
||||
if (account) {
|
||||
this.applyReceiptAccount(account);
|
||||
return;
|
||||
}
|
||||
this.clearReceiptAccount();
|
||||
},
|
||||
async handlePaymentMethodChange() {
|
||||
if (!this.billPayment) {
|
||||
@@ -624,7 +1064,10 @@ export default {
|
||||
await this.loadReferences();
|
||||
this.referenceVisible = true;
|
||||
},
|
||||
selectContract(row) {
|
||||
async selectContract(row) {
|
||||
this.referenceRows = [];
|
||||
this.clearReceiptAccount();
|
||||
const settlementType = row.settlementType || 'payable';
|
||||
Object.assign(this.form, {
|
||||
projectId: row.projectId,
|
||||
projectName: row.projectName,
|
||||
@@ -633,21 +1076,31 @@ export default {
|
||||
contractId: row.id,
|
||||
contractNo: row.contractNo,
|
||||
contractName: row.contractName,
|
||||
payerName: row.payerName,
|
||||
payeeName: row.payeeName,
|
||||
payerName:
|
||||
row.payerName || (settlementType === 'receivable' ? row.partyB : row.partyA) || '',
|
||||
payeeName:
|
||||
row.payeeName || (settlementType === 'receivable' ? row.partyA : row.partyB) || '',
|
||||
billType: '项目预付',
|
||||
});
|
||||
this.referenceVisible = false;
|
||||
await Promise.all([this.loadReceiptAccountOptions(), this.loadAttachmentRuleData([])]);
|
||||
if (this.billPayment) this.loadBillOptions();
|
||||
},
|
||||
selectFormal(row) {
|
||||
async selectFormal(row) {
|
||||
this.referenceRows = [this.createReferenceRow(row)];
|
||||
this.clearReceiptAccount();
|
||||
Object.assign(this.form, {
|
||||
settlementId: row.id,
|
||||
preSettlementId: null,
|
||||
preSettlementIds: [],
|
||||
settlementNo: row.formalSettlementNo,
|
||||
preSettlementNo: '',
|
||||
projectId: row.projectId,
|
||||
projectName: row.projectName,
|
||||
deptId: row.deptId,
|
||||
deptName: row.deptName,
|
||||
contractId: row.contractId,
|
||||
contractNo: row.contractNo,
|
||||
contractName: row.contractName,
|
||||
settlementAmount: row.settlementAmount,
|
||||
payableAmount: Math.max(
|
||||
@@ -655,19 +1108,32 @@ export default {
|
||||
Number(row.settlementAmount || 0) - Number(row.appliedPaymentAmount || 0)
|
||||
),
|
||||
billType: '正式结算单',
|
||||
payerName: row.payerName,
|
||||
payeeName: row.payeeName,
|
||||
});
|
||||
this.referenceVisible = false;
|
||||
const detail = this.unwrapData(await formalApi.getDetail(row.id));
|
||||
await Promise.all([
|
||||
this.loadReceiptAccountOptions(),
|
||||
this.loadAttachmentRuleData(detail?.id ? [detail] : []),
|
||||
]);
|
||||
if (this.billPayment) this.loadBillOptions();
|
||||
},
|
||||
selectPre(row) {
|
||||
async selectPre(row) {
|
||||
this.referenceRows = [this.createReferenceRow(row)];
|
||||
this.clearReceiptAccount();
|
||||
Object.assign(this.form, {
|
||||
preSettlementId: row.id,
|
||||
preSettlementIds: [row.id],
|
||||
settlementId: null,
|
||||
preSettlementNo: row.preSettlementNo,
|
||||
settlementNo: '',
|
||||
projectId: row.projectId,
|
||||
projectName: row.projectName,
|
||||
deptId: row.deptId,
|
||||
deptName: row.deptName,
|
||||
contractId: row.contractId,
|
||||
contractNo: row.contractNo,
|
||||
contractName: row.contractName,
|
||||
settlementAmount: row.settlementAmount,
|
||||
payableAmount: Math.max(
|
||||
@@ -675,9 +1141,15 @@ export default {
|
||||
Number(row.settlementAmount || 0) - Number(row.advanceAppliedAmount || 0)
|
||||
),
|
||||
billType: '预结算单',
|
||||
payerName: row.payerName,
|
||||
payeeName: row.payeeName,
|
||||
});
|
||||
this.referenceVisible = false;
|
||||
const detail = this.unwrapData(await preApi.getDetail(row.id));
|
||||
await Promise.all([
|
||||
this.loadReceiptAccountOptions(),
|
||||
this.loadAttachmentRuleData(detail?.id ? [detail] : []),
|
||||
]);
|
||||
if (this.billPayment) this.loadBillOptions();
|
||||
},
|
||||
addInvoice() {
|
||||
@@ -698,7 +1170,10 @@ export default {
|
||||
const time = this.$dayjs().format('YYYY-MM-DD HH:mm:ss');
|
||||
this.form.attachments = (files || []).map(file => ({
|
||||
...file,
|
||||
attachmentType: file.attachmentType || 'other',
|
||||
attachmentType:
|
||||
file.attachmentType ||
|
||||
MATERIAL_TYPE_MAP[this.resolveAttachmentMaterial(file)?.key] ||
|
||||
'other',
|
||||
description: file.description || '',
|
||||
uploadUserName: file.uploadUserName || userName,
|
||||
uploadTime: file.uploadTime || time,
|
||||
@@ -710,6 +1185,7 @@ export default {
|
||||
paymentType,
|
||||
settlementId,
|
||||
preSettlementId,
|
||||
preSettlementIds,
|
||||
projectId,
|
||||
projectName,
|
||||
deptId,
|
||||
@@ -740,6 +1216,7 @@ export default {
|
||||
paymentType,
|
||||
settlementId,
|
||||
preSettlementId,
|
||||
preSettlementIds,
|
||||
projectId,
|
||||
projectName,
|
||||
deptId,
|
||||
@@ -766,12 +1243,13 @@ export default {
|
||||
invoices,
|
||||
};
|
||||
},
|
||||
async saveDraft() {
|
||||
async saveDraft(validateMaterials = false) {
|
||||
await this.$refs.formRef.validate();
|
||||
if (this.form.paymentType === 'project_advance' && !this.form.projectId) {
|
||||
this.$message.warning('请选择所属项目');
|
||||
return false;
|
||||
}
|
||||
if (validateMaterials && !this.validateRequiredAttachments()) return false;
|
||||
try {
|
||||
this.validateInvoices();
|
||||
} catch (error) {
|
||||
@@ -784,13 +1262,14 @@ export default {
|
||||
return true;
|
||||
},
|
||||
async submitForm() {
|
||||
const saved = await this.saveDraft();
|
||||
const saved = await this.saveDraft(true);
|
||||
if (!saved) return;
|
||||
await api.submit({ id: this.form.id });
|
||||
this.$message.success('提交成功');
|
||||
this.goBack();
|
||||
},
|
||||
goBack() {
|
||||
removeSettlementTransfer(this.$route.query.transferToken);
|
||||
this.$router.push('/payment/payment-application');
|
||||
},
|
||||
formatMoney(value) {
|
||||
@@ -818,6 +1297,23 @@ export default {
|
||||
justify-content: flex-start;
|
||||
margin-top: 12px;
|
||||
}
|
||||
.payment-form-page__missing-text {
|
||||
margin-left: 12px;
|
||||
color: var(--el-color-danger);
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
}
|
||||
.payment-form-page__attachment-checklist {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.payment-form-page__attachment-checklist-label {
|
||||
color: var(--el-text-color-regular);
|
||||
font-weight: 600;
|
||||
}
|
||||
.payment-form-page__attachment-upload .vehicle-attachment-upload {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user