ERP-node/frontend/lib/zebraBrowserPrint.ts

122 lines
4.1 KiB
TypeScript
Raw Permalink Normal View History

2026-03-04 20:51:00 +09:00
/**
* Zebra Browser Print
* - "Zebra Browser Print" (Windows/macOS/Android)
* - ·Bluetooth ZPL (Chrome )
* - Android: Browser Print APK Chrome에서
* 참고: https://developer.zebra.com/products/printers/browser-print
*/
const BROWSER_PRINT_SCRIPT_URL =
"https://cdn.jsdelivr.net/npm/zebra-browser-print-min@3.0.216/BrowserPrint-3.0.216.min.js";
/** ZebraPrintResult와 동일한 형태 (zebraBluetooth와 공유) */
export interface ZebraPrintResult {
success: boolean;
message: string;
}
declare global {
interface Window {
BrowserPrint?: {
getDefaultDevice: (
type: string,
onSuccess: (device: BrowserPrintDevice) => void,
onError: (err: string) => void
) => void;
};
}
}
interface BrowserPrintDevice {
send: (
data: string,
onSuccess: () => void,
onError: (err: string) => void
) => void;
}
let scriptLoadPromise: Promise<boolean> | null = null;
/** Browser Print 스크립트를 한 번만 동적 로드 */
function loadBrowserPrintScript(): Promise<boolean> {
if (typeof window === "undefined") return Promise.resolve(false);
if (window.BrowserPrint) return Promise.resolve(true);
if (scriptLoadPromise) return scriptLoadPromise;
scriptLoadPromise = new Promise((resolve) => {
const existing = document.querySelector(
`script[src="${BROWSER_PRINT_SCRIPT_URL}"]`
);
if (existing) {
resolve(!!window.BrowserPrint);
return;
}
const script = document.createElement("script");
script.src = BROWSER_PRINT_SCRIPT_URL;
script.async = true;
script.onload = () => resolve(!!window.BrowserPrint);
script.onerror = () => resolve(false);
document.head.appendChild(script);
});
return scriptLoadPromise;
}
/** Browser Print 앱이 설치되어 있고 기본 프린터를 사용할 수 있는지 확인 */
export function isBrowserPrintAvailable(): boolean {
return typeof window !== "undefined" && !!window.BrowserPrint;
}
/**
* Zebra Browser Print ZPL ( )
* -
*/
export function printZPLToBrowserPrint(zpl: string): Promise<ZebraPrintResult> {
return loadBrowserPrintScript().then((loaded) => {
if (!loaded || !window.BrowserPrint) {
return {
success: false,
message:
"Zebra Browser Print 스크립트를 불러올 수 없습니다. CDN 연결을 확인하세요.",
};
}
return new Promise<ZebraPrintResult>((resolve) => {
window.BrowserPrint!.getDefaultDevice(
"printer",
(device) => {
if (!device) {
resolve({
success: false,
message:
"기본 Zebra 프린터가 설정되지 않았습니다. Browser Print 앱에서 프린터를 검색해 기본으로 지정해 주세요.",
});
return;
}
device.send(
zpl,
() => resolve({ success: true, message: "Zebra Browser Print로 전송했습니다." }),
(err) =>
resolve({
success: false,
message: err || "Browser Print 전송 중 오류가 발생했습니다.",
})
);
},
(err) =>
resolve({
success: false,
message:
err ||
"Zebra Browser Print 앱이 설치되어 있지 않거나 연결할 수 없습니다. Android에서는 'Zebra Browser Print' 앱을 설치한 뒤 Chrome에서 이 페이지를 허용해 주세요.",
})
);
});
});
}
/** Browser Print 앱 설치/다운로드 안내 문구 */
export function getBrowserPrintHelpMessage(): string {
return "Android에서 Bluetooth 목록에 프린터가 안 나오면, Zebra 공식 'Zebra Browser Print' 앱을 설치한 뒤 앱에서 프린터를 검색·기본 설정하고, 이 사이트를 허용하면 'Zebra 프린터로 출력'으로 인쇄할 수 있습니다.";
}