91 lines
3.4 KiB
JavaScript
91 lines
3.4 KiB
JavaScript
/**
|
||
* 金蝶侧发票附件查看/下载公共工具
|
||
*
|
||
* 票池发票附件为 {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 || '金蝶附件预览失败');
|
||
}
|
||
};
|