diff --git a/background/db/index.js b/background/db/index.js index b2c3cf3..5b648ff 100644 --- a/background/db/index.js +++ b/background/db/index.js @@ -1,3 +1,4 @@ +// 添加缺失的导入 const { getSystemDbPath, getUserDbPath } = require('./path.js'); const { systemSchema, userSchema, defaultData } = require('./schema.js'); const { openDatabase, batchInsert } = require('./utils.js'); @@ -35,15 +36,58 @@ exports.closeAllConnections = function closeAllConnections() { exports.checkDatabaseInitialized = async function checkDatabaseInitialized() { try { console.log('开始检查数据库初始化状态...'); - const systemDb = await exports.getDbConnection(getSystemDbPath()); + const systemDbPath = getSystemDbPath(); + console.log('系统数据库路径:', systemDbPath); + + // 首先检查数据库文件是否存在 + const fs = require('fs'); + const dbExists = fs.existsSync(systemDbPath); + console.log('系统数据库文件存在:', dbExists); + + if (!dbExists) { + console.log('系统数据库文件不存在,返回未初始化状态'); + return false; + } + + // 检查文件大小,如果是空文件则认为未初始化 + const stats = fs.statSync(systemDbPath); + if (stats.size === 0) { + console.log('系统数据库文件为空,返回未初始化状态'); + return false; + } + + // 尝试打开数据库连接 + const systemDb = await exports.getDbConnection(systemDbPath); console.log('成功打开系统数据库'); - const result = await systemDb.getAsync('SELECT value FROM config WHERE key = ?', ['initialized']); - console.log('查询初始化状态结果:', result); + try { + // 尝试查询config表 + const result = await systemDb.getAsync('SELECT value FROM config WHERE key = ?', ['initialized']); + console.log('查询初始化状态结果:', result); - const isInitialized = result && result.value === 'true'; - console.log('数据库初始化状态:', isInitialized ? '已初始化' : '未初始化'); - return isInitialized; + const isInitialized = result && result.value === 'true'; + console.log('数据库初始化状态:', isInitialized ? '已初始化' : '未初始化'); + return isInitialized; + } catch (queryError) { + // 如果查询失败,可能是表不存在,说明数据库未初始化 + console.log('查询config表失败,可能表不存在:', queryError.message); + + // 尝试检查数据库是否有表结构 + try { + const tables = await systemDb.allAsync("SELECT name FROM sqlite_master WHERE type='table'"); + console.log('数据库中的表:', tables.map(t => t.name).join(', ')); + + // 如果有表但没有config表,可能是结构不完整 + if (tables.length > 0) { + console.log('数据库有表结构但可能不完整,需要重新初始化'); + return false; + } + } catch (tablesError) { + console.error('检查数据库表结构失败:', tablesError); + } + + return false; + } } catch (error) { console.error('检查数据库初始化状态失败:', error); return false; diff --git a/background/db/path.js b/background/db/path.js index f84695c..ede7913 100644 --- a/background/db/path.js +++ b/background/db/path.js @@ -1,3 +1,4 @@ +// 添加缺失的path模块导入 const path = require('path'); const fs = require('fs'); const { app } = require('electron'); @@ -10,37 +11,55 @@ let isPortable = false; let appDir; let dataDir; +// 调试信息 +console.log('环境检测:'); +console.log('- 开发环境:', isDev); +console.log('- 当前工作目录:', process.cwd()); +console.log('- 可执行文件路径:', app.getPath('exe')); + if (isDev) { // 开发环境:数据存储在工程的data目录 dataDir = path.join(process.cwd(), 'data'); + console.log('开发环境数据目录:', dataDir); } else { // 非开发环境:确定应用目录 const exePath = app.getPath('exe'); appDir = path.dirname(exePath); + console.log('应用目录:', appDir); - // 检测是否存在便携模式标记文件 - const portableFlagPath = path.join(appDir, 'portable.txt'); - if (fs.existsSync(portableFlagPath)) { - isPortable = true; + // 检测便携模式的多种可能性 + // 1. 检查可执行文件同级目录是否有data文件夹 + const dataPathSameLevel = path.join(appDir, 'data'); + // 2. 检查可执行文件所在目录是否为portable-app,如果是,检查其父目录下是否有data + const isPortableAppDir = path.basename(appDir) === 'portable-app'; + const dataPathParentLevel = isPortableAppDir ? path.join(path.dirname(appDir), 'data') : null; + // 3. 检查可执行文件同级目录是否有portable-app/data文件夹 + const dataPathInPortableApp = path.join(appDir, 'portable-app', 'data'); + + console.log('检测便携模式:'); + console.log('- 同级data目录存在:', fs.existsSync(dataPathSameLevel)); + if (isPortableAppDir) { + console.log('- 父级data目录存在:', fs.existsSync(dataPathParentLevel)); } + console.log('- portable-app/data目录存在:', fs.existsSync(dataPathInPortableApp)); - // 关键修改:在便携模式下,data目录与可执行文件同级 - // 如果可执行文件在portable-app目录中,则data目录与portable-app目录同级 - if (path.basename(appDir) === 'portable-app') { - dataDir = path.join(path.dirname(appDir), 'data'); + // 优先级顺序:同级data > portable-app内data > 父级data + if (fs.existsSync(dataPathSameLevel)) { + dataDir = dataPathSameLevel; isPortable = true; + console.log('使用同级data目录:', dataDir); + } else if (fs.existsSync(dataPathInPortableApp)) { + dataDir = dataPathInPortableApp; + isPortable = true; + console.log('使用portable-app内data目录:', dataDir); + } else if (isPortableAppDir && fs.existsSync(dataPathParentLevel)) { + dataDir = dataPathParentLevel; + isPortable = true; + console.log('使用父级data目录:', dataDir); } else { - // 否则data目录与可执行文件同级 - dataDir = path.join(appDir, 'data'); - } - - // 确保便携模式标记文件存在于data目录同级 - if (isPortable) { - const flagDir = path.dirname(dataDir); - const flagPath = path.join(flagDir, 'portable.txt'); - if (!fs.existsSync(flagPath)) { - fs.writeFileSync(flagPath, ''); - } + // 默认使用用户数据目录 + dataDir = path.join(app.getPath('userData'), 'data'); + console.log('使用用户数据目录:', dataDir); } } diff --git a/background/main.js b/background/main.js index a95dd82..15a0b1a 100644 --- a/background/main.js +++ b/background/main.js @@ -301,27 +301,81 @@ let appDataPath = ""; // 初始化应用路径 - 兼容Node.js 12和Windows 7 function initializeAppPaths() { - // 检查应用根目录是否存在data文件夹,如果存在则认为是便携模式 - // Windows路径兼容处理 + console.log("开始初始化应用路径..."); + + // 获取应用相关路径 const appRoot = process.cwd(); - const portableDataPath = path.join(appRoot, "data"); - const defaultDataPath = path.join(app.getPath("userData"), "data"); - - // 检查是否为便携模式 - if (fs.existsSync(portableDataPath)) { - isPortableMode = true; - appDataPath = portableDataPath; - console.log("检测到便携模式,使用当前目录的data文件夹:", appDataPath); - } else { - isPortableMode = false; - appDataPath = defaultDataPath; - console.log("使用默认数据目录:", appDataPath); - - // 确保默认数据目录存在 + const exePath = app.getPath("exe"); + const appDir = path.dirname(exePath); + const userDataPath = app.getPath("userData"); + + console.log("应用路径信息:"); + console.log("- 当前工作目录:", appRoot); + console.log("- 可执行文件路径:", exePath); + console.log("- 应用目录:", appDir); + console.log("- 用户数据目录:", userDataPath); + + // 检查多个可能的便携模式数据目录位置 + const possibleDataPaths = [ + // 1. 当前工作目录下的data + path.join(appRoot, "data"), + // 2. 可执行文件同级目录下的data + path.join(appDir, "data"), + // 3. 如果在portable-app目录中,检查其父目录下的data + path.basename(appDir) === "portable-app" ? path.join(path.dirname(appDir), "data") : null, + // 4. 可执行文件同级目录下的portable-app/data + path.join(appDir, "portable-app", "data") + ].filter(Boolean); // 过滤掉null值 + + // 检查便携模式标记文件 + const possibleFlagPaths = [ + path.join(appRoot, "portable.txt"), + path.join(appDir, "portable.txt"), + path.basename(appDir) === "portable-app" ? path.join(path.dirname(appDir), "portable.txt") : null + ].filter(Boolean); + + // 记录检测结果 + console.log("便携模式检测:"); + possibleDataPaths.forEach((p, i) => { + console.log(`- 数据路径 ${i+1} 存在:`, fs.existsSync(p) ? "是" : "否", p); + }); + possibleFlagPaths.forEach((p, i) => { + console.log(`- 标记文件 ${i+1} 存在:`, fs.existsSync(p) ? "是" : "否", p); + }); + + // 确定是否为便携模式 + // 1. 如果存在便携模式标记文件,则为便携模式 + const flagFileExists = possibleFlagPaths.some(p => fs.existsSync(p)); + // 2. 如果存在data目录,也视为便携模式 + const dataPathExists = possibleDataPaths.some(p => fs.existsSync(p)); + + isPortableMode = flagFileExists || dataPathExists; + + // 确定数据目录路径 + if (isPortableMode) { + // 按优先级选择第一个存在的数据目录 + appDataPath = possibleDataPaths.find(p => fs.existsSync(p)) || possibleDataPaths[0]; + console.log("检测到便携模式,使用数据文件夹:", appDataPath); + + // 确保数据目录存在 if (!fs.existsSync(appDataPath)) { - // 递归创建目录,兼容Windows路径 try { fs.mkdirSync(appDataPath, { recursive: true }); + console.log("已创建便携模式数据目录:", appDataPath); + } catch (error) { + console.error("创建便携模式数据目录失败:", error); + } + } + } else { + // 非便携模式使用默认用户数据目录 + appDataPath = path.join(userDataPath, "data"); + console.log("使用默认数据目录:", appDataPath); + + // 确保默认数据目录存在 + if (!fs.existsSync(appDataPath)) { + try { + fs.mkdirSync(appDataPath, { recursive: true }); + console.log("已创建默认数据目录:", appDataPath); } catch (error) { console.error("创建默认数据目录失败:", error); } diff --git a/package-windows-portable.js b/package-windows-portable.js index 9fbe0aa..167a418 100644 --- a/package-windows-portable.js +++ b/package-windows-portable.js @@ -101,19 +101,19 @@ function buildPortableApp() { console.log('已复制.gitignore文件'); } - // 创建空的system.db和user.db文件(如果不存在) + // 不再创建空的数据库文件,而是确保复制已初始化的数据库文件 const systemDbPath = path.join(destDataDir, 'system.db'); const userDbPath = path.join(destDataDir, 'user.db'); - - if (!fs.existsSync(systemDbPath)) { - fs.writeFileSync(systemDbPath, ''); - console.log('已创建空的system.db文件'); - } - - if (!fs.existsSync(userDbPath)) { - fs.writeFileSync(userDbPath, ''); - console.log('已创建空的user.db文件'); - } + + // 创建便携模式标记文件 + const portableFlagPath = path.join(path.dirname(destDataDir), 'portable.txt'); + fs.writeFileSync(portableFlagPath, 'This file indicates portable mode operation.'); + console.log('已创建便携模式标记文件:', portableFlagPath); + + // 在portable-app目录内也创建一个标记文件,以防万一 + const innerPortableFlagPath = path.join(portableAppDir, 'portable.txt'); + fs.writeFileSync(innerPortableFlagPath, 'This file indicates portable mode operation.'); + console.log('已在portable-app目录内创建便携模式标记文件'); // 可选:如果项目中已有数据库文件,可以复制它们 const projectSystemDb = path.join(projectRoot, 'data', 'system.db'); diff --git a/src/views/WelcomeView.vue b/src/views/WelcomeView.vue index d3d7ded..8340bd1 100644 --- a/src/views/WelcomeView.vue +++ b/src/views/WelcomeView.vue @@ -165,10 +165,47 @@ export default { console.log('组件挂载 - 开始检查数据库初始化状态') const initialized = await window.electronAPI.checkDatabaseInitialized() console.log('组件挂载 - 数据库初始化状态检查完成:', initialized) - this.isDatabaseInitialized = initialized + + // 处理undefined或null的情况 + if (initialized === undefined || initialized === null) { + console.warn('数据库初始化状态未知,可能是便携模式下的问题') + + // 检查user.db是否存在 + const userDbExists = await window.electronAPI.checkUserDbExists() + console.log('user.db存在状态:', userDbExists) + + if (userDbExists) { + console.log('user.db存在但初始化状态未知,尝试静默初始化系统数据库') + // 尝试初始化数据库 + try { + const initResult = await window.electronAPI.initializeDatabase() + console.log('静默初始化数据库结果:', initResult) + + if (initResult === true || (initResult && initResult.success)) { + console.log('静默初始化数据库成功,设置初始化状态为true') + this.isDatabaseInitialized = true + } else { + console.warn('静默初始化数据库失败,显示初始化界面') + this.isDatabaseInitialized = false + } + } catch (initError) { + console.error('静默初始化数据库出错:', initError) + this.isDatabaseInitialized = false + } + } else { + // user.db不存在,需要显示初始化界面 + console.log('user.db不存在,显示初始化界面') + this.isDatabaseInitialized = false + } + } else { + // 正常情况,使用返回的初始化状态 + this.isDatabaseInitialized = initialized + } } catch (error) { console.error('检查数据库初始化状态失败:', error) Message.error('检查数据库初始化状态失败,请重试') + // 出错时默认显示初始化界面 + this.isDatabaseInitialized = false } },