| @@ -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<void> => { | |||
| 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}`); | |||
| } | |||
| }; | |||
| @@ -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<void> => { | |||
| 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<UserResult[]> => { | |||
| if (!searchTerm.trim()) { | |||
| return []; | |||
| @@ -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<void> => { | |||
| 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<WarehouseResult[]> => { | |||
| const token = localStorage.getItem("accessToken"); | |||
| @@ -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<Props> = ({ 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<Props> = ({ 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<Props> = ({ equipmentDetails, printe | |||
| variant="contained" | |||
| startIcon={<PrintIcon />} | |||
| onClick={handlePrint} | |||
| disabled={checkboxIds.length === 0 || filteredPrinters.length === 0} | |||
| disabled={checkboxIds.length === 0 || filteredPrinters.length === 0 || !selectedPrinter} | |||
| color="primary" | |||
| > | |||
| 列印 | |||
| @@ -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<Props> = ({ 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<Props> = ({ 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<Props> = ({ users, printerCombo }) => { | |||
| variant="contained" | |||
| startIcon={<PrintIcon />} | |||
| onClick={handlePrint} | |||
| disabled={checkboxIds.length === 0 || filteredPrinters.length === 0} | |||
| disabled={checkboxIds.length === 0 || filteredPrinters.length === 0 || !selectedPrinter} | |||
| color="primary" | |||
| > | |||
| 列印 | |||
| @@ -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<Props> = ({ 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<Props> = ({ 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<Props> = ({ warehouses, printerCombo | |||
| variant="contained" | |||
| startIcon={<PrintIcon />} | |||
| onClick={handlePrint} | |||
| disabled={checkboxIds.length === 0 || filteredPrinters.length === 0} | |||
| disabled={checkboxIds.length === 0 || filteredPrinters.length === 0 || !selectedPrinter} | |||
| color="primary" | |||
| > | |||
| 列印 | |||