Merge remote-tracking branch 'origin/feature/bfi-api-rate' into feature/bfi-api-rate
# Conflicts: # src/api/payment/invoiceReceipt.js
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
pnpm-lock.yaml
|
||||
/dist
|
||||
|
||||
/tests/e2e/videos/
|
||||
|
||||
+5
-2
@@ -6,7 +6,8 @@
|
||||
"prod": "vite --mode production",
|
||||
"build": "vite build",
|
||||
"build:prod": "vite build --mode production",
|
||||
"serve": "vite preview --host"
|
||||
"serve": "vite preview --host",
|
||||
"typecheck": "vue-tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@element-plus/icons-vue": "^2.3.1",
|
||||
@@ -46,9 +47,11 @@
|
||||
"prettier": "^2.8.7",
|
||||
"sass": "^1.85.1",
|
||||
"terser": "^5.31.1",
|
||||
"typescript": "^7.0.2",
|
||||
"unplugin-auto-import": "^0.11.2",
|
||||
"vite": "^5.4.19",
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
"vite-plugin-vue-setup-extend": "^0.4.0"
|
||||
"vite-plugin-vue-setup-extend": "^0.4.0",
|
||||
"vue-tsc": "^3.3.11"
|
||||
}
|
||||
}
|
||||
|
||||
Generated
-4259
File diff suppressed because it is too large
Load Diff
@@ -5,8 +5,8 @@ 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 getSettlementCandidates = (keyword, receiptId) =>
|
||||
request({
|
||||
url: `${baseUrl}/settlement-candidates`,
|
||||
@@ -25,8 +25,8 @@ export const submit = data => request({ url: `${baseUrl}/submit`, method: 'post'
|
||||
export const approve = data => request({ url: `${baseUrl}/approve`, method: 'post', data });
|
||||
export const returnBill = data => request({ url: `${baseUrl}/return`, method: 'post', data });
|
||||
export const voidBill = data => request({ url: `${baseUrl}/void`, method: 'post', data });
|
||||
export const syncKingdee = id =>
|
||||
request({ url: `${baseUrl}/sync-kingdee`, method: 'post', params: { id }, timeout: 120000 });
|
||||
export const pushKingdee = ids =>
|
||||
request({ url: `${baseUrl}/push-kingdee`, method: 'post', data: ids });
|
||||
|
||||
export const approvalStatusOptions = [
|
||||
{ label: '草稿', value: 'draft' },
|
||||
@@ -36,8 +36,9 @@ export const approvalStatusOptions = [
|
||||
{ label: '已作废', value: 'voided' },
|
||||
];
|
||||
|
||||
export const kingdeeStatusOptions = [
|
||||
{ label: '未同步', value: 'unsynced' },
|
||||
{ label: '已同步', value: 'synced' },
|
||||
{ label: '同步失败', value: 'failed' },
|
||||
export const kingdeePushStatusOptions = [
|
||||
{ label: '未推送', value: 'unsynced' },
|
||||
{ label: '已保存收票单', value: 'pushed' },
|
||||
{ label: '已指定应付', value: 'assigned' },
|
||||
{ label: '推送失败', value: 'failed' },
|
||||
];
|
||||
|
||||
@@ -0,0 +1,310 @@
|
||||
<template>
|
||||
<el-dialog v-model="visible" :title="title" width="92%" append-to-body destroy-on-close @open="handleOpen">
|
||||
<el-form :model="query" inline label-width="130px" @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.salerTaxNo"
|
||||
clearable
|
||||
style="width: 180px"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="购方(收票方税号)">
|
||||
<el-input
|
||||
v-model="query.buyerTaxNo"
|
||||
clearable
|
||||
style="width: 180px"
|
||||
@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="option in invoiceTypeOptions"
|
||||
:key="option.value"
|
||||
:label="option.label"
|
||||
:value="option.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button :disabled="loading" @click="resetQuery">重置</el-button>
|
||||
<el-button type="primary" :disabled="loading" @click="handleQuery">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-table
|
||||
ref="poolTable"
|
||||
v-loading="loading"
|
||||
:data="rows"
|
||||
:row-key="rowKey"
|
||||
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.invoiceNo"
|
||||
:value="row.invoiceNo"
|
||||
@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 label="剩余可用金额" min-width="130" align="right">
|
||||
<template #default="{ row }">{{ formatMoney(row.availableTaxAmount) }}</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 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__pager">
|
||||
<span class="kingdee-pool-dialog__pager-info">第 {{ page.current }} 页</span>
|
||||
<el-button :disabled="page.current <= 1 || loading" @click="prevPage">上一页</el-button>
|
||||
<el-button :disabled="!page.hasMore || loading" @click="nextPage">下一页</el-button>
|
||||
<el-select v-model="page.size" style="width: 110px" @change="handleSizeChange">
|
||||
<el-option v-for="n in [10, 20, 50, 100]" :key="n" :label="`${n}条/页`" :value="n" />
|
||||
</el-select>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="visible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleConfirm">{{ confirmText }}</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
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 },
|
||||
},
|
||||
emits: ['update:modelValue', 'confirm'],
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
// 与后端 BfiConstant.INVOICE_TYPE_NAMES 对齐:value 为发票类型编码,label 为中文名
|
||||
// 选票场景只开放数电票(普票/专票)
|
||||
invoiceTypeOptions: [
|
||||
{ value: '26', label: '数电发票(普通发票)' },
|
||||
{ value: '27', label: '数电发票(增值税专用发票)' },
|
||||
],
|
||||
rows: [],
|
||||
selected: [],
|
||||
current: null,
|
||||
page: { current: 1, size: 10, hasMore: false },
|
||||
// 续扫游标(服务端过滤补页后翻页须按游标对齐,防漏行/重行)
|
||||
nextCursor: null,
|
||||
// 下一页请求待回传的游标:nextPage 时暂存,load 成功或失败后清空
|
||||
pendingCursor: null,
|
||||
// 已浏览页缓存:上一页直接回显不再请求(0 远程调用)
|
||||
pageCache: {},
|
||||
query: this.emptyQuery(),
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
visible: {
|
||||
get() {
|
||||
return this.modelValue;
|
||||
},
|
||||
set(value) {
|
||||
this.$emit('update:modelValue', value);
|
||||
},
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
emptyQuery() {
|
||||
return {
|
||||
invoiceNo: '',
|
||||
// 默认查近一个月,随请求传后端并在页面回显
|
||||
invoiceDateRange: [this.$dayjs().subtract(1, 'month').format('YYYY-MM-DD'), this.$dayjs().format('YYYY-MM-DD')],
|
||||
salerTaxNo: '',
|
||||
buyerTaxNo: '',
|
||||
invoiceType: '',
|
||||
};
|
||||
},
|
||||
// 远程实时查询的票未入本地镜像,id 恒空,用发票号码兜底作为行主键
|
||||
rowKey(row) {
|
||||
return row.invoiceNo || row.id;
|
||||
},
|
||||
handleOpen() {
|
||||
this.query = this.emptyQuery();
|
||||
this.query.invoiceNo = this.initialInvoiceNo || '';
|
||||
this.current = null;
|
||||
this.selected = [];
|
||||
this.$refs.poolTable?.clearSelection();
|
||||
this.page.current = 1;
|
||||
this.resetScanState();
|
||||
this.load();
|
||||
},
|
||||
handleQuery() {
|
||||
this.page.current = 1;
|
||||
this.resetScanState();
|
||||
this.load();
|
||||
},
|
||||
handleSizeChange() {
|
||||
this.page.current = 1;
|
||||
this.resetScanState();
|
||||
this.load();
|
||||
},
|
||||
prevPage() {
|
||||
// 已浏览页直接回显缓存,不再请求
|
||||
const cached = this.pageCache[this.page.current - 1];
|
||||
if (cached) {
|
||||
this.page.current -= 1;
|
||||
this.rows = cached.rows;
|
||||
this.page.hasMore = cached.hasMore;
|
||||
this.nextCursor = cached.nextCursor;
|
||||
return;
|
||||
}
|
||||
this.page.current -= 1;
|
||||
this.load();
|
||||
},
|
||||
nextPage() {
|
||||
this.pendingCursor = this.nextCursor;
|
||||
this.page.current += 1;
|
||||
this.load();
|
||||
},
|
||||
resetQuery() {
|
||||
this.query = this.emptyQuery();
|
||||
this.handleQuery();
|
||||
},
|
||||
// 新查询/换页容量/重新打开时清空游标与已浏览页缓存,重新锚定扫描
|
||||
resetScanState() {
|
||||
this.nextCursor = null;
|
||||
this.pendingCursor = null;
|
||||
this.pageCache = {};
|
||||
},
|
||||
unwrap(response) {
|
||||
const body = response?.data || response || {};
|
||||
return body?.data || body;
|
||||
},
|
||||
async load() {
|
||||
this.loading = true;
|
||||
// 请求前快照页码:prev/next 会先改写 current,远程失败时回滚避免停留在错页
|
||||
const lastRequested = this.page.current;
|
||||
const cursor = this.pendingCursor;
|
||||
this.pendingCursor = null;
|
||||
try {
|
||||
const range = this.query.invoiceDateRange || [];
|
||||
const data = this.unwrap(
|
||||
await this.queryApi({
|
||||
current: this.page.current,
|
||||
size: this.page.size,
|
||||
cursor: cursor || undefined,
|
||||
invoiceNo: this.query.invoiceNo || undefined,
|
||||
invoiceDateStart: range[0] || undefined,
|
||||
invoiceDateEnd: range[1] || undefined,
|
||||
salerTaxNo: this.query.salerTaxNo || undefined,
|
||||
buyerTaxNo: this.query.buyerTaxNo || undefined,
|
||||
invoiceType: this.query.invoiceType || undefined,
|
||||
})
|
||||
);
|
||||
this.rows = data.records || [];
|
||||
this.page.hasMore = !!data.hasMore;
|
||||
this.nextCursor = data.nextCursor || null;
|
||||
this.pageCache[this.page.current] = { rows: this.rows, hasMore: this.page.hasMore, nextCursor: this.nextCursor };
|
||||
} catch (error) {
|
||||
if (this.page.current !== lastRequested) {
|
||||
this.page.current = lastRequested;
|
||||
}
|
||||
throw error;
|
||||
} 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;
|
||||
},
|
||||
formatMoney(value) {
|
||||
const number = Number(value);
|
||||
return Number.isFinite(number) ? number.toFixed(2) : '-';
|
||||
},
|
||||
formatRate(value) {
|
||||
const number = Number(value);
|
||||
return Number.isFinite(number) ? `${number}%` : '-';
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.kingdee-pool-dialog__pager {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
justify-content: flex-end;
|
||||
margin-top: 12px;
|
||||
}
|
||||
</style>
|
||||
@@ -11,6 +11,7 @@ export const invoiceReceiptTableColumns = [
|
||||
{ prop: 'currentProcessor', label: '当前处理人', minWidth: 130 },
|
||||
{ prop: 'createUserName', label: '创建人', minWidth: 110 },
|
||||
{ prop: 'createTime', label: '创建时间', minWidth: 170 },
|
||||
{ prop: 'kingdeeBillNo', label: '金蝶单据号', minWidth: 150 },
|
||||
{ prop: 'kingdeeStatusName', label: '金蝶单据状态', minWidth: 140 },
|
||||
{ prop: 'kingdeeReceivedInvoiceNo', label: '金蝶单据号', minWidth: 150 },
|
||||
{ prop: 'kingdeePushStatusName', label: '金蝶状态', minWidth: 130 },
|
||||
{ prop: 'kingdeePushMsg', label: '失败原因', minWidth: 160 },
|
||||
];
|
||||
|
||||
@@ -88,6 +88,8 @@ export const updateFeeFormFields = [
|
||||
];
|
||||
|
||||
export const transferSearchFields = [
|
||||
{ label: '单据号', prop: 'documentNo', type: 'input' },
|
||||
{ label: '合同编码', prop: 'contractNo', type: 'input' },
|
||||
{ label: '合同名称', prop: 'contractName', type: 'input' },
|
||||
{ label: '批次号', prop: 'batchNo', type: 'input' },
|
||||
{ label: '生成日期', prop: 'generateDateRange', type: 'daterange' },
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
<el-col :span="6">
|
||||
<el-form-item label="开票金额">
|
||||
<el-input
|
||||
:model-value="form.kingdeeInvoicePoolId ? formatMoney(form.invoiceAmount) : ''"
|
||||
:model-value="form.invoiceNo ? formatMoney(form.invoiceAmount) : ''"
|
||||
disabled
|
||||
placeholder="从金蝶票据池带出"
|
||||
/>
|
||||
@@ -56,7 +56,7 @@
|
||||
<el-col :span="6">
|
||||
<el-form-item label="税额">
|
||||
<el-input
|
||||
:model-value="form.kingdeeInvoicePoolId ? formatMoney(form.taxAmount) : ''"
|
||||
:model-value="form.invoiceNo ? formatMoney(form.taxAmount) : ''"
|
||||
disabled
|
||||
placeholder="从金蝶票据池带出"
|
||||
/>
|
||||
@@ -149,62 +149,13 @@
|
||||
</div>
|
||||
</el-form>
|
||||
|
||||
<el-dialog v-model="invoiceDialog.visible" title="查询金蝶票据池" width="86%" append-to-body>
|
||||
<div class="receipt-form-page__dialog-search">
|
||||
<el-input
|
||||
v-model="invoiceDialog.keyword"
|
||||
clearable
|
||||
placeholder="发票号码、开票单位或受票单位"
|
||||
@keyup.enter="loadInvoicePool"
|
||||
/>
|
||||
<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>
|
||||
<kingdee-invoice-pool-dialog
|
||||
v-model="invoiceDialog.visible"
|
||||
title="查询金蝶票据池"
|
||||
:initial-invoice-no="form.invoiceNo"
|
||||
:query-api="apiQueryInvoicePool"
|
||||
@confirm="handleInvoicePicked"
|
||||
/>
|
||||
|
||||
<el-dialog
|
||||
v-model="settlementDialog.visible"
|
||||
@@ -259,80 +210,11 @@
|
||||
import { Search } from '@element-plus/icons-vue';
|
||||
import { mapGetters } from 'vuex';
|
||||
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';
|
||||
|
||||
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 = () => ({
|
||||
id: null,
|
||||
kingdeeInvoicePoolId: null,
|
||||
invoiceNo: '',
|
||||
invoiceDate: '',
|
||||
invoiceType: '',
|
||||
@@ -344,8 +226,6 @@ const emptyForm = () => ({
|
||||
bankName: '',
|
||||
bankAccount: '',
|
||||
issuingBank: '',
|
||||
kingdeeBillNo: '',
|
||||
kingdeeStatus: 'unsynced',
|
||||
phone: '',
|
||||
customerEmails: [],
|
||||
departmentEmails: [],
|
||||
@@ -361,24 +241,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 +294,12 @@ export default {
|
||||
this.initialize();
|
||||
},
|
||||
methods: {
|
||||
apiQueryInvoicePool(params) {
|
||||
return api.queryInvoicePool(params);
|
||||
},
|
||||
handleInvoicePicked(rows) {
|
||||
this.confirmInvoice(rows[0]);
|
||||
},
|
||||
hasPermission(code) {
|
||||
return this.permission?.[code] !== false;
|
||||
},
|
||||
@@ -466,7 +345,7 @@ export default {
|
||||
if (this.settlementIds.length) await this.loadReferenceInformation();
|
||||
},
|
||||
validateInvoice(rule, value, callback) {
|
||||
if (!value || !this.form.kingdeeInvoicePoolId) {
|
||||
if (!value) {
|
||||
callback(new Error('请选择金蝶票据池发票'));
|
||||
return;
|
||||
}
|
||||
@@ -492,99 +371,17 @@ 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;
|
||||
}
|
||||
const preserveUserInput = options.preserveUserInput === true;
|
||||
Object.assign(this.form, {
|
||||
kingdeeInvoicePoolId: selected.id,
|
||||
invoiceNo: selected.invoiceNo,
|
||||
invoiceDate: selected.invoiceDate,
|
||||
invoiceType: selected.invoiceType,
|
||||
@@ -596,8 +393,6 @@ export default {
|
||||
bankName: selected.bankName,
|
||||
bankAccount: selected.bankAccount,
|
||||
issuingBank: selected.issuingBank,
|
||||
kingdeeBillNo: selected.kingdeeBillNo || '',
|
||||
kingdeeStatus: selected.kingdeeStatus || 'unsynced',
|
||||
phone: preserveUserInput ? this.form.phone : selected.phone || '',
|
||||
customerEmails: preserveUserInput
|
||||
? this.form.customerEmails
|
||||
@@ -708,7 +503,6 @@ export default {
|
||||
payload() {
|
||||
return {
|
||||
id: this.form.id,
|
||||
kingdeeInvoicePoolId: this.form.kingdeeInvoicePoolId,
|
||||
invoiceNo: this.form.invoiceNo,
|
||||
invoiceDate: this.form.invoiceDate,
|
||||
invoiceType: this.form.invoiceType,
|
||||
@@ -720,8 +514,6 @@ export default {
|
||||
bankName: this.form.bankName,
|
||||
bankAccount: this.form.bankAccount,
|
||||
issuingBank: this.form.issuingBank,
|
||||
kingdeeBillNo: this.form.kingdeeBillNo,
|
||||
kingdeeStatus: this.form.kingdeeStatus,
|
||||
phone: this.form.phone,
|
||||
customerEmails: this.form.customerEmails.join(';'),
|
||||
departmentEmails: this.form.departmentEmails.join(';'),
|
||||
@@ -758,13 +550,12 @@ 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);
|
||||
const data = this.unwrapData(
|
||||
await api.queryInvoicePool({ current: 1, size: 1, invoiceNo: this.form.invoiceNo })
|
||||
);
|
||||
const invoice = (data.records || []).find(item => item.invoiceNo === this.form.invoiceNo);
|
||||
if (!invoice) {
|
||||
this.$message.warning('金蝶票据池中未查询到该发票');
|
||||
this.$message.warning('金蝶票池未查询到该发票');
|
||||
return;
|
||||
}
|
||||
if (!this.confirmInvoice(invoice, { preserveUserInput: true })) return;
|
||||
@@ -827,11 +618,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;
|
||||
}
|
||||
|
||||
@@ -40,10 +40,10 @@
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="searchExpanded" label="金蝶单据状态">
|
||||
<el-select v-model="query.kingdeeStatus" clearable placeholder="请选择">
|
||||
<el-form-item v-if="searchExpanded" label="金蝶状态">
|
||||
<el-select v-model="query.kingdeePushStatus" clearable placeholder="请选择">
|
||||
<el-option
|
||||
v-for="item in kingdeeStatusOptions"
|
||||
v-for="item in kingdeePushStatusOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
@@ -70,7 +70,7 @@
|
||||
v-if="hasPermission('invoice_receipt_sync')"
|
||||
type="primary"
|
||||
plain
|
||||
@click="handleBatchSync"
|
||||
@click="handlePushKingdee"
|
||||
>批量同步</el-button
|
||||
>
|
||||
<el-button v-if="hasPermission('invoice_receipt_add')" type="primary" @click="openCreate"
|
||||
@@ -244,7 +244,7 @@ const emptyQuery = () => ({
|
||||
deptName: '',
|
||||
deptPath: [],
|
||||
approvalStatus: '',
|
||||
kingdeeStatus: '',
|
||||
kingdeePushStatus: '',
|
||||
});
|
||||
|
||||
export default {
|
||||
@@ -258,7 +258,7 @@ export default {
|
||||
query: emptyQuery(),
|
||||
searchExpanded: false,
|
||||
approvalStatusOptions: api.approvalStatusOptions,
|
||||
kingdeeStatusOptions: api.kingdeeStatusOptions,
|
||||
kingdeePushStatusOptions: api.kingdeePushStatusOptions,
|
||||
columns: invoiceReceiptTableColumns,
|
||||
rows: [],
|
||||
selection: [],
|
||||
@@ -363,14 +363,17 @@ export default {
|
||||
this.$message.success('作废成功');
|
||||
this.loadTable();
|
||||
},
|
||||
async handleBatchSync() {
|
||||
async handlePushKingdee() {
|
||||
const rows = this.selection.filter(row => row.approvalStatus === 'approved');
|
||||
if (!rows.length) {
|
||||
this.$message.warning('请选择至少一条审批通过的收票登记');
|
||||
return;
|
||||
}
|
||||
await Promise.all(rows.map(row => api.syncKingdee(row.id)));
|
||||
this.$message.success(`已同步${rows.length}条收票登记`);
|
||||
await this.$confirm(`确认将选中的 ${rows.length} 条收票登记同步至金蝶?`, '提示', {
|
||||
type: 'warning',
|
||||
});
|
||||
const summary = this.unwrapData(await api.pushKingdee(rows.map(row => row.id)));
|
||||
this.$alert(summary || '推送完成', '推送结果', { confirmButtonText: '知道了' });
|
||||
this.loadTable();
|
||||
},
|
||||
async handleExport() {
|
||||
@@ -388,8 +391,9 @@ export default {
|
||||
当前处理人: item.currentProcessor,
|
||||
创建人: item.createUserName,
|
||||
创建时间: item.createTime,
|
||||
金蝶单据号: item.kingdeeBillNo,
|
||||
金蝶单据状态: item.kingdeeStatusName,
|
||||
金蝶单据号: item.kingdeeReceivedInvoiceNo,
|
||||
金蝶状态: item.kingdeePushStatusName,
|
||||
失败原因: item.kingdeePushMsg,
|
||||
}));
|
||||
const workbook = XLSX.utils.book_new();
|
||||
XLSX.utils.book_append_sheet(workbook, XLSX.utils.json_to_sheet(exportRows), '收票登记');
|
||||
|
||||
@@ -412,126 +412,15 @@
|
||||
</el-table>
|
||||
</section-card>
|
||||
|
||||
<el-dialog
|
||||
<kingdee-invoice-pool-dialog
|
||||
v-model="invoiceClaimDialog.visible"
|
||||
title="查询可认领发票"
|
||||
width="92%"
|
||||
append-to-body
|
||||
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
|
||||
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>
|
||||
confirm-text="确认认领"
|
||||
multiple
|
||||
:initial-invoice-no="String(invoiceClaimNo || '').trim()"
|
||||
:query-api="invoicePoolQueryApi"
|
||||
@confirm="handleInvoiceClaimConfirm"
|
||||
/>
|
||||
|
||||
<section-card
|
||||
v-if="readonly"
|
||||
@@ -1026,11 +915,12 @@ import { h } from 'vue';
|
||||
import { InfoFilled } from '@element-plus/icons-vue';
|
||||
import { mapGetters } from 'vuex';
|
||||
import { downloadFileByUrl } from '@/utils/util';
|
||||
import KingdeeInvoicePoolDialog from '@/components/kingdee-invoice-pool-dialog/main.vue';
|
||||
import * as XLSX from 'xlsx';
|
||||
|
||||
export default {
|
||||
name: 'FormalSettlementEditor',
|
||||
components: { InfoFilled },
|
||||
components: { InfoFilled, KingdeeInvoicePoolDialog },
|
||||
props: {
|
||||
modelValue: Boolean,
|
||||
recordId: [String, Number],
|
||||
@@ -1062,25 +952,9 @@ export default {
|
||||
invoiceClaimLoading: false,
|
||||
invoiceClaimDialog: {
|
||||
visible: false,
|
||||
loading: false,
|
||||
confirming: false,
|
||||
rows: [],
|
||||
selected: [],
|
||||
page: { current: 1, size: 10, total: 0 },
|
||||
query: {
|
||||
invoiceNo: '',
|
||||
invoiceDateRange: [],
|
||||
salerTaxNo: '',
|
||||
buyerTaxNo: '',
|
||||
expenseStatus: '',
|
||||
},
|
||||
confirming: false,
|
||||
},
|
||||
expenseStatusOptions: [
|
||||
{ value: '1', label: '未用' },
|
||||
{ value: '30', label: '在用' },
|
||||
{ value: '60', label: '已用' },
|
||||
{ value: '65', label: '已入账' },
|
||||
],
|
||||
attachmentUploadFiles: [],
|
||||
attachmentTypeOptions: [],
|
||||
attachmentFileTypes: [
|
||||
@@ -1300,15 +1174,7 @@ export default {
|
||||
this.invoices = [];
|
||||
this.invoiceClaimNo = '';
|
||||
this.invoiceClaimDialog.visible = false;
|
||||
this.invoiceClaimDialog.rows = [];
|
||||
this.invoiceClaimDialog.selected = [];
|
||||
this.invoiceClaimDialog.query = {
|
||||
invoiceNo: '',
|
||||
invoiceDateRange: [],
|
||||
salerTaxNo: '',
|
||||
buyerTaxNo: '',
|
||||
expenseStatus: '',
|
||||
};
|
||||
this.attachmentUploadFiles = [];
|
||||
this.billingRuleDialog = {
|
||||
visible: false,
|
||||
@@ -2300,50 +2166,18 @@ export default {
|
||||
}
|
||||
},
|
||||
openInvoiceClaimDialog() {
|
||||
this.invoiceClaimDialog.query.invoiceNo = String(this.invoiceClaimNo || '').trim();
|
||||
this.invoiceClaimDialog.visible = true;
|
||||
this.handleInvoiceClaimQuery();
|
||||
},
|
||||
handleInvoiceClaimQuery() {
|
||||
this.invoiceClaimDialog.page.current = 1;
|
||||
this.loadInvoiceClaims();
|
||||
invoicePoolQueryApi(params) {
|
||||
return queryInvoicePool(params);
|
||||
},
|
||||
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;
|
||||
}
|
||||
async handleInvoiceClaimConfirm(rows) {
|
||||
// 统一票池行附件字段为复数 attachmentsJson,认领请求契约是单数 attachmentJson,中转处归一
|
||||
this.invoiceClaimDialog.selected = rows.map(row => ({
|
||||
...row,
|
||||
attachmentJson: row.attachmentJson || row.attachmentsJson,
|
||||
}));
|
||||
await this.confirmInvoiceClaims();
|
||||
},
|
||||
async confirmInvoiceClaims() {
|
||||
if (!this.invoiceClaimDialog.selected.length) {
|
||||
|
||||
Reference in New Issue
Block a user