preload.js & data

This commit is contained in:
chenqiang 2025-09-09 22:52:15 +08:00
parent 93daaf49f4
commit 1c7dd98118
5 changed files with 91 additions and 170 deletions

View File

@ -1,4 +1,4 @@
const { getSystemDbPath, getUserDbPath } = require('./path.js'); // 确保这行代码存在 const { getSystemDbPath, getUserDbPath } = require('./path.js');
const { systemSchema, userSchema, defaultData } = require('./schema.js'); const { systemSchema, userSchema, defaultData } = require('./schema.js');
const { openDatabase, batchInsert } = require('./utils.js'); const { openDatabase, batchInsert } = require('./utils.js');
const bcrypt = require('bcryptjs'); const bcrypt = require('bcryptjs');

View File

@ -1,5 +1,5 @@
const fs = require('fs'); // 确保这行代码存在
const path = require('path'); const path = require('path');
const fs = require('fs');
const { app } = require('electron'); const { app } = require('electron');
// 判断是否为开发环境 // 判断是否为开发环境
@ -7,31 +7,16 @@ const isDev = process.env.NODE_ENV === 'development' || !app.isPackaged;
// 检测是否为便携模式 // 检测是否为便携模式
let isPortable = false; let isPortable = false;
let appDir; const exePath = app.getPath('exe');
let portableFlagPath; const appDir = path.dirname(exePath);
const portableFlagPath = path.join(appDir, 'portable.txt');
// 确保app已经初始化后再获取路径 // 如果应用目录中存在portable.txt文件则启用便携模式
if (app && app.getPath) { if (!isDev && fs.existsSync(portableFlagPath)) {
try { isPortable = true;
// 在Windows上使用process.execPath获取可执行文件路径 console.log('启用便携模式');
const exePath = process.execPath;
appDir = path.dirname(exePath);
portableFlagPath = path.join(appDir, 'portable.txt');
// 如果应用目录中存在portable.txt文件则启用便携模式
if (!isDev && fs.existsSync(portableFlagPath)) {
isPortable = true;
console.log('启用便携模式');
}
} catch (error) {
console.error('获取应用路径时出错:', error);
appDir = process.cwd();
}
} else {
appDir = process.cwd();
} }
// 在第35行左右更新数据目录选择逻辑
// 根据模式选择数据目录 // 根据模式选择数据目录
let dataDir; let dataDir;
if (isDev) { if (isDev) {
@ -42,35 +27,15 @@ if (isDev) {
dataDir = path.join(appDir, 'data'); dataDir = path.join(appDir, 'data');
} else { } else {
// 非便携模式数据存储在应用同级的data目录 // 非便携模式数据存储在应用同级的data目录
dataDir = path.join(path.dirname(appDir), 'data');
}
// 增强路径处理:添加备选路径检测
if (!isDev && !fs.existsSync(dataDir) && fs.existsSync(path.join(appDir, 'data'))) {
console.log('检测到应用目录下存在data目录自动切换到便携模式');
dataDir = path.join(appDir, 'data'); dataDir = path.join(appDir, 'data');
isPortable = true;
} }
// 确保数据目录存在 // 确保数据目录存在
if (!fs.existsSync(dataDir)) { if (!fs.existsSync(dataDir)) {
try { fs.mkdirSync(dataDir, { recursive: true });
fs.mkdirSync(dataDir, { recursive: true }); console.log(`创建数据目录: ${dataDir}`);
console.log(`创建数据目录: ${dataDir}`);
} catch (mkdirError) {
console.error(`创建数据目录失败: ${dataDir}`, mkdirError);
// 作为最后的备选方案,使用当前工作目录
dataDir = process.cwd();
console.log(`备选数据目录: ${dataDir}`);
}
} }
// 添加更多调试日志
console.log(`当前运行模式: ${isDev ? '开发环境' : (isPortable ? '便携模式' : '安装模式')}`);
console.log(`数据目录路径: ${dataDir}`);
console.log(`系统数据库路径: ${path.join(dataDir, 'system.db')}`);
console.log(`用户数据库路径: ${path.join(dataDir, 'user.db')}`);
// 系统数据库路径 // 系统数据库路径
function getSystemDbPath() { function getSystemDbPath() {
return path.join(dataDir, 'system.db'); return path.join(dataDir, 'system.db');
@ -84,7 +49,5 @@ function getUserDbPath() {
// 导出函数供其他模块使用 // 导出函数供其他模块使用
module.exports = { module.exports = {
getSystemDbPath, getSystemDbPath,
getUserDbPath, getUserDbPath
dataDir, // 导出数据目录路径,方便其他地方使用
isPortable // 导出便携模式状态
}; };

View File

@ -41,57 +41,28 @@ protocol.registerSchemesAsPrivileged([
let mainWindow = null; let mainWindow = null;
async function createWindow() { async function createWindow() {
console.log('开始创建应用窗口...'); // Create the browser window.
// 创建浏览器窗口
mainWindow = new BrowserWindow({ mainWindow = new BrowserWindow({
width: 800, width: 800, // 默认宽度(实际会被最大化覆盖)
height: 600, height: 600, // 默认高度(实际会被最大化覆盖)
// 确保在Windows 7上能正常显示 show: false, // 先隐藏窗口,避免闪烁
show: false,
webPreferences: { webPreferences: {
// 更新preload路径使用__dirname确保路径正确 // 更新preload路径为background目录下的preload.js
preload: path.join(__dirname, 'preload.js'), preload: require("path").join(process.cwd(), "background/preload.js"),
nodeIntegration: false, nodeIntegration: false,
contextIsolation: true, contextIsolation: true,
} },
}); });
// 设置隐藏菜单栏 // 设置隐藏菜单栏
mainWindow.setMenu(null); mainWindow.setMenu(null);
// 添加窗口准备好显示时的事件 // 在窗口显示前设置最大化
mainWindow.once('ready-to-show', () => { mainWindow.maximize();
console.log('窗口准备就绪,开始显示...'); // 然后显示窗口
try { mainWindow.show();
// 在Windows 7上使用try-catch确保最大化操作不失败
try {
mainWindow.maximize();
console.log('窗口已最大化');
} catch (e) {
console.error('窗口最大化失败:', e);
}
// 显示窗口
mainWindow.show();
console.log('窗口已显示');
} catch (error) {
console.error('显示窗口时出错:', error);
// 作为备用方案,再次尝试显示窗口
mainWindow.show();
}
});
// 添加窗口显示事件 // 添加窗口关闭事件监听
mainWindow.on('show', () => {
console.log('窗口已成功显示');
});
// 添加webContents加载完成事件
mainWindow.webContents.on('did-finish-load', () => {
console.log('页面加载完成');
});
// 添加窗口关闭事件监听 - 保持原有逻辑
mainWindow.on("close", (event) => { mainWindow.on("close", (event) => {
console.log("检测到窗口关闭事件"); console.log("检测到窗口关闭事件");
@ -133,14 +104,13 @@ async function createWindow() {
} }
}); });
// 加载应用内容
if (process.env.WEBPACK_DEV_SERVER_URL) { if (process.env.WEBPACK_DEV_SERVER_URL) {
// 开发模式加载开发服务器URL // Load the url of the dev server if in development mode
await mainWindow.loadURL(process.env.WEBPACK_DEV_SERVER_URL); await mainWindow.loadURL(process.env.WEBPACK_DEV_SERVER_URL);
if (!process.env.IS_TEST) mainWindow.webContents.openDevTools(); if (!process.env.IS_TEST) mainWindow.webContents.openDevTools();
} else { } else {
createProtocol("app"); createProtocol("app");
// 生产模式加载本地HTML文件 // Load the index.html when not in development
mainWindow.loadURL("app://./index.html"); mainWindow.loadURL("app://./index.html");
} }
} }
@ -242,7 +212,6 @@ app.on("ready", async () => {
console.error("数据库初始化失败:", error); console.error("数据库初始化失败:", error);
} }
// 创建窗口
createWindow(); createWindow();
}); });
@ -274,8 +243,48 @@ ipcMain.handle("hashTest", async (event, inputString) => {
} }
}); });
// 移除所有重复的IPC处理器 // 数据库相关IPC接口
// 这些处理器应该已经在各个service的init函数中被注册了 ipcMain.handle("check-database-initialized", async () => {
try {
return await checkDatabaseInitialized();
} catch (error) {
console.error("Failed to check database initialization:", error);
return false;
}
});
ipcMain.handle("initialize-database", async () => {
try {
return await initializeDatabase();
} catch (error) {
console.error("Failed to initialize database:", error);
return false;
}
});
// 检查user.db是否存在
ipcMain.handle("checkUserDbExists", async () => {
try {
const userDbPath = getUserDbPath();
return fs.existsSync(userDbPath);
} catch (error) {
console.error("检查user.db文件是否存在失败:", error);
return false;
}
});
// 静默初始化用户数据库
ipcMain.handle("initializeUserDatabaseSilently", async () => {
try {
console.log("开始静默初始化用户数据库...");
const result = await initializeUserDatabase();
console.log("静默初始化用户数据库完成:", result);
return { success: true, result };
} catch (error) {
console.error("静默初始化用户数据库失败:", error);
return { success: false, error: error.message };
}
});
// 检测是否为便携模式运行 // 检测是否为便携模式运行
let isPortableMode = false; let isPortableMode = false;

View File

@ -1,4 +1,4 @@
const fs = require('fs'); // 添加缺失的fs模块导入 const fs = require('fs');
const path = require('path'); const path = require('path');
const { execSync } = require('child_process'); const { execSync } = require('child_process');
@ -38,15 +38,13 @@ function prepareForBuild() {
const dataDir = path.join(__dirname, 'data'); const dataDir = path.join(__dirname, 'data');
if (!fs.existsSync(dataDir)) { if (!fs.existsSync(dataDir)) {
fs.mkdirSync(dataDir); fs.mkdirSync(dataDir);
fs.writeFileSync(path.join(dataDir, '.gitignore'), '*\n!.gitignore');
console.log('创建data目录完成'); console.log('创建data目录完成');
} }
// 创建便携模式标识文件 // 创建.gitignore文件如果不存在
const portableFlagPath = path.join(__dirname, 'portable.txt'); const gitignorePath = path.join(dataDir, '.gitignore');
if (!fs.existsSync(portableFlagPath)) { if (!fs.existsSync(gitignorePath)) {
fs.writeFileSync(portableFlagPath, ''); fs.writeFileSync(gitignorePath, '*\n!.gitignore');
console.log('创建便携模式标识文件完成');
} }
console.log('准备工作完成'); console.log('准备工作完成');
@ -68,64 +66,20 @@ function buildPortableApp() {
process.env.ELECTRON_BUILDER_SKIP_NOTARIZATION = 'true'; process.env.ELECTRON_BUILDER_SKIP_NOTARIZATION = 'true';
process.env.ELECTRON_SKIP_NOTARIZE = 'true'; process.env.ELECTRON_SKIP_NOTARIZE = 'true';
// 使用最基本的命令行参数 // 使用最基本的命令行参数,移除不支持的--no-sign
execSync( execSync(
'npm run electron:build -- --win portable --ia32 --x64 --publish never', 'npm run electron:build -- --win portable --ia32 --x64 --publish never',
{ stdio: 'inherit' } { stdio: 'inherit' }
); );
// 构建完成后,创建最终的便携应用结构
console.log('创建便携应用最终结构...');
createPortableStructure();
console.log('Windows 7便携应用构建完成'); console.log('Windows 7便携应用构建完成');
console.log('构建产物位于 dist_electron 目录下的 portable-app 文件夹'); console.log('构建产物位于 dist_electron 目录');
} catch (error) { } catch (error) {
console.error('构建失败:', error); console.error('构建失败:', error);
process.exit(1); process.exit(1);
} }
} }
// 创建便携应用最终结构可执行文件和data目录在同一级
function createPortableStructure() {
const distDir = path.join(__dirname, 'dist_electron');
const portableAppDir = path.join(distDir, 'portable-app');
// 创建目标目录
if (fs.existsSync(portableAppDir)) {
deleteFolderRecursive(portableAppDir);
}
fs.mkdirSync(portableAppDir, { recursive: true });
// 复制可执行文件
const exeFiles = fs.readdirSync(distDir).filter(file => file.endsWith('.exe'));
if (exeFiles.length > 0) {
const exeFile = exeFiles[0];
fs.copyFileSync(path.join(distDir, exeFile), path.join(portableAppDir, exeFile));
console.log(`已复制可执行文件: ${exeFile}`);
}
// 创建data目录并复制数据库文件
const srcDataDir = path.join(__dirname, 'data');
const destDataDir = path.join(portableAppDir, 'data');
fs.mkdirSync(destDataDir, { recursive: true });
// 复制data目录下的所有文件
if (fs.existsSync(srcDataDir)) {
const dataFiles = fs.readdirSync(srcDataDir);
dataFiles.forEach(file => {
const srcPath = path.join(srcDataDir, file);
const destPath = path.join(destDataDir, file);
fs.copyFileSync(srcPath, destPath);
console.log(`已复制数据文件: ${file}`);
});
}
// 确保portable.txt文件在可执行文件同级目录
fs.copyFileSync(path.join(__dirname, 'portable.txt'), path.join(portableAppDir, 'portable.txt'));
console.log('已复制便携模式标识文件');
}
// 主函数 // 主函数
function main() { function main() {
console.log('==== Windows 7便携应用打包工具 ===='); console.log('==== Windows 7便携应用打包工具 ====');

View File

@ -15,7 +15,7 @@ module.exports = {
// 基础配置 // 基础配置
nodeIntegration: false, nodeIntegration: false,
contextIsolation: true, contextIsolation: true,
// 更新preload路径到新位置 // 更新preload路径为background目录下的preload.js
preload: "background/preload.js", preload: "background/preload.js",
mainProcessFile: "background/main.js", mainProcessFile: "background/main.js",
lintPreloadFiles: false, lintPreloadFiles: false,
@ -60,7 +60,7 @@ module.exports = {
main: "background.js" main: "background.js"
}, },
// Windows构建配置 // Windows构建配置 - 修改输出目录结构
win: { win: {
// 架构设置 // 架构设置
target: [ target: [
@ -69,7 +69,6 @@ module.exports = {
arch: ["ia32", "x64"], arch: ["ia32", "x64"],
}, },
], ],
// 图标设置
icon: "public/favicon.ico", icon: "public/favicon.ico",
// 明确禁用签名的多种配置 // 明确禁用签名的多种配置
sign: false, sign: false,
@ -77,39 +76,35 @@ module.exports = {
certificateFile: null, certificateFile: null,
certificatePassword: null, certificatePassword: null,
// 额外资源配置 // 额外资源配置 - 确保data目录被正确打包
extraResources: [ extraResources: [
{
from: "data",
to: "data",
filter: ["**/*"], // 包含data目录中的所有内容
},
{ {
from: "background", from: "background",
to: "background", to: "background",
filter: ["**/*"], filter: ["**/*"],
}, },
{
from: "data",
to: "data",
filter: ["**/*"], // 确保包含data目录下的所有文件
},
{
from: "portable.txt",
to: ".", // 确保portable.txt文件放在根目录
},
], ],
}, },
// 便携应用特定配置 // 便携应用特定配置 - 修改输出结构
portable: { portable: {
artifactName: "统计技能考试系统_便携版_${version}_${arch}.exe", // 修改artifactName以控制输出路径
}, artifactName: "portable-app/统计技能考试系统_便携版_${version}_${arch}.exe",
// 发布设置
publish: {
provider: 'generic',
url: 'https://example.com/',
}, },
// 全局禁用签名配置 // 全局禁用签名配置
forceCodeSigning: false, forceCodeSigning: false,
asar: true, asar: true,
// 配置输出目录
directories: {
output: "dist_electron",
},
}, },
}, },
}, },