122 lines
4.1 KiB
TypeScript
122 lines
4.1 KiB
TypeScript
|
|
/**
|
||
|
|
* 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 프린터로 출력'으로 인쇄할 수 있습니다.";
|
||
|
|
}
|