From 1c7dd98118eb9b239a089de78ec49e1bf74f6fe9 Mon Sep 17 00:00:00 2001 From: chenqiang Date: Tue, 9 Sep 2025 22:52:15 +0800 Subject: [PATCH] preload.js & data --- background/db/index.js | 2 +- background/db/path.js | 59 ++++----------------- background/main.js | 103 ++++++++++++++++++++---------------- package-windows-portable.js | 60 +++------------------ vue.config.js | 37 ++++++------- 5 files changed, 91 insertions(+), 170 deletions(-) diff --git a/background/db/index.js b/background/db/index.js index f5c0ff6..b2c3cf3 100644 --- a/background/db/index.js +++ b/background/db/index.js @@ -1,4 +1,4 @@ -const { getSystemDbPath, getUserDbPath } = require('./path.js'); // 确保这行代码存在 +const { getSystemDbPath, getUserDbPath } = require('./path.js'); const { systemSchema, userSchema, defaultData } = require('./schema.js'); const { openDatabase, batchInsert } = require('./utils.js'); const bcrypt = require('bcryptjs'); diff --git a/background/db/path.js b/background/db/path.js index dd2c0fb..845f42f 100644 --- a/background/db/path.js +++ b/background/db/path.js @@ -1,5 +1,5 @@ -const fs = require('fs'); // 确保这行代码存在 const path = require('path'); +const fs = require('fs'); const { app } = require('electron'); // 判断是否为开发环境 @@ -7,31 +7,16 @@ const isDev = process.env.NODE_ENV === 'development' || !app.isPackaged; // 检测是否为便携模式 let isPortable = false; -let appDir; -let portableFlagPath; +const exePath = app.getPath('exe'); +const appDir = path.dirname(exePath); +const portableFlagPath = path.join(appDir, 'portable.txt'); -// 确保app已经初始化后再获取路径 -if (app && app.getPath) { - try { - // 在Windows上,使用process.execPath获取可执行文件路径 - 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(); +// 如果应用目录中存在portable.txt文件,则启用便携模式 +if (!isDev && fs.existsSync(portableFlagPath)) { + isPortable = true; + console.log('启用便携模式'); } -// 在第35行左右,更新数据目录选择逻辑 // 根据模式选择数据目录 let dataDir; if (isDev) { @@ -42,35 +27,15 @@ if (isDev) { dataDir = path.join(appDir, 'data'); } else { // 非便携模式:数据存储在应用同级的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'); - isPortable = true; } // 确保数据目录存在 if (!fs.existsSync(dataDir)) { - try { - fs.mkdirSync(dataDir, { recursive: true }); - console.log(`创建数据目录: ${dataDir}`); - } catch (mkdirError) { - console.error(`创建数据目录失败: ${dataDir}`, mkdirError); - // 作为最后的备选方案,使用当前工作目录 - dataDir = process.cwd(); - console.log(`备选数据目录: ${dataDir}`); - } + fs.mkdirSync(dataDir, { recursive: true }); + 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() { return path.join(dataDir, 'system.db'); @@ -84,7 +49,5 @@ function getUserDbPath() { // 导出函数供其他模块使用 module.exports = { getSystemDbPath, - getUserDbPath, - dataDir, // 导出数据目录路径,方便其他地方使用 - isPortable // 导出便携模式状态 + getUserDbPath }; \ No newline at end of file diff --git a/background/main.js b/background/main.js index c9d093d..aa49154 100644 --- a/background/main.js +++ b/background/main.js @@ -41,57 +41,28 @@ protocol.registerSchemesAsPrivileged([ let mainWindow = null; async function createWindow() { - console.log('开始创建应用窗口...'); - - // 创建浏览器窗口 + // Create the browser window. mainWindow = new BrowserWindow({ - width: 800, - height: 600, - // 确保在Windows 7上能正常显示 - show: false, + width: 800, // 默认宽度(实际会被最大化覆盖) + height: 600, // 默认高度(实际会被最大化覆盖) + show: false, // 先隐藏窗口,避免闪烁 webPreferences: { - // 更新preload路径,使用__dirname确保路径正确 - preload: path.join(__dirname, 'preload.js'), + // 更新preload路径为background目录下的preload.js + preload: require("path").join(process.cwd(), "background/preload.js"), nodeIntegration: false, contextIsolation: true, - } + }, }); // 设置隐藏菜单栏 mainWindow.setMenu(null); - // 添加窗口准备好显示时的事件 - mainWindow.once('ready-to-show', () => { - console.log('窗口准备就绪,开始显示...'); - try { - // 在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.maximize(); + // 然后显示窗口 + mainWindow.show(); - // 添加窗口显示事件 - mainWindow.on('show', () => { - console.log('窗口已成功显示'); - }); - - // 添加webContents加载完成事件 - mainWindow.webContents.on('did-finish-load', () => { - console.log('页面加载完成'); - }); - - // 添加窗口关闭事件监听 - 保持原有逻辑 + // 添加窗口关闭事件监听 mainWindow.on("close", (event) => { console.log("检测到窗口关闭事件"); @@ -133,14 +104,13 @@ async function createWindow() { } }); - // 加载应用内容 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); if (!process.env.IS_TEST) mainWindow.webContents.openDevTools(); } else { createProtocol("app"); - // 生产模式加载本地HTML文件 + // Load the index.html when not in development mainWindow.loadURL("app://./index.html"); } } @@ -242,7 +212,6 @@ app.on("ready", async () => { console.error("数据库初始化失败:", error); } - // 创建窗口 createWindow(); }); @@ -274,8 +243,48 @@ ipcMain.handle("hashTest", async (event, inputString) => { } }); -// 移除所有重复的IPC处理器 -// 这些处理器应该已经在各个service的init函数中被注册了 +// 数据库相关IPC接口 +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; diff --git a/package-windows-portable.js b/package-windows-portable.js index 1a5b45d..f22b8a2 100644 --- a/package-windows-portable.js +++ b/package-windows-portable.js @@ -1,4 +1,4 @@ -const fs = require('fs'); // 添加缺失的fs模块导入 +const fs = require('fs'); const path = require('path'); const { execSync } = require('child_process'); @@ -38,15 +38,13 @@ function prepareForBuild() { const dataDir = path.join(__dirname, 'data'); if (!fs.existsSync(dataDir)) { fs.mkdirSync(dataDir); - fs.writeFileSync(path.join(dataDir, '.gitignore'), '*\n!.gitignore'); console.log('创建data目录完成'); } - // 创建便携模式标识文件 - const portableFlagPath = path.join(__dirname, 'portable.txt'); - if (!fs.existsSync(portableFlagPath)) { - fs.writeFileSync(portableFlagPath, ''); - console.log('创建便携模式标识文件完成'); + // 创建.gitignore文件(如果不存在) + const gitignorePath = path.join(dataDir, '.gitignore'); + if (!fs.existsSync(gitignorePath)) { + fs.writeFileSync(gitignorePath, '*\n!.gitignore'); } console.log('准备工作完成'); @@ -68,64 +66,20 @@ function buildPortableApp() { process.env.ELECTRON_BUILDER_SKIP_NOTARIZATION = 'true'; process.env.ELECTRON_SKIP_NOTARIZE = 'true'; - // 使用最基本的命令行参数 + // 使用最基本的命令行参数,移除不支持的--no-sign execSync( 'npm run electron:build -- --win portable --ia32 --x64 --publish never', { stdio: 'inherit' } ); - // 构建完成后,创建最终的便携应用结构 - console.log('创建便携应用最终结构...'); - createPortableStructure(); - console.log('Windows 7便携应用构建完成!'); - console.log('构建产物位于 dist_electron 目录下的 portable-app 文件夹'); + console.log('构建产物位于 dist_electron 目录'); } catch (error) { console.error('构建失败:', error); 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() { console.log('==== Windows 7便携应用打包工具 ===='); diff --git a/vue.config.js b/vue.config.js index 2ac7ffb..fbb7570 100644 --- a/vue.config.js +++ b/vue.config.js @@ -15,7 +15,7 @@ module.exports = { // 基础配置 nodeIntegration: false, contextIsolation: true, - // 更新preload路径到新位置 + // 更新preload路径为background目录下的preload.js preload: "background/preload.js", mainProcessFile: "background/main.js", lintPreloadFiles: false, @@ -60,7 +60,7 @@ module.exports = { main: "background.js" }, - // Windows构建配置 + // Windows构建配置 - 修改输出目录结构 win: { // 架构设置 target: [ @@ -69,7 +69,6 @@ module.exports = { arch: ["ia32", "x64"], }, ], - // 图标设置 icon: "public/favicon.ico", // 明确禁用签名的多种配置 sign: false, @@ -77,39 +76,35 @@ module.exports = { certificateFile: null, certificatePassword: null, - // 额外资源配置 + // 额外资源配置 - 确保data目录被正确打包 extraResources: [ + { + from: "data", + to: "data", + filter: ["**/*"], // 包含data目录中的所有内容 + }, { from: "background", to: "background", filter: ["**/*"], }, - { - from: "data", - to: "data", - filter: ["**/*"], // 确保包含data目录下的所有文件 - }, - { - from: "portable.txt", - to: ".", // 确保portable.txt文件放在根目录 - }, ], }, - // 便携应用特定配置 + // 便携应用特定配置 - 修改输出结构 portable: { - artifactName: "统计技能考试系统_便携版_${version}_${arch}.exe", - }, - - // 发布设置 - publish: { - provider: 'generic', - url: 'https://example.com/', + // 修改artifactName以控制输出路径 + artifactName: "portable-app/统计技能考试系统_便携版_${version}_${arch}.exe", }, // 全局禁用签名配置 forceCodeSigning: false, asar: true, + + // 配置输出目录 + directories: { + output: "dist_electron", + }, }, }, },