193 lines
5.1 KiB
TypeScript
193 lines
5.1 KiB
TypeScript
// src/utils/hiprintPrinter.ts
|
||
import { io, Socket } from "socket.io-client";
|
||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||
import { usePrintStore } from '@/store/modules/printStore'
|
||
import { onUnmounted } from "vue"
|
||
// @ts-ignore
|
||
import Download from '@/plugins/download';
|
||
// ... 类型定义 ...
|
||
type PrinterInfo = {
|
||
name: string;
|
||
isDefault?: boolean;
|
||
[key: string]: any;
|
||
};
|
||
|
||
|
||
interface ClientInfo {
|
||
id?: string;
|
||
version?: string;
|
||
os?: string;
|
||
[key: string]: string | number | boolean | undefined;
|
||
}
|
||
|
||
type OnPrinterUpdate = (printerList: PrinterInfo[]) => void;
|
||
let socket: Socket | null = null;
|
||
|
||
let clientInfo: ClientInfo | null = null;
|
||
// 初始化 Socket 连接
|
||
function initSocket(onPrinterUpdate?: OnPrinterUpdate) {
|
||
const printStore = usePrintStore();
|
||
|
||
if (socket) {
|
||
socket.disconnect();
|
||
}
|
||
|
||
socket = io("http://localhost:17521", {
|
||
transports: ["websocket"],
|
||
reconnection: false, //闭自动重连
|
||
auth: {
|
||
token: "vue-plugin-hiprint",
|
||
},
|
||
});
|
||
// 连接成功
|
||
socket.on("connect", () => {
|
||
printStore.setConnected(true);
|
||
console.log("✅ 已连接 electron-hiprint 客户端");
|
||
socket?.emit("getClientInfo");
|
||
socket?.emit("refreshPrinterList");
|
||
});
|
||
// 客户端信息
|
||
socket.on("clientInfo", (info: ClientInfo) => {
|
||
printStore.setClientInfo(info);
|
||
console.log("📱 客户端信息:", info);
|
||
});
|
||
// 打印机列表 (更新默认打印机)
|
||
socket.on("printerList", (list: PrinterInfo[]) => {
|
||
printStore.setPrinterList(list);
|
||
onPrinterUpdate?.(list);
|
||
console.log("🖨️ 打印机列表更新:", list);
|
||
});
|
||
// 连接断开
|
||
socket.on("disconnect", (reason: string) => {
|
||
printStore.setConnected(false);
|
||
console.error("❌ 客户端连接断开:", reason);
|
||
if (reason === "io server disconnect") {
|
||
socket?.connect();
|
||
}
|
||
});
|
||
|
||
socket.on("connect_error", (err: Error) => {
|
||
console.log('连接错误', err);
|
||
ElMessageBox.alert(
|
||
`连接失败!<br>请确保目标服务器已<a style="color: #1f79db" onclick="downExe()">下载安装</a> 并<a style="color: #1f79db" onclick="yxHiprint()"> 运行 </a> 打印服务!`,
|
||
"客户端未连接",
|
||
{
|
||
dangerouslyUseHTMLString: true,
|
||
}
|
||
)
|
||
printStore.setConnected(false);
|
||
socket?.close();
|
||
});
|
||
|
||
|
||
}
|
||
|
||
|
||
const downExe = () => {
|
||
// 下载逻辑实现
|
||
// console.log('开始下载打印服务');
|
||
Download.name('hiprint_win_x64-1.0.13.exe', false)
|
||
};
|
||
const yxHiprint = () => {
|
||
// 唤起客户端
|
||
window.open("hiprint://");
|
||
};
|
||
|
||
// 挂载到window,使其能被全局访问
|
||
(window as any).downExe = downExe;
|
||
(window as any).yxHiprint = yxHiprint;
|
||
|
||
|
||
// 自定义打印参数(可选)
|
||
interface PrintOptions {
|
||
orientation?: "portrait" | "landscape"; // 纵向(landscape=横向)
|
||
copies?: number;
|
||
monochrome?: boolean; // 是否黑白打印
|
||
paperName?: 'A2' | 'A3' | 'A4' | 'A5' | 'A6' | 'letter' | 'legal' | 'tabloid' | 'statement'; //纸张大小
|
||
}
|
||
/**
|
||
* 执行批量静默打印
|
||
* @param urls PDF文件URL数组
|
||
* @param options 打印选项(可选)
|
||
*/
|
||
function silentPrint(urls: string[], options?: PrintOptions) {
|
||
if (urls.length === 0) return ElMessage.error('没有打印数据');
|
||
const printStore = usePrintStore();
|
||
const handlePrint = () => {
|
||
ElMessage.success('正在打印文件,请稍候...');
|
||
urls.forEach(url => silentPrintPdf(url, options));
|
||
};
|
||
|
||
// 已连接直接打印,未连接则初始化后打印
|
||
if (printStore.isConnected) {
|
||
handlePrint();
|
||
} else {
|
||
initSocket((printerList) => {
|
||
if (printerList.length > 0) {
|
||
handlePrint();
|
||
} else {
|
||
ElMessage.warning('未检测到可用打印机');
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
//静默打印单个PDF文件
|
||
function silentPrintPdf(url: string, options?: PrintOptions) {
|
||
const printStore = usePrintStore();
|
||
const templateId = `pdf-print-${Date.now()}`;
|
||
const targetPrinter = printStore.defaultPrinter;
|
||
if (!targetPrinter) {
|
||
console.log("未检测到打印机,请先连接打印机!");
|
||
return;
|
||
}
|
||
socket?.emit("news", {
|
||
client: clientInfo,
|
||
printer: targetPrinter,
|
||
type: "url_pdf",
|
||
templateId: templateId,
|
||
pdf_path: url,
|
||
});
|
||
// console.log(`🚀 PDF打印请求已发送,任务ID:${templateId},打印机:${targetPrinter}`);
|
||
|
||
}
|
||
// 销毁
|
||
function destroy() {
|
||
const printStore = usePrintStore();
|
||
if (socket) {
|
||
socket.disconnect();
|
||
socket = null;
|
||
printStore.setConnected(false);
|
||
console.log("🔌 已断开与 electron-hiprint 的连接");
|
||
}
|
||
}
|
||
|
||
// 更新 getter 函数以从 store 获取值
|
||
export const HiprintPrinter = {
|
||
initSocket,
|
||
silentPrint,
|
||
silentPrintPdf,
|
||
destroy,
|
||
get isConnected() {
|
||
const printStore = usePrintStore();
|
||
return printStore.isConnected;
|
||
},
|
||
get clientInfo() {
|
||
const printStore = usePrintStore();
|
||
return printStore.clientInfo;
|
||
},
|
||
get printerList() {
|
||
const printStore = usePrintStore();
|
||
return printStore.printerList;
|
||
},
|
||
get defaultPrinter() {
|
||
const printStore = usePrintStore();
|
||
return printStore.defaultPrinter;
|
||
},
|
||
};
|
||
|
||
onUnmounted(() => {
|
||
if ('downExe' in window) {
|
||
delete (window as any).downExe;
|
||
}
|
||
}); |