const Database = require('better-sqlite3'); const { getXNCorePath } = require('./file-utils'); // 查询ATAChapters表 function getATAChapters() { try { const xnCorePath = getXNCorePath(); if (!xnCorePath) { throw new Error('XNCore环境变量未设置,无法获取数据库路径'); } const dbPath = xnCorePath + '/database/XNSim.db'; if (!dbPath) { throw new Error('无法找到数据库文件'); } // 打开数据库连接 const db = new Database(dbPath, { readonly: true }); // 直接使用ATAChapters表名查询 const chapters = db.prepare("SELECT ID, Name, Name_CN FROM 'ATAChapters' ORDER BY ID").all(); db.close(); return chapters; } catch (error) { console.error('获取ATA章节数据失败:', error.message); throw error; } } // 根据章节ID查询XNModels表中的模型 function getModelsByChapterId(chapterId, productName) { try { const xnCorePath = getXNCorePath(); if (!xnCorePath) { throw new Error('XNCore环境变量未设置,无法获取数据库路径'); } const dbPath = xnCorePath + '/database/XNSim.db'; if (!dbPath) { throw new Error('无法找到数据库文件'); } // 打开数据库连接 const db = new Database(dbPath, { readonly: true }); // 根据productName是否为空构建不同的查询 let query; let params; if (!productName || productName === '' || productName === 'undefined') { query = ` SELECT ProductName, Chapters_ID, ModelName, ModelName_CN, Description, ClassName FROM 'XNModels' WHERE Chapters_ID = ? ORDER BY ModelName `; params = [chapterId]; } else { query = ` SELECT ProductName, Chapters_ID, ModelName, ModelName_CN, Description, ClassName FROM 'XNModels' WHERE Chapters_ID = ? AND ProductName = ? ORDER BY ModelName `; params = [chapterId, productName]; } const models = db.prepare(query).all(...params); db.close(); return models; } catch (error) { console.error(`获取章节${chapterId}的模型数据失败:`, error.message); throw error; } } // 根据ClassName查询XNModelsVersion表中的模型版本 function getModelVersionsByClassName(className, productName) { try { const xnCorePath = getXNCorePath(); if (!xnCorePath) { throw new Error('XNCore环境变量未设置,无法获取数据库路径'); } const dbPath = xnCorePath + '/database/XNSim.db'; if (!dbPath) { throw new Error('无法找到数据库文件'); } // 打开数据库连接 const db = new Database(dbPath, { readonly: true }); // 根据productName是否为空构建不同的查询 let query; let params; if (!productName || productName === '') { query = ` SELECT ProductName, ClassName, Name, Version, CodePath, Author, Description, CreatTime, ChangeTime, RunFreqGroup, RunNode, Priority, DataPackagePath, DataPackageHeaderPath, DataPackageEntryPoint, DataPackageInterfaceName FROM 'XNModelsVersion' WHERE ClassName = ? ORDER BY Version DESC `; params = [className]; } else { query = ` SELECT ProductName, ClassName, Name, Version, CodePath, Author, Description, CreatTime, ChangeTime, RunFreqGroup, RunNode, Priority, DataPackagePath, DataPackageHeaderPath, DataPackageEntryPoint, DataPackageInterfaceName FROM 'XNModelsVersion' WHERE ClassName = ? AND ProductName = ? ORDER BY Version DESC `; params = [className, productName]; } const versions = db.prepare(query).all(...params); db.close(); return versions; } catch (error) { console.error(`获取模型${className}的版本数据失败:`, error.message); throw error; } } // 保存或更新模型版本信息 function saveModelVersion(versionData) { try { // 验证必填字段 const requiredFields = ['ClassName', 'Name', 'Version', 'Author', 'ProductName']; for (const field of requiredFields) { if (!versionData[field]) { throw new Error(`${field} 是必填字段`); } } const xnCorePath = getXNCorePath(); if (!xnCorePath) { throw new Error('XNCore环境变量未设置,无法获取数据库路径'); } const dbPath = xnCorePath + '/database/XNSim.db'; if (!dbPath) { throw new Error('无法找到数据库文件'); } // 打开数据库连接 const db = new Database(dbPath); // 检查是否为更新模式 if (versionData.isUpdate) { // 查询是否存在要更新的版本 const existingVersion = db.prepare(` SELECT COUNT(*) as count FROM 'XNModelsVersion' WHERE ClassName = ? AND Version = ? AND ProductName = ? `).get(versionData.ClassName, versionData.originalVersion || versionData.Version, versionData.ProductName); if (existingVersion.count === 0) { // 不存在要更新的版本,创建新版本 return saveNewVersion(db, versionData); } // 使用前端传来的修改时间,如果没有则生成当前时间 let changeTime = versionData.ChangeTime; if (!changeTime) { // 生成当前时间,格式为YYYY-MM-DD HH:MM:SS const now = new Date(); const year = now.getFullYear(); const month = String(now.getMonth() + 1).padStart(2, '0'); const day = String(now.getDate()).padStart(2, '0'); const hours = String(now.getHours()).padStart(2, '0'); const minutes = String(now.getMinutes()).padStart(2, '0'); const seconds = String(now.getSeconds()).padStart(2, '0'); changeTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; } // 更新现有版本 const updateResult = db.prepare(` UPDATE 'XNModelsVersion' SET Name = ?, Version = ?, Author = ?, Description = ?, CodePath = ?, ChangeTime = ?, RunFreqGroup = ?, RunNode = ?, Priority = ?, DataPackagePath = ?, DataPackageHeaderPath = ?, DataPackageEntryPoint = ?, DataPackageInterfaceName = ?, ProductName = ? WHERE ClassName = ? AND Version = ? AND ProductName = ? `).run( versionData.Name, versionData.Version, versionData.Author, versionData.Description || '', versionData.CodePath || '', changeTime, versionData.RunFreqGroup || '', versionData.RunNode || '', versionData.Priority || '0', versionData.DataPackagePath || '', versionData.DataPackageHeaderPath || '', versionData.DataPackageEntryPoint || '', versionData.DataPackageInterfaceName || '', versionData.ProductName, versionData.ClassName, versionData.originalVersion || versionData.Version, versionData.ProductName ); db.close(); return { success: true, isNew: false, changes: updateResult.changes, message: '模型版本更新成功' }; } else { // 创建新版本 return saveNewVersion(db, versionData); } } catch (error) { console.error('保存模型版本时出错:', error); throw error; } } // 内部函数:保存新版本 function saveNewVersion(db, versionData) { try { // 检查版本是否已存在 const existingVersion = db.prepare(` SELECT COUNT(*) as count FROM 'XNModelsVersion' WHERE ClassName = ? AND Version = ? AND ProductName = ? `).get(versionData.ClassName, versionData.Version, versionData.ProductName); if (existingVersion.count > 0) { db.close(); throw new Error(`版本 ${versionData.Version} 已存在,请使用其他版本号`); } // 生成当前时间,格式为YYYY-MM-DD HH:MM:SS const now = new Date(); const year = now.getFullYear(); const month = String(now.getMonth() + 1).padStart(2, '0'); const day = String(now.getDate()).padStart(2, '0'); const hours = String(now.getHours()).padStart(2, '0'); const minutes = String(now.getMinutes()).padStart(2, '0'); const seconds = String(now.getSeconds()).padStart(2, '0'); const formattedDateTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; // 使用前端传来的时间或生成的时间 const createTime = versionData.CreatTime || formattedDateTime; const changeTime = versionData.ChangeTime || formattedDateTime; // 插入新版本 const insertResult = db.prepare(` INSERT INTO 'XNModelsVersion' ( ProductName, ClassName, Name, Version, CodePath, Author, Description, CreatTime, ChangeTime, RunFreqGroup, RunNode, Priority, DataPackagePath, DataPackageHeaderPath, DataPackageEntryPoint, DataPackageInterfaceName ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) `).run( versionData.ProductName, versionData.ClassName, versionData.Name, versionData.Version, versionData.CodePath || '', versionData.Author, versionData.Description || '', createTime, changeTime, versionData.RunFreqGroup || '', versionData.RunNode || '', versionData.Priority || '0', versionData.DataPackagePath || '', versionData.DataPackageHeaderPath || '', versionData.DataPackageEntryPoint || '', versionData.DataPackageInterfaceName || '' ); db.close(); return { success: true, isNew: true, id: insertResult.lastInsertRowid, message: '模型版本创建成功' }; } catch (error) { if (db) db.close(); console.error('创建模型版本失败:', error); throw error; } } // 查询XNServices表中的所有服务 function getServices() { try { const xnCorePath = getXNCorePath(); if (!xnCorePath) { throw new Error('XNCore环境变量未设置,无法获取数据库路径'); } const dbPath = xnCorePath + '/database/XNSim.db'; if (!dbPath) { throw new Error('无法找到数据库文件'); } // 打开数据库连接 const db = new Database(dbPath, { readonly: true }); // 查询所有服务 const services = db.prepare(` SELECT ServiceName, ServiceName_CN, Description, ClassName FROM 'XNServices' ORDER BY ServiceName `).all(); db.close(); return services; } catch (error) { console.error('获取服务列表数据失败:', error.message); throw error; } } // 根据ClassName查询XNServiceVersion表中的服务版本 function getServiceVersionsByClassName(className) { try { const xnCorePath = getXNCorePath(); if (!xnCorePath) { throw new Error('XNCore环境变量未设置,无法获取数据库路径'); } const dbPath = xnCorePath + '/database/XNSim.db'; if (!dbPath) { throw new Error('无法找到数据库文件'); } // 打开数据库连接 const db = new Database(dbPath, { readonly: true }); // 查询该类名下的所有版本 const versions = db.prepare(` SELECT ClassName, Name, Version, CodePath, Author, Description, CreatTime, ChangeTime FROM 'XNServiceVersion' WHERE ClassName = ? ORDER BY Version DESC `).all(className); db.close(); return versions; } catch (error) { console.error(`获取服务${className}的版本数据失败:`, error.message); throw error; } } // 保存或更新服务版本信息 function saveServiceVersion(versionData) { try { // 验证必填字段 const requiredFields = ['ClassName', 'Name', 'Version', 'Author']; for (const field of requiredFields) { if (!versionData[field]) { throw new Error(`${field} 是必填字段`); } } const xnCorePath = getXNCorePath(); if (!xnCorePath) { throw new Error('XNCore环境变量未设置,无法获取数据库路径'); } const dbPath = xnCorePath + '/database/XNSim.db'; if (!dbPath) { throw new Error('无法找到数据库文件'); } // 打开数据库连接 const db = new Database(dbPath); // 检查是否为更新模式 if (versionData.isUpdate) { // 查询是否存在要更新的版本 const existingVersion = db.prepare(` SELECT COUNT(*) as count FROM 'XNServiceVersion' WHERE ClassName = ? AND Version = ? `).get(versionData.ClassName, versionData.originalVersion || versionData.Version); if (existingVersion.count === 0) { // 不存在要更新的版本,创建新版本 return saveNewServiceVersion(db, versionData); } // 使用前端传来的修改时间,如果没有则生成当前时间 let changeTime = versionData.ChangeTime; if (!changeTime) { // 生成当前时间,格式为YYYY-MM-DD HH:MM:SS const now = new Date(); const year = now.getFullYear(); const month = String(now.getMonth() + 1).padStart(2, '0'); const day = String(now.getDate()).padStart(2, '0'); const hours = String(now.getHours()).padStart(2, '0'); const minutes = String(now.getMinutes()).padStart(2, '0'); const seconds = String(now.getSeconds()).padStart(2, '0'); changeTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; } // 更新现有版本 const updateResult = db.prepare(` UPDATE 'XNServiceVersion' SET Name = ?, Version = ?, Author = ?, Description = ?, CodePath = ?, ChangeTime = ? WHERE ClassName = ? AND Version = ? `).run( versionData.Name, versionData.Version, versionData.Author, versionData.Description || '', versionData.CodePath || '', changeTime, // 使用前端传来的时间或生成的当前时间 versionData.ClassName, versionData.originalVersion || versionData.Version ); db.close(); return { success: true, isNew: false, changes: updateResult.changes, message: '服务版本更新成功' }; } else { // 创建新版本 return saveNewServiceVersion(db, versionData); } } catch (error) { console.error('保存服务版本时出错:', error); throw error; } } // 内部函数:保存新的服务版本 function saveNewServiceVersion(db, versionData) { try { // 检查版本是否已存在 const existingVersion = db.prepare(` SELECT COUNT(*) as count FROM 'XNServiceVersion' WHERE ClassName = ? AND Version = ? `).get(versionData.ClassName, versionData.Version); if (existingVersion.count > 0) { db.close(); throw new Error(`版本 ${versionData.Version} 已存在,请使用其他版本号`); } // 生成当前时间,格式为YYYY-MM-DD HH:MM:SS const now = new Date(); const year = now.getFullYear(); const month = String(now.getMonth() + 1).padStart(2, '0'); const day = String(now.getDate()).padStart(2, '0'); const hours = String(now.getHours()).padStart(2, '0'); const minutes = String(now.getMinutes()).padStart(2, '0'); const seconds = String(now.getSeconds()).padStart(2, '0'); const formattedDateTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; // 使用前端传来的时间或生成的时间 const createTime = versionData.CreatTime || formattedDateTime; const changeTime = versionData.ChangeTime || formattedDateTime; // 插入新版本 const insertResult = db.prepare(` INSERT INTO 'XNServiceVersion' ( ClassName, Name, Version, CodePath, Author, Description, CreatTime, ChangeTime ) VALUES (?, ?, ?, ?, ?, ?, ?, ?) `).run( versionData.ClassName, versionData.Name, versionData.Version, versionData.CodePath || '', versionData.Author, versionData.Description || '', createTime, // 使用前端传来的创建时间或生成的当前时间 changeTime // 使用前端传来的修改时间或生成的当前时间 ); db.close(); return { success: true, isNew: true, id: insertResult.lastInsertRowid, message: '服务版本创建成功' }; } catch (error) { if (db) db.close(); console.error('创建服务版本失败:', error); throw error; } } // 创建新服务 function createService(serviceData) { try { // 验证必填字段 const requiredFields = ['ClassName', 'ServiceName', 'ServiceName_CN']; for (const field of requiredFields) { if (!serviceData[field]) { throw new Error(`${field} 是必填字段`); } } // 验证类名是否以XN开头 if (!serviceData.ClassName.startsWith('XN')) { throw new Error('服务类名必须以XN开头'); } const xnCorePath = getXNCorePath(); if (!xnCorePath) { throw new Error('XNCore环境变量未设置,无法获取数据库路径'); } const dbPath = xnCorePath + '/database/XNSim.db'; if (!dbPath) { throw new Error('无法找到数据库文件'); } // 打开数据库连接 const db = new Database(dbPath); // 检查服务类名是否已存在 const existingService = db.prepare(` SELECT COUNT(*) as count FROM 'XNServices' WHERE ClassName = ? `).get(serviceData.ClassName); if (existingService.count > 0) { db.close(); throw new Error(`服务类名 ${serviceData.ClassName} 已存在,请使用其他类名`); } // 检查服务名称是否已存在 const existingServiceName = db.prepare(` SELECT COUNT(*) as count FROM 'XNServices' WHERE ServiceName = ? `).get(serviceData.ServiceName); if (existingServiceName.count > 0) { db.close(); throw new Error(`服务名称 ${serviceData.ServiceName} 已存在,请使用其他名称`); } // 插入新服务 const insertResult = db.prepare(` INSERT INTO 'XNServices' ( ClassName, ServiceName, ServiceName_CN, Description ) VALUES (?, ?, ?, ?) `).run( serviceData.ClassName, serviceData.ServiceName, serviceData.ServiceName_CN, serviceData.Description || '' ); db.close(); return { success: true, id: insertResult.lastInsertRowid, message: '服务创建成功' }; } catch (error) { console.error('创建服务失败:', error); throw error; } } // 查询Products表中的所有产品 function getProducts() { try { const xnCorePath = getXNCorePath(); if (!xnCorePath) { throw new Error('XNCore环境变量未设置,无法获取数据库路径'); } const dbPath = xnCorePath + '/database/XNSim.db'; if (!dbPath) { throw new Error('无法找到数据库文件'); } // 打开数据库连接 const db = new Database(dbPath, { readonly: true }); // 查询所有产品 const products = db.prepare(` SELECT ProductName, Description FROM 'Products' ORDER BY ProductName `).all(); db.close(); return products; } catch (error) { console.error('获取产品列表数据失败:', error.message); throw error; } } module.exports = { getATAChapters, getModelsByChapterId, getModelVersionsByClassName, saveModelVersion, getServices, getServiceVersionsByClassName, saveServiceVersion, createService, getProducts };