网页端:平台桥与部署修复(宝塔/Nginx)

- lib/platform:网页 Electron 统一 bridge/web/electron,子目录 API 基路径、返回首页跳站点根、路径末尾斜杠兼容
- index/design*.web.html:网页入口,web.js 加缓存参数避免旧脚本缓存
- api:PHP 读写 soon;文档说明目录权限与 Nginx
- lib/design*、lib/index:与 platformBridge 对接及网页侧逻辑
- 公共资源 JsBarcode/jr-qrcode;文档与 package/README/.gitignore 等同步更新

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
24kycj
2026-05-09 18:57:53 +08:00
parent ee6ef462ca
commit 2e6578247e
27 changed files with 6606 additions and 3542 deletions
+145
View File
@@ -0,0 +1,145 @@
/**
* 平台抽象层 - Electron 实现
* 仅在存在 require 且可加载 electron 时使用;封装 IPC、dialog、fs、remote。
*/
(function () {
'use strict';
if (typeof require === 'undefined') {
return;
}
var ipcRenderer, dialog, path, fs, remote, clipboard;
try {
ipcRenderer = require('electron').ipcRenderer;
dialog = require('@electron/remote').dialog;
path = require('path');
fs = require('fs');
remote = require('@electron/remote');
clipboard = require('electron').clipboard;
} catch (e) {
console.warn('[platform] Electron modules not available', e);
return;
}
var exePath = remote.app.getPath('userData');
var historyFilePath = path.join(exePath, 'data.json');
var bridge = {
readHistory: function () {
return ipcRenderer.invoke('history:read');
},
writeHistory: function (data) {
return ipcRenderer.invoke('history:write', data);
},
readJsonFile: function (filePath) {
if (!filePath) return Promise.resolve(null);
return ipcRenderer.invoke('file:read-json', filePath);
},
showOpenDialog: function (options) {
return dialog.showOpenDialog(options).then(function (result) {
return { canceled: result.canceled, filePaths: result.filePaths };
});
},
showSaveDialog: function (options) {
return dialog.showSaveDialog(options);
},
writeFile: function (filePath, content) {
return new Promise(function (resolve, reject) {
var buf = Buffer.isBuffer(content) ? content : (typeof content === 'string' ? Buffer.from(content, 'utf8') : Buffer.from(content));
fs.writeFile(filePath, buf, 'utf8', function (err) {
if (err) reject(err);
else resolve();
});
});
},
writeFileSync: function (filePath, content) {
fs.writeFileSync(filePath, content, 'utf8');
},
readFile: function (filePath) {
return new Promise(function (resolve, reject) {
fs.readFile(filePath, function (err, data) {
if (err) reject(err);
else resolve(data);
});
});
},
readFileSync: function (filePath) {
return fs.readFileSync(filePath);
},
existsSync: function (p) {
return fs.existsSync(p);
},
getAppVersion: function () {
return ipcRenderer.invoke('app:get-version');
},
getLocale: function () {
return remote.app.getLocale();
},
getUserDataPath: function () {
return exePath;
},
getSystemFonts: function () {
return new Promise(function (resolve, reject) {
ipcRenderer.once('font-list', function (ev, fonts) {
resolve(fonts || []);
});
ipcRenderer.send('get-sys-fonts');
setTimeout(function () {
resolve([]);
}, 10000);
});
},
openDesignPage: function (file, type) {
ipcRenderer.send('open-design-page', file || 'empty', type || '1');
},
openFirstPage: function () {
ipcRenderer.send('open-first-page');
},
onClose: function (callback) {
ipcRenderer.on('close', callback);
},
runClose: function () {
ipcRenderer.send('run-close');
},
openHelp: function () {
ipcRenderer.send('open-help-file');
},
printPdf: function (urlOrBlob) {
ipcRenderer.send('print-pdf', urlOrBlob);
},
getScaleRate: function () {
return typeof window !== 'undefined' && window.devicePixelRatio ? window.devicePixelRatio : 1;
},
clipboard: {
readText: function () {
return Promise.resolve(clipboard.readText());
},
writeText: function (text) {
clipboard.writeText(text);
return Promise.resolve();
}
}
};
window.platformBridge = bridge;
// 兼容现有命名
window.sysAPI = {
readHistory: bridge.readHistory,
writeHistory: bridge.writeHistory,
readJsonFile: bridge.readJsonFile,
getAppVersion: bridge.getAppVersion
};
window.dialog = {
showOpenDialog: bridge.showOpenDialog,
showSaveDialog: bridge.showSaveDialog
};
window.path = path;
window.fs = fs;
window.remote = remote;
window.ipcRenderer = ipcRenderer;
window.clipboard = clipboard;
window.exePath = exePath;
window.fullPath = historyFilePath;
})();