✨ 金蝶票池选票统一查镜像前端接线(新增统一选票弹窗组件,替换收票与结算认领弹窗并删除Mock)
This commit is contained in:
@@ -5,8 +5,10 @@ const baseUrl = '/blade-transport/invoice-receipt';
|
|||||||
export const getList = (current, size, params) =>
|
export const getList = (current, size, params) =>
|
||||||
request({ url: `${baseUrl}/list`, method: 'get', params: { 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 getDetail = id => request({ url: `${baseUrl}/detail`, method: 'get', params: { id } });
|
||||||
export const getInvoicePool = keyword =>
|
export const queryInvoicePool = params =>
|
||||||
request({ url: `${baseUrl}/invoice-pool`, method: 'get', params: { keyword } });
|
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) =>
|
export const getSettlementCandidates = (keyword, receiptId) =>
|
||||||
request({
|
request({
|
||||||
url: `${baseUrl}/settlement-candidates`,
|
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 voidBill = data => request({ url: `${baseUrl}/void`, method: 'post', data });
|
||||||
export const syncKingdee = id =>
|
export const syncKingdee = id =>
|
||||||
request({ url: `${baseUrl}/sync-kingdee`, method: 'post', params: { 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 = [
|
export const approvalStatusOptions = [
|
||||||
{ label: '草稿', value: 'draft' },
|
{ label: '草稿', value: 'draft' },
|
||||||
|
|||||||
@@ -50,3 +50,5 @@ export const claimInvoices = data =>
|
|||||||
request({ url: `${baseUrl}/claim-invoices`, method: 'post', data });
|
request({ url: `${baseUrl}/claim-invoices`, method: 'post', data });
|
||||||
export const queryInvoicePool = params =>
|
export const queryInvoicePool = params =>
|
||||||
request({ url: `${baseUrl}/invoice-pool`, method: 'get', params });
|
request({ url: `${baseUrl}/invoice-pool`, method: 'get', params });
|
||||||
|
export const fetchInvoicePoolByNo = invoiceNo =>
|
||||||
|
request({ url: `${baseUrl}/invoice-pool/fetch`, method: 'post', params: { invoiceNo } });
|
||||||
|
|||||||
@@ -0,0 +1,364 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog
|
||||||
|
v-model="visible"
|
||||||
|
:title="title"
|
||||||
|
width="92%"
|
||||||
|
append-to-body
|
||||||
|
destroy-on-close
|
||||||
|
:show-close="!syncing"
|
||||||
|
:close-on-click-modal="!syncing"
|
||||||
|
:close-on-press-escape="!syncing"
|
||||||
|
@open="handleOpen"
|
||||||
|
>
|
||||||
|
<el-form :model="query" inline label-width="90px" @submit.prevent>
|
||||||
|
<el-form-item label="发票号码">
|
||||||
|
<el-input v-model="query.invoiceNo" clearable @keyup.enter="handleQuery" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="开票日期">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="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="query.salerName" clearable @keyup.enter="handleQuery" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="受票单位">
|
||||||
|
<el-input v-model="query.buyerName" clearable @keyup.enter="handleQuery" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="发票类型">
|
||||||
|
<el-select
|
||||||
|
v-model="query.invoiceType"
|
||||||
|
clearable
|
||||||
|
filterable
|
||||||
|
placeholder="不限"
|
||||||
|
style="width: 230px"
|
||||||
|
>
|
||||||
|
<el-option v-for="type in invoiceTypeOptions" :key="type" :label="type" :value="type" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="认领状态">
|
||||||
|
<el-select v-model="query.claimed" clearable placeholder="不限" style="width: 130px">
|
||||||
|
<el-option label="未认领" :value="false" />
|
||||||
|
<el-option label="已认领" :value="true" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="登记状态">
|
||||||
|
<el-select v-model="query.registered" clearable placeholder="不限" style="width: 130px">
|
||||||
|
<el-option label="未登记" :value="false" />
|
||||||
|
<el-option label="已登记" :value="true" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button @click="resetQuery">重置</el-button>
|
||||||
|
<el-button type="primary" @click="handleQuery">查询</el-button>
|
||||||
|
<el-button v-if="syncApi" :loading="syncing" @click="handleSync">立即同步</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<el-table
|
||||||
|
ref="poolTable"
|
||||||
|
v-loading="loading"
|
||||||
|
:data="rows"
|
||||||
|
row-key="id"
|
||||||
|
border
|
||||||
|
height="520"
|
||||||
|
:highlight-current-row="!multiple"
|
||||||
|
@selection-change="selection => (selected = selection)"
|
||||||
|
@row-dblclick="handleRowDblclick"
|
||||||
|
>
|
||||||
|
<el-table-column v-if="multiple" type="selection" width="52" fixed="left" align="center" reserve-selection />
|
||||||
|
<el-table-column v-else width="52" align="center" fixed="left">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-radio :model-value="current && current.id" :value="row.id" @change="current = row">
|
||||||
|
<span></span>
|
||||||
|
</el-radio>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="invoiceNo" label="发票号码" min-width="180" />
|
||||||
|
<el-table-column prop="invoiceDate" label="开票日期" min-width="120" />
|
||||||
|
<el-table-column prop="invoiceType" label="发票类型" min-width="140" />
|
||||||
|
<el-table-column prop="issuerName" label="开票单位" min-width="180" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="receiverName" label="受票单位" min-width="180" show-overflow-tooltip />
|
||||||
|
<el-table-column label="金额(含税)" min-width="130" align="right">
|
||||||
|
<template #default="{ row }">{{ formatMoney(row.invoiceAmount) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="税率" min-width="90" align="center">
|
||||||
|
<template #default="{ row }">{{ formatRate(row.taxRate) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="税额" min-width="120" align="right">
|
||||||
|
<template #default="{ row }">{{ formatMoney(row.taxAmount) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="kingdeeBillNo" label="金蝶单据号" min-width="210" show-overflow-tooltip />
|
||||||
|
<el-table-column label="认领状态" min-width="100" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-tag v-if="row.claimed" type="danger" size="small">已认领</el-tag>
|
||||||
|
<el-tag v-else type="info" size="small">未认领</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="登记状态" min-width="100" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-tag v-if="row.registered" type="warning" size="small">已登记</el-tag>
|
||||||
|
<el-tag v-else type="info" size="small">未登记</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="金蝶同步" min-width="100" align="center">
|
||||||
|
<template #default="{ row }">{{ kingdeeStatusText(row.kingdeeStatus) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column v-if="!multiple" label="操作" width="90" fixed="right" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-link type="primary" @click.stop="confirmRows([row])">选择</el-link>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<div class="kingdee-pool-dialog__footer-bar">
|
||||||
|
<div class="kingdee-pool-dialog__fetch">
|
||||||
|
<el-input
|
||||||
|
v-model="fetchNo"
|
||||||
|
placeholder="查不到票?输入发票号码从金蝶补查"
|
||||||
|
clearable
|
||||||
|
style="width: 260px"
|
||||||
|
@keyup.enter="handleFetch"
|
||||||
|
/>
|
||||||
|
<el-button :loading="fetching" @click="handleFetch">补查</el-button>
|
||||||
|
</div>
|
||||||
|
<el-pagination
|
||||||
|
v-model:current-page="page.current"
|
||||||
|
v-model:page-size="page.size"
|
||||||
|
:total="page.total"
|
||||||
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
@current-change="load"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="visible = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="handleConfirm">{{ confirmText }}</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { ElLoading } from 'element-plus';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'KingdeeInvoicePoolDialog',
|
||||||
|
props: {
|
||||||
|
modelValue: { type: Boolean, required: true },
|
||||||
|
title: { type: String, default: '查询金蝶票据池' },
|
||||||
|
confirmText: { type: String, default: '确定' },
|
||||||
|
multiple: { type: Boolean, default: false },
|
||||||
|
initialInvoiceNo: { type: String, default: '' },
|
||||||
|
queryApi: { type: Function, required: true },
|
||||||
|
fetchApi: { type: Function, required: true },
|
||||||
|
syncApi: { type: Function, default: null },
|
||||||
|
},
|
||||||
|
emits: ['update:modelValue', 'confirm'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loading: false,
|
||||||
|
fetching: false,
|
||||||
|
syncing: false,
|
||||||
|
// 与后端 BfiConstant.INVOICE_TYPE_NAMES 中文名对齐(镜像落库即中文名)
|
||||||
|
invoiceTypeOptions: [
|
||||||
|
'增值税电子普通发票',
|
||||||
|
'增值税电子专用发票',
|
||||||
|
'增值税普通发票',
|
||||||
|
'增值税专用发票',
|
||||||
|
'增值税普通发票(卷票)',
|
||||||
|
'通用机打发票',
|
||||||
|
'出租车票',
|
||||||
|
'火车票',
|
||||||
|
'飞机票',
|
||||||
|
'其他票',
|
||||||
|
'机动车销售统一发票',
|
||||||
|
'二手车销售统一发票',
|
||||||
|
'定额发票',
|
||||||
|
'增值税电子普通发票(通行费)',
|
||||||
|
'汽车票',
|
||||||
|
'过路(过桥)费发票',
|
||||||
|
'税收完税证明',
|
||||||
|
'轮船票',
|
||||||
|
'海关缴款书',
|
||||||
|
'通用机打电子发票',
|
||||||
|
'火车票退票凭证',
|
||||||
|
'财政电子票据',
|
||||||
|
'数电发票(普通发票)',
|
||||||
|
'数电发票(增值税专用发票)',
|
||||||
|
'数电发票(航空运输电子客票行程单)',
|
||||||
|
'数电发票(铁路电子客票)',
|
||||||
|
'海外发票',
|
||||||
|
'海外收据',
|
||||||
|
'增值税代扣代缴完税凭证',
|
||||||
|
'数电发票(通行费发票)',
|
||||||
|
'数电发票(机动车销售统一发票)',
|
||||||
|
'数电发票(二手车销售统一发票)',
|
||||||
|
],
|
||||||
|
rows: [],
|
||||||
|
selected: [],
|
||||||
|
current: null,
|
||||||
|
fetchNo: '',
|
||||||
|
page: { current: 1, size: 10, total: 0 },
|
||||||
|
query: this.emptyQuery(),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
visible: {
|
||||||
|
get() {
|
||||||
|
return this.modelValue;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.$emit('update:modelValue', value);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
emptyQuery() {
|
||||||
|
return {
|
||||||
|
invoiceNo: '',
|
||||||
|
invoiceDateRange: [],
|
||||||
|
salerName: '',
|
||||||
|
buyerName: '',
|
||||||
|
invoiceType: '',
|
||||||
|
claimed: null,
|
||||||
|
registered: null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
handleOpen() {
|
||||||
|
this.query = this.emptyQuery();
|
||||||
|
this.query.invoiceNo = this.initialInvoiceNo || '';
|
||||||
|
this.current = null;
|
||||||
|
this.selected = [];
|
||||||
|
this.$refs.poolTable?.clearSelection();
|
||||||
|
this.page.current = 1;
|
||||||
|
this.load();
|
||||||
|
},
|
||||||
|
handleQuery() {
|
||||||
|
this.page.current = 1;
|
||||||
|
this.load();
|
||||||
|
},
|
||||||
|
handleSizeChange() {
|
||||||
|
this.page.current = 1;
|
||||||
|
this.load();
|
||||||
|
},
|
||||||
|
resetQuery() {
|
||||||
|
this.query = this.emptyQuery();
|
||||||
|
this.handleQuery();
|
||||||
|
},
|
||||||
|
unwrap(response) {
|
||||||
|
const body = response?.data || response || {};
|
||||||
|
return body?.data || body;
|
||||||
|
},
|
||||||
|
async load() {
|
||||||
|
this.loading = true;
|
||||||
|
try {
|
||||||
|
const range = this.query.invoiceDateRange || [];
|
||||||
|
const data = this.unwrap(
|
||||||
|
await this.queryApi({
|
||||||
|
current: this.page.current,
|
||||||
|
size: this.page.size,
|
||||||
|
invoiceNo: this.query.invoiceNo || undefined,
|
||||||
|
invoiceDateStart: range[0] || undefined,
|
||||||
|
invoiceDateEnd: range[1] || undefined,
|
||||||
|
salerName: this.query.salerName || undefined,
|
||||||
|
buyerName: this.query.buyerName || undefined,
|
||||||
|
invoiceType: this.query.invoiceType || undefined,
|
||||||
|
claimed: this.query.claimed ?? undefined,
|
||||||
|
registered: this.query.registered ?? undefined,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
this.rows = data.records || [];
|
||||||
|
this.page.total = Number(data.total || 0);
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleRowDblclick(row) {
|
||||||
|
if (!this.multiple) {
|
||||||
|
this.confirmRows([row]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleConfirm() {
|
||||||
|
const picked = this.multiple ? this.selected : this.current ? [this.current] : [];
|
||||||
|
this.confirmRows(picked);
|
||||||
|
},
|
||||||
|
confirmRows(rows) {
|
||||||
|
if (!rows.length) {
|
||||||
|
this.$message.warning(this.multiple ? '请至少选择一条发票' : '请选择一张发票');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.$emit('confirm', rows);
|
||||||
|
this.visible = false;
|
||||||
|
},
|
||||||
|
async handleFetch() {
|
||||||
|
const invoiceNo = String(this.fetchNo || '').trim();
|
||||||
|
if (!invoiceNo) {
|
||||||
|
this.$message.warning('请输入发票号码');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.fetching = true;
|
||||||
|
try {
|
||||||
|
await this.fetchApi(invoiceNo);
|
||||||
|
this.$message.success('补查成功,已刷新列表');
|
||||||
|
this.page.current = 1;
|
||||||
|
await this.load();
|
||||||
|
} finally {
|
||||||
|
this.fetching = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async handleSync() {
|
||||||
|
this.syncing = true;
|
||||||
|
// 全量同步为服务端分钟级同步接口(per-request 超时 300s),全程遮罩提示并锁定弹窗防误关
|
||||||
|
const loading = ElLoading.service({
|
||||||
|
lock: true,
|
||||||
|
text: '正在从金蝶全票池同步发票,预计 1~3 分钟,请勿关闭窗口…',
|
||||||
|
background: 'rgba(0, 0, 0, 0.5)',
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
const summary = this.unwrap(await this.syncApi());
|
||||||
|
this.$message.success(String(summary) || '同步完成');
|
||||||
|
this.page.current = 1;
|
||||||
|
await this.load();
|
||||||
|
} finally {
|
||||||
|
loading.close();
|
||||||
|
this.syncing = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
formatMoney(value) {
|
||||||
|
const number = Number(value);
|
||||||
|
return Number.isFinite(number) ? number.toFixed(2) : '-';
|
||||||
|
},
|
||||||
|
kingdeeStatusText(value) {
|
||||||
|
const statusMap = {
|
||||||
|
unsynced: '未同步',
|
||||||
|
synced: '已同步',
|
||||||
|
failed: '同步失败',
|
||||||
|
};
|
||||||
|
return statusMap[value] || value || '-';
|
||||||
|
},
|
||||||
|
formatRate(value) {
|
||||||
|
const number = Number(value);
|
||||||
|
return Number.isFinite(number) ? `${number}%` : '-';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.kingdee-pool-dialog__footer-bar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-top: 12px;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
.kingdee-pool-dialog__fetch {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -149,62 +149,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<el-dialog v-model="invoiceDialog.visible" title="查询金蝶票据池" width="86%" append-to-body>
|
<kingdee-invoice-pool-dialog
|
||||||
<div class="receipt-form-page__dialog-search">
|
v-model="invoiceDialog.visible"
|
||||||
<el-input
|
title="查询金蝶票据池"
|
||||||
v-model="invoiceDialog.keyword"
|
:initial-invoice-no="form.invoiceNo"
|
||||||
clearable
|
:query-api="apiQueryInvoicePool"
|
||||||
placeholder="发票号码、开票单位或受票单位"
|
:fetch-api="apiFetchInvoicePool"
|
||||||
@keyup.enter="loadInvoicePool"
|
:sync-api="apiSyncInvoicePool"
|
||||||
|
@confirm="handleInvoicePicked"
|
||||||
/>
|
/>
|
||||||
<el-button type="primary" @click="loadInvoicePool">查询</el-button>
|
|
||||||
</div>
|
|
||||||
<el-table
|
|
||||||
v-loading="invoiceDialog.loading"
|
|
||||||
:data="invoiceDialog.rows"
|
|
||||||
border
|
|
||||||
empty-text="暂无票据数据"
|
|
||||||
highlight-current-row
|
|
||||||
@current-change="invoiceDialog.current = $event"
|
|
||||||
@row-dblclick="confirmInvoice"
|
|
||||||
>
|
|
||||||
<el-table-column prop="invoiceNo" label="发票号码" min-width="180" />
|
|
||||||
<el-table-column prop="invoiceDate" label="开票日期" min-width="120" />
|
|
||||||
<el-table-column prop="invoiceType" label="发票类型" min-width="130" />
|
|
||||||
<el-table-column prop="issuerName" label="开票单位" min-width="170" />
|
|
||||||
<el-table-column prop="receiverName" label="受票单位" min-width="170" />
|
|
||||||
<el-table-column label="开票金额" min-width="130" align="right">
|
|
||||||
<template #default="{ row }">{{ formatMoney(row.invoiceAmount) }}</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="税率" min-width="100" align="center">
|
|
||||||
<template #default="{ row }">{{ formatRate(row.taxRate) }}</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="税额" min-width="120" align="right">
|
|
||||||
<template #default="{ row }">{{ formatMoney(row.taxAmount) }}</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="kingdeeBillNo" label="金蝶单据号" min-width="150" />
|
|
||||||
<el-table-column label="操作" width="100" fixed="right" align="center">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<el-link type="primary" @click.stop="confirmInvoice(row)">选择</el-link>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
<div class="receipt-form-page__dialog-pagination">
|
|
||||||
<el-pagination
|
|
||||||
v-model:current-page="invoiceDialog.page.current"
|
|
||||||
v-model:page-size="invoiceDialog.page.size"
|
|
||||||
:total="invoiceDialog.page.total"
|
|
||||||
:page-sizes="[10, 20, 50, 100]"
|
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
|
||||||
@current-change="refreshInvoicePoolPage"
|
|
||||||
@size-change="handleInvoicePoolSizeChange"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<template #footer>
|
|
||||||
<el-button @click="invoiceDialog.visible = false">取消</el-button>
|
|
||||||
<el-button type="primary" @click="confirmInvoice()">确定</el-button>
|
|
||||||
</template>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<el-dialog
|
<el-dialog
|
||||||
v-model="settlementDialog.visible"
|
v-model="settlementDialog.visible"
|
||||||
@@ -259,77 +212,9 @@
|
|||||||
import { Search } from '@element-plus/icons-vue';
|
import { Search } from '@element-plus/icons-vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import * as api from '@/api/payment/invoiceReceipt';
|
import * as api from '@/api/payment/invoiceReceipt';
|
||||||
import { getList as getCustomerList } from '@/api/vehicle/customer-archive';
|
import KingdeeInvoicePoolDialog from '@/components/kingdee-invoice-pool-dialog/main.vue';
|
||||||
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
||||||
|
|
||||||
const mockInvoiceTypes = ['增值税专用发票', '增值税普通发票'];
|
|
||||||
const mockTaxRates = [3, 6, 9, 13];
|
|
||||||
const mockBankNames = ['中国工商银行', '中国农业银行', '中国银行', '中国建设银行', '招商银行'];
|
|
||||||
|
|
||||||
const randomDigits = length =>
|
|
||||||
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 = () => ({
|
const emptyForm = () => ({
|
||||||
id: null,
|
id: null,
|
||||||
kingdeeInvoicePoolId: null,
|
kingdeeInvoicePoolId: null,
|
||||||
@@ -361,24 +246,17 @@ const emptyForm = () => ({
|
|||||||
export default {
|
export default {
|
||||||
name: 'InvoiceReceiptForm',
|
name: 'InvoiceReceiptForm',
|
||||||
components: {
|
components: {
|
||||||
|
KingdeeInvoicePoolDialog,
|
||||||
VehicleAttachmentTable,
|
VehicleAttachmentTable,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
Search,
|
Search,
|
||||||
form: emptyForm(),
|
form: emptyForm(),
|
||||||
invoicePoolMockRows: [],
|
|
||||||
invoicePoolMockLoaded: false,
|
|
||||||
customerEmailOptions: [],
|
customerEmailOptions: [],
|
||||||
departmentEmailOptions: [],
|
departmentEmailOptions: [],
|
||||||
invoiceDialog: {
|
invoiceDialog: {
|
||||||
visible: false,
|
visible: false,
|
||||||
loading: false,
|
|
||||||
keyword: '',
|
|
||||||
sourceRows: [],
|
|
||||||
rows: [],
|
|
||||||
current: null,
|
|
||||||
page: { current: 1, size: 10, total: 0 },
|
|
||||||
},
|
},
|
||||||
settlementDialog: {
|
settlementDialog: {
|
||||||
visible: false,
|
visible: false,
|
||||||
@@ -421,6 +299,18 @@ export default {
|
|||||||
this.initialize();
|
this.initialize();
|
||||||
},
|
},
|
||||||
methods: {
|
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) {
|
hasPermission(code) {
|
||||||
return this.permission?.[code] !== false;
|
return this.permission?.[code] !== false;
|
||||||
},
|
},
|
||||||
@@ -492,92 +382,11 @@ export default {
|
|||||||
}
|
}
|
||||||
callback();
|
callback();
|
||||||
},
|
},
|
||||||
async openInvoiceDialog() {
|
openInvoiceDialog() {
|
||||||
this.invoiceDialog.visible = true;
|
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 = {}) {
|
confirmInvoice(row, options = {}) {
|
||||||
const selected = row?.id ? row : this.invoiceDialog.current;
|
const selected = row;
|
||||||
if (!selected) {
|
if (!selected) {
|
||||||
this.$message.warning('请选择一张金蝶票据池发票');
|
this.$message.warning('请选择一张金蝶票据池发票');
|
||||||
return;
|
return;
|
||||||
@@ -758,16 +567,8 @@ export default {
|
|||||||
this.$message.warning('请先选择金蝶票据池发票');
|
this.$message.warning('请先选择金蝶票据池发票');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const data = this.recordId
|
const invoice = this.unwrapData(await api.fetchInvoicePoolByNo(this.form.invoiceNo));
|
||||||
? this.unwrapData(await api.getInvoicePool(this.form.invoiceNo))
|
if (!invoice || !this.confirmInvoice(invoice, { preserveUserInput: true })) return;
|
||||||
: 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;
|
|
||||||
if (this.settlementIds.length) await this.loadReferenceInformation();
|
if (this.settlementIds.length) await this.loadReferenceInformation();
|
||||||
this.$message.success('同步成功');
|
this.$message.success('同步成功');
|
||||||
},
|
},
|
||||||
@@ -827,11 +628,6 @@ export default {
|
|||||||
.receipt-form-page__dialog-search .el-input {
|
.receipt-form-page__dialog-search .el-input {
|
||||||
width: 360px;
|
width: 360px;
|
||||||
}
|
}
|
||||||
.receipt-form-page__dialog-pagination {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
margin-top: 12px;
|
|
||||||
}
|
|
||||||
.receipt-form-page :deep(.el-table) {
|
.receipt-form-page :deep(.el-table) {
|
||||||
--el-table-border-color: #eff1f7;
|
--el-table-border-color: #eff1f7;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -412,126 +412,16 @@
|
|||||||
</el-table>
|
</el-table>
|
||||||
</section-card>
|
</section-card>
|
||||||
|
|
||||||
<el-dialog
|
<kingdee-invoice-pool-dialog
|
||||||
v-model="invoiceClaimDialog.visible"
|
v-model="invoiceClaimDialog.visible"
|
||||||
title="查询可认领发票"
|
title="查询可认领发票"
|
||||||
width="92%"
|
confirm-text="确认认领"
|
||||||
append-to-body
|
multiple
|
||||||
destroy-on-close
|
:initial-invoice-no="String(invoiceClaimNo || '').trim()"
|
||||||
>
|
:query-api="invoicePoolQueryApi"
|
||||||
<el-form
|
:fetch-api="invoicePoolFetchApi"
|
||||||
:model="invoiceClaimDialog.query"
|
@confirm="handleInvoiceClaimConfirm"
|
||||||
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
|
|
||||||
ref="invoiceClaimTable"
|
|
||||||
v-loading="invoiceClaimDialog.loading"
|
|
||||||
:data="invoiceClaimDialog.rows"
|
|
||||||
row-key="serialNo"
|
|
||||||
border
|
|
||||||
height="520"
|
|
||||||
@selection-change="invoiceClaimDialog.selected = $event"
|
|
||||||
>
|
|
||||||
<el-table-column
|
|
||||||
type="selection"
|
|
||||||
width="52"
|
|
||||||
fixed="left"
|
|
||||||
align="center"
|
|
||||||
reserve-selection
|
|
||||||
/>
|
|
||||||
<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="invoiceDate" label="开票日期" min-width="130" align="center" />
|
|
||||||
<el-table-column prop="invoiceTypeName" label="发票类型" min-width="150" align="center" />
|
|
||||||
<el-table-column prop="salerName" label="开票单位" min-width="180" align="center" />
|
|
||||||
<el-table-column prop="buyerName" label="受票单位" min-width="180" align="center" />
|
|
||||||
<el-table-column
|
|
||||||
prop="invoiceAmount"
|
|
||||||
label="发票金额(含税)"
|
|
||||||
min-width="160"
|
|
||||||
align="right"
|
|
||||||
>
|
|
||||||
<template #default="{ row }">{{ formatMoney(row.invoiceAmount) }}</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="matchedAmount" label="认领金额" min-width="140" align="right">
|
|
||||||
<template #default="{ row }">{{ formatMoney(row.matchedAmount) }}</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
<div class="formal-editor__pagination">
|
|
||||||
<el-pagination
|
|
||||||
v-model:current-page="invoiceClaimDialog.page.current"
|
|
||||||
v-model:page-size="invoiceClaimDialog.page.size"
|
|
||||||
:total="invoiceClaimDialog.page.total"
|
|
||||||
:page-sizes="[10, 20, 50, 100]"
|
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
|
||||||
@current-change="loadInvoiceClaims"
|
|
||||||
@size-change="handleInvoiceClaimSizeChange"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<template #footer>
|
|
||||||
<el-button @click="invoiceClaimDialog.visible = false">取消</el-button>
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
:loading="invoiceClaimDialog.confirming"
|
|
||||||
@click="confirmInvoiceClaims"
|
|
||||||
>确认认领</el-button
|
|
||||||
>
|
|
||||||
</template>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<section-card
|
<section-card
|
||||||
v-if="readonly"
|
v-if="readonly"
|
||||||
@@ -1002,6 +892,7 @@ import {
|
|||||||
getReceiptClaims,
|
getReceiptClaims,
|
||||||
claimInvoices as claimInvoicesApi,
|
claimInvoices as claimInvoicesApi,
|
||||||
queryInvoicePool,
|
queryInvoicePool,
|
||||||
|
fetchInvoicePoolByNo,
|
||||||
save,
|
save,
|
||||||
} from '@/api/settlement/formalSettlement';
|
} from '@/api/settlement/formalSettlement';
|
||||||
import {
|
import {
|
||||||
@@ -1026,11 +917,12 @@ import { h } from 'vue';
|
|||||||
import { InfoFilled } from '@element-plus/icons-vue';
|
import { InfoFilled } from '@element-plus/icons-vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { downloadFileByUrl } from '@/utils/util';
|
import { downloadFileByUrl } from '@/utils/util';
|
||||||
|
import KingdeeInvoicePoolDialog from '@/components/kingdee-invoice-pool-dialog/main.vue';
|
||||||
import * as XLSX from 'xlsx';
|
import * as XLSX from 'xlsx';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'FormalSettlementEditor',
|
name: 'FormalSettlementEditor',
|
||||||
components: { InfoFilled },
|
components: { InfoFilled, KingdeeInvoicePoolDialog },
|
||||||
props: {
|
props: {
|
||||||
modelValue: Boolean,
|
modelValue: Boolean,
|
||||||
recordId: [String, Number],
|
recordId: [String, Number],
|
||||||
@@ -1062,25 +954,9 @@ export default {
|
|||||||
invoiceClaimLoading: false,
|
invoiceClaimLoading: false,
|
||||||
invoiceClaimDialog: {
|
invoiceClaimDialog: {
|
||||||
visible: false,
|
visible: false,
|
||||||
loading: false,
|
|
||||||
confirming: false,
|
|
||||||
rows: [],
|
|
||||||
selected: [],
|
selected: [],
|
||||||
page: { current: 1, size: 10, total: 0 },
|
confirming: false,
|
||||||
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: [
|
||||||
@@ -1300,15 +1176,7 @@ export default {
|
|||||||
this.invoices = [];
|
this.invoices = [];
|
||||||
this.invoiceClaimNo = '';
|
this.invoiceClaimNo = '';
|
||||||
this.invoiceClaimDialog.visible = false;
|
this.invoiceClaimDialog.visible = false;
|
||||||
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,
|
||||||
@@ -2300,50 +2168,21 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
openInvoiceClaimDialog() {
|
openInvoiceClaimDialog() {
|
||||||
this.invoiceClaimDialog.query.invoiceNo = String(this.invoiceClaimNo || '').trim();
|
|
||||||
this.invoiceClaimDialog.visible = true;
|
this.invoiceClaimDialog.visible = true;
|
||||||
this.handleInvoiceClaimQuery();
|
|
||||||
},
|
},
|
||||||
handleInvoiceClaimQuery() {
|
invoicePoolQueryApi(params) {
|
||||||
this.invoiceClaimDialog.page.current = 1;
|
return queryInvoicePool(params);
|
||||||
this.loadInvoiceClaims();
|
|
||||||
},
|
},
|
||||||
resetInvoiceClaimQuery() {
|
invoicePoolFetchApi(invoiceNo) {
|
||||||
this.invoiceClaimDialog.query = {
|
return fetchInvoicePoolByNo(invoiceNo);
|
||||||
invoiceNo: '',
|
|
||||||
invoiceDateRange: [],
|
|
||||||
salerTaxNo: '',
|
|
||||||
buyerTaxNo: '',
|
|
||||||
expenseStatus: '',
|
|
||||||
};
|
|
||||||
this.handleInvoiceClaimQuery();
|
|
||||||
},
|
},
|
||||||
handleInvoiceClaimSizeChange() {
|
async handleInvoiceClaimConfirm(rows) {
|
||||||
this.invoiceClaimDialog.page.current = 1;
|
// 统一票池行附件字段为复数 attachmentsJson,认领请求契约是单数 attachmentJson,中转处归一
|
||||||
this.loadInvoiceClaims();
|
this.invoiceClaimDialog.selected = rows.map(row => ({
|
||||||
},
|
...row,
|
||||||
async loadInvoiceClaims() {
|
attachmentJson: row.attachmentJson || row.attachmentsJson,
|
||||||
this.invoiceClaimDialog.loading = true;
|
}));
|
||||||
try {
|
await this.confirmInvoiceClaims();
|
||||||
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;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
async confirmInvoiceClaims() {
|
async confirmInvoiceClaims() {
|
||||||
if (!this.invoiceClaimDialog.selected.length) {
|
if (!this.invoiceClaimDialog.selected.length) {
|
||||||
|
|||||||
Reference in New Issue
Block a user