From 17240ec3691a29b2e6185949a5c8e2ebb1d2a499 Mon Sep 17 00:00:00 2001 From: "B.E.N.S.O.N" Date: Thu, 30 Apr 2026 14:56:19 +0800 Subject: [PATCH] QR Code Printing Update --- .../api/settings/equipmentDetail/client.ts | 26 +++++++++++++++ src/app/api/user/client.ts | 26 +++++++++++++++ src/app/api/warehouse/client.ts | 26 +++++++++++++++ .../qrCodeHandleEquipmentSearch.tsx | 32 ++++++------------- .../qrCodeHandles/qrCodeHandleSearch.tsx | 32 ++++++------------- .../qrCodeHandleWarehouseSearch.tsx | 32 ++++++------------- 6 files changed, 105 insertions(+), 69 deletions(-) diff --git a/src/app/api/settings/equipmentDetail/client.ts b/src/app/api/settings/equipmentDetail/client.ts index 8627b52..3ef2cac 100644 --- a/src/app/api/settings/equipmentDetail/client.ts +++ b/src/app/api/settings/equipmentDetail/client.ts @@ -31,3 +31,29 @@ export const exportEquipmentQrCode = async (equipmentDetailIds: number[]): Promi return { blobValue, filename }; }; + +export interface PrintEquipmentQrCodeRequest { + equipmentDetailIds: number[]; + printerId: number; + printQty?: number; +} + +export const printEquipmentQrCode = async (data: PrintEquipmentQrCodeRequest): Promise => { + const token = localStorage.getItem("accessToken"); + + const response = await fetch(`${NEXT_PUBLIC_API_URL}/Equipment/print-qrcode`, { + method: "POST", + headers: { + "Content-Type": "application/json", + ...(token && { Authorization: `Bearer ${token}` }), + }, + body: JSON.stringify(data), + }); + + if (!response.ok) { + if (response.status === 401) { + throw new Error("Unauthorized: Please log in again"); + } + throw new Error(`Failed to print QR code: ${response.status} ${response.statusText}`); + } +}; diff --git a/src/app/api/user/client.ts b/src/app/api/user/client.ts index ecfe62e..f07f7d6 100644 --- a/src/app/api/user/client.ts +++ b/src/app/api/user/client.ts @@ -32,6 +32,32 @@ export const exportUserQrCode = async (userIds: number[]): Promise<{ blobValue: return { blobValue, filename }; }; +export interface PrintUserQrCodeRequest { + userIds: number[]; + printerId: number; + printQty?: number; +} + +export const printUserQrCode = async (data: PrintUserQrCodeRequest): Promise => { + const token = localStorage.getItem("accessToken"); + + const response = await fetch(`${NEXT_PUBLIC_API_URL}/user/print-qrcode`, { + method: "POST", + headers: { + "Content-Type": "application/json", + ...(token && { Authorization: `Bearer ${token}` }), + }, + body: JSON.stringify(data), + }); + + if (!response.ok) { + if (response.status === 401) { + throw new Error("Unauthorized: Please log in again"); + } + throw new Error(`Failed to print QR code: ${response.status} ${response.statusText}`); + } +}; + export const searchUsersByUsernameOrName = async (searchTerm: string): Promise => { if (!searchTerm.trim()) { return []; diff --git a/src/app/api/warehouse/client.ts b/src/app/api/warehouse/client.ts index 526f09d..8d49b36 100644 --- a/src/app/api/warehouse/client.ts +++ b/src/app/api/warehouse/client.ts @@ -32,6 +32,32 @@ export const exportWarehouseQrCode = async (warehouseIds: number[]): Promise<{ b return { blobValue, filename }; }; +export interface PrintWarehouseQrCodeRequest { + warehouseIds: number[]; + printerId: number; + printQty?: number; +} + +export const printWarehouseQrCode = async (data: PrintWarehouseQrCodeRequest): Promise => { + const token = localStorage.getItem("accessToken"); + + const response = await fetch(`${NEXT_PUBLIC_API_URL}/warehouse/print-qrcode`, { + method: "POST", + headers: { + "Content-Type": "application/json", + ...(token && { Authorization: `Bearer ${token}` }), + }, + body: JSON.stringify(data), + }); + + if (!response.ok) { + if (response.status === 401) { + throw new Error("Unauthorized: Please log in again"); + } + throw new Error(`Failed to print QR code: ${response.status} ${response.statusText}`); + } +}; + export const fetchWarehouseListClient = async (): Promise => { const token = localStorage.getItem("accessToken"); diff --git a/src/components/qrCodeHandles/qrCodeHandleEquipmentSearch.tsx b/src/components/qrCodeHandles/qrCodeHandleEquipmentSearch.tsx index 212a28e..69c2ae9 100644 --- a/src/components/qrCodeHandles/qrCodeHandleEquipmentSearch.tsx +++ b/src/components/qrCodeHandles/qrCodeHandleEquipmentSearch.tsx @@ -9,7 +9,7 @@ import { successDialog } from "../Swal/CustomAlerts"; import useUploadContext from "../UploadProvider/useUploadContext"; import { downloadFile } from "@/app/utils/commonUtil"; import { EquipmentDetailResult } from "@/app/api/settings/equipmentDetail"; -import { exportEquipmentQrCode } from "@/app/api/settings/equipmentDetail/client"; +import { exportEquipmentQrCode, printEquipmentQrCode } from "@/app/api/settings/equipmentDetail/client"; import { Checkbox, Box, @@ -276,31 +276,17 @@ const QrCodeHandleEquipmentSearch: React.FC = ({ equipmentDetails, printe }, [setIsUploading, t]); const handlePrint = useCallback(async () => { - if (checkboxIds.length === 0) { + if (checkboxIds.length === 0 || !selectedPrinter) { return; } try { setIsUploading(true); const numericIds = checkboxIds.map(id => typeof id === 'string' ? parseInt(id) : id); - const response = await exportEquipmentQrCode(numericIds); - - const blob = new Blob([new Uint8Array(response.blobValue)], { type: "application/pdf" }); - const url = URL.createObjectURL(blob); - - const printWindow = window.open(url, '_blank'); - if (printWindow) { - printWindow.onload = () => { - for (let i = 0; i < printQty; i++) { - setTimeout(() => { - printWindow.print(); - }, i * 500); - } - }; - } - - setTimeout(() => { - URL.revokeObjectURL(url); - }, 1000); + await printEquipmentQrCode({ + equipmentDetailIds: numericIds, + printerId: selectedPrinter.id, + printQty, + }); setSelectedEquipmentDetailsModalOpen(false); successDialog("二維碼已列印", t); } catch (error) { @@ -308,7 +294,7 @@ const QrCodeHandleEquipmentSearch: React.FC = ({ equipmentDetails, printe } finally { setIsUploading(false); } - }, [checkboxIds, printQty, setIsUploading, t]); + }, [checkboxIds, printQty, selectedPrinter, setIsUploading, t]); const handleViewSelectedQrCodes = useCallback(() => { if (checkboxIds.length === 0) { @@ -530,7 +516,7 @@ const QrCodeHandleEquipmentSearch: React.FC = ({ equipmentDetails, printe variant="contained" startIcon={} onClick={handlePrint} - disabled={checkboxIds.length === 0 || filteredPrinters.length === 0} + disabled={checkboxIds.length === 0 || filteredPrinters.length === 0 || !selectedPrinter} color="primary" > 列印 diff --git a/src/components/qrCodeHandles/qrCodeHandleSearch.tsx b/src/components/qrCodeHandles/qrCodeHandleSearch.tsx index 7c95170..c5dbaf9 100644 --- a/src/components/qrCodeHandles/qrCodeHandleSearch.tsx +++ b/src/components/qrCodeHandles/qrCodeHandleSearch.tsx @@ -12,7 +12,7 @@ import { downloadFile } from "@/app/utils/commonUtil"; import { UserResult } from "@/app/api/user"; import { deleteUser } from "@/app/api/user/actions"; import QrCodeIcon from "@mui/icons-material/QrCode"; -import { exportUserQrCode, searchUsersByUsernameOrName } from "@/app/api/user/client"; +import { exportUserQrCode, printUserQrCode, searchUsersByUsernameOrName } from "@/app/api/user/client"; import { Checkbox, Box, @@ -171,30 +171,16 @@ const QrCodeHandleSearch: React.FC = ({ users, printerCombo }) => { }, [setIsUploading, t]); const handlePrint = useCallback(async () => { - if (checkboxIds.length === 0) { + if (checkboxIds.length === 0 || !selectedPrinter) { return; } try { setIsUploading(true); - const response = await exportUserQrCode(checkboxIds); - - const blob = new Blob([new Uint8Array(response.blobValue)], { type: "application/pdf" }); - const url = URL.createObjectURL(blob); - - const printWindow = window.open(url, '_blank'); - if (printWindow) { - printWindow.onload = () => { - for (let i = 0; i < printQty; i++) { - setTimeout(() => { - printWindow.print(); - }, i * 500); - } - }; - } - - setTimeout(() => { - URL.revokeObjectURL(url); - }, 1000); + await printUserQrCode({ + userIds: checkboxIds, + printerId: selectedPrinter.id, + printQty, + }); setSelectedUsersModalOpen(false); successDialog("二維碼已列印", t); } catch (error) { @@ -202,7 +188,7 @@ const QrCodeHandleSearch: React.FC = ({ users, printerCombo }) => { } finally { setIsUploading(false); } - }, [checkboxIds, printQty, setIsUploading, t]); + }, [checkboxIds, printQty, selectedPrinter, setIsUploading, t]); const handleViewSelectedQrCodes = useCallback(() => { if (checkboxIds.length === 0) { @@ -451,7 +437,7 @@ const QrCodeHandleSearch: React.FC = ({ users, printerCombo }) => { variant="contained" startIcon={} onClick={handlePrint} - disabled={checkboxIds.length === 0 || filteredPrinters.length === 0} + disabled={checkboxIds.length === 0 || filteredPrinters.length === 0 || !selectedPrinter} color="primary" > 列印 diff --git a/src/components/qrCodeHandles/qrCodeHandleWarehouseSearch.tsx b/src/components/qrCodeHandles/qrCodeHandleWarehouseSearch.tsx index 51f3efc..19d5905 100644 --- a/src/components/qrCodeHandles/qrCodeHandleWarehouseSearch.tsx +++ b/src/components/qrCodeHandles/qrCodeHandleWarehouseSearch.tsx @@ -7,7 +7,7 @@ import { successDialog } from "../Swal/CustomAlerts"; import useUploadContext from "../UploadProvider/useUploadContext"; import { downloadFile } from "@/app/utils/commonUtil"; import { WarehouseResult } from "@/app/api/warehouse"; -import { exportWarehouseQrCode } from "@/app/api/warehouse/client"; +import { exportWarehouseQrCode, printWarehouseQrCode } from "@/app/api/warehouse/client"; import { Checkbox, Box, @@ -254,30 +254,16 @@ const QrCodeHandleWarehouseSearch: React.FC = ({ warehouses, printerCombo }, [setIsUploading, t]); const handlePrint = useCallback(async () => { - if (checkboxIds.length === 0) { + if (checkboxIds.length === 0 || !selectedPrinter) { return; } try { setIsUploading(true); - const response = await exportWarehouseQrCode(checkboxIds); - - const blob = new Blob([new Uint8Array(response.blobValue)], { type: "application/pdf" }); - const url = URL.createObjectURL(blob); - - const printWindow = window.open(url, '_blank'); - if (printWindow) { - printWindow.onload = () => { - for (let i = 0; i < printQty; i++) { - setTimeout(() => { - printWindow.print(); - }, i * 500); - } - }; - } - - setTimeout(() => { - URL.revokeObjectURL(url); - }, 1000); + await printWarehouseQrCode({ + warehouseIds: checkboxIds, + printerId: selectedPrinter.id, + printQty, + }); setSelectedWarehousesModalOpen(false); successDialog("二維碼已列印", t); } catch (error) { @@ -285,7 +271,7 @@ const QrCodeHandleWarehouseSearch: React.FC = ({ warehouses, printerCombo } finally { setIsUploading(false); } - }, [checkboxIds, printQty, setIsUploading, t]); + }, [checkboxIds, printQty, selectedPrinter, setIsUploading, t]); const handleViewSelectedQrCodes = useCallback(() => { if (checkboxIds.length === 0) { @@ -595,7 +581,7 @@ const QrCodeHandleWarehouseSearch: React.FC = ({ warehouses, printerCombo variant="contained" startIcon={} onClick={handlePrint} - disabled={checkboxIds.length === 0 || filteredPrinters.length === 0} + disabled={checkboxIds.length === 0 || filteredPrinters.length === 0 || !selectedPrinter} color="primary" > 列印