Files
cashier_desktop/electron/main.js

368 lines
11 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import path from "path";
import { app, BrowserWindow, ipcMain } from "electron";
import axios from "axios";
import os from "os";
import fs from "fs";
import { exec } from "child_process";
// ===== 核心配置:单文件缓存 =====
// 固定的缓存文件路径永远只存这1个文件
const CACHE_LOGO_PATH = path.join(app.getPath("temp"), "yinshouke_print", "cache_logo.png");
// 记录上次的Logo URL用于对比
let lastLogoUrl = "";
// 1. 初始化缓存目录(应用启动时执行)
const initLogoCacheDir = () => {
const cacheDir = path.dirname(CACHE_LOGO_PATH);
if (!fs.existsSync(cacheDir)) {
fs.mkdirSync(cacheDir, { recursive: true });
}
// 清理目录下除了cache_logo.png之外的所有文件应用启动时
if (fs.existsSync(cacheDir)) {
fs.readdirSync(cacheDir).forEach(file => {
const filePath = path.join(cacheDir, file);
if (filePath !== CACHE_LOGO_PATH) {
fs.unlinkSync(filePath);
console.log("启动清理删除历史残留Logo文件", filePath);
}
});
}
};
let win;
app.whenReady().then(() => {
initLogoCacheDir();
win = new BrowserWindow({
title: "银收客",
width: 1024,
height: 768,
fullscreenable: true,
fullscreen: process.env.VITE_DEV_SERVER_URL ? false : true,
simpleFullscreen: true,
frame: process.env.VITE_DEV_SERVER_URL ? true : false,
webPreferences: {
// 集成网页和 Node.js也就是在渲染进程中可以调用 Node.js 方法
nodeIntegration: true,
contextIsolation: false,
},
});
// You can use `process.env.VITE_DEV_SERVER_URL` when the vite command is called `serve`
if (process.env.VITE_DEV_SERVER_URL) {
win.loadURL(process.env.VITE_DEV_SERVER_URL);
// 使用vite开发服务的url路径访问应用
// win.webContents.openDevTools();
} else {
win.loadFile(path.resolve(__dirname, "../dist/index.html")); // 打包后使用文件路径访问应用
}
// 安装最新版本的exe文件
const installExe = async (exePath) => {
return new Promise((resolve, reject) => {
exec(`${exePath}`, (error, stdout, stderr) => {
if (error) {
reject(error);
} else {
resolve(stdout);
}
});
});
};
ipcMain.on("downloadFile", async (event, arg) => {
let _parmas = JSON.parse(arg);
axios({
url: _parmas.url,
method: "get",
responseType: "arraybuffer",
onDownloadProgress: (propessEvent) => {
// 更新进度条
const propress = Math.round(
(propessEvent.loaded / propessEvent.total) * 100
);
win.webContents.send("updateProgress", propress);
},
})
.then(async (response) => {
try {
const tempFilePath = path.join(
app.getPath("temp"),
"temp-exe-file.exe"
);
fs.writeFileSync(tempFilePath, response.data);
setTimeout(() => {
win = null;
app.exit();
}, 1500);
const installResult = await installExe(tempFilePath);
console.log(`安装结果:${installResult}`);
} catch (error) {
console.log("error", error);
}
})
.catch((err) => {
console.log("下载失败", JSON.stringify(err));
});
});
app.on("activate", () => {
// 在 macOS 系统内, 如果没有已开启的应用窗口
// 点击托盘图标时通常会重新创建一个新窗口
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
ipcMain.on("quitHandler", (_, msg) => {
win = null;
app.exit();
});
// 给渲染进程返回打印机列表
ipcMain.on("getPrintList", () => {
win.webContents.getPrintersAsync().then((res) => {
// console.log("打印机列表", res);
win.webContents.send("printList", res);
});
});
// 获取本机mac
ipcMain.on("getOSmacSync", () => {
let mac = "";
if (os.networkInterfaces().WLAN) {
mac = os.networkInterfaces().WLAN[0].mac;
console.log("wlan.mac===", mac);
} else {
mac = os.networkInterfaces()["以太网"][0].mac;
console.log("以太网.mac===", mac);
}
win.webContents.send("getOSmacRes", mac);
});
// 创建打印小票子窗口
// const printWin = new BrowserWindow({
// show: false,
// width: 464,
// height: 1726,
// webPreferences: {
// // 集成网页和 Node.js也就是在渲染进程中可以调用 Node.js 方法
// nodeIntegration: true,
// contextIsolation: false,
// },
// });
// if (process.env.VITE_DEV_SERVER_URL) {
// // 加载打印的html文件
// printWin.loadFile(path.join(__dirname, "../public/print.html"));
// } else {
// printWin.loadFile(path.resolve(__dirname, "../dist/print.html")); // 打包后使用文件路径访问应用
// }
// // 接收订单页面发过来的参数发送给打印页
// ipcMain.on("printerInfoSync", (event, arg) => {
// printWin.webContents.send("getParams", arg);
// });
// // 执行打印操作
// ipcMain.on("printStart", (event, arg) => {
// console.log(arg);
// const _parmas = JSON.parse(arg);
// // console.log(_parmas)
// let name = _parmas.deviceName;
// printWin.webContents.print({
// silent: true,
// deviceName: name,
// pageSize: {
// width: 58000,
// height: 216000,
// },
// scaleFactor: 80,
// landscape: false,
// margins: {
// marginType: "none",
// top: 0,
// bottom: 0,
// left: 0,
// right: 0,
// },
// dpi: {
// horizontal: 203,
// vertical: 203,
// },
// });
// });
// // 交班小票的窗口
// const workPrintWin = new BrowserWindow({
// show: false,
// width: 464,
// height: 1726,
// webPreferences: {
// nodeIntegration: true,
// contextIsolation: false,
// },
// });
// if (process.env.VITE_DEV_SERVER_URL) {
// // 加载打印的html文件
// workPrintWin.loadFile(path.join(__dirname, "../public/work_print.html"));
// } else {
// workPrintWin.loadFile(path.resolve(__dirname, "../dist/work_print.html")); // 打包后使用文件路径访问应用
// }
// // 接收渲染进程发送的数据
// ipcMain.on("printerWorkSync", (event, arg) => {
// workPrintWin.webContents.send("getParams", arg);
// });
// // 执行交班小票的打印操作
// ipcMain.on("printWorkStart", (event, arg) => {
// // console.log(arg);
// const _parmas = JSON.parse(arg);
// // console.log(_parmas)
// let name = _parmas.deviceName;
// workPrintWin.webContents.print({
// silent: true,
// deviceName: name,
// pageSize: {
// width: 58000,
// height: 216000,
// },
// scaleFactor: 80,
// landscape: false,
// margins: {
// marginType: "none",
// top: 0,
// bottom: 0,
// left: 0,
// right: 0,
// },
// dpi: {
// horizontal: 203,
// vertical: 203,
// },
// });
// });
// 2. 下载/复用Logo核心函数
const getCachedLogoPath = async (logoUrl) => {
// 情况1Logo URL为空 → 用默认Logo
if (!logoUrl || !logoUrl.startsWith('http')) {
return "./logo.png";
}
// 情况2Logo URL和上次一致 → 直接用缓存文件
if (logoUrl === lastLogoUrl && fs.existsSync(CACHE_LOGO_PATH)) {
console.log("Logo未变化复用本地缓存");
return CACHE_LOGO_PATH;
}
// 情况3Logo URL变化 → 删除旧缓存,下载新的
try {
// 删除旧缓存(如果存在)
if (fs.existsSync(CACHE_LOGO_PATH)) {
fs.unlinkSync(CACHE_LOGO_PATH);
console.log("Logo已更新删除旧缓存文件");
}
// 下载新Logo到固定缓存路径
const response = await axios({
url: logoUrl,
method: "GET",
responseType: "stream",
});
await new Promise((resolve, reject) => {
const writer = fs.createWriteStream(CACHE_LOGO_PATH);
response.data.pipe(writer);
writer.on("finish", resolve);
writer.on("error", reject);
});
// 更新上次的Logo URL记录
lastLogoUrl = logoUrl;
console.log("新Logo下载完成缓存路径", CACHE_LOGO_PATH);
return CACHE_LOGO_PATH;
} catch (error) {
console.error("下载新Logo失败使用默认Logo", error);
return "./logo.png";
}
};
// 标签小票的窗口
const tagPrintWin = new BrowserWindow({
show: false,
width: 360,
height: 240,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
// 允许访问本地文件(关键)
webSecurity: false,
},
// 新增2禁止后台节流隐藏窗口也能加载资源
backgroundThrottling: false,
});
if (process.env.VITE_DEV_SERVER_URL) {
// 加载打印的html文件
tagPrintWin.loadFile(path.join(__dirname, "../public/tag_print.html"));
} else {
tagPrintWin.loadFile(path.resolve(__dirname, "../dist/tag_print.html")); // 打包后使用文件路径访问应用
}
// 接收渲染进程发送的数据
ipcMain.on("printerTagSync", async (event, arg) => {
console.log("接收打印参数:", arg);
const data = JSON.parse(arg);
// ===== 核心获取缓存的Logo路径 =====
const logoPath = await getCachedLogoPath(data.ticketLogo);
data.ticketLogo = logoPath; // 替换为本地缓存路径
// 传给打印窗口
tagPrintWin.webContents.send("getParams", JSON.stringify(data));
});
// 执行标签小票的打印操作
ipcMain.on("printTagStart", (event, arg) => {
const _parmas = JSON.parse(arg);
let name = _parmas.deviceName;
tagPrintWin.webContents.print({
silent: true,
deviceName: name,
pageSize: { width: 45000, height: 30000 },
scaleFactor: 80,
landscape: false,
margins: { marginType: "none", top: 0, bottom: 0, left: 0, right: 0 },
dpi: { horizontal: 203, vertical: 203 },
// 新增:必须开启,否则图片打印不出来
printBackground: true
});
});
const gotTheLock = app.requestSingleInstanceLock();
if (!gotTheLock) {
app.quit();
} else {
app.on("second-instance", (event, commandLine, workingDirectory) => {
// 当运行第二个实例时,将会聚焦到mainWindow这个窗口
if (win) {
if (win.isMinimized()) win.restore();
win.focus();
win.show();
}
});
}
// 阻止默认关闭
win.on("close", (e) => {
e.preventDefault();
win.webContents.send("showCloseDialog");
});
});
app.on("window-all-closed", () => {
if (process.platform !== "darwin") app.quit();
});