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; } } // 获取接口列表 function getDataInterfaces(systemName = 'XNSim', 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 SystemName, ProductName, ATAName, ModelStructName, InterfaceName, InterfaceType, InterfaceOption, InterfaceIsArray, InterfaceArraySize_1, InterfaceArraySize_2, InterfaceNotes FROM 'DataInterface' WHERE SystemName = ? ORDER BY ProductName, ATAName, ModelStructName, InterfaceName `; params = [systemName]; } else { query = ` SELECT SystemName, ProductName, ATAName, ModelStructName, InterfaceName, InterfaceType, InterfaceOption, InterfaceIsArray, InterfaceArraySize_1, InterfaceArraySize_2, InterfaceNotes FROM 'DataInterface' WHERE SystemName = ? AND ProductName = ? ORDER BY ATAName, ModelStructName, InterfaceName `; params = [systemName, productName]; } const interfaces = db.prepare(query).all(...params); db.close(); return interfaces; } catch (error) { console.error('获取接口列表数据失败:', error.message); throw error; } } // 添加接口 function addDataInterface(interfaceData) { try { // 验证必填字段 const requiredFields = [ 'SystemName', 'ProductName', 'ATAName', 'ModelStructName', 'InterfaceName', 'InterfaceType', 'InterfaceOption', 'InterfaceIsArray', 'InterfaceArraySize_1', 'InterfaceArraySize_2' ]; for (const field of requiredFields) { if (interfaceData[field] === undefined || interfaceData[field] === null) { 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); // 检查接口是否已存在 const existingInterface = db.prepare(` SELECT COUNT(*) as count FROM 'DataInterface' WHERE SystemName = ? AND ProductName = ? AND ATAName = ? AND ModelStructName = ? AND InterfaceName = ? `).get( interfaceData.SystemName, interfaceData.ProductName, interfaceData.ATAName, interfaceData.ModelStructName, interfaceData.InterfaceName ); if (existingInterface.count > 0) { db.close(); throw new Error('接口已存在'); } // 插入新接口 const insertResult = db.prepare(` INSERT INTO 'DataInterface' ( SystemName, ProductName, ATAName, ModelStructName, InterfaceName, InterfaceType, InterfaceOption, InterfaceIsArray, InterfaceArraySize_1, InterfaceArraySize_2, InterfaceNotes ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) `).run( interfaceData.SystemName, interfaceData.ProductName, interfaceData.ATAName, interfaceData.ModelStructName, interfaceData.InterfaceName, interfaceData.InterfaceType, interfaceData.InterfaceOption, interfaceData.InterfaceIsArray, interfaceData.InterfaceArraySize_1, interfaceData.InterfaceArraySize_2, interfaceData.InterfaceNotes || null ); db.close(); return { success: true, id: insertResult.lastInsertRowid, message: '接口添加成功' }; } catch (error) { console.error('添加接口失败:', error); throw error; } } // 更新接口 function updateDataInterface(interfaceData) { try { // 验证必填字段 const requiredFields = [ 'SystemName', 'ProductName', 'ATAName', 'ModelStructName', 'InterfaceName', 'InterfaceType', 'InterfaceOption', 'InterfaceIsArray', 'InterfaceArraySize_1', 'InterfaceArraySize_2' ]; // 检查数据结构 if (!interfaceData.currentData || !interfaceData.originalData) { throw new Error('数据格式错误:缺少 currentData 或 originalData'); } // 验证 currentData 中的必填字段 for (const field of requiredFields) { if (interfaceData.currentData[field] === undefined || interfaceData.currentData[field] === null) { 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); // 首先检查记录是否存在 const existingRecord = db.prepare(` SELECT COUNT(*) as count FROM 'DataInterface' WHERE SystemName = ? AND ProductName = ? AND ATAName = ? AND ModelStructName = ? AND InterfaceName = ? `).get( interfaceData.originalData.SystemName, interfaceData.originalData.ProductName, interfaceData.originalData.ATAName, interfaceData.originalData.ModelStructName, interfaceData.originalData.InterfaceName ); if (existingRecord.count === 0) { db.close(); throw new Error('要更新的记录不存在'); } // 更新接口,包括所有字段 const updateResult = db.prepare(` UPDATE 'DataInterface' SET SystemName = ?, ProductName = ?, ATAName = ?, ModelStructName = ?, InterfaceName = ?, InterfaceType = ?, InterfaceOption = ?, InterfaceIsArray = ?, InterfaceArraySize_1 = ?, InterfaceArraySize_2 = ?, InterfaceNotes = ? WHERE SystemName = ? AND ProductName = ? AND ATAName = ? AND ModelStructName = ? AND InterfaceName = ? `).run( interfaceData.currentData.SystemName, interfaceData.currentData.ProductName, interfaceData.currentData.ATAName, interfaceData.currentData.ModelStructName, interfaceData.currentData.InterfaceName, interfaceData.currentData.InterfaceType, interfaceData.currentData.InterfaceOption, interfaceData.currentData.InterfaceIsArray, interfaceData.currentData.InterfaceArraySize_1, interfaceData.currentData.InterfaceArraySize_2, interfaceData.currentData.InterfaceNotes || null, interfaceData.originalData.SystemName, interfaceData.originalData.ProductName, interfaceData.originalData.ATAName, interfaceData.originalData.ModelStructName, interfaceData.originalData.InterfaceName ); db.close(); if (updateResult.changes === 0) { throw new Error('更新失败:没有记录被修改'); } return { success: true, changes: updateResult.changes, message: '接口更新成功' }; } catch (error) { console.error('更新接口失败:', error); throw error; } } // 删除接口 function deleteDataInterface(systemName, productName, ataName, modelStructName, interfaceName) { 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); // 删除接口 const deleteResult = db.prepare(` DELETE FROM 'DataInterface' WHERE SystemName = ? AND ProductName = ? AND ATAName = ? AND ModelStructName = ? AND InterfaceName = ? `).run( systemName || 'XNSim', productName || 'C909', ataName, modelStructName, interfaceName ); db.close(); return { success: true, changes: deleteResult.changes, message: '接口删除成功' }; } catch (error) { console.error('删除接口失败:', error); throw error; } } // 获取接口结构体列表 function getDataInterfaceStructs(systemName = 'XNSim', productName, ataName) { 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 SystemName, ProductName, ATAName, ModelStructName FROM 'DataInterface' WHERE SystemName = ? GROUP BY ModelStructName ORDER BY ProductName, ATAName, ModelStructName `; params = [systemName]; } else { query = ` SELECT SystemName, ProductName, ATAName, ModelStructName FROM 'DataInterface' WHERE SystemName = ? AND ProductName = ? GROUP BY ModelStructName ORDER BY ATAName, ModelStructName `; params = [systemName, productName]; } if (ataName) { query = query.replace('GROUP BY', 'AND ATAName = ? GROUP BY'); params.push(ataName); } const structs = db.prepare(query).all(...params); db.close(); return structs; } catch (error) { console.error('获取接口结构体列表数据失败:', error.message); throw error; } } // 获取所有问题 function getQuestions() { 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 questions = db.prepare(` SELECT q.*, COUNT(a.id) as answer_count, MAX(a.created_at) as last_answer_time FROM questions q LEFT JOIN answers a ON q.id = a.question_id GROUP BY q.id ORDER BY q.created_at DESC `).all(); // 获取每个问题的回答 questions.forEach(question => { question.answers = db.prepare(` SELECT * FROM answers WHERE question_id = ? ORDER BY created_at ASC `).all(question.id); }); db.close(); return questions; } catch (error) { console.error('获取问题列表失败:', error); throw error; } } // 创建新问题 function createQuestion(title, content, author) { try { if (!title || !content) { throw new Error('标题和内容不能为空'); } 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 result = db.prepare(` INSERT INTO questions (title, content, author) VALUES (?, ?, ?) `).run(title, content, author || '匿名用户'); db.close(); if (result.changes > 0) { return { success: true, questionId: result.lastInsertRowid, message: '问题创建成功' }; } else { throw new Error('问题创建失败'); } } catch (error) { console.error('创建问题失败:', error); throw error; } } // 添加回答 function addAnswer(questionId, content, author) { try { if (!content) { throw new Error('回答内容不能为空'); } 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 question = db.prepare('SELECT id FROM questions WHERE id = ?').get(questionId); if (!question) { db.close(); throw new Error('问题不存在'); } const result = db.prepare(` INSERT INTO answers (question_id, content, author) VALUES (?, ?, ?) `).run(questionId, content, author || '匿名用户'); db.close(); if (result.changes > 0) { return { success: true, answerId: result.lastInsertRowid, message: '回答添加成功' }; } else { throw new Error('回答添加失败'); } } catch (error) { console.error('添加回答失败:', error); throw error; } } // 删除问题 function deleteQuestion(questionId) { 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); const result = db.prepare('DELETE FROM questions WHERE id = ?').run(questionId); db.close(); if (result.changes > 0) { return { success: true, message: '问题删除成功' }; } else { throw new Error('问题不存在'); } } catch (error) { console.error('删除问题失败:', error); throw error; } } // 删除回答 function deleteAnswer(answerId) { 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); const result = db.prepare('DELETE FROM answers WHERE id = ?').run(answerId); db.close(); if (result.changes > 0) { return { success: true, message: '回答删除成功' }; } else { throw new Error('回答不存在'); } } catch (error) { console.error('删除回答失败:', error); throw error; } } module.exports = { getATAChapters, getModelsByChapterId, getModelVersionsByClassName, saveModelVersion, getServices, getServiceVersionsByClassName, saveServiceVersion, createService, getProducts, getDataInterfaces, addDataInterface, updateDataInterface, deleteDataInterface, getDataInterfaceStructs, getQuestions, createQuestion, addAnswer, deleteQuestion, deleteAnswer };