优化调整bug与加密

This commit is contained in:
24kycj
2026-01-11 01:06:02 +08:00
parent f4aef8abaa
commit c26c4fa66e
19 changed files with 124 additions and 966 deletions
-3
View File
@@ -7,7 +7,4 @@ npm-debug.log
npm-debug.log.* npm-debug.log.*
thumbs.db thumbs.db
!.gitkeep !.gitkeep
# 加密相关文件(不要提交到 Git)
*.jsc
.backup/ .backup/
+3 -25
View File
@@ -874,31 +874,9 @@
const path = require('path'), fs = require('fs'), remote = require('@electron/remote'); const path = require('path'), fs = require('fs'), remote = require('@electron/remote');
const appPath = (() => { try { return remote.app.getAppPath(); } catch(e) { return __dirname || process.cwd(); } })(); const appPath = (() => { try { return remote.app.getAppPath(); } catch(e) { return __dirname || process.cwd(); } })();
// 读取模块映射配置
let mappedName = 'design1';
try {
const moduleMapPath = path.join(appPath, 'lib', 'module-map.json');
if (fs.existsSync(moduleMapPath)) {
const moduleMap = JSON.parse(fs.readFileSync(moduleMapPath, 'utf8'));
mappedName = moduleMap.mappings?.main?.design1 || 'design1';
}
} catch(e) {}
const jscPath = path.join(appPath, 'lib', `${mappedName}.jsc`);
const jsPath = path.join(appPath, 'lib', 'design1.js'); const jsPath = path.join(appPath, 'lib', 'design1.js');
// 优先加载映射的 .jsc 文件 // 加载 .js 文件
try {
require('bytenode');
require.extensions['.dl'] = require.extensions['.jsc'];
if (fs.existsSync(jscPath)) {
require(jscPath);
console.log(`[加载] ✅ design1 → ${mappedName}.jsc`);
return;
}
} catch(e) { console.error('[加载] .jsc 加载失败:', e.message); }
// 回退到 .js 源文件
if (fs.existsSync(jsPath)) { if (fs.existsSync(jsPath)) {
try { try {
require(jsPath); require(jsPath);
@@ -907,8 +885,8 @@
alert('文件加载失败!\n\n错误: ' + e.message); alert('文件加载失败!\n\n错误: ' + e.message);
} }
} else { } else {
alert('文件不存在!\n\n请检查:\n1. ' + jscPath + '\n2. ' + jsPath); alert('文件不存在!\n\n请检查:' + jsPath);
} }
})(); })();
</script> </script>
</body> </body>
+2 -24
View File
@@ -663,31 +663,9 @@
const path = require('path'), fs = require('fs'), remote = require('@electron/remote'); const path = require('path'), fs = require('fs'), remote = require('@electron/remote');
const appPath = (() => { try { return remote.app.getAppPath(); } catch(e) { return __dirname || process.cwd(); } })(); const appPath = (() => { try { return remote.app.getAppPath(); } catch(e) { return __dirname || process.cwd(); } })();
// 读取模块映射配置
let mappedName = 'design2';
try {
const moduleMapPath = path.join(appPath, 'lib', 'module-map.json');
if (fs.existsSync(moduleMapPath)) {
const moduleMap = JSON.parse(fs.readFileSync(moduleMapPath, 'utf8'));
mappedName = moduleMap.mappings?.main?.design2 || 'design2';
}
} catch(e) {}
const jscPath = path.join(appPath, 'lib', `${mappedName}.jsc`);
const jsPath = path.join(appPath, 'lib', 'design2.js'); const jsPath = path.join(appPath, 'lib', 'design2.js');
// 优先加载映射的 .jsc 文件 // 加载 .js 文件
try {
require('bytenode');
require.extensions['.dl'] = require.extensions['.jsc'];
if (fs.existsSync(jscPath)) {
require(jscPath);
console.log(`[加载] ✅ design2 → ${mappedName}.jsc`);
return;
}
} catch(e) { console.error('[加载] .jsc 加载失败:', e.message); }
// 回退到 .js 源文件
if (fs.existsSync(jsPath)) { if (fs.existsSync(jsPath)) {
try { try {
require(jsPath); require(jsPath);
@@ -696,7 +674,7 @@
alert('文件加载失败!\n\n错误: ' + e.message); alert('文件加载失败!\n\n错误: ' + e.message);
} }
} else { } else {
alert('文件不存在!\n\n请检查:\n1. ' + jscPath + '\n2. ' + jsPath); alert('文件不存在!\n\n请检查:' + jsPath);
} }
})(); })();
+2 -24
View File
@@ -220,31 +220,9 @@
const path = require('path'), fs = require('fs'), remote = require('@electron/remote'); const path = require('path'), fs = require('fs'), remote = require('@electron/remote');
const appPath = (() => { try { return remote.app.getAppPath(); } catch(e) { return __dirname || process.cwd(); } })(); const appPath = (() => { try { return remote.app.getAppPath(); } catch(e) { return __dirname || process.cwd(); } })();
// 读取模块映射配置
let mappedName = 'index';
try {
const moduleMapPath = path.join(appPath, 'lib', 'module-map.json');
if (fs.existsSync(moduleMapPath)) {
const moduleMap = JSON.parse(fs.readFileSync(moduleMapPath, 'utf8'));
mappedName = moduleMap.mappings?.main?.index || 'index';
}
} catch(e) {}
const jscPath = path.join(appPath, 'lib', `${mappedName}.jsc`);
const jsPath = path.join(appPath, 'lib', 'index.js'); const jsPath = path.join(appPath, 'lib', 'index.js');
// 优先加载映射的 .jsc 文件 // 加载 .js 文件
try {
require('bytenode');
require.extensions['.dl'] = require.extensions['.jsc'];
if (fs.existsSync(jscPath)) {
require(jscPath);
console.log(`[加载] ✅ index → ${mappedName}.jsc`);
return;
}
} catch(e) { console.error('[加载] .jsc 加载失败:', e.message); }
// 回退到 .js 源文件
if (fs.existsSync(jsPath)) { if (fs.existsSync(jsPath)) {
try { try {
require(jsPath); require(jsPath);
@@ -253,7 +231,7 @@
alert('文件加载失败!\n\n错误: ' + e.message); alert('文件加载失败!\n\n错误: ' + e.message);
} }
} else { } else {
alert('文件不存在!\n\n请检查:\n1. ' + jscPath + '\n2. ' + jsPath); alert('文件不存在!\n\n请检查:' + jsPath);
} }
})(); })();
</script> </script>
+4 -40
View File
@@ -491,57 +491,21 @@ const dpi = 600;
// 加载design1模块 // 加载design1模块
const fs = require('fs'); const fs = require('fs');
let bytenode;
try {
bytenode = require('bytenode');
require.extensions['.dl'] = require.extensions['.jsc'];
} catch (e) {
}
const appPath = (() => { try { return remote.app.getAppPath(); } catch (e) { return __dirname || process.cwd(); } })(); const appPath = (() => { try { return remote.app.getAppPath(); } catch (e) { return __dirname || process.cwd(); } })();
// 读取模块映射配置(从 lib 目录读取,跨平台兼容)
let moduleMap = {};
try {
const moduleMapPath = path.join(appPath, 'lib', 'module-map.json');
if (fs.existsSync(moduleMapPath)) {
moduleMap = JSON.parse(fs.readFileSync(moduleMapPath, 'utf8'));
}
} catch (e) {
}
// 获取映射后的文件名(跨平台兼容)
function getMappedFileName(moduleName) {
if (moduleMap.mappings && moduleMap.mappings.design1 && moduleMap.mappings.design1[moduleName]) {
return moduleMap.mappings.design1[moduleName];
}
return moduleName; // 默认使用原文件名
}
const loadModule = (moduleName) => { const loadModule = (moduleName) => {
const mappedName = getMappedFileName(moduleName);
const jscPath = path.join(appPath, 'lib', 'design1', `${mappedName}.jsc`);
const jsPath = path.join(appPath, 'lib', 'design1', `${moduleName}.js`); const jsPath = path.join(appPath, 'lib', 'design1', `${moduleName}.js`);
// 优先加载映射的 .jsc 文件 // 加载 .js 文件
if (fs.existsSync(jscPath) && bytenode) {
try {
require(jscPath);
return;
} catch (e) {
}
}
// 回退到 .js 源文件
if (fs.existsSync(jsPath)) { if (fs.existsSync(jsPath)) {
try { try {
eval(fs.readFileSync(jsPath, 'utf8')); eval(fs.readFileSync(jsPath, 'utf8'));
} catch (e) { } catch (e) {
alert(`加载 ${moduleName} 失败!\n\n错误: ${e.message}`); alert(`加载 ${moduleName} 失败!\n\n错误: ${e.message}`);
} }
} else { } else {
alert(`文件不存在!\n\n请检查:\n1. ${jscPath}\n2. ${jsPath}`); alert(`文件不存在!\n\n请检查:${jsPath}`);
} }
}; };
loadModule('output'); // 先加载 output,因为 core 中的 addBackground() 需要调用 output 中的 open() loadModule('output'); // 先加载 output,因为 core 中的 addBackground() 需要调用 output 中的 open()
loadModule('core'); loadModule('core');
+5 -4
View File
@@ -54,7 +54,7 @@ window.display_func = function display_func(img1, img2, img3) {
$("#component_type").text(language_str("bg"));//"背景" $("#component_type").text(language_str("bg"));//"背景"
canvas1.discardActiveObject().renderAll(); canvas1.discardActiveObject().renderAll();
canvas2.discardActiveObject().renderAll(); canvas2.discardActiveObject().renderAll();
// 保存所有对象的 selectable 和 evented 状态,确保预览后能恢复 // 保存所有对象的 selectable 和 evented 状态,确保预览后能恢复
const objStates1 = []; const objStates1 = [];
const objStates2 = []; const objStates2 = [];
@@ -74,7 +74,7 @@ window.display_func = function display_func(img1, img2, img3) {
}; };
} }
}); });
// 过滤掉辅助线 // 过滤掉辅助线
let _objs1 = canvas1.getObjects().filter(obj => !obj.isGuideLine); let _objs1 = canvas1.getObjects().filter(obj => !obj.isGuideLine);
let g1 = []; let g1 = [];
@@ -399,7 +399,7 @@ window.display_func = function display_func(img1, img2, img3) {
// 只处理打印 // 只处理打印
printJS({ printable: printPath, type: 'image', style: 'img { width: 100%; height: auto; }' }) printJS({ printable: printPath, type: 'image', style: 'img { width: 100%; height: auto; }' })
}, },
end: function() { end: function () {
// 预览窗口关闭后,恢复所有对象的 selectable 和 evented 状态 // 预览窗口关闭后,恢复所有对象的 selectable 和 evented 状态
canvas1.getObjects().forEach((obj, index) => { canvas1.getObjects().forEach((obj, index) => {
if (!obj.isGuideLine && objStates1[index]) { if (!obj.isGuideLine && objStates1[index]) {
@@ -1033,7 +1033,8 @@ window.regenerateQrCodesAndBarcodes = function regenerateQrCodesAndBarcodes(canv
margin: 0, margin: 0,
lineColor: objMeta.color || '#000000', lineColor: objMeta.color || '#000000',
fontSize: objMeta.fontSize || 18, fontSize: objMeta.fontSize || 18,
font: objMeta.font || 'Arial' font: objMeta.font || 'Arial',
displayValue: !objMeta.show
}); });
const barcode = document.getElementById('barcode'); const barcode = document.getElementById('barcode');
const bar = barcode.toDataURL("image/png"); const bar = barcode.toDataURL("image/png");
+7 -4
View File
@@ -1603,7 +1603,7 @@ $("#qrcode_color").bind('input propertychange', function () {
window.recordState(); window.recordState();
}); });
}); });
$("#qrcode_val").bind('change', function () { $("#qrcode_val").bind('input propertychange', function () {
let val = $(this).val() ? $(this).val() : 'https://www.cardsoon.com' let val = $(this).val() ? $(this).val() : 'https://www.cardsoon.com'
let item = canvas.getActiveObject(); let item = canvas.getActiveObject();
let qr = jrQrcode.getQrBase64(val, { padding: 0, foreground: $("#qrcode_color").val() }); let qr = jrQrcode.getQrBase64(val, { padding: 0, foreground: $("#qrcode_color").val() });
@@ -1877,14 +1877,17 @@ $("#barcode_val").bind('input propertychange', function () {
$("#barcode_show").click(function () { $("#barcode_show").click(function () {
let item = canvas.getActiveObject(); let item = canvas.getActiveObject();
let idx = getIndex(canvas.getActiveObject()); let idx = getIndex(canvas.getActiveObject());
let val = $("#barcode_size").val() let val = $("#barcode_size").val();
let displayValue = true;
if ($(this).prop("checked")) { if ($(this).prop("checked")) {
objs[idx - 1].show = true; objs[idx - 1].show = true;
val = 0 displayValue = false;
} else { } else {
objs[idx - 1].show = false; objs[idx - 1].show = false;
displayValue = true;
} }
JsBarcode("#barcode", objs[idx - 1].val, { margin: 0, lineColor: objs[idx - 1].color, fontSize: val * dpi / 72, font: objs[idx - 1].font }); //val = 0; // Remove this hack
JsBarcode("#barcode", objs[idx - 1].val, { margin: 0, lineColor: objs[idx - 1].color, fontSize: val * dpi / 72, font: objs[idx - 1].font, displayValue: displayValue });
let barcode = document.getElementById('barcode'); let barcode = document.getElementById('barcode');
let bar = barcode.toDataURL("image/png"); let bar = barcode.toDataURL("image/png");
item.setSrc(bar, function (img) { item.setSrc(bar, function (img) {
+4 -40
View File
@@ -484,57 +484,21 @@ ipcRenderer.send('get-scale-rate');
// 加载design2模块 // 加载design2模块
const fs = require('fs'); const fs = require('fs');
let bytenode;
try {
bytenode = require('bytenode');
require.extensions['.dl'] = require.extensions['.jsc'];
} catch(e) {
}
const appPath = (() => { try { return remote.app.getAppPath(); } catch(e) { return __dirname || process.cwd(); } })(); const appPath = (() => { try { return remote.app.getAppPath(); } catch(e) { return __dirname || process.cwd(); } })();
// 读取模块映射配置
let moduleMap = {};
try {
const moduleMapPath = path.join(appPath, 'lib', 'module-map.json');
if (fs.existsSync(moduleMapPath)) {
moduleMap = JSON.parse(fs.readFileSync(moduleMapPath, 'utf8'));
}
} catch (e) {
}
// 获取映射后的文件名(跨平台兼容)
function getMappedFileName(moduleName) {
if (moduleMap.mappings && moduleMap.mappings.design2 && moduleMap.mappings.design2[moduleName]) {
return moduleMap.mappings.design2[moduleName];
}
return moduleName; // 默认使用原文件名
}
const loadModule = (moduleName) => { const loadModule = (moduleName) => {
const mappedName = getMappedFileName(moduleName);
const jscPath = path.join(appPath, 'lib', 'design2', `${mappedName}.jsc`);
const jsPath = path.join(appPath, 'lib', 'design2', `${moduleName}.js`); const jsPath = path.join(appPath, 'lib', 'design2', `${moduleName}.js`);
// 优先加载映射的 .jsc 文件 // 加载 .js 文件
if (fs.existsSync(jscPath) && bytenode) {
try {
require(jscPath);
return;
} catch (e) {
}
}
// 回退到 .js 源文件
if (fs.existsSync(jsPath)) { if (fs.existsSync(jsPath)) {
try { try {
eval(fs.readFileSync(jsPath, 'utf8')); eval(fs.readFileSync(jsPath, 'utf8'));
} catch (e) { } catch (e) {
alert(`加载 ${moduleName} 失败!\n\n错误: ${e.message}`); alert(`加载 ${moduleName} 失败!\n\n错误: ${e.message}`);
} }
} else { } else {
alert(`文件不存在!\n\n请检查:\n1. ${jscPath}\n2. ${jsPath}`); alert(`文件不存在!\n\n请检查:${jsPath}`);
} }
}; };
loadModule('output'); // 先加载 output,因为 core 中的 addBackground() 需要调用 output 中的 open() loadModule('output'); // 先加载 output,因为 core 中的 addBackground() 需要调用 output 中的 open()
loadModule('core'); loadModule('core');
+15 -14
View File
@@ -16,7 +16,7 @@ window.display_func = function display_func(img1, img2, img3) {
$('#component_type').text(language_str('bg')) //"背景" $('#component_type').text(language_str('bg')) //"背景"
canvas1.discardActiveObject().renderAll() canvas1.discardActiveObject().renderAll()
canvas2.discardActiveObject().renderAll() canvas2.discardActiveObject().renderAll()
// 保存所有对象的 selectable 和 evented 状态,确保预览后能恢复 // 保存所有对象的 selectable 和 evented 状态,确保预览后能恢复
const objStates1 = []; const objStates1 = [];
const objStates2 = []; const objStates2 = [];
@@ -36,7 +36,7 @@ window.display_func = function display_func(img1, img2, img3) {
}; };
} }
}); });
// 过滤掉辅助线 // 过滤掉辅助线
let _objs1 = canvas1.getObjects().filter(obj => !obj.isGuideLine) let _objs1 = canvas1.getObjects().filter(obj => !obj.isGuideLine)
let g1 = [] let g1 = []
@@ -362,7 +362,7 @@ window.display_func = function display_func(img1, img2, img3) {
// 打印背面(两面都有时,btn3 对应 btns[2] = '打印背面' // 打印背面(两面都有时,btn3 对应 btns[2] = '打印背面'
printJS({ printable: printPath4, type: 'image', style: 'img { width: 100%; height: auto; }' }) printJS({ printable: printPath4, type: 'image', style: 'img { width: 100%; height: auto; }' })
}, },
end: function() { end: function () {
// 预览窗口关闭后,恢复所有对象的 selectable 和 evented 状态 // 预览窗口关闭后,恢复所有对象的 selectable 和 evented 状态
canvas1.getObjects().forEach((obj, index) => { canvas1.getObjects().forEach((obj, index) => {
if (!obj.isGuideLine && objStates1[index]) { if (!obj.isGuideLine && objStates1[index]) {
@@ -981,8 +981,9 @@ window.regenerateQrCodesAndBarcodes = function regenerateQrCodesAndBarcodes(canv
margin: 0, margin: 0,
lineColor: objMeta.color || '#000000', lineColor: objMeta.color || '#000000',
fontSize: objMeta.fontSize || 18, fontSize: objMeta.fontSize || 18,
font: objMeta.font || 'Arial' font: objMeta.font || 'Arial',
}) displayValue: !objMeta.show
});
const barcode = document.getElementById('barcode') const barcode = document.getElementById('barcode')
const bar = barcode.toDataURL("image/png") const bar = barcode.toDataURL("image/png")
obj.setSrc(bar, function (img) { obj.setSrc(bar, function (img) {
@@ -1255,7 +1256,7 @@ window.openFile = function open(file) {
recordJson2 = [] recordJson2 = []
recordObjs1 = [] recordObjs1 = []
recordObjs2 = [] recordObjs2 = []
// 同步更新 window 变量 // 同步更新 window 变量
window.objs1 = objs1 window.objs1 = objs1
window.objs2 = objs2 window.objs2 = objs2
@@ -1265,7 +1266,7 @@ window.openFile = function open(file) {
window.recordJson2 = recordJson2 window.recordJson2 = recordJson2
window.recordObjs1 = recordObjs1 window.recordObjs1 = recordObjs1
window.recordObjs2 = recordObjs2 window.recordObjs2 = recordObjs2
if ($('#front_side').hasClass('ui-button-active')) { if ($('#front_side').hasClass('ui-button-active')) {
objs = objs1 objs = objs1
recordObjs = recordObjs1 recordObjs = recordObjs1
@@ -1291,11 +1292,11 @@ window.openFile = function open(file) {
// 使用 Promise 确保两个画布都加载完成后再保存初始状态 // 使用 Promise 确保两个画布都加载完成后再保存初始状态
let canvas1Loaded = false let canvas1Loaded = false
let canvas2Loaded = false let canvas2Loaded = false
function saveInitialState() { function saveInitialState() {
// 两个画布都加载完成后才保存初始状态 // 两个画布都加载完成后才保存初始状态
if (!canvas1Loaded || !canvas2Loaded) return if (!canvas1Loaded || !canvas2Loaded) return
// 确保使用正确的 objs1 和 objs2(从文件加载的 fo 和 bo // 确保使用正确的 objs1 和 objs2(从文件加载的 fo 和 bo
// 注意:必须使用 fo 和 bo,因为它们是直接从文件 JSON 中读取的 // 注意:必须使用 fo 和 bo,因为它们是直接从文件 JSON 中读取的
// 同时确保 objs1 和 objs2 也被正确设置 // 同时确保 objs1 和 objs2 也被正确设置
@@ -1303,13 +1304,13 @@ window.openFile = function open(file) {
objs2 = bo || [] objs2 = bo || []
window.objs1 = objs1 window.objs1 = objs1
window.objs2 = objs2 window.objs2 = objs2
// 更新背景图引用 // 更新背景图引用
background_image1 = canvas1.getObjects()[0] background_image1 = canvas1.getObjects()[0]
background_image2 = canvas2.getObjects()[0] background_image2 = canvas2.getObjects()[0]
window.background_image1 = background_image1 window.background_image1 = background_image1
window.background_image2 = background_image2 window.background_image2 = background_image2
if ($('#front_side').hasClass('ui-button-active')) { if ($('#front_side').hasClass('ui-button-active')) {
background_image = background_image1 background_image = background_image1
window.background_image = background_image1 window.background_image = background_image1
@@ -1321,7 +1322,7 @@ window.openFile = function open(file) {
objs = objs2 objs = objs2
window.objs = objs2 window.objs = objs2
} }
// 保存初始状态(使用从文件加载的 objs 数组) // 保存初始状态(使用从文件加载的 objs 数组)
recordObjs1.push(JSON.stringify(objs1)) recordObjs1.push(JSON.stringify(objs1))
const props = window.TO_JSON_PROPERTIES || ['selectable', 'hoverable', 'hoverCursor', 'text', 'fontStyle', 'fontWeight', 'underline', 'evented', 'linethrough', 'textBackgroundColor', 'diameter', 'flipped']; const props = window.TO_JSON_PROPERTIES || ['selectable', 'hoverable', 'hoverCursor', 'text', 'fontStyle', 'fontWeight', 'underline', 'evented', 'linethrough', 'textBackgroundColor', 'diameter', 'flipped'];
@@ -1333,7 +1334,7 @@ window.openFile = function open(file) {
let j2 = canvas2.toJSON(props) let j2 = canvas2.toJSON(props)
j2.objects[0].hoverCursor = 'default' j2.objects[0].hoverCursor = 'default'
recordJson2.push(j2) recordJson2.push(j2)
// 同步更新 window 变量和局部变量 // 同步更新 window 变量和局部变量
window.recordObjs1 = recordObjs1 window.recordObjs1 = recordObjs1
window.recordJson1 = recordJson1 window.recordJson1 = recordJson1
@@ -1350,7 +1351,7 @@ window.openFile = function open(file) {
step = step2 step = step2
} }
} }
canvas1.loadFromJSON(j.f, function () { canvas1.loadFromJSON(j.f, function () {
// 加载后解锁所有对象(背景除外) // 加载后解锁所有对象(背景除外)
if (typeof window.unlockAllObjects === 'function') { if (typeof window.unlockAllObjects === 'function') {
+79 -76
View File
@@ -566,7 +566,7 @@ $('#center_y_alignment').click(function () {
let itemMaxY = getCoordsMaxY(coords) let itemMaxY = getCoordsMaxY(coords)
if (itemMinY < minTop) minTop = itemMinY if (itemMinY < minTop) minTop = itemMinY
if (itemMaxY > maxBottom) maxBottom = itemMaxY if (itemMaxY > maxBottom) maxBottom = itemMaxY
} }
let groupCenterY = (minTop + maxBottom) / 2 let groupCenterY = (minTop + maxBottom) / 2
// 将所有对象对齐到中心Y值 // 将所有对象对齐到中心Y值
groupItems = [] groupItems = []
@@ -713,7 +713,7 @@ $('#center_x_alignment').click(function () {
let itemMaxX = getCoordsMaxX(coords) let itemMaxX = getCoordsMaxX(coords)
if (itemMinX < minLeft) minLeft = itemMinX if (itemMinX < minLeft) minLeft = itemMinX
if (itemMaxX > maxRight) maxRight = itemMaxX if (itemMaxX > maxRight) maxRight = itemMaxX
} }
let groupCenterX = (minLeft + maxRight) / 2 let groupCenterX = (minLeft + maxRight) / 2
// 将所有对象对齐到中心X值 // 将所有对象对齐到中心X值
groupItems = [] groupItems = []
@@ -750,8 +750,8 @@ $('#up_obj').click(function () {
recordState() recordState()
if (typeof window.updateList === 'function') { if (typeof window.updateList === 'function') {
window.updateList(); window.updateList();
} }
if (typeof window.selectObj === 'function') { if (typeof window.selectObj === 'function') {
window.selectObj(idx); window.selectObj(idx);
} }
@@ -770,8 +770,8 @@ $('#down_obj').click(function () {
objs[idx - 2] = temp objs[idx - 2] = temp
recordState() recordState()
if (typeof window.updateList === 'function') { if (typeof window.updateList === 'function') {
window.updateList(); window.updateList();
} }
if (typeof window.selectObj === 'function') { if (typeof window.selectObj === 'function') {
window.selectObj(idx - 2); window.selectObj(idx - 2);
} }
@@ -814,7 +814,7 @@ $('#set_bg').click(function () {
canvas.renderAll() canvas.renderAll()
let objItem = objs.splice(idx - 1, 1)[0] let objItem = objs.splice(idx - 1, 1)[0]
objs.unshift(objItem) objs.unshift(objItem)
// 确保背景图(索引0)的锁定属性被正确设置 // 确保背景图(索引0)的锁定属性被正确设置
setTimeout(() => { setTimeout(() => {
let bgObj = canvas.getObjects()[0]; let bgObj = canvas.getObjects()[0];
@@ -833,7 +833,7 @@ $('#set_bg').click(function () {
canvas.renderAll(); canvas.renderAll();
} }
}, 100); }, 100);
recordState() recordState()
if (typeof window.updateList === 'function') { if (typeof window.updateList === 'function') {
window.updateList(); window.updateList();
@@ -853,7 +853,7 @@ $('#previous').click(function () {
} }
step.val-- step.val--
if ($('#front_side').hasClass('ui-button-active')) { if ($('#front_side').hasClass('ui-button-active')) {
// 使用 recordJson1 和 recordObjs1 // 使用 recordJson1 和 recordObjs1
if (recordObjs1 && recordObjs1[step.val]) { if (recordObjs1 && recordObjs1[step.val]) {
@@ -863,10 +863,10 @@ $('#previous').click(function () {
window.objs1 = objs1; window.objs1 = objs1;
window.objs = objs; window.objs = objs;
} }
if (recordJson1 && recordJson1[step.val]) { if (recordJson1 && recordJson1[step.val]) {
window._isApplyingHistory = true; window._isApplyingHistory = true;
canvas.loadFromJSON(recordJson1[step.val], function() { canvas.loadFromJSON(recordJson1[step.val], function () {
// 加载后解锁所有对象(背景除外) // 加载后解锁所有对象(背景除外)
if (typeof window.unlockAllObjects === 'function') { if (typeof window.unlockAllObjects === 'function') {
window.unlockAllObjects(canvas); window.unlockAllObjects(canvas);
@@ -891,10 +891,10 @@ $('#previous').click(function () {
window.objs2 = objs2; window.objs2 = objs2;
window.objs = objs; window.objs = objs;
} }
if (recordJson2 && recordJson2[step.val]) { if (recordJson2 && recordJson2[step.val]) {
window._isApplyingHistory = true; window._isApplyingHistory = true;
canvas.loadFromJSON(recordJson2[step.val], function() { canvas.loadFromJSON(recordJson2[step.val], function () {
// 加载后解锁所有对象(背景除外) // 加载后解锁所有对象(背景除外)
if (typeof window.unlockAllObjects === 'function') { if (typeof window.unlockAllObjects === 'function') {
window.unlockAllObjects(canvas); window.unlockAllObjects(canvas);
@@ -923,7 +923,7 @@ $('#next').click(function () {
if ($('#front_side').hasClass('ui-button-active')) { if ($('#front_side').hasClass('ui-button-active')) {
maxLen = recordObjs1 ? recordObjs1.length : 0; maxLen = recordObjs1 ? recordObjs1.length : 0;
if (step.val >= maxLen - 1) { if (step.val >= maxLen - 1) {
return return
} }
} else if ($('#back_side').hasClass('ui-button-active')) { } else if ($('#back_side').hasClass('ui-button-active')) {
maxLen = recordObjs2 ? recordObjs2.length : 0; maxLen = recordObjs2 ? recordObjs2.length : 0;
@@ -935,7 +935,7 @@ $('#next').click(function () {
} }
++step.val ++step.val
if ($('#front_side').hasClass('ui-button-active')) { if ($('#front_side').hasClass('ui-button-active')) {
// 使用 recordJson1 和 recordObjs1 // 使用 recordJson1 和 recordObjs1
if (recordObjs1 && recordObjs1[step.val]) { if (recordObjs1 && recordObjs1[step.val]) {
@@ -945,10 +945,10 @@ $('#next').click(function () {
window.objs1 = objs1; window.objs1 = objs1;
window.objs = objs; window.objs = objs;
} }
if (recordJson1 && recordJson1[step.val]) { if (recordJson1 && recordJson1[step.val]) {
window._isApplyingHistory = true; window._isApplyingHistory = true;
canvas.loadFromJSON(recordJson1[step.val], function() { canvas.loadFromJSON(recordJson1[step.val], function () {
// 加载后解锁所有对象(背景除外) // 加载后解锁所有对象(背景除外)
if (typeof window.unlockAllObjects === 'function') { if (typeof window.unlockAllObjects === 'function') {
window.unlockAllObjects(canvas); window.unlockAllObjects(canvas);
@@ -973,10 +973,10 @@ $('#next').click(function () {
window.objs2 = objs2; window.objs2 = objs2;
window.objs = objs; window.objs = objs;
} }
if (recordJson2 && recordJson2[step.val]) { if (recordJson2 && recordJson2[step.val]) {
window._isApplyingHistory = true; window._isApplyingHistory = true;
canvas.loadFromJSON(recordJson2[step.val], function() { canvas.loadFromJSON(recordJson2[step.val], function () {
// 加载后解锁所有对象(背景除外) // 加载后解锁所有对象(背景除外)
if (typeof window.unlockAllObjects === 'function') { if (typeof window.unlockAllObjects === 'function') {
window.unlockAllObjects(canvas); window.unlockAllObjects(canvas);
@@ -1464,7 +1464,7 @@ function selectObject(target, index) {
function updateControls() { function updateControls() {
// 检查是否有选中对象,如果没有则直接返回 // 检查是否有选中对象,如果没有则直接返回
if (!canvas || !canvas.getActiveObject()) return; if (!canvas || !canvas.getActiveObject()) return;
const activeObj = canvas.getActiveObject(); const activeObj = canvas.getActiveObject();
$('#text_r').val(activeObj.get('angle').toFixed(0)) $('#text_r').val(activeObj.get('angle').toFixed(0))
$('#text_x').val((activeObj.get('left') - background_image.left).toFixed(0)) $('#text_x').val((activeObj.get('left') - background_image.left).toFixed(0))
@@ -1517,20 +1517,20 @@ function addPic(pointer) {
function selectPic(target, index) { function selectPic(target, index) {
// 检查是否有选中对象,如果没有则直接返回 // 检查是否有选中对象,如果没有则直接返回
if (!canvas || !canvas.getActiveObject()) return; if (!canvas || !canvas.getActiveObject()) return;
let activeObj = canvas.getActiveObject(); let activeObj = canvas.getActiveObject();
// 检查对象是否被锁定 // 检查对象是否被锁定
if (isObjectLocked(activeObj)) { if (isObjectLocked(activeObj)) {
canvas.discardActiveObject(); canvas.discardActiveObject();
canvas.renderAll(); canvas.renderAll();
return; return;
} }
//透明度 //透明度
$('#pic_control').show() $('#pic_control').show()
$("#set_bg").show(); $("#set_bg").show();
// 检查 pic_op 是否存在且有 setValue 方法 // 检查 pic_op 是否存在且有 setValue 方法
if (typeof pic_op !== 'undefined' && pic_op && typeof pic_op.setValue === 'function') { if (typeof pic_op !== 'undefined' && pic_op && typeof pic_op.setValue === 'function') {
pic_op.setValue(100 - activeObj.get('opacity') * 100); pic_op.setValue(100 - activeObj.get('opacity') * 100);
@@ -1565,8 +1565,8 @@ function addOutPic(pointer) {
objs.push({ type: 2, name: resName('OUT_PIC_'), black: false }) objs.push({ type: 2, name: resName('OUT_PIC_'), black: false })
canvas.renderAll() canvas.renderAll()
if (typeof window.updateList === 'function') { if (typeof window.updateList === 'function') {
window.updateList(); window.updateList();
} }
recordState() recordState()
}) })
}) })
@@ -1987,8 +1987,8 @@ function addQrCode(pointer) {
objs.push({ type: 8, name: resName('QR_CODE_'), color: '#000000', val: 'http://www.cardsoon.com', black: false }) objs.push({ type: 8, name: resName('QR_CODE_'), color: '#000000', val: 'http://www.cardsoon.com', black: false })
canvas.renderAll() canvas.renderAll()
if (typeof window.updateList === 'function') { if (typeof window.updateList === 'function') {
window.updateList(); window.updateList();
} }
recordState() recordState()
}) })
} }
@@ -2022,8 +2022,8 @@ function addBarCode(pointer) {
objs.push({ type: 9, name: resName('BAR_CODE_'), val: '123456789', color: '#000000', fontSize: 18, font: 'Arial', show: false, black: false }) //show是取消文字显示 objs.push({ type: 9, name: resName('BAR_CODE_'), val: '123456789', color: '#000000', fontSize: 18, font: 'Arial', show: false, black: false }) //show是取消文字显示
canvas.renderAll() canvas.renderAll()
if (typeof window.updateList === 'function') { if (typeof window.updateList === 'function') {
window.updateList(); window.updateList();
} }
recordState() recordState()
}) })
} }
@@ -2285,7 +2285,7 @@ $('#qrcode_color').bind('input propertychange', function () {
recordState() recordState()
}) })
}) })
$("#qrcode_val").bind('change', function () { $("#qrcode_val").bind('input propertychange', function () {
let val = $(this).val() ? $(this).val() : 'https://www.cardsoon.com' let val = $(this).val() ? $(this).val() : 'https://www.cardsoon.com'
let item = canvas.getActiveObject(); let item = canvas.getActiveObject();
let qr = jrQrcode.getQrBase64(val, { padding: 0, foreground: $("#qrcode_color").val() }); let qr = jrQrcode.getQrBase64(val, { padding: 0, foreground: $("#qrcode_color").val() });
@@ -2551,14 +2551,17 @@ $('#barcode_val').bind('input propertychange', function () {
$("#barcode_show").click(function () { $("#barcode_show").click(function () {
let item = canvas.getActiveObject(); let item = canvas.getActiveObject();
let idx = getIndex(canvas.getActiveObject()); let idx = getIndex(canvas.getActiveObject());
let val = $("#barcode_size").val() let val = $("#barcode_size").val();
let displayValue = true;
if ($(this).prop("checked")) { if ($(this).prop("checked")) {
objs[idx - 1].show = true; objs[idx - 1].show = true;
val = 0 displayValue = false;
} else { } else {
objs[idx - 1].show = false; objs[idx - 1].show = false;
displayValue = true;
} }
JsBarcode("#barcode", objs[idx - 1].val, { margin: 0, lineColor: objs[idx - 1].color, fontSize: val * dpi / 72, font: objs[idx - 1].font }); // val = 0; // Remove this hack
JsBarcode("#barcode", objs[idx - 1].val, { margin: 0, lineColor: objs[idx - 1].color, fontSize: val * dpi / 72, font: objs[idx - 1].font, displayValue: displayValue });
let barcode = document.getElementById('barcode'); let barcode = document.getElementById('barcode');
let bar = barcode.toDataURL("image/png"); let bar = barcode.toDataURL("image/png");
item.setSrc(bar, function (img) { item.setSrc(bar, function (img) {
@@ -2755,47 +2758,47 @@ $("#output").click(function () {
if (typeof window._design2CanvasEventsInitialized === 'undefined') { if (typeof window._design2CanvasEventsInitialized === 'undefined') {
window._design2CanvasEventsInitialized = true; window._design2CanvasEventsInitialized = true;
// 所有 canvas 事件已在 core.js 的 initCanvasEvents() 中统一处理,这里不再重复监听 // 所有 canvas 事件已在 core.js 的 initCanvasEvents() 中统一处理,这里不再重复监听
// 如果需要 canvas1 特定的 mouse:move 处理,可以在这里添加 // 如果需要 canvas1 特定的 mouse:move 处理,可以在这里添加
canvas1.on('mouse:move', (e) => { canvas1.on('mouse:move', (e) => {
if (!e.pointer || typeof background_image === 'undefined' || !background_image) return; if (!e.pointer || typeof background_image === 'undefined' || !background_image) return;
let width = canvas.getWidth() let width = canvas.getWidth()
let height = canvas.getHeight() let height = canvas.getHeight()
$('#posText').text( $('#posText').text(
'X: ' + (e.pointer.x - (width / 2 - (width / 2 - background_image.left) * zoom)).toFixed(0) + ' Y: ' + (e.pointer.y - (height / 2 - (height / 2 - background_image.top) * zoom)).toFixed(0) 'X: ' + (e.pointer.x - (width / 2 - (width / 2 - background_image.left) * zoom)).toFixed(0) + ' Y: ' + (e.pointer.y - (height / 2 - (height / 2 - background_image.top) * zoom)).toFixed(0)
) )
}) })
// 注意:以下事件已在 core.js 的 initCanvasEvents() 中统一处理,移除重复监听以避免冲突: // 注意:以下事件已在 core.js 的 initCanvasEvents() 中统一处理,移除重复监听以避免冲突:
// - mouse:down (通过 handleObjectSelected 处理) // - mouse:down (通过 handleObjectSelected 处理)
// - object:scaling, object:rotating, object:rotated // - object:scaling, object:rotating, object:rotated
// - text:editing:entered, text:editing:exited // - text:editing:entered, text:editing:exited
// - object:modified (已在 core.js 中处理) // - object:modified (已在 core.js 中处理)
// - mouse:up (已在 core.js 中处理) // - mouse:up (已在 core.js 中处理)
// 如果需要 canvas1 特定的处理逻辑,请修改 core.js 中的相应函数 // 如果需要 canvas1 特定的处理逻辑,请修改 core.js 中的相应函数
// 保留 canvas1 特定的 after:render 处理 // 保留 canvas1 特定的 after:render 处理
canvas1.on('after:render', function () { canvas1.on('after:render', function () {
if (is_bgi_add) { if (is_bgi_add) {
var image = document.getElementById('source_front') var image = document.getElementById('source_front')
ctx1.drawImage(image, (canvas.width - $('#source_front').width()) / 2, (canvas.height - $('#source_front').height()) / 2, $('#source_front').width(), $('#source_front').height()) ctx1.drawImage(image, (canvas.width - $('#source_front').width()) / 2, (canvas.height - $('#source_front').height()) / 2, $('#source_front').width(), $('#source_front').height())
} }
}) })
// 保留 canvas1 特定的 text:changed 处理 // 保留 canvas1 特定的 text:changed 处理
canvas1.on('text:changed', (e) => { canvas1.on('text:changed', (e) => {
$('#text_text').val(e.target.get('text')) $('#text_text').val(e.target.get('text'))
}) })
// 保留 canvas2 特定的 after:render 处理 // 保留 canvas2 特定的 after:render 处理
canvas2.on('after:render', function () { canvas2.on('after:render', function () {
if (is_bgi_add) { if (is_bgi_add) {
var image = document.getElementById('source_back') var image = document.getElementById('source_back')
ctx2.drawImage(image, (canvas.width - $('#source_back').width()) / 2, (canvas1.height - $('#source_back').height()) / 2, $('#source_back').width(), $('#source_back').height()) ctx2.drawImage(image, (canvas.width - $('#source_back').width()) / 2, (canvas1.height - $('#source_back').height()) / 2, $('#source_back').width(), $('#source_back').height())
} }
}) })
// 注意:以下事件已在 core.js 的 initCanvasEvents() 中统一处理,移除重复监听以避免冲突: // 注意:以下事件已在 core.js 的 initCanvasEvents() 中统一处理,移除重复监听以避免冲突:
// - mouse:down (通过 handleObjectSelected 处理) // - mouse:down (通过 handleObjectSelected 处理)
// - mouse:up (已在 core.js 中处理) // - mouse:up (已在 core.js 中处理)
// - object:scaling, object:rotating, object:rotated, object:added // - object:scaling, object:rotating, object:rotated, object:added
// - text:editing:entered, text:editing:exited // - text:editing:entered, text:editing:exited
// - object:modified (已在 core.js 中处理) // - object:modified (已在 core.js 中处理)
// 如果需要 canvas2 特定的处理逻辑,请修改 core.js 中的相应函数 // 如果需要 canvas2 特定的处理逻辑,请修改 core.js 中的相应函数
} }
-28
View File
@@ -1,28 +0,0 @@
{
"description": "模块文件名映射配置 - 用于加密后重命名文件",
"version": "1.0.0",
"mappings": {
"design1": {
"core": "core1",
"output": "output1",
"ui": "ui1"
},
"design2": {
"core": "core2",
"output": "output2",
"ui": "ui2"
},
"main": {
"index": "index1",
"design1": "design11",
"design2": "design22"
}
},
"notes": [
"修改此文件中的映射值可以重命名加密后的文件",
"例如:将 'core' 改为 'core_v2',加密后会生成 core_v2.jsc",
"修改后需要重新运行加密脚本",
"确保映射值唯一,避免冲突"
]
}
+3 -9
View File
@@ -7,20 +7,15 @@
"main": "main.js", "main": "main.js",
"scripts": { "scripts": {
"start": "electron .", "start": "electron .",
"encrypt:win": "scripts/encrypt/encrypt-electron-win.bat",
"encrypt:linux": "./scripts/encrypt/encrypt-electron.sh",
"cleanup:jsc": "node scripts/encrypt/cleanup-jsc.js",
"cleanup": "node scripts/encrypt/cleanup.js",
"restore": "node scripts/encrypt/restore.js",
"package": "electron-packager ./ SoonDesign --out ./OutApp --platform=win32 --arch=x64 --electron-version 15.1.1 --icon public/images/favicon.icns --asar --overwrite --download.mirrorOptions.mirror=https://npmmirror.com/mirrors/electron/", "package": "electron-packager ./ SoonDesign --out ./OutApp --platform=win32 --arch=x64 --electron-version 15.1.1 --icon public/images/favicon.icns --asar --overwrite --download.mirrorOptions.mirror=https://npmmirror.com/mirrors/electron/",
"dist": "webpack", "dist": "webpack",
"build": "electron-builder --arm64 --x64", "build": "electron-builder --arm64 --x64",
"build:win": "electron-builder --win --x64", "build:win": "electron-builder --win --x64",
"build:mac": "electron-builder --mac --x64", "build:mac": "electron-builder --mac --x64",
"build:linux": "electron-builder --linux --x64", "build:linux": "electron-builder --linux --x64",
"release:win": "yarn encrypt:win && yarn cleanup && yarn build:win", "release:win": "yarn build:win",
"release:mac": "yarn encrypt:linux && yarn cleanup && yarn build:mac", "release:mac": "yarn build:mac",
"release:linux": "yarn encrypt:linux && yarn cleanup && yarn build:linux" "release:linux": "yarn build:linux"
}, },
"electronPackagerConfig": { "electronPackagerConfig": {
"packageManager": "npm", "packageManager": "npm",
@@ -104,7 +99,6 @@
"dependencies": { "dependencies": {
"@electron/remote": "^2.0.8", "@electron/remote": "^2.0.8",
"buffer": "^6.0.3", "buffer": "^6.0.3",
"bytenode": "^1.5.7",
"font-list": "^1.4.2", "font-list": "^1.4.2",
"jr-qrcode": "^1.1.4", "jr-qrcode": "^1.1.4",
"jsbarcode": "^3.11.5", "jsbarcode": "^3.11.5",
-116
View File
@@ -1,116 +0,0 @@
# 加密脚本使用说明
## 📁 文件说明
- `encrypt-electron.js` - 主加密脚本
- `encrypt-electron-win.bat` - Windows 批处理脚本
- `encrypt-electron.sh` - Linux/Mac Shell 脚本
- `cleanup-jsc.js` - 清理 .jsc 文件脚本
- `cleanup.js` - 清理源文件脚本(备份到 .backup)
- `restore.js` - 恢复源文件脚本(从 .backup)
- `module-map.json` - **模块文件名映射配置**(位于 `lib` 目录)
## 🔧 模块文件名映射配置
### 功能说明
`module-map.json` 允许你自定义加密后生成的文件名。这对于:
- 版本管理:不同版本使用不同的文件名
- 安全加固:使用不易猜测的文件名
- 多版本共存:同时保留多个版本的加密文件
### 配置文件结构
```json
{
"mappings": {
"design1": {
"core": "core", // 原文件名 → 加密后文件名(不含扩展名)
"output": "output",
"ui": "ui"
},
"design2": {
"core": "core",
"output": "output",
"ui": "ui"
},
"main": {
"index": "index",
"design1": "design1",
"design2": "design2"
}
}
}
```
### 使用示例
#### 示例 1:添加版本号
```json
{
"mappings": {
"design1": {
"core": "core_v2",
"output": "output_v2",
"ui": "ui_v2"
}
}
}
```
加密后会生成:`core_v2.jsc`, `output_v2.jsc`, `ui_v2.jsc`
#### 示例 2:使用随机名称
```json
{
"mappings": {
"design1": {
"core": "a1b2c3",
"output": "x9y8z7",
"ui": "m5n6o4"
}
}
}
```
加密后会生成:`a1b2c3.jsc`, `x9y8z7.jsc`, `m5n6o4.jsc`
### 使用步骤
1. **修改配置文件**
```bash
# 编辑 lib/module-map.json
# 修改 mappings 中的值
```
2. **运行加密脚本**
```bash
yarncrypt:win # Windows
yarncrypt:linux # Linux/Mac
```
3. **验证结果**
- 检查 `lib/design1/` 和 `lib/design2/` 目录
- 确认生成了映射后的 `.jsc` 文件
### ⚠️ 注意事项
1. **唯一性**:确保映射值唯一,避免文件名冲突
2. **重新加密**:修改配置后必须重新运行加密脚本
3. **备份**:修改前建议备份配置文件
4. **兼容性**:映射后的文件名会在运行时自动识别,无需修改代码
5. **清理**:清理脚本会自动识别映射后的文件名
### 🔄 恢复默认
如果不想使用映射,将所有值改回原文件名即可:
```json
{
"mappings": {
"design1": {
"core": "core",
"output": "output",
"ui": "ui"
}
}
}
```
-95
View File
@@ -1,95 +0,0 @@
const fs = require('fs');
const path = require('path');
// 获取项目根目录(脚本在 scripts/encrypt 目录下,需要向上两级)
const projectRoot = path.resolve(__dirname, '../..');
// 读取模块映射配置(从 lib 目录读取)
const moduleMapPath = path.join(projectRoot, 'lib', 'module-map.json');
let moduleMap = {};
if (fs.existsSync(moduleMapPath)) {
try {
moduleMap = JSON.parse(fs.readFileSync(moduleMapPath, 'utf8'));
} catch (error) {
console.warn(`⚠️ 读取模块映射配置失败: ${error.message},将清理所有 .jsc 文件\n`);
}
}
// 文件映射函数:根据配置返回加密后的文件名(跨平台兼容)
function getEncryptedFileName(originalPath) {
// 使用 path 模块处理路径,确保跨平台兼容
const normalizedPath = originalPath.replace(/\\/g, '/'); // 统一使用正斜杠
const parts = normalizedPath.split('/');
const fileName = parts[parts.length - 1].replace('.js', '');
const dirName = parts[parts.length - 2];
// 检查是否有映射配置
if (moduleMap.mappings) {
if (dirName === 'design1' && moduleMap.mappings.design1 && moduleMap.mappings.design1[fileName]) {
return moduleMap.mappings.design1[fileName] + '.jsc';
}
if (dirName === 'design2' && moduleMap.mappings.design2 && moduleMap.mappings.design2[fileName]) {
return moduleMap.mappings.design2[fileName] + '.jsc';
}
if (dirName === 'lib' && moduleMap.mappings.main && moduleMap.mappings.main[fileName]) {
return moduleMap.mappings.main[fileName] + '.jsc';
}
}
// 默认:原文件名 + 'c'
return fileName + '.jsc';
}
const filesToClean = [
'lib/index.js', 'lib/design1.js', 'lib/design2.js',
'lib/design1/core.js', 'lib/design1/output.js', 'lib/design1/ui.js',
'lib/design2/core.js', 'lib/design2/output.js', 'lib/design2/ui.js'
];
console.log('正在删除所有 .jsc 文件...\n');
let deletedCount = 0;
let notFoundCount = 0;
filesToClean.forEach(filePath => {
// 跨平台兼容的路径处理
const fullPath = path.join(projectRoot, filePath);
const dir = path.dirname(fullPath);
const encryptedFileName = getEncryptedFileName(filePath);
// 尝试删除映射后的文件名
const mappedJscPath = path.join(dir, encryptedFileName);
const defaultJscPath = fullPath + 'c';
// 使用 path.resolve 进行规范化比较,确保跨平台兼容
const normalizedDefault = path.resolve(defaultJscPath);
const normalizedMapped = path.resolve(mappedJscPath);
if (fs.existsSync(mappedJscPath)) {
try {
fs.unlinkSync(mappedJscPath);
console.log(`✅ 已删除: ${mappedJscPath}`);
deletedCount++;
} catch (error) {
console.error(`❌ 删除失败: ${mappedJscPath} - ${error.message}`);
}
}
// 也尝试删除默认名称的 .jsc 文件(兼容旧版本)
if (fs.existsSync(defaultJscPath) && normalizedMapped !== normalizedDefault) {
try {
fs.unlinkSync(defaultJscPath);
console.log(`✅ 已删除: ${defaultJscPath}`);
deletedCount++;
} catch (error) {
console.error(`❌ 删除失败: ${defaultJscPath} - ${error.message}`);
}
}
if (!fs.existsSync(mappedJscPath) && !fs.existsSync(defaultJscPath)) {
notFoundCount++;
}
});
console.log(`\n完成!已删除 ${deletedCount} 个文件,${notFoundCount} 个文件不存在`);
-162
View File
@@ -1,162 +0,0 @@
/**
* 清理脚本 - 删除源 JS 文件(保留 .jsc 文件)
*
* 使用方法:
* node cleanup.js
*
* 注意:此脚本会自动备份源文件到 .backup 目录
*/
const fs = require('fs');
const path = require('path');
// 获取项目根目录(脚本在 scripts/encrypt 目录下,需要向上两级)
const projectRoot = path.resolve(__dirname, '../..');
// 读取模块映射配置(从 lib 目录读取,跨平台兼容)
const moduleMapPath = path.join(projectRoot, 'lib', 'module-map.json');
let moduleMap = {};
if (fs.existsSync(moduleMapPath)) {
try {
moduleMap = JSON.parse(fs.readFileSync(moduleMapPath, 'utf8'));
} catch (error) {
console.warn(`⚠️ 读取模块映射配置失败: ${error.message},将使用默认文件名\n`);
}
}
// 文件映射函数:根据配置返回加密后的文件名(跨平台兼容)
function getEncryptedFileName(originalPath) {
// 使用 path 模块处理路径,确保跨平台兼容
const normalizedPath = originalPath.replace(/\\/g, '/'); // 统一使用正斜杠
const parts = normalizedPath.split('/');
const fileName = parts[parts.length - 1].replace('.js', '');
const dirName = parts[parts.length - 2];
// 检查是否有映射配置
if (moduleMap.mappings) {
if (dirName === 'design1' && moduleMap.mappings.design1 && moduleMap.mappings.design1[fileName]) {
return moduleMap.mappings.design1[fileName] + '.jsc';
}
if (dirName === 'design2' && moduleMap.mappings.design2 && moduleMap.mappings.design2[fileName]) {
return moduleMap.mappings.design2[fileName] + '.jsc';
}
if (dirName === 'lib' && moduleMap.mappings.main && moduleMap.mappings.main[fileName]) {
return moduleMap.mappings.main[fileName] + '.jsc';
}
}
// 默认:原文件名 + 'c'
return fileName + '.jsc';
}
// 需要删除的源文件列表(对应的 .jsc 文件会被保留)
const filesToDelete = [
'lib/index.js',
'lib/design1.js',
'lib/design2.js',
'lib/design1/core.js',
'lib/design1/output.js',
'lib/design1/ui.js',
'lib/design2/core.js',
'lib/design2/output.js',
'lib/design2/ui.js',
];
// 备份目录
const backupDir = path.join(projectRoot, '.backup');
console.log('开始清理源文件...\n');
console.log('⚠️ 警告:此操作将删除源 JS 文件,只保留 .jsc 文件!\n');
// 创建备份目录
if (!fs.existsSync(backupDir)) {
fs.mkdirSync(backupDir, { recursive: true });
console.log(`✅ 已创建备份目录: ${backupDir}\n`);
}
let deletedCount = 0;
let notFoundCount = 0;
let errorCount = 0;
let backedUpCount = 0;
filesToDelete.forEach(filePath => {
try {
const fullPath = path.join(projectRoot, filePath);
const dir = path.dirname(fullPath);
// 检查默认名称的 .jsc 文件
const defaultJscPath = fullPath + 'c';
// 检查映射后的 .jsc 文件
const encryptedFileName = getEncryptedFileName(filePath);
const mappedJscPath = path.join(dir, encryptedFileName);
// 检查是否存在 .jsc 文件(默认或映射后的)
const jscExists = fs.existsSync(defaultJscPath) || fs.existsSync(mappedJscPath);
if (!jscExists) {
console.warn(`⚠️ 跳过: ${filePath} (对应的 .jsc 文件不存在)`);
notFoundCount++;
return;
}
// 备份源文件
if (fs.existsSync(fullPath)) {
const backupPath = path.join(backupDir, filePath);
const backupDirPath = path.dirname(backupPath);
// 确保备份目录存在
if (!fs.existsSync(backupDirPath)) {
fs.mkdirSync(backupDirPath, { recursive: true });
}
// 复制文件到备份目录
fs.copyFileSync(fullPath, backupPath);
console.log(`📦 已备份: ${filePath} -> .backup/${filePath}`);
backedUpCount++;
// 删除源文件
fs.unlinkSync(fullPath);
console.log(`✅ 已删除: ${filePath}`);
deletedCount++;
} else {
console.log(`️ 不存在: ${filePath} (可能已删除)`);
notFoundCount++;
}
} catch (error) {
console.error(`❌ 处理失败: ${filePath}`);
console.error(` 错误: ${error.message}`);
errorCount++;
}
});
// 创建备份信息文件
const backupInfo = {
timestamp: new Date().toISOString(),
files: filesToDelete.filter((filePath, index) => {
const fullPath = path.join(projectRoot, filePath);
return fs.existsSync(path.join(backupDir, filePath));
})
};
const backupInfoPath = path.join(backupDir, 'backup-info.json');
fs.writeFileSync(backupInfoPath, JSON.stringify(backupInfo, null, 2));
console.log(`\n📝 已创建备份信息文件: .backup/backup-info.json`);
console.log('\n' + '='.repeat(50));
console.log(`清理完成!`);
console.log(` 已备份: ${backedUpCount}`);
console.log(` 已删除: ${deletedCount}`);
console.log(` 未找到: ${notFoundCount}`);
console.log(` 错误: ${errorCount}`);
console.log(` 备份位置: ${backupDir}`);
console.log('='.repeat(50));
if (errorCount > 0) {
console.log('\n⚠️ 有文件处理失败,请检查错误信息');
process.exit(1);
} else {
console.log('\n✅ 清理完成!源文件已备份到 .backup 目录');
console.log('\n💡 恢复方法:');
console.log(' 运行: node scripts/encrypt/restore.js');
console.log(' 或手动从 .backup 目录复制文件回原位置');
}
-8
View File
@@ -1,8 +0,0 @@
@echo off
chcp 65001 >nul
set ELECTRON_RUN_AS_NODE=true
set NODE_OPTIONS=--max-old-space-size=4096
cd /d "%~dp0\..\.."
electron scripts\encrypt\encrypt-electron.js
pause
-154
View File
@@ -1,154 +0,0 @@
// 设置输出编码为 UTF-8(修复 Windows 中文乱码问题)
if (process.platform === 'win32') {
process.stdout.setDefaultEncoding('utf8');
process.stderr.setDefaultEncoding('utf8');
// 设置环境变量确保中文正确显示
if (!process.env.CHCP) {
process.env.CHCP = '65001';
}
}
// 确保在 Electron 环境中运行
if (!process.versions.electron) {
console.error('❌ 错误:此脚本必须在 Electron 环境中运行!');
console.error('请使用以下方式运行:');
console.error(' Windows: encrypt-electron-win.bat');
console.error(' Linux/Mac: ./encrypt-electron.sh');
console.error(' 或: yarncrypt:win / yaryarnpt:linux');
process.exit(1);
}
const bytenode = require('bytenode');
const fs = require('fs');
const path = require('path');
// 获取项目根目录(脚本在 scripts/encrypt 目录下,需要向上两级)
const projectRoot = path.resolve(__dirname, '../..');
// 读取模块映射配置(从 lib 目录读取)
const moduleMapPath = path.join(projectRoot, 'lib', 'module-map.json');
let moduleMap = {};
if (fs.existsSync(moduleMapPath)) {
try {
moduleMap = JSON.parse(fs.readFileSync(moduleMapPath, 'utf8'));
console.log('✅ 已加载模块映射配置\n');
} catch (error) {
console.warn(`⚠️ 读取模块映射配置失败: ${error.message},使用默认文件名\n`);
}
}
// 文件映射函数:根据配置返回加密后的文件名(跨平台兼容)
function getEncryptedFileName(originalPath) {
// 使用 path 模块处理路径,确保跨平台兼容
const normalizedPath = originalPath.replace(/\\/g, '/'); // 统一使用正斜杠
const parts = normalizedPath.split('/');
const fileName = parts[parts.length - 1].replace('.js', '');
const dirName = parts[parts.length - 2];
// 检查是否有映射配置
if (moduleMap.mappings) {
if (dirName === 'design1' && moduleMap.mappings.design1 && moduleMap.mappings.design1[fileName]) {
return moduleMap.mappings.design1[fileName] + '.jsc';
}
if (dirName === 'design2' && moduleMap.mappings.design2 && moduleMap.mappings.design2[fileName]) {
return moduleMap.mappings.design2[fileName] + '.jsc';
}
if (dirName === 'lib' && moduleMap.mappings.main && moduleMap.mappings.main[fileName]) {
return moduleMap.mappings.main[fileName] + '.jsc';
}
}
// 默认:原文件名 + 'c'
return fileName + '.jsc';
}
const filesToEncrypt = [
'lib/index.js', 'lib/design1.js', 'lib/design2.js',
'lib/design1/core.js', 'lib/design1/output.js', 'lib/design1/ui.js',
'lib/design2/core.js', 'lib/design2/output.js', 'lib/design2/ui.js'
];
// 先删除所有旧的 .jsc 文件(包括映射后的文件名)
console.log('正在删除旧的 .jsc 文件...');
let deletedCount = 0;
filesToEncrypt.forEach(filePath => {
// 删除默认名称的 .jsc 文件(跨平台兼容)
const fullPath = path.join(projectRoot, filePath);
const defaultJscPath = fullPath + 'c';
if (fs.existsSync(defaultJscPath)) {
try {
fs.unlinkSync(defaultJscPath);
deletedCount++;
} catch (error) {
console.error(`⚠️ 删除失败: ${defaultJscPath} - ${error.message}`);
}
}
// 删除映射后的 .jsc 文件(跨平台兼容)
const dir = path.dirname(fullPath);
const encryptedFileName = getEncryptedFileName(filePath);
const mappedJscPath = path.join(dir, encryptedFileName);
// 使用 path.resolve 进行规范化比较,确保跨平台兼容
const normalizedDefault = path.resolve(defaultJscPath);
const normalizedMapped = path.resolve(mappedJscPath);
if (fs.existsSync(mappedJscPath) && normalizedMapped !== normalizedDefault) {
try {
fs.unlinkSync(mappedJscPath);
deletedCount++;
} catch (error) {
console.error(`⚠️ 删除失败: ${mappedJscPath} - ${error.message}`);
}
}
});
console.log(`已删除 ${deletedCount} 个旧的 .jsc 文件\n`);
// 开始编译
let successCount = 0, failCount = 0;
filesToEncrypt.forEach(filePath => {
try {
const fullPath = path.join(projectRoot, filePath);
if (!fs.existsSync(fullPath)) {
console.error(`❌ 文件不存在: ${filePath}`);
failCount++;
return;
}
// 编译文件(bytenode 会生成默认的 .jsc 文件)
bytenode.compileFile({ filename: fullPath });
// 检查默认的 .jsc 文件是否生成
const defaultJscPath = fullPath + 'c';
if (!fs.existsSync(defaultJscPath)) {
console.error(`❌ 编译失败: ${filePath}`);
failCount++;
return;
}
// 如果配置了映射,重命名文件(跨平台兼容)
const dir = path.dirname(fullPath);
const encryptedFileName = getEncryptedFileName(filePath);
const mappedJscPath = path.join(dir, encryptedFileName);
// 使用 path.resolve 进行规范化比较,确保跨平台兼容
const normalizedDefault = path.resolve(defaultJscPath);
const normalizedMapped = path.resolve(mappedJscPath);
if (normalizedMapped !== normalizedDefault) {
// 重命名文件
fs.renameSync(defaultJscPath, mappedJscPath);
console.log(`${filePath}${encryptedFileName}`);
} else {
console.log(`${filePath}${path.basename(defaultJscPath)}`);
}
successCount++;
} catch (error) {
console.error(`❌ 编译失败: ${filePath} - ${error.message}`);
failCount++;
}
});
console.log(`\n编译完成!成功: ${successCount}, 失败: ${failCount}`);
process.exit(failCount > 0 ? 1 : 0);
-14
View File
@@ -1,14 +0,0 @@
#!/bin/bash
# 设置 UTF-8 编码环境变量,确保中文正确显示
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
export LC_CTYPE=en_US.UTF-8
export ELECTRON_RUN_AS_NODE=true
export NODE_OPTIONS=--max-old-space-size=4096
# 切换到项目根目录
cd "$(dirname "$0")/../.."
# 运行加密脚本
electron scripts/encrypt/encrypt-electron.js
-126
View File
@@ -1,126 +0,0 @@
/**
* 恢复脚本 - 从备份目录恢复源 JS 文件
*
* 使用方法:
* node restore.js
*
* 此脚本会从 .backup 目录恢复所有备份的源文件
*/
const fs = require('fs');
const path = require('path');
// 获取项目根目录(脚本在 scripts/encrypt 目录下,需要向上两级)
const projectRoot = path.resolve(__dirname, '../..');
// 备份目录
const backupDir = path.join(projectRoot, '.backup');
const backupInfoPath = path.join(backupDir, 'backup-info.json');
console.log('开始恢复源文件...\n');
// 检查备份目录是否存在
if (!fs.existsSync(backupDir)) {
console.error('❌ 错误:备份目录不存在!');
console.error(` 路径: ${backupDir}`);
console.error('\n💡 提示:如果没有备份,请从 Git 仓库恢复文件');
process.exit(1);
}
// 检查备份信息文件
if (!fs.existsSync(backupInfoPath)) {
console.warn('⚠️ 警告:备份信息文件不存在,将尝试恢复所有 .js 文件\n');
}
let restoredCount = 0;
let notFoundCount = 0;
let errorCount = 0;
// 读取备份信息
let filesToRestore = [];
if (fs.existsSync(backupInfoPath)) {
try {
const backupInfo = JSON.parse(fs.readFileSync(backupInfoPath, 'utf8'));
filesToRestore = backupInfo.files || [];
console.log(`📋 从备份信息读取到 ${filesToRestore.length} 个文件\n`);
} catch (error) {
console.warn(`⚠️ 无法读取备份信息文件: ${error.message}\n`);
}
}
// 如果没有备份信息,扫描备份目录
if (filesToRestore.length === 0) {
console.log('📂 扫描备份目录...\n');
function scanDir(dir, baseDir = '') {
const files = [];
const entries = fs.readdirSync(dir, { withFileTypes: true });
for (const entry of entries) {
const fullPath = path.join(dir, entry.name);
const relativePath = path.join(baseDir, entry.name);
if (entry.isDirectory()) {
files.push(...scanDir(fullPath, relativePath));
} else if (entry.isFile() && entry.name.endsWith('.js')) {
files.push(relativePath);
}
}
return files;
}
filesToRestore = scanDir(backupDir);
console.log(`📋 扫描到 ${filesToRestore.length} 个备份文件\n`);
}
if (filesToRestore.length === 0) {
console.error('❌ 错误:没有找到任何备份文件!');
process.exit(1);
}
// 恢复文件
filesToRestore.forEach(filePath => {
try {
const backupPath = path.join(backupDir, filePath);
const restorePath = path.join(projectRoot, filePath);
// 检查备份文件是否存在
if (!fs.existsSync(backupPath)) {
console.warn(`⚠️ 备份文件不存在: ${filePath}`);
notFoundCount++;
return;
}
// 确保目标目录存在
const restoreDir = path.dirname(restorePath);
if (!fs.existsSync(restoreDir)) {
fs.mkdirSync(restoreDir, { recursive: true });
}
// 复制文件
fs.copyFileSync(backupPath, restorePath);
console.log(`✅ 已恢复: ${filePath}`);
restoredCount++;
} catch (error) {
console.error(`❌ 恢复失败: ${filePath}`);
console.error(` 错误: ${error.message}`);
errorCount++;
}
});
console.log('\n' + '='.repeat(50));
console.log(`恢复完成!`);
console.log(` 已恢复: ${restoredCount}`);
console.log(` 未找到: ${notFoundCount}`);
console.log(` 错误: ${errorCount}`);
console.log('='.repeat(50));
if (errorCount > 0) {
console.log('\n⚠️ 有文件恢复失败,请检查错误信息');
process.exit(1);
} else {
console.log('\n✅ 恢复完成!源文件已从备份目录恢复');
console.log('\n💡 提示:');
console.log(' - 备份文件仍保留在 .backup 目录');
console.log(' - 如需删除备份,请手动删除 .backup 目录');
}