From 10fecb5a540efba993faf42c24a10c4e0101f740 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=88=98=E6=B3=89=E4=BD=B3?= <1107186916@qq.com>
Date: Tue, 22 Sep 2026 21:26:50 +0800
Subject: [PATCH] =?UTF-8?q?:sparkles:=20=E9=87=91=E8=9D=B6=E7=A5=A8?=
=?UTF-8?q?=E6=B1=A0=E9=80=89=E7=A5=A8=E7=BB=9F=E4=B8=80=E6=9F=A5=E9=95=9C?=
=?UTF-8?q?=E5=83=8F=E5=89=8D=E7=AB=AF=E6=8E=A5=E7=BA=BF=EF=BC=88=E6=96=B0?=
=?UTF-8?q?=E5=A2=9E=E7=BB=9F=E4=B8=80=E9=80=89=E7=A5=A8=E5=BC=B9=E7=AA=97?=
=?UTF-8?q?=E7=BB=84=E4=BB=B6=EF=BC=8C=E6=9B=BF=E6=8D=A2=E6=94=B6=E7=A5=A8?=
=?UTF-8?q?=E4=B8=8E=E7=BB=93=E7=AE=97=E8=AE=A4=E9=A2=86=E5=BC=B9=E7=AA=97?=
=?UTF-8?q?=E5=B9=B6=E5=88=A0=E9=99=A4Mock=EF=BC=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/api/payment/invoiceReceipt.js | 9 +-
src/api/settlement/formalSettlement.js | 2 +
.../kingdee-invoice-pool-dialog/main.vue | 364 ++++++++++++++++++
src/views/payment/invoice-receipt-form.vue | 258 ++-----------
.../components/formal-settlement-editor.vue | 207 ++--------
5 files changed, 423 insertions(+), 417 deletions(-)
create mode 100644 src/components/kingdee-invoice-pool-dialog/main.vue
diff --git a/src/api/payment/invoiceReceipt.js b/src/api/payment/invoiceReceipt.js
index d4cf692..d4d0b3e 100644
--- a/src/api/payment/invoiceReceipt.js
+++ b/src/api/payment/invoiceReceipt.js
@@ -5,8 +5,10 @@ const baseUrl = '/blade-transport/invoice-receipt';
export const getList = (current, size, params) =>
request({ url: `${baseUrl}/list`, method: 'get', params: { current, size, ...params } });
export const getDetail = id => request({ url: `${baseUrl}/detail`, method: 'get', params: { id } });
-export const getInvoicePool = keyword =>
- request({ url: `${baseUrl}/invoice-pool`, method: 'get', params: { keyword } });
+export const queryInvoicePool = params =>
+ request({ url: `${baseUrl}/invoice-pool`, method: 'get', params });
+export const fetchInvoicePoolByNo = invoiceNo =>
+ request({ url: `${baseUrl}/invoice-pool/fetch`, method: 'post', params: { invoiceNo } });
export const getSettlementCandidates = (keyword, receiptId) =>
request({
url: `${baseUrl}/settlement-candidates`,
@@ -27,6 +29,9 @@ export const returnBill = data => request({ url: `${baseUrl}/return`, method: 'p
export const voidBill = data => request({ url: `${baseUrl}/void`, method: 'post', data });
export const syncKingdee = id =>
request({ url: `${baseUrl}/sync-kingdee`, method: 'post', params: { id } });
+// 手动同步为分钟级长任务,单独放宽超时(全局默认 10s 必超时)
+export const syncInvoicePool = () =>
+ request({ url: `${baseUrl}/sync-invoice-pool`, method: 'post', timeout: 300000 });
export const approvalStatusOptions = [
{ label: '草稿', value: 'draft' },
diff --git a/src/api/settlement/formalSettlement.js b/src/api/settlement/formalSettlement.js
index 23b280a..c1fc420 100644
--- a/src/api/settlement/formalSettlement.js
+++ b/src/api/settlement/formalSettlement.js
@@ -50,3 +50,5 @@ export const claimInvoices = data =>
request({ url: `${baseUrl}/claim-invoices`, method: 'post', data });
export const queryInvoicePool = params =>
request({ url: `${baseUrl}/invoice-pool`, method: 'get', params });
+export const fetchInvoicePoolByNo = invoiceNo =>
+ request({ url: `${baseUrl}/invoice-pool/fetch`, method: 'post', params: { invoiceNo } });
diff --git a/src/components/kingdee-invoice-pool-dialog/main.vue b/src/components/kingdee-invoice-pool-dialog/main.vue
new file mode 100644
index 0000000..8e311eb
--- /dev/null
+++ b/src/components/kingdee-invoice-pool-dialog/main.vue
@@ -0,0 +1,364 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 重置
+ 查询
+ 立即同步
+
+
+ (selected = selection)"
+ @row-dblclick="handleRowDblclick"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ formatMoney(row.invoiceAmount) }}
+
+
+ {{ formatRate(row.taxRate) }}
+
+
+ {{ formatMoney(row.taxAmount) }}
+
+
+
+
+ 已认领
+ 未认领
+
+
+
+
+ 已登记
+ 未登记
+
+
+
+ {{ kingdeeStatusText(row.kingdeeStatus) }}
+
+
+
+ 选择
+
+
+
+
+
+ 取消
+ {{ confirmText }}
+
+
+
+
+
+
+
diff --git a/src/views/payment/invoice-receipt-form.vue b/src/views/payment/invoice-receipt-form.vue
index c74498f..e23c555 100644
--- a/src/views/payment/invoice-receipt-form.vue
+++ b/src/views/payment/invoice-receipt-form.vue
@@ -149,62 +149,15 @@
-
-
-
- 查询
-
-
-
-
-
-
-
-
- {{ formatMoney(row.invoiceAmount) }}
-
-
- {{ formatRate(row.taxRate) }}
-
-
- {{ formatMoney(row.taxAmount) }}
-
-
-
-
- 选择
-
-
-
-
-
- 取消
- 确定
-
-
+
- Array.from({ length }, () => Math.floor(Math.random() * 10)).join('');
-
-const formatMockDate = date => {
- const year = date.getFullYear();
- const month = String(date.getMonth() + 1).padStart(2, '0');
- const day = String(date.getDate()).padStart(2, '0');
- return `${year}-${month}-${day}`;
-};
-
-const customerName = customer =>
- customer.fullName || customer.shortName || customer.customerCode || `客商${customer.id}`;
-
-const customerEmail = (customer, index) => {
- const prefix = String(customer.customerCode || customer.id || `customer${index + 1}`)
- .replace(/[^a-zA-Z0-9_-]/g, '')
- .toLowerCase();
- return `finance@${prefix || `customer${index + 1}`}.example.com`;
-};
-
-const createInvoicePoolMockRows = (customers, counterpartyName, departmentEmail) => {
- const rows = [];
- const baseId = Date.now();
- customers.forEach((customer, customerIndex) => {
- const name = customerName(customer);
- ['issuer', 'receiver'].forEach((role, roleIndex) => {
- const count = 3 + Math.floor(Math.random() * 5);
- for (let index = 0; index < count; index += 1) {
- const rowIndex = rows.length;
- const invoiceDateValue = new Date();
- invoiceDateValue.setDate(invoiceDateValue.getDate() - Math.floor(Math.random() * 90));
- const invoiceDate = formatMockDate(invoiceDateValue);
- const taxRate = mockTaxRates[(customerIndex + roleIndex + index) % mockTaxRates.length];
- const invoiceAmount = Math.floor(10000 + Math.random() * 190000);
- const taxAmount = Number(
- ((invoiceAmount * Number(taxRate)) / (100 + Number(taxRate))).toFixed(2)
- );
- const bankName = mockBankNames[(customerIndex + index) % mockBankNames.length];
- rows.push({
- id: baseId + rowIndex,
- invoiceNo: `25${randomDigits(18)}`,
- invoiceDate,
- invoiceType: mockInvoiceTypes[(customerIndex + index) % mockInvoiceTypes.length],
- taxRate,
- invoiceAmount,
- taxAmount,
- receiverName: role === 'receiver' ? name : counterpartyName,
- issuerName: role === 'issuer' ? name : counterpartyName,
- bankName,
- bankAccount: randomDigits(19),
- issuingBank: `${bankName}营业部`,
- phone: customer.contactPhone || '',
- customerEmails: customerEmail(customer, customerIndex),
- departmentEmails: departmentEmail || '',
- attachmentsJson: '[]',
- kingdeeBillNo: `KD-FP-${invoiceDate.replaceAll('-', '')}${randomDigits(5)}`,
- kingdeeStatus: 'unsynced',
- });
- }
- });
- });
- return rows;
-};
-
const emptyForm = () => ({
id: null,
kingdeeInvoicePoolId: null,
@@ -361,24 +246,17 @@ const emptyForm = () => ({
export default {
name: 'InvoiceReceiptForm',
components: {
+ KingdeeInvoicePoolDialog,
VehicleAttachmentTable,
},
data() {
return {
Search,
form: emptyForm(),
- invoicePoolMockRows: [],
- invoicePoolMockLoaded: false,
customerEmailOptions: [],
departmentEmailOptions: [],
invoiceDialog: {
visible: false,
- loading: false,
- keyword: '',
- sourceRows: [],
- rows: [],
- current: null,
- page: { current: 1, size: 10, total: 0 },
},
settlementDialog: {
visible: false,
@@ -421,6 +299,18 @@ export default {
this.initialize();
},
methods: {
+ apiQueryInvoicePool(params) {
+ return api.queryInvoicePool(params);
+ },
+ apiFetchInvoicePool(invoiceNo) {
+ return api.fetchInvoicePoolByNo(invoiceNo);
+ },
+ apiSyncInvoicePool() {
+ return api.syncInvoicePool();
+ },
+ handleInvoicePicked(rows) {
+ this.confirmInvoice(rows[0]);
+ },
hasPermission(code) {
return this.permission?.[code] !== false;
},
@@ -492,92 +382,11 @@ export default {
}
callback();
},
- async openInvoiceDialog() {
+ openInvoiceDialog() {
this.invoiceDialog.visible = true;
- this.invoiceDialog.keyword = this.form.invoiceNo || '';
- await this.loadInvoicePool();
- },
- async loadInvoicePool() {
- this.invoiceDialog.loading = true;
- this.invoiceDialog.page.current = 1;
- this.invoiceDialog.current = null;
- try {
- if (!this.recordId) {
- if (!this.invoicePoolMockLoaded) await this.loadInvoicePoolMockRows();
- this.invoiceDialog.sourceRows = this.filterInvoicePoolMockRows(
- this.invoiceDialog.keyword
- );
- this.refreshInvoicePoolPage();
- return;
- }
- const data = this.unwrapData(await api.getInvoicePool(this.invoiceDialog.keyword));
- this.invoiceDialog.sourceRows = Array.isArray(data) ? data : data?.records || [];
- this.refreshInvoicePoolPage();
- } finally {
- this.invoiceDialog.loading = false;
- }
- },
- async loadInvoicePoolMockRows() {
- const pageSize = 500;
- const firstData = this.unwrapData(await getCustomerList(1, pageSize, {}));
- const firstRows = Array.isArray(firstData) ? firstData : firstData?.records || [];
- const total = Number(firstData?.total || firstRows.length);
- const pageCount = Math.ceil(total / pageSize);
- const remainingPages = await Promise.all(
- Array.from({ length: Math.max(pageCount - 1, 0) }, (_, index) =>
- getCustomerList(index + 2, pageSize, {})
- )
- );
- const customers = [
- ...firstRows,
- ...remainingPages.flatMap(response => {
- const data = this.unwrapData(response);
- return Array.isArray(data) ? data : data?.records || [];
- }),
- ].filter(
- (customer, index, rows) =>
- rows.findIndex(item => String(item.id) === String(customer.id)) === index
- );
- const userInfo = this.$store.getters.userInfo || {};
- const counterpartyName = userInfo.deptName || userInfo.dept_name || '本企业';
- this.invoicePoolMockRows = createInvoicePoolMockRows(
- customers,
- counterpartyName,
- userInfo.email || ''
- );
- this.invoicePoolMockLoaded = true;
- },
- refreshInvoicePoolPage() {
- const page = this.invoiceDialog.page;
- const total = this.invoiceDialog.sourceRows.length;
- const maxPage = Math.max(Math.ceil(total / page.size), 1);
- if (page.current > maxPage) page.current = maxPage;
- const start = (page.current - 1) * page.size;
- page.total = total;
- this.invoiceDialog.current = null;
- this.invoiceDialog.rows = this.invoiceDialog.sourceRows.slice(start, start + page.size);
- },
- handleInvoicePoolSizeChange() {
- this.invoiceDialog.page.current = 1;
- this.refreshInvoicePoolPage();
- },
- filterInvoicePoolMockRows(keyword) {
- const normalizedKeyword = String(keyword || '')
- .trim()
- .toLowerCase();
- if (!normalizedKeyword) return this.invoicePoolMockRows.map(item => ({ ...item }));
- return this.invoicePoolMockRows
- .filter(item =>
- [item.invoiceNo, item.issuerName, item.receiverName].some(value =>
- String(value || '')
- .toLowerCase()
- .includes(normalizedKeyword)
- )
- )
- .map(item => ({ ...item }));
},
confirmInvoice(row, options = {}) {
- const selected = row?.id ? row : this.invoiceDialog.current;
+ const selected = row;
if (!selected) {
this.$message.warning('请选择一张金蝶票据池发票');
return;
@@ -758,16 +567,8 @@ export default {
this.$message.warning('请先选择金蝶票据池发票');
return;
}
- const data = this.recordId
- ? this.unwrapData(await api.getInvoicePool(this.form.invoiceNo))
- : this.filterInvoicePoolMockRows(this.form.invoiceNo);
- const rows = Array.isArray(data) ? data : data?.records || [];
- const invoice = rows.find(item => item.invoiceNo === this.form.invoiceNo);
- if (!invoice) {
- this.$message.warning('金蝶票据池中未查询到该发票');
- return;
- }
- if (!this.confirmInvoice(invoice, { preserveUserInput: true })) return;
+ const invoice = this.unwrapData(await api.fetchInvoicePoolByNo(this.form.invoiceNo));
+ if (!invoice || !this.confirmInvoice(invoice, { preserveUserInput: true })) return;
if (this.settlementIds.length) await this.loadReferenceInformation();
this.$message.success('同步成功');
},
@@ -827,11 +628,6 @@ export default {
.receipt-form-page__dialog-search .el-input {
width: 360px;
}
-.receipt-form-page__dialog-pagination {
- display: flex;
- justify-content: flex-end;
- margin-top: 12px;
-}
.receipt-form-page :deep(.el-table) {
--el-table-border-color: #eff1f7;
}
diff --git a/src/views/settlement/components/formal-settlement-editor.vue b/src/views/settlement/components/formal-settlement-editor.vue
index 589f736..1077f81 100644
--- a/src/views/settlement/components/formal-settlement-editor.vue
+++ b/src/views/settlement/components/formal-settlement-editor.vue
@@ -412,126 +412,16 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 重置
- 查询
-
-
-
-
-
-
-
-
-
-
-
- {{ formatMoney(row.invoiceAmount) }}
-
-
- {{ formatMoney(row.matchedAmount) }}
-
-
-
-
- 取消
- 确认认领
-
-
+ confirm-text="确认认领"
+ multiple
+ :initial-invoice-no="String(invoiceClaimNo || '').trim()"
+ :query-api="invoicePoolQueryApi"
+ :fetch-api="invoicePoolFetchApi"
+ @confirm="handleInvoiceClaimConfirm"
+ />
({
+ ...row,
+ attachmentJson: row.attachmentJson || row.attachmentsJson,
+ }));
+ await this.confirmInvoiceClaims();
},
async confirmInvoiceClaims() {
if (!this.invoiceClaimDialog.selected.length) {