✨ 正式结算单认领查询对接发票云全票池(多条件搜索+服务端分页)
This commit is contained in:
@@ -48,3 +48,5 @@ export const applyPayments = data =>
|
|||||||
request({ url: `${baseUrl}/apply-payments`, method: 'post', data });
|
request({ url: `${baseUrl}/apply-payments`, method: 'post', data });
|
||||||
export const claimInvoices = data =>
|
export const claimInvoices = data =>
|
||||||
request({ url: `${baseUrl}/claim-invoices`, method: 'post', data });
|
request({ url: `${baseUrl}/claim-invoices`, method: 'post', data });
|
||||||
|
export const queryInvoicePool = params =>
|
||||||
|
request({ url: `${baseUrl}/invoice-pool`, method: 'get', params });
|
||||||
|
|||||||
@@ -419,11 +419,69 @@
|
|||||||
append-to-body
|
append-to-body
|
||||||
destroy-on-close
|
destroy-on-close
|
||||||
>
|
>
|
||||||
|
<el-form
|
||||||
|
:model="invoiceClaimDialog.query"
|
||||||
|
inline
|
||||||
|
label-position="right"
|
||||||
|
label-width="100px"
|
||||||
|
class="formal-editor__invoice-claim-search"
|
||||||
|
@submit.prevent
|
||||||
|
>
|
||||||
|
<el-form-item label="发票号码">
|
||||||
|
<el-input
|
||||||
|
v-model="invoiceClaimDialog.query.invoiceNo"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleInvoiceClaimQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="开票日期">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="invoiceClaimDialog.query.invoiceDateRange"
|
||||||
|
type="daterange"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
format="YYYY-MM-DD"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="销方税号">
|
||||||
|
<el-input
|
||||||
|
v-model="invoiceClaimDialog.query.salerTaxNo"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleInvoiceClaimQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="购方税号">
|
||||||
|
<el-input
|
||||||
|
v-model="invoiceClaimDialog.query.buyerTaxNo"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleInvoiceClaimQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="单据使用状态">
|
||||||
|
<el-select
|
||||||
|
v-model="invoiceClaimDialog.query.expenseStatus"
|
||||||
|
clearable
|
||||||
|
placeholder="请选择"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in expenseStatusOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button @click="resetInvoiceClaimQuery">重置</el-button>
|
||||||
|
<el-button type="primary" @click="handleInvoiceClaimQuery">查询</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
<el-table
|
<el-table
|
||||||
ref="invoiceClaimTable"
|
ref="invoiceClaimTable"
|
||||||
v-loading="invoiceClaimDialog.loading"
|
v-loading="invoiceClaimDialog.loading"
|
||||||
:data="invoiceClaimPagedRows"
|
:data="invoiceClaimDialog.rows"
|
||||||
row-key="invoiceNo"
|
row-key="serialNo"
|
||||||
border
|
border
|
||||||
height="520"
|
height="520"
|
||||||
@selection-change="invoiceClaimDialog.selected = $event"
|
@selection-change="invoiceClaimDialog.selected = $event"
|
||||||
@@ -438,9 +496,9 @@
|
|||||||
<el-table-column type="index" label="序号" width="64" align="center" />
|
<el-table-column type="index" label="序号" width="64" align="center" />
|
||||||
<el-table-column prop="invoiceNo" label="发票号" min-width="180" align="center" />
|
<el-table-column prop="invoiceNo" label="发票号" min-width="180" align="center" />
|
||||||
<el-table-column prop="invoiceDate" label="开票日期" min-width="130" align="center" />
|
<el-table-column prop="invoiceDate" label="开票日期" min-width="130" align="center" />
|
||||||
<el-table-column prop="invoiceType" label="发票类型" min-width="150" align="center" />
|
<el-table-column prop="invoiceTypeName" label="发票类型" min-width="150" align="center" />
|
||||||
<el-table-column prop="issuerName" label="开票单位" min-width="180" align="center" />
|
<el-table-column prop="salerName" label="开票单位" min-width="180" align="center" />
|
||||||
<el-table-column prop="receiverName" label="受票单位" min-width="180" align="center" />
|
<el-table-column prop="buyerName" label="受票单位" min-width="180" align="center" />
|
||||||
<el-table-column
|
<el-table-column
|
||||||
prop="invoiceAmount"
|
prop="invoiceAmount"
|
||||||
label="发票金额(含税)"
|
label="发票金额(含税)"
|
||||||
@@ -460,6 +518,8 @@
|
|||||||
:total="invoiceClaimDialog.page.total"
|
:total="invoiceClaimDialog.page.total"
|
||||||
:page-sizes="[10, 20, 50, 100]"
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
@current-change="loadInvoiceClaims"
|
||||||
|
@size-change="handleInvoiceClaimSizeChange"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
@@ -941,6 +1001,7 @@ import {
|
|||||||
getNextNo,
|
getNextNo,
|
||||||
getReceiptClaims,
|
getReceiptClaims,
|
||||||
claimInvoices as claimInvoicesApi,
|
claimInvoices as claimInvoicesApi,
|
||||||
|
queryInvoicePool,
|
||||||
save,
|
save,
|
||||||
} from '@/api/settlement/formalSettlement';
|
} from '@/api/settlement/formalSettlement';
|
||||||
import {
|
import {
|
||||||
@@ -1006,7 +1067,20 @@ export default {
|
|||||||
rows: [],
|
rows: [],
|
||||||
selected: [],
|
selected: [],
|
||||||
page: { current: 1, size: 10, total: 0 },
|
page: { current: 1, size: 10, total: 0 },
|
||||||
|
query: {
|
||||||
|
invoiceNo: '',
|
||||||
|
invoiceDateRange: [],
|
||||||
|
salerTaxNo: '',
|
||||||
|
buyerTaxNo: '',
|
||||||
|
expenseStatus: '',
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
expenseStatusOptions: [
|
||||||
|
{ value: '1', label: '未用' },
|
||||||
|
{ value: '30', label: '在用' },
|
||||||
|
{ value: '60', label: '已用' },
|
||||||
|
{ value: '65', label: '已入账' },
|
||||||
|
],
|
||||||
attachmentUploadFiles: [],
|
attachmentUploadFiles: [],
|
||||||
attachmentTypeOptions: [],
|
attachmentTypeOptions: [],
|
||||||
attachmentFileTypes: [
|
attachmentFileTypes: [
|
||||||
@@ -1148,11 +1222,6 @@ export default {
|
|||||||
});
|
});
|
||||||
return Array.from(names);
|
return Array.from(names);
|
||||||
},
|
},
|
||||||
invoiceClaimPagedRows() {
|
|
||||||
const { current, size } = this.invoiceClaimDialog.page;
|
|
||||||
const start = (current - 1) * size;
|
|
||||||
return this.invoiceClaimDialog.rows.slice(start, start + size);
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
modelValue: {
|
modelValue: {
|
||||||
@@ -1233,6 +1302,13 @@ export default {
|
|||||||
this.invoiceClaimDialog.visible = false;
|
this.invoiceClaimDialog.visible = false;
|
||||||
this.invoiceClaimDialog.rows = [];
|
this.invoiceClaimDialog.rows = [];
|
||||||
this.invoiceClaimDialog.selected = [];
|
this.invoiceClaimDialog.selected = [];
|
||||||
|
this.invoiceClaimDialog.query = {
|
||||||
|
invoiceNo: '',
|
||||||
|
invoiceDateRange: [],
|
||||||
|
salerTaxNo: '',
|
||||||
|
buyerTaxNo: '',
|
||||||
|
expenseStatus: '',
|
||||||
|
};
|
||||||
this.attachmentUploadFiles = [];
|
this.attachmentUploadFiles = [];
|
||||||
this.billingRuleDialog = {
|
this.billingRuleDialog = {
|
||||||
visible: false,
|
visible: false,
|
||||||
@@ -2223,79 +2299,51 @@ export default {
|
|||||||
this.adjust.saving = false;
|
this.adjust.saving = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
claimInvoices() {
|
|
||||||
this.invoiceClaimLoading = true;
|
|
||||||
try {
|
|
||||||
const keyword = String(this.invoiceClaimNo || '').trim();
|
|
||||||
const defaultNo = `MOCK${this.$dayjs().format('YYYYMMDD')}`;
|
|
||||||
const baseNo = (keyword || defaultNo).slice(0, 29);
|
|
||||||
const numbers = [baseNo, `${baseNo}-02`, `${baseNo}-03`];
|
|
||||||
const invoiceAmounts = [1000, 2000, 3000];
|
|
||||||
const availableAmounts = [1000, 1000, 3000];
|
|
||||||
const preferredMatchedAmounts = [1000, 1000, 2000];
|
|
||||||
let remainingAmount = Math.max(
|
|
||||||
Number(this.form.settlementAmount || this.summaryTotal || 0) -
|
|
||||||
this.invoices.reduce((total, item) => total + Number(item.matchedAmount || 0), 0),
|
|
||||||
0
|
|
||||||
);
|
|
||||||
const existingNumbers = new Set(this.invoices.map(item => String(item.invoiceNo)));
|
|
||||||
const mockRows = numbers
|
|
||||||
.map((invoiceNo, index) => {
|
|
||||||
const matchedAmount = Math.min(
|
|
||||||
preferredMatchedAmounts[index],
|
|
||||||
availableAmounts[index],
|
|
||||||
remainingAmount
|
|
||||||
);
|
|
||||||
remainingAmount = Number((remainingAmount - matchedAmount).toFixed(2));
|
|
||||||
return {
|
|
||||||
invoiceNo,
|
|
||||||
invoiceDate: this.$dayjs().subtract(index, 'day').format('YYYY-MM-DD'),
|
|
||||||
invoiceType: index === 1 ? '增值税普通发票' : '增值税专用发票',
|
|
||||||
taxRate: [3, 6, 9][index],
|
|
||||||
invoiceAmount: invoiceAmounts[index],
|
|
||||||
availableInvoiceAmount: availableAmounts[index],
|
|
||||||
matchedAmount,
|
|
||||||
attachmentJson: '',
|
|
||||||
mockData: true,
|
|
||||||
};
|
|
||||||
})
|
|
||||||
.filter(item => !existingNumbers.has(item.invoiceNo));
|
|
||||||
if (!mockRows.length) {
|
|
||||||
this.$message.warning('当前发票号码的Mock数据已认领');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.invoices = [...this.invoices, ...mockRows];
|
|
||||||
this.$message.success(`已生成${mockRows.length}条Mock发票数据`);
|
|
||||||
} finally {
|
|
||||||
this.invoiceClaimLoading = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
openInvoiceClaimDialog() {
|
openInvoiceClaimDialog() {
|
||||||
const stamp = Date.now();
|
this.invoiceClaimDialog.query.invoiceNo = String(this.invoiceClaimNo || '').trim();
|
||||||
this.invoiceClaimDialog.loading = true;
|
|
||||||
this.invoiceClaimDialog.rows = Array.from({ length: 80 }, (_, index) => {
|
|
||||||
const amount = Math.floor(1000 + Math.random() * 49000);
|
|
||||||
return {
|
|
||||||
invoiceNo: `MOCK${stamp}${String(index + 1).padStart(3, '0')}`.slice(0, 32),
|
|
||||||
invoiceDate: this.$dayjs()
|
|
||||||
.subtract(Math.floor(Math.random() * 90), 'day')
|
|
||||||
.format('YYYY-MM-DD'),
|
|
||||||
invoiceType: index % 2 ? '增值税普通发票' : '增值税专用发票',
|
|
||||||
issuerName: this.form.payerName || 'Mock开票单位',
|
|
||||||
receiverName: this.form.payeeName || 'Mock受票单位',
|
|
||||||
invoiceAmount: amount,
|
|
||||||
availableInvoiceAmount: amount,
|
|
||||||
matchedAmount: amount,
|
|
||||||
taxRate: [3, 6, 9, 13][index % 4],
|
|
||||||
attachmentJson: '',
|
|
||||||
mockData: true,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
this.invoiceClaimDialog.selected = [];
|
|
||||||
this.invoiceClaimDialog.page.current = 1;
|
|
||||||
this.invoiceClaimDialog.page.total = 80;
|
|
||||||
this.invoiceClaimDialog.visible = true;
|
this.invoiceClaimDialog.visible = true;
|
||||||
|
this.handleInvoiceClaimQuery();
|
||||||
|
},
|
||||||
|
handleInvoiceClaimQuery() {
|
||||||
|
this.invoiceClaimDialog.page.current = 1;
|
||||||
|
this.loadInvoiceClaims();
|
||||||
|
},
|
||||||
|
resetInvoiceClaimQuery() {
|
||||||
|
this.invoiceClaimDialog.query = {
|
||||||
|
invoiceNo: '',
|
||||||
|
invoiceDateRange: [],
|
||||||
|
salerTaxNo: '',
|
||||||
|
buyerTaxNo: '',
|
||||||
|
expenseStatus: '',
|
||||||
|
};
|
||||||
|
this.handleInvoiceClaimQuery();
|
||||||
|
},
|
||||||
|
handleInvoiceClaimSizeChange() {
|
||||||
|
this.invoiceClaimDialog.page.current = 1;
|
||||||
|
this.loadInvoiceClaims();
|
||||||
|
},
|
||||||
|
async loadInvoiceClaims() {
|
||||||
|
this.invoiceClaimDialog.loading = true;
|
||||||
|
try {
|
||||||
|
const query = this.invoiceClaimDialog.query;
|
||||||
|
const range = query.invoiceDateRange || [];
|
||||||
|
const data = this.unwrapData(
|
||||||
|
await queryInvoicePool({
|
||||||
|
current: this.invoiceClaimDialog.page.current,
|
||||||
|
size: this.invoiceClaimDialog.page.size,
|
||||||
|
invoiceNo: query.invoiceNo || undefined,
|
||||||
|
invoiceDateStart: range[0] || undefined,
|
||||||
|
invoiceDateEnd: range[1] || undefined,
|
||||||
|
salerTaxNo: query.salerTaxNo || undefined,
|
||||||
|
buyerTaxNo: query.buyerTaxNo || undefined,
|
||||||
|
expenseStatus: query.expenseStatus || undefined,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
this.invoiceClaimDialog.rows = data.records || [];
|
||||||
|
this.invoiceClaimDialog.page.total = Number(data.total || 0);
|
||||||
|
} finally {
|
||||||
this.invoiceClaimDialog.loading = false;
|
this.invoiceClaimDialog.loading = false;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
async confirmInvoiceClaims() {
|
async confirmInvoiceClaims() {
|
||||||
if (!this.invoiceClaimDialog.selected.length) {
|
if (!this.invoiceClaimDialog.selected.length) {
|
||||||
@@ -2321,7 +2369,11 @@ export default {
|
|||||||
if (Number(this.form.settlementAmount || 0) > 0) {
|
if (Number(this.form.settlementAmount || 0) > 0) {
|
||||||
remaining = Math.max(0, remaining - matchedAmount);
|
remaining = Math.max(0, remaining - matchedAmount);
|
||||||
}
|
}
|
||||||
return { ...row, matchedAmount };
|
return {
|
||||||
|
...row,
|
||||||
|
invoiceType: row.invoiceTypeName || row.invoiceType || '',
|
||||||
|
matchedAmount,
|
||||||
|
};
|
||||||
})
|
})
|
||||||
.filter(row => row.matchedAmount > 0);
|
.filter(row => row.matchedAmount > 0);
|
||||||
if (!invoices.length) {
|
if (!invoices.length) {
|
||||||
@@ -2409,12 +2461,12 @@ export default {
|
|||||||
},
|
},
|
||||||
viewInvoiceAttachment(row) {
|
viewInvoiceAttachment(row) {
|
||||||
const url = this.invoiceAttachmentUrl(row);
|
const url = this.invoiceAttachmentUrl(row);
|
||||||
if (!url) return this.$message.warning('当前Mock发票暂无可查看附件');
|
if (!url) return this.$message.warning('当前发票暂无可查看附件');
|
||||||
window.open(url, '_blank');
|
window.open(url, '_blank');
|
||||||
},
|
},
|
||||||
downloadInvoiceAttachment(row) {
|
downloadInvoiceAttachment(row) {
|
||||||
const url = this.invoiceAttachmentUrl(row);
|
const url = this.invoiceAttachmentUrl(row);
|
||||||
if (!url) return this.$message.warning('当前Mock发票暂无可下载附件');
|
if (!url) return this.$message.warning('当前发票暂无可下载附件');
|
||||||
downloadFileByUrl(url, this.invoiceAttachmentName(row));
|
downloadFileByUrl(url, this.invoiceAttachmentName(row));
|
||||||
},
|
},
|
||||||
buildSavePayload() {
|
buildSavePayload() {
|
||||||
|
|||||||
Reference in New Issue
Block a user