Merge remote-tracking branch 'origin/feature/kingdee-attachment-sync' into feature/bfi-api-rate
# Conflicts: # src/api/payment/invoiceApplication.js # src/api/payment/invoiceReceipt.js # src/api/payment/paymentApplication.js # src/api/settlement/formalSettlement.js # src/views/payment/invoice-application.vue # src/views/payment/invoice-receipt.vue # src/views/payment/payment-application-form.vue # src/views/payment/payment-application.vue # src/views/settlement/formal-settlement.vue
This commit is contained in:
@@ -7,6 +7,15 @@ export const getList = (current, size, params) =>
|
||||
export const getDetail = id => request({ url: `${baseUrl}/detail`, method: 'get', params: { id } });
|
||||
export const queryInvoicePool = params =>
|
||||
request({ url: `${baseUrl}/invoice-pool`, method: 'get', params });
|
||||
export const downloadInvoicePoolAttachment = invoiceNo =>
|
||||
// 金蝶票池发票文件下载(后端代理 A801-2 流式回源),耗时较普通接口长,放宽到 120s
|
||||
request({
|
||||
url: `${baseUrl}/invoice-pool/attachment/download`,
|
||||
method: 'get',
|
||||
params: { invoiceNo },
|
||||
responseType: 'blob',
|
||||
timeout: 120000,
|
||||
});
|
||||
export const getSettlementCandidates = (keyword, receiptId) =>
|
||||
request({
|
||||
url: `${baseUrl}/settlement-candidates`,
|
||||
|
||||
@@ -16,10 +16,13 @@ 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 });
|
||||
// 同步金蝶涉及多次金蝶远程接口调用(A103-2 预检 + A103-1/A103-3 推送),单笔可达 20s+,覆盖全局 10s 超时
|
||||
export const syncKingdee = id =>
|
||||
request({ url: `${baseUrl}/sync-kingdee`, method: 'post', timeout: 30000, params: { id } });
|
||||
// 批量同步逐单单据级事务串行推送,耗时随单量线性增长
|
||||
export const syncKingdeeBatch = ids =>
|
||||
request({ url: `${baseUrl}/sync-kingdee-batch`, method: 'post', timeout: 30000, data: ids });
|
||||
// 回写任务按 paymentNo 分批远程查询 A103-2/A103-4,同样可能超过全局超时
|
||||
export const syncKingdeeResult = () =>
|
||||
request({ url: `${baseUrl}/sync-kingdee-result`, method: 'post', timeout: 30000 });
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ 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 });
|
||||
// 同步金蝶涉及多次金蝶远程接口调用(A102-4 预检 + A102-2 保存),可达 20s+,覆盖全局 10s 超时
|
||||
export const syncKingdee = id =>
|
||||
request({ url: `${baseUrl}/sync-kingdee`, method: 'post', timeout: 30000, params: { id } });
|
||||
export const getDetailFees = detailId =>
|
||||
|
||||
@@ -104,6 +104,24 @@
|
||||
<el-tag v-else type="info" size="small">未登记</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="附件" width="120" fixed="right" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-link
|
||||
type="primary"
|
||||
:underline="false"
|
||||
:disabled="attachmentBusy === row.invoiceNo"
|
||||
@click.stop="viewAttachment(row)"
|
||||
>查看</el-link
|
||||
>
|
||||
<el-link
|
||||
type="primary"
|
||||
:underline="false"
|
||||
:disabled="attachmentBusy === row.invoiceNo"
|
||||
@click.stop="downloadAttachment(row)"
|
||||
>下载</el-link
|
||||
>
|
||||
</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>
|
||||
@@ -126,6 +144,12 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
downloadKingdeeInvoiceFile,
|
||||
isKingdeePathAttachment,
|
||||
viewKingdeeInvoiceFile,
|
||||
} from '@/utils/kingdee-attachment';
|
||||
|
||||
export default {
|
||||
name: 'KingdeeInvoicePoolDialog',
|
||||
props: {
|
||||
@@ -156,6 +180,8 @@ export default {
|
||||
pendingCursor: null,
|
||||
// 已浏览页缓存:上一页直接回显不再请求(0 远程调用)
|
||||
pageCache: {},
|
||||
// 正在查看/下载附件的发票号(行级 loading 守卫)
|
||||
attachmentBusy: null,
|
||||
query: this.emptyQuery(),
|
||||
};
|
||||
},
|
||||
@@ -184,6 +210,50 @@ export default {
|
||||
rowKey(row) {
|
||||
return row.invoiceNo || row.id;
|
||||
},
|
||||
// 票池行附件字段为复数 attachmentsJson,行内首项即发票文件({source,path,name})
|
||||
rowAttachment(row = {}) {
|
||||
const value = row.attachmentsJson;
|
||||
if (!value) return null;
|
||||
let parsed = value;
|
||||
if (typeof value === 'string') {
|
||||
try {
|
||||
parsed = JSON.parse(value);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return Array.isArray(parsed) ? parsed[0] || null : parsed || null;
|
||||
},
|
||||
attachmentName(row) {
|
||||
const attachment = this.rowAttachment(row);
|
||||
return attachment?.name || `${row.invoiceNo || '发票'}.pdf`;
|
||||
},
|
||||
async viewAttachment(row) {
|
||||
const attachment = this.rowAttachment(row);
|
||||
if (!isKingdeePathAttachment(attachment)) {
|
||||
this.$message.warning('当前发票暂无可查看附件');
|
||||
return;
|
||||
}
|
||||
this.attachmentBusy = row.invoiceNo;
|
||||
try {
|
||||
await viewKingdeeInvoiceFile(row.invoiceNo, this.attachmentName(row));
|
||||
} finally {
|
||||
this.attachmentBusy = null;
|
||||
}
|
||||
},
|
||||
async downloadAttachment(row) {
|
||||
const attachment = this.rowAttachment(row);
|
||||
if (!isKingdeePathAttachment(attachment)) {
|
||||
this.$message.warning('当前发票暂无可下载附件');
|
||||
return;
|
||||
}
|
||||
this.attachmentBusy = row.invoiceNo;
|
||||
try {
|
||||
await downloadKingdeeInvoiceFile(row.invoiceNo, this.attachmentName(row));
|
||||
} finally {
|
||||
this.attachmentBusy = null;
|
||||
}
|
||||
},
|
||||
handleOpen() {
|
||||
this.query = this.emptyQuery();
|
||||
this.query.invoiceNo = this.initialInvoiceNo || '';
|
||||
|
||||
@@ -13,6 +13,7 @@ export const invoiceApplicationTableColumns = [
|
||||
{ prop: 'currentProcessor', label: '当前处理人', minWidth: 130 },
|
||||
{ prop: 'kingdeeBillNo', label: '金蝶单据号', minWidth: 150 },
|
||||
{ prop: 'kingdeeStatusName', label: '金蝶单据状态', minWidth: 140 },
|
||||
{ prop: 'attachmentSyncStatusName', label: '附件同步', minWidth: 100 },
|
||||
];
|
||||
|
||||
export const invoiceApplicationDetailColumns = [
|
||||
|
||||
@@ -14,4 +14,5 @@ export const invoiceReceiptTableColumns = [
|
||||
{ prop: 'kingdeeReceivedInvoiceNo', label: '金蝶单据号', minWidth: 150 },
|
||||
{ prop: 'kingdeePushStatusName', label: '金蝶状态', minWidth: 130 },
|
||||
{ prop: 'kingdeePushMsg', label: '失败原因', minWidth: 160 },
|
||||
{ prop: 'attachmentSyncStatusName', label: '附件同步', minWidth: 100 },
|
||||
];
|
||||
|
||||
@@ -17,4 +17,5 @@ export const paymentApplicationTableColumns = [
|
||||
{ prop: 'currentProcessor', label: '当前处理人', minWidth: 120 },
|
||||
{ prop: 'kingdeeBillNo', label: '金蝶单据号', minWidth: 130 },
|
||||
{ prop: 'kingdeeStatusName', label: '金蝶单据状态', minWidth: 130 },
|
||||
{ prop: 'attachmentSyncStatusName', label: '附件同步', minWidth: 100 },
|
||||
];
|
||||
|
||||
@@ -21,6 +21,7 @@ export const formalSettlementTableColumns = [
|
||||
{ label: '当前处理人', prop: 'currentProcessor', minWidth: 130 },
|
||||
{ label: '金蝶单据号', prop: 'kingdeeBillNo', minWidth: 150 },
|
||||
{ label: '金蝶单据状态', prop: 'kingdeeSyncStatus', minWidth: 135 },
|
||||
{ label: '附件同步', prop: 'attachmentSyncStatusName', minWidth: 100 },
|
||||
{ label: '创建人', prop: 'createUserName', minWidth: 110 },
|
||||
{ label: '创建时间', prop: 'createTime', minWidth: 170 },
|
||||
];
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* 金蝶侧发票附件查看/下载公共工具
|
||||
*
|
||||
* 票池发票附件为 {source:'piaozone', path, name}:path 是金蝶侧文件 id(非 http 直链),
|
||||
* 须由后端代理 A801-2 流式回源;OSS 直链附件(url/link/fileUrl)仍由前端直连下载/预览。
|
||||
* 三处入口共用:票池弹窗、正式结算认领发票行、付款申请发票附件行。
|
||||
*/
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { downloadFile } from '@/utils/util';
|
||||
import { downloadInvoicePoolAttachment } from '@/api/payment/invoiceReceipt';
|
||||
|
||||
/**
|
||||
* 金蝶侧附件判定:source=piaozone,或有 path 且非 http(s) 直链
|
||||
* @param {Object|Null} attachment 附件对象(attachmentsJson/attachmentJson 行内首项)
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export const isKingdeePathAttachment = attachment => {
|
||||
if (!attachment) return false;
|
||||
if (attachment.source === 'piaozone') return true;
|
||||
return Boolean(attachment.path) && !/^https?:\/\//i.test(attachment.path);
|
||||
};
|
||||
|
||||
/**
|
||||
* 请求金蝶文件流:成功返回 Blob;业务失败为 HTTP 200 + R.fail JSON(响应通道未写流时后端即失败),
|
||||
* 按 Content-Type 识别并抛出带 msg 的错误;网络级失败拦截器已提示,标记 silent 避免重复提示
|
||||
* @param {String} invoiceNo 发票号码
|
||||
* @returns {Promise<Blob>}
|
||||
*/
|
||||
const requestKingdeeFile = async invoiceNo => {
|
||||
let res;
|
||||
try {
|
||||
res = await downloadInvoicePoolAttachment(invoiceNo);
|
||||
} catch (error) {
|
||||
throw Object.assign(new Error(error?.message || '附件下载失败'), { silent: true });
|
||||
}
|
||||
const blob = res?.data;
|
||||
if (!(blob instanceof Blob)) {
|
||||
throw new Error('响应不是文件流');
|
||||
}
|
||||
if (blob.type && blob.type.includes('application/json')) {
|
||||
let message = '附件下载失败';
|
||||
try {
|
||||
const parsed = JSON.parse(await blob.text());
|
||||
message = parsed.msg || parsed.message || message;
|
||||
} catch {
|
||||
// 错误体非 JSON 时按默认提示
|
||||
}
|
||||
throw new Error(message);
|
||||
}
|
||||
return blob;
|
||||
};
|
||||
|
||||
/**
|
||||
* 下载金蝶侧发票附件(经 A801-2 后端代理),失败统一 ElMessage 提示
|
||||
* @param {String} invoiceNo 发票号码
|
||||
* @param {String} fileName 下载文件名(缺省按 发票号.pdf)
|
||||
*/
|
||||
export const downloadKingdeeInvoiceFile = async (invoiceNo, fileName) => {
|
||||
if (!invoiceNo) {
|
||||
ElMessage.warning('当前发票缺少发票号码,无法下载金蝶侧附件');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const blob = await requestKingdeeFile(invoiceNo);
|
||||
downloadFile(blob, fileName || `${invoiceNo}.pdf`);
|
||||
} catch (error) {
|
||||
if (!error?.silent) ElMessage.error(error?.message || '金蝶附件下载失败');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 新窗口预览金蝶侧发票附件:拉取 Blob 转 objectURL(PDF 可预览;OFD 等浏览器不可预览的格式由浏览器触发下载)
|
||||
* @param {String} invoiceNo 发票号码
|
||||
* @param {String} fileName 预览文件名(缺省按 发票号.pdf)
|
||||
*/
|
||||
export const viewKingdeeInvoiceFile = async (invoiceNo, fileName) => {
|
||||
if (!invoiceNo) {
|
||||
ElMessage.warning('当前发票缺少发票号码,无法预览金蝶侧附件');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const blob = await requestKingdeeFile(invoiceNo);
|
||||
const url = URL.createObjectURL(blob);
|
||||
window.open(url, '_blank');
|
||||
// 延迟释放 objectURL:立即回收可能导致新窗口尚未加载完成即失效
|
||||
setTimeout(() => URL.revokeObjectURL(url), 60000);
|
||||
} catch (error) {
|
||||
if (!error?.silent) ElMessage.error(error?.message || '金蝶附件预览失败');
|
||||
}
|
||||
};
|
||||
@@ -411,7 +411,18 @@ export default {
|
||||
try {
|
||||
await Promise.all(rows.map(row => api.syncKingdee(row.id)));
|
||||
this.$message.success(`已同步${rows.length}条开票申请`);
|
||||
this.loadTable();
|
||||
await this.loadTable();
|
||||
// 附件联带同步提示:同步成功但附件未全部上传时追加 warning,重推即自动补传
|
||||
const idSet = new Set(rows.map(row => String(row.id)));
|
||||
const pendingCount = (this.rows || []).filter(row => idSet.has(String(row.id))
|
||||
&& ['pending', 'partial'].includes(row.attachmentSyncStatus)).length;
|
||||
if (pendingCount) {
|
||||
this.$message({
|
||||
type: 'warning',
|
||||
message: `其中${pendingCount}单附件未全部上传,可重推补传`,
|
||||
duration: 8000,
|
||||
});
|
||||
}
|
||||
} finally {
|
||||
this.batchSyncing = false;
|
||||
}
|
||||
|
||||
@@ -378,8 +378,13 @@ export default {
|
||||
this.pushLoading = true;
|
||||
try {
|
||||
const summary = this.unwrapData(await api.pushKingdee(rows.map(row => row.id)));
|
||||
this.$alert(summary || '推送完成', '推送结果', { confirmButtonText: '知道了' });
|
||||
this.loadTable();
|
||||
await this.loadTable();
|
||||
// 附件联带同步提示:推送成功但附件未全部上传时在结果弹窗追加说明,重推即自动补传
|
||||
const idSet = new Set(rows.map(row => String(row.id)));
|
||||
const pendingCount = (this.rows || []).filter(row => idSet.has(String(row.id))
|
||||
&& ['pending', 'partial'].includes(row.attachmentSyncStatus)).length;
|
||||
const attachmentTip = pendingCount ? `\n其中${pendingCount}单附件未全部上传,可重推补传` : '';
|
||||
this.$alert((summary || '推送完成') + attachmentTip, '推送结果', { confirmButtonText: '知道了' });
|
||||
} finally {
|
||||
this.pushLoading = false;
|
||||
}
|
||||
|
||||
@@ -281,8 +281,18 @@
|
||||
<el-table-column label="操作" width="220" fixed="right" align="center">
|
||||
<template #default="{ row, $index }">
|
||||
<div class="payment-form-page__invoice-actions">
|
||||
<el-link type="primary" @click="viewInvoiceAttachment(row)">查看</el-link>
|
||||
<el-link type="primary" @click="downloadInvoiceAttachment(row)">下载</el-link>
|
||||
<el-link
|
||||
type="primary"
|
||||
:disabled="kingdeeAttachmentBusy"
|
||||
@click="viewInvoiceAttachment(row)"
|
||||
>查看</el-link
|
||||
>
|
||||
<el-link
|
||||
type="primary"
|
||||
:disabled="kingdeeAttachmentBusy"
|
||||
@click="downloadInvoiceAttachment(row)"
|
||||
>下载</el-link
|
||||
>
|
||||
<el-link
|
||||
v-if="!readonly"
|
||||
type="danger"
|
||||
@@ -663,6 +673,11 @@ import {
|
||||
import { readSettlementTransfer, removeSettlementTransfer } from '@/utils/settlement-transfer';
|
||||
import { downloadFileByUrl } from '@/utils/util';
|
||||
import { submitMkApprovalFlow } from '@/utils/mk-approval';
|
||||
import {
|
||||
downloadKingdeeInvoiceFile,
|
||||
isKingdeePathAttachment,
|
||||
viewKingdeeInvoiceFile,
|
||||
} from '@/utils/kingdee-attachment';
|
||||
import PdfPreview from '@/components/pdf-preview/main.vue';
|
||||
|
||||
const attachmentViewerPlugins = [
|
||||
@@ -743,6 +758,8 @@ export default {
|
||||
form: emptyForm(),
|
||||
amountSyncing: false,
|
||||
transferPayload: null,
|
||||
// 金蝶侧发票附件查看/下载进行中(行组级 loading 守卫)
|
||||
kingdeeAttachmentBusy: false,
|
||||
referenceRows: [],
|
||||
paymentRecords: [],
|
||||
referenceVisible: false,
|
||||
@@ -1584,8 +1601,19 @@ export default {
|
||||
this.attachmentFileName(this.invoiceAttachment(row)) || `${row.invoiceNo || '发票'}.pdf`
|
||||
);
|
||||
},
|
||||
viewInvoiceAttachment(row) {
|
||||
async viewInvoiceAttachment(row) {
|
||||
const attachment = this.invoiceAttachment(row);
|
||||
// 金蝶侧附件(path 型)经后端代理 A801-2 预览,OSS 直链维持本地预览组件
|
||||
if (isKingdeePathAttachment(attachment)) {
|
||||
if (this.kingdeeAttachmentBusy) return;
|
||||
this.kingdeeAttachmentBusy = true;
|
||||
try {
|
||||
await viewKingdeeInvoiceFile(row.invoiceNo, this.invoiceAttachmentName(row));
|
||||
} finally {
|
||||
this.kingdeeAttachmentBusy = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!this.attachmentFileUrl(attachment)) {
|
||||
this.$message.warning('当前发票暂无可查看附件');
|
||||
return;
|
||||
@@ -1595,8 +1623,20 @@ export default {
|
||||
[attachment]
|
||||
);
|
||||
},
|
||||
downloadInvoiceAttachment(row) {
|
||||
const url = this.invoiceAttachmentUrl(row);
|
||||
async downloadInvoiceAttachment(row) {
|
||||
const attachment = this.invoiceAttachment(row);
|
||||
// 金蝶侧附件(path 型)经后端代理 A801-2 下载,OSS 直链维持前端直连下载
|
||||
if (isKingdeePathAttachment(attachment)) {
|
||||
if (this.kingdeeAttachmentBusy) return;
|
||||
this.kingdeeAttachmentBusy = true;
|
||||
try {
|
||||
await downloadKingdeeInvoiceFile(row.invoiceNo, this.invoiceAttachmentName(row));
|
||||
} finally {
|
||||
this.kingdeeAttachmentBusy = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
const url = this.attachmentFileUrl(attachment);
|
||||
if (!url) {
|
||||
this.$message.warning('当前发票暂无可下载附件');
|
||||
return;
|
||||
|
||||
@@ -406,7 +406,8 @@ export default {
|
||||
async handleSyncRow(row) {
|
||||
const data = this.unwrapData(await api.syncKingdee(row.id));
|
||||
this.$message.success(`已生成金蝶付款单:${data}`);
|
||||
this.loadTable();
|
||||
await this.loadTable();
|
||||
this.warnAttachmentNotUploaded([row.id]);
|
||||
},
|
||||
async handleSync() {
|
||||
if (this.syncLoading) return;
|
||||
@@ -428,11 +429,25 @@ export default {
|
||||
} else {
|
||||
this.$message.success(`已同步${data.length}条付款申请`);
|
||||
}
|
||||
this.loadTable();
|
||||
await this.loadTable();
|
||||
this.warnAttachmentNotUploaded(rows.map(row => row.id));
|
||||
} finally {
|
||||
this.syncLoading = false;
|
||||
}
|
||||
},
|
||||
// 附件联带同步提示:同步成功但附件未全部上传时追加 warning,重推即自动补传
|
||||
warnAttachmentNotUploaded(ids) {
|
||||
const idSet = new Set(ids.map(String));
|
||||
const pendingCount = (this.rows || []).filter(row => idSet.has(String(row.id))
|
||||
&& ['pending', 'partial'].includes(row.attachmentSyncStatus)).length;
|
||||
if (pendingCount) {
|
||||
this.$message({
|
||||
type: 'warning',
|
||||
message: `其中${pendingCount}单附件未全部上传,可重推补传`,
|
||||
duration: 8000,
|
||||
});
|
||||
}
|
||||
},
|
||||
async handleSyncResult() {
|
||||
if (this.resultSyncing) return;
|
||||
this.resultSyncing = true;
|
||||
|
||||
@@ -420,8 +420,18 @@
|
||||
<el-table-column label="操作" width="220" align="center">
|
||||
<template #default="{ row, $index }">
|
||||
<div class="formal-editor__links">
|
||||
<el-link type="primary" @click="viewInvoiceAttachment(row)">查看</el-link>
|
||||
<el-link type="primary" @click="downloadInvoiceAttachment(row)">下载</el-link>
|
||||
<el-link
|
||||
type="primary"
|
||||
:disabled="kingdeeAttachmentBusy"
|
||||
@click="viewInvoiceAttachment(row)"
|
||||
>查看</el-link
|
||||
>
|
||||
<el-link
|
||||
type="primary"
|
||||
:disabled="kingdeeAttachmentBusy"
|
||||
@click="downloadInvoiceAttachment(row)"
|
||||
>下载</el-link
|
||||
>
|
||||
<el-link v-if="editable" type="danger" @click="removeInvoice($index)">删除</el-link>
|
||||
</div>
|
||||
</template>
|
||||
@@ -933,6 +943,11 @@ import { h } from 'vue';
|
||||
import { InfoFilled } from '@element-plus/icons-vue';
|
||||
import { mapGetters } from 'vuex';
|
||||
import { downloadFileByUrl } from '@/utils/util';
|
||||
import {
|
||||
downloadKingdeeInvoiceFile,
|
||||
isKingdeePathAttachment,
|
||||
viewKingdeeInvoiceFile,
|
||||
} from '@/utils/kingdee-attachment';
|
||||
import KingdeeInvoicePoolDialog from '@/components/kingdee-invoice-pool-dialog/main.vue';
|
||||
import * as XLSX from 'xlsx';
|
||||
|
||||
@@ -972,6 +987,8 @@ export default {
|
||||
invoices: [],
|
||||
invoiceClaimNo: '',
|
||||
invoiceClaimLoading: false,
|
||||
// 金蝶侧发票附件查看/下载进行中(行组级 loading 守卫)
|
||||
kingdeeAttachmentBusy: false,
|
||||
invoiceClaimDialog: {
|
||||
visible: false,
|
||||
selected: [],
|
||||
@@ -2355,12 +2372,36 @@ export default {
|
||||
const attachment = this.invoiceAttachment(row);
|
||||
return attachment.originalName || attachment.name || `${row.invoiceNo || '发票'}.pdf`;
|
||||
},
|
||||
viewInvoiceAttachment(row) {
|
||||
async viewInvoiceAttachment(row) {
|
||||
const attachment = this.invoiceAttachment(row);
|
||||
// 金蝶侧附件(path 型)经后端代理 A801-2 预览,OSS 直链维持 window.open
|
||||
if (isKingdeePathAttachment(attachment)) {
|
||||
if (this.kingdeeAttachmentBusy) return;
|
||||
this.kingdeeAttachmentBusy = true;
|
||||
try {
|
||||
await viewKingdeeInvoiceFile(row.invoiceNo, this.invoiceAttachmentName(row));
|
||||
} finally {
|
||||
this.kingdeeAttachmentBusy = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
const url = this.invoiceAttachmentUrl(row);
|
||||
if (!url) return this.$message.warning('当前发票暂无可查看附件');
|
||||
window.open(url, '_blank');
|
||||
},
|
||||
downloadInvoiceAttachment(row) {
|
||||
async downloadInvoiceAttachment(row) {
|
||||
const attachment = this.invoiceAttachment(row);
|
||||
// 金蝶侧附件(path 型)经后端代理 A801-2 下载,OSS 直链维持前端直连下载
|
||||
if (isKingdeePathAttachment(attachment)) {
|
||||
if (this.kingdeeAttachmentBusy) return;
|
||||
this.kingdeeAttachmentBusy = true;
|
||||
try {
|
||||
await downloadKingdeeInvoiceFile(row.invoiceNo, this.invoiceAttachmentName(row));
|
||||
} finally {
|
||||
this.kingdeeAttachmentBusy = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
const url = this.invoiceAttachmentUrl(row);
|
||||
if (!url) return this.$message.warning('当前发票暂无可下载附件');
|
||||
downloadFileByUrl(url, this.invoiceAttachmentName(row));
|
||||
|
||||
@@ -387,12 +387,22 @@ export default {
|
||||
if (this.syncLoading) return;
|
||||
const row = this.selectedOne('同步金蝶');
|
||||
if (!row) return;
|
||||
|
||||
this.syncLoading = true;
|
||||
try {
|
||||
const response = await api.syncKingdee(row.id);
|
||||
const data = this.unwrapData(response);
|
||||
this.$message.success(`同步成功,金蝶单据号:${data}`);
|
||||
this.loadTable();
|
||||
await this.loadTable();
|
||||
// 附件联带同步提示:同步成功但附件未全部上传时追加 warning,重推即自动补传
|
||||
const freshRow = (this.rows || []).find(item => String(item.id) === String(row.id));
|
||||
if (freshRow && ['pending', 'partial'].includes(freshRow.attachmentSyncStatus)) {
|
||||
this.$message({
|
||||
type: 'warning',
|
||||
message: '该单附件未全部上传,可重推补传',
|
||||
duration: 8000,
|
||||
});
|
||||
}
|
||||
} finally {
|
||||
this.syncLoading = false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user