数据格式示例
// 抖音打印
let request1 = {
cmd: "print",
requestID: `dy-print-${Date.now()}${i}`,
version: "1.0",
task: {
taskID: `dy-print-${Date.now()}${i}`,
printer: form.expressPrinter,
preview: false,
documents: [
{
docNo: element.trackNo, //实际打印业务的单号
documentID: (
Math.floor(Math.random() * (999999999 - 100000000 + 1)) + 100000000
).toString(), //面单号,可选
copy: 1, //打印两份,默认1份
contents: [
{
params: res.params,
signature: element.sign,
encryptedData: element.printData, //实体打印机打印后是明文,虚拟打印机打印后是收件人脱敏信息
templateURL: res.templateURL,
},
{
//自定义区模板,如果没有,就不要传此对象
data: res.data,
templateURL: res.diyTemplateURL,
},
],
},
],
config: {
paperSize: {
width: form.templateDiy == 0 ? 76 : form.width,
height: form.templateDiy == 0 ? 130 : form.height,
},
},
},
};
// 拼多多打印
let payload = {
cmd: "print",
requestID: `pdd-print-${Date.now()}${i}`,
version: "1.0",
task: {
documents: [
{
contents: [
{
encryptedData: data.encryptedData,
signature: data.signature,
templateUrl: data.templateUrl,
userid: res.shopId,
ver: data.ver,
},
// 如果是用系统模版的话这下面的对象可以不用
{
data: res.data,
templateURL: res.diyTemplateURL,
},
],
documentID: `${Date.now()}${i}`,
},
],
printer: form.expressPrinter,
taskID: `pdd-print-${Date.now()}${i}`,
// preview: true,
// previewType: "image",
},
};
// 京东打印
payload = {
orderType: "PRINT",
key: `jd-print-${Date.now()}`,
parameters: {
printName: form.expressPrinter,
printData: [data.perPrintData],
// offsetTop: "10mm",
// offsetLeft: "10mm",
tempUrl: res.templateURL,
// 如果是用系统模版的话这下面的customTempUrl可以不用
customTempUrl: res.diyTemplateURL,
customData: [
{
...res.data,
},
],
},
};
// 淘宝打印
payload = {
cmd: "print",
requestID: `tb-print-${Date.now()}${i}`,
version: "1.0",
task: {
documents: [
{
contents: [
{
encryptedData: data.encryptedData,
signature: data.signature,
templateURL: data.templateURL,
userid: res.shopId,
ver: data.ver,
},
// 如果是用系统模版的话这下面的对象可以不用,下面是自定义的模版
{
data: res.data,
templateURL: res.diyTemplateURL,
},
],
documentID: `${Date.now()}${i}`,
},
],
printer: form.expressPrinter,
taskID: `tb-print-${Date.now()}${i}`,
},
};
打印代码
import { ElNotification } from "element-plus";
const PLATFORM_URLS = {
DY: "ws://127.0.0.1:13888", // 抖音
PDD: "ws://127.0.0.1:5000", // 拼多多
JD: "ws://127.0.0.1:9113", // 京东
TB: "ws://127.0.0.1:13528", // 淘宝
};
const PLATFORM_NAMES = {
DY: "抖音",
PDD: "拼多多",
JD: "京东",
TB: "淘宝",
};
type Platform = "DY" | "PDD" | "JD" | "TB";
const sockets: Record<Platform, WebSocket | null> = {
DY: null,
PDD: null,
JD: null,
TB: null,
};
const printers: Record<Platform, any[]> = {
DY: [],
PDD: [],
JD: [],
TB: [],
};
const callbacks: Record<Platform, Record<string, ((data: any) => void)[]>> = {
DY: {},
PDD: {},
JD: {},
TB: {},
};
const reconnectTimers: Record<Platform, any> = {
DY: null,
PDD: null,
JD: null,
TB: null,
};
const heartbeatTimers: Record<Platform, any> = {
DY: null,
PDD: null,
JD: null,
TB: null,
};
const errorShown: Record<Platform, boolean> = {
DY: false,
PDD: false,
JD: false,
TB: false,
};
function connect(platform: Platform): Promise<void> {
return new Promise((resolve, reject) => {
const url = PLATFORM_URLS[platform];
if (sockets[platform]?.readyState === WebSocket.OPEN) {
resolve();
return;
}
try {
const socket = new WebSocket(url);
sockets[platform] = socket;
socket.onopen = () => {
console.log(`[${platform}] 连接成功`);
errorShown[platform] = false;
startHeartbeat(platform);
requestPrinters(platform);
trigger(platform, "connected", true);
resolve();
};
socket.onmessage = (event) => {
try {
const data = JSON.parse(event.data);
handleMessage(platform, data);
} catch (e) {
console.error(`[${platform}] 解析消息失败`, e);
}
};
socket.onerror = () => {
console.error(`[${platform}] 连接错误`);
showError(platform);
trigger(platform, "connected", false);
reject(new Error("连接失败"));
};
socket.onclose = () => {
console.log(`[${platform}] 连接关闭`);
stopHeartbeat(platform);
trigger(platform, "connected", false);
scheduleReconnect(platform);
};
} catch (error) {
reject(error);
}
});
}
function disconnect(platform: Platform) {
stopHeartbeat(platform);
clearTimeout(reconnectTimers[platform]);
if (sockets[platform]) {
sockets[platform]!.close();
sockets[platform] = null;
}
}
function send(platform: Platform, data: any) {
const socket = sockets[platform];
if (socket?.readyState === WebSocket.OPEN) {
socket.send(JSON.stringify(data));
}
}
function handleMessage(platform: Platform, data: any) {
trigger(platform, "message", data);
if (data.cmd === "getPrinters" || data.message === "get printers success") {
if (data.printers?.length > 0) {
printers[platform] = data.printers;
trigger(platform, "printers", data.printers);
}
if (data.detailinfo?.printers?.length > 0) {
printers[platform] = data.detailinfo.printers.map((p: string) => ({ name: p }));
trigger(platform, "printers", printers[platform]);
}
}
if (data.cmd === "notifyPrintResult" && data.status === "success") {
trigger(platform, "print:success", data);
}
if (data.cmd === "notifyPrintResult" && data.status === "failed") {
trigger(platform, "print:failed", data);
}
if (data.cmd === "print" && data.status === "success") {
trigger(platform, "print:processing", data);
}
}
function requestPrinters(platform: Platform) {
if (platform === "JD") {
send(platform, { orderType: "GET_Printers" });
} else {
send(platform, {
requestID: `${Date.now()}`,
version: "1.0",
cmd: "getPrinters",
});
}
}
function startHeartbeat(platform: Platform) {
stopHeartbeat(platform);
heartbeatTimers[platform] = setInterval(() => {
send(platform, { type: "heartbeat" });
}, 30000);
}
function stopHeartbeat(platform: Platform) {
if (heartbeatTimers[platform]) {
clearInterval(heartbeatTimers[platform]);
heartbeatTimers[platform] = null;
}
}
function scheduleReconnect(platform: Platform) {
clearTimeout(reconnectTimers[platform]);
reconnectTimers[platform] = setTimeout(() => {
connect(platform).catch(() => {});
}, 3000);
}
function showError(platform: Platform) {
if (errorShown[platform]) return;
errorShown[platform] = true;
ElNotification({
title: `${PLATFORM_NAMES[platform]}打印组件连接错误`,
dangerouslyUseHTMLString: true,
message: `
<div>未检测到${PLATFORM_NAMES[platform]}打印组件,请检查是否已打开。</div>
<div style="margin-top: 10px;">
<div>1. 已安装并启动:请刷新页面后重试</div>
<div>2. 未安装:请下载并安装${PLATFORM_NAMES[platform]}打印组件</div>
<div>3. 连接地址:${PLATFORM_URLS[platform]}</div>
</div>
`,
type: "error",
duration: 5000,
onClose: () => {
errorShown[platform] = false;
},
});
}
function trigger(platform: Platform, event: string, data?: any) {
const cbs = callbacks[platform][event] || [];
cbs.forEach((cb) => cb(data));
}
function on(platform: Platform, event: string, cb: (data: any) => void) {
if (!callbacks[platform][event]) {
callbacks[platform][event] = [];
}
callbacks[platform][event].push(cb);
}
function off(platform: Platform, event: string, cb?: (data: any) => void) {
if (!callbacks[platform][event]) return;
if (cb) {
const idx = callbacks[platform][event].indexOf(cb);
if (idx > -1) callbacks[platform][event].splice(idx, 1);
} else {
callbacks[platform][event] = [];
}
}
function isConnected(platform: Platform): boolean {
return sockets[platform]?.readyState === WebSocket.OPEN;
}
function getPrinters(platform: Platform): any[] {
return printers[platform];
}
function print(platform: Platform, request: any) {
send(platform, request);
}
export const dyPrint = {
connect: () => connect("DY"),
disconnect: () => disconnect("DY"),
isConnected: () => isConnected("DY"),
getPrinters: () => getPrinters("DY"),
print: (req: any) => print("DY", req),
on: (event: string, cb: (data: any) => void) => on("DY", event, cb),
off: (event: string, cb?: (data: any) => void) => off("DY", event, cb),
};
export const pddPrint = {
connect: () => connect("PDD"),
disconnect: () => disconnect("PDD"),
isConnected: () => isConnected("PDD"),
getPrinters: () => getPrinters("PDD"),
print: (req: any) => print("PDD", req),
on: (event: string, cb: (data: any) => void) => on("PDD", event, cb),
off: (event: string, cb?: (data: any) => void) => off("PDD", event, cb),
};
export const jdPrint = {
connect: () => connect("JD"),
disconnect: () => disconnect("JD"),
isConnected: () => isConnected("JD"),
getPrinters: () => getPrinters("JD"),
print: (req: any) => print("JD", req),
on: (event: string, cb: (data: any) => void) => on("JD", event, cb),
off: (event: string, cb?: (data: any) => void) => off("JD", event, cb),
};
export const tbPrint = {
connect: () => connect("TB"),
disconnect: () => disconnect("TB"),
isConnected: () => isConnected("TB"),
getPrinters: () => getPrinters("TB"),
print: (req: any) => print("TB", req),
on: (event: string, cb: (data: any) => void) => on("TB", event, cb),
off: (event: string, cb?: (data: any) => void) => off("TB", event, cb),
};
export async function connectAll() {
const results = await Promise.allSettled([
connect("DY"),
connect("PDD"),
connect("JD"),
connect("TB"),
]);
return {
DY: results[0].status === "fulfilled",
PDD: results[1].status === "fulfilled",
JD: results[2].status === "fulfilled",
TB: results[3].status === "fulfilled",
};
}
export function disconnectAll() {
disconnect("DY");
disconnect("PDD");
disconnect("JD");
disconnect("TB");
}