Files
electron/frontend/public/electron.js
T
2026-09-01 11:47:15 +03:00

233 lines
6.6 KiB
JavaScript

const { app, BrowserWindow, protocol, ipcMain, globalShortcut } = require('electron');
const path = require('path');
require('dotenv').config({path: path.join(__dirname, 'config.env')})
const isDev = require('electron-is-dev');
const fs = require('fs');
const axios = require('axios');
const { logger } = require('../../backend/src/config/logger');
const config = require('../src/config.json')
const { print } = require('pdf-to-printer');
protocol.registerSchemesAsPrivileged([
{
scheme: 'app',
privileges: {
secure: true,
standard: true,
supportFetchAPI: true,
corsEnabled: true
}
}
]);
if (!Promise.withResolvers) {
Promise.withResolvers = function () {
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
return { promise, resolve, reject };
};
}
let mainWindow;
let appConfig = {};
const configPath = isDev
? path.join(__dirname, '../src/config.json')
: path.join(process.resourcesPath, 'config.json');
try {
logger.info(`[Config] Trying to load config from: ${configPath}`);
if (fs.existsSync(configPath)) {
appConfig = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
logger.info('[Config] External config loaded successfully:', appConfig);
} else {
logger.warn('[Config] External config file not found. Using default values.');
}
} catch (error) {
logger.error('[Config] Could not load external config file:', error);
}
global.allowClose = false;
function createWindow() {
const preloadPath = path.join(__dirname, 'preload.js');
try {
fs.accessSync(preloadPath);
logger.debug(`[DEBUG] Preload script found at: ${preloadPath}`);
} catch (e) {
logger.error(`[FATAL] Preload script not found at: ${preloadPath}`);
app.quit();
return;
}
mainWindow = new BrowserWindow({
kiosk: true,
titleBarStyle: 'hidden',
alwaysOnTop: false,
webPreferences: {
preload: preloadPath,
contextIsolation: true,
nodeIntegration: false
},
});
mainWindow.loadURL(
isDev
? `${config.frontUrl}`
: `file://${path.join(__dirname, '../build/index.html')}`
);
mainWindow.on('close', (e) => {
if (!global.allowClose) {
e.preventDefault();
}
});
mainWindow.on('minimize', (e) => {
e.preventDefault();
});
}
// ============================================
// 📄 ПЕЧАТЬ PDF ЧЕРЕЗ pdf-to-printer
// ============================================
ipcMain.handle('print-pdf', async (event, data = {}) => {
let tempFile = null;
try {
if (!data.pdfUrl) {
throw new Error('URL файла PDF не передан');
}
const cleanUrl = data.pdfUrl.split('#')[0];
logger.info('[PRINT] Загрузка PDF:', cleanUrl);
// ✅ Скачиваем PDF
const response = await axios.get(cleanUrl, {
responseType: 'arraybuffer',
timeout: 30000
});
const pdfBuffer = Buffer.from(response.data);
logger.info('[PRINT] Размер PDF:', pdfBuffer.length, 'байт');
if (pdfBuffer.length < 100) {
throw new Error('PDF слишком маленький или пустой');
}
// ✅ Сохраняем во временный файл
const tempDir = app.getPath('temp');
tempFile = path.join(tempDir, `print_${Date.now()}.pdf`);
fs.writeFileSync(tempFile, pdfBuffer);
logger.info('[PRINT] Временный файл создан:', tempFile);
// ✅ ПЕЧАТАЕМ ЧЕРЕЗ pdf-to-printer
const printerName = 'GP-80250 Series';
logger.info('[PRINT] Отправляем на печать через pdf-to-printer:', printerName);
// ✅ Опции печати
const options = {
printer: printerName,
// scale: 'fit', // Масштабирование
// paperSize: 'A4',
// landscape: false,
// copies: 1,
// silent: true // Тихая печать
};
const result = await print(tempFile, options);
logger.info('[PRINT] Результат печати:', result);
// ✅ Удаляем временный файл
try {
if (tempFile && fs.existsSync(tempFile)) {
fs.unlinkSync(tempFile);
logger.info('[PRINT] Временный файл удален');
}
} catch (e) {}
logger.info('[PRINT] ✅ Документ отправлен на печать');
return true;
} catch (error) {
logger.error('[PRINT] ❌ Ошибка:', error.message);
try {
if (tempFile && fs.existsSync(tempFile)) {
fs.unlinkSync(tempFile);
}
} catch (e) {}
throw error;
}
});
// ============================================
// 📄 ПОЛУЧЕНИЕ СПИСКА ПРИНТЕРОВ
// ============================================
ipcMain.handle('get-printers', async () => {
return [
{
name: 'GP-80250 Series',
displayName: 'GP-80250 Series',
isDefault: true,
status: 'ready'
}
];
});
// ============================================
// 🚀 ЗАПУСК
// ============================================
app.whenReady().then(() => {
createWindow();
global.allowMinimize = false;
globalShortcut.register('Control+Alt+Backspace', () => {
global.allowMinimize = true;
if (mainWindow) mainWindow.minimize();
});
mainWindow.on('minimize', function (event) {
if (global.allowMinimize) {
global.allowMinimize = false;
return;
}
event.preventDefault();
setTimeout(() => {
if (mainWindow.isMinimized()) {
mainWindow.restore();
mainWindow.focus();
}
}, 10);
});
globalShortcut.register('Control+Alt+Enter', () => {
global.allowClose = true;
app.quit();
});
globalShortcut.register('F11', () => {});
});
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
if (mainWindow === null) {
createWindow();
}
});
app.on('will-quit', () => {
globalShortcut.unregisterAll();
});
ipcMain.handle('get-app-config', async (event) => {
return appConfig;
});