From 9162b0a8432ff8303352f6d611d4b9e806737b21 Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Wed, 13 May 2026 16:33:21 +0800 Subject: [PATCH] 11 --- .../wallet-recharge-invoice/print-dialog.vue | 89 ++++++++++++++----- 1 file changed, 66 insertions(+), 23 deletions(-) diff --git a/src/views/wallet/wallet-recharge-invoice/print-dialog.vue b/src/views/wallet/wallet-recharge-invoice/print-dialog.vue index 59862a5..9f2f20e 100644 --- a/src/views/wallet/wallet-recharge-invoice/print-dialog.vue +++ b/src/views/wallet/wallet-recharge-invoice/print-dialog.vue @@ -117,7 +117,6 @@ import { formatDate } from "/@/utils/formatTime" import { displayPrice } from "/@/utils/formatMoney" import printJS from "print-js" import * as WalletRechargeInvoiceApi from "/@/api/wallet/wallet-recharge-invoice" -import { useDict } from "/@/hooks/dict" interface ReceiptData { id: string @@ -138,8 +137,7 @@ interface ReceiptData { const emit = defineEmits(["refresh"]) -const { check_status } = useDict("check_status") -let timer +let timer: ReturnType | null = null const visible = ref(false) const loading = ref(false) const refreshLoading = ref(false) @@ -178,6 +176,7 @@ const openDialog = (data: ReceiptData, id: string) => { visible.value = true receiptData.value = data receiptData.value.id = id + if (timer) clearTimeout(timer) timer = setTimeout(() => { deptOrUserInput.value?.focus() }, 50) @@ -185,6 +184,7 @@ const openDialog = (data: ReceiptData, id: string) => { const handleClose = () => { visible.value = false + if (timer) clearTimeout(timer) timer = null } @@ -201,7 +201,7 @@ const refreshInvoice = async () => { visibleStampPic.value = false // 申请审批 const blob = await genImage() - await new Promise((resolve) => setTimeout(resolve, 3000)) + await new Promise((resolve) => setTimeout(resolve, 1000)) if (!blob) return useMessage().error("图片生成失败") const picUrl = await uploadImage(blob) if (!picUrl) return useMessage().error("图片上传失败") @@ -241,23 +241,62 @@ const backInvoice = async () => { } // 生成图片 -const genImage = async (): Promise => { - if (receiptRef.value) { - const blob = await htmlToImage - .toBlob(receiptRef.value, { - canvasWidth: 661.5, - canvasHeight: 359.1, - backgroundColor: "#ffffff", - pixelRatio: 6, - }) - .catch((error) => { - console.error(error) - return useMessage().error("图片生成错误") - }) - return blob +const waitForFrames = async (count: number) => { + for (let i = 0; i < count; i += 1) { + await new Promise((resolve) => requestAnimationFrame(() => resolve())) } } +const captureFilter = (node: Node) => { + if (!(node instanceof HTMLElement)) return true + if (node.classList.contains("el-loading-mask")) return false + if (node.classList.contains("el-loading-spinner")) return false + return true +} + +const withReceiptCaptureStyle = async (fn: () => Promise) => { + const el = receiptRef.value + if (!el) return fn() + + const prevBackgroundColor = el.style.backgroundColor + const prevTransition = el.style.transition + const prevOpacity = el.style.opacity + + el.style.backgroundColor = "#ffffff" + el.style.transition = "none" + el.style.opacity = "1" + + await waitForFrames(2) + + try { + return await fn() + } finally { + el.style.backgroundColor = prevBackgroundColor + el.style.transition = prevTransition + el.style.opacity = prevOpacity + } +} + +const genImage = async (): Promise => { + if (!receiptRef.value) return + + const blob = await withReceiptCaptureStyle(async () => { + await new Promise((resolve) => setTimeout(resolve, 120)) + return await htmlToImage.toBlob(receiptRef.value!, { + canvasWidth: 661.5, + canvasHeight: 359.1, + backgroundColor: "#ffffff", + pixelRatio: 3, + filter: captureFilter, + }) + }).catch((error) => { + console.error(error) + return useMessage().error("图片生成错误") + }) + + return blob +} + // 图片上传 const uploadImage = async (blob: Blob): Promise => { const formData = new FormData() @@ -337,11 +376,15 @@ const applyStamp = async () => { // 打印 const handlePrint = async () => { if (receiptRef.value) { - const pngBase64 = await htmlToImage.toPng(receiptRef.value, { - canvasWidth: 661.5, - canvasHeight: 359.1, - pixelRatio: 10, - backgroundColor: "#ffffff", + const pngBase64 = await withReceiptCaptureStyle(async () => { + await new Promise((resolve) => setTimeout(resolve, 120)) + return await htmlToImage.toPng(receiptRef.value!, { + canvasWidth: 661.5, + canvasHeight: 359.1, + pixelRatio: 4, + backgroundColor: "#ffffff", + filter: captureFilter, + }) }) printJS({ printable: pngBase64, type: "image", targetStyles: ["*"], maxWidth: 661.5 }) }