diff --git a/Release/database/XNSim.db b/Release/database/XNSim.db index 1f099b0..6b4b3a7 100644 Binary files a/Release/database/XNSim.db and b/Release/database/XNSim.db differ diff --git a/XNSimHtml/components/configuration-config.js b/XNSimHtml/components/configuration-config.js index 9772f79..1dd6482 100644 --- a/XNSimHtml/components/configuration-config.js +++ b/XNSimHtml/components/configuration-config.js @@ -455,7 +455,7 @@ class ConfigurationConfig extends HTMLElement {
@@ -775,7 +775,8 @@ class ConfigurationConfig extends HTMLElement { LogDebug: baseConfig?.LogDebug ?? 0, LogInfo: baseConfig?.LogInfo ?? 1, LogWarning: baseConfig?.LogWarning ?? 1, - LogError: baseConfig?.LogError ?? 1 + LogError: baseConfig?.LogError ?? 1, + sourceConfId: baseConfig?.ConfID // 添加源构型ID }; this.showEditor(defaultConfig, planeName, true); } @@ -811,22 +812,24 @@ class ConfigurationConfig extends HTMLElement { const configId = parseInt(button.dataset.configId, 10); const config = configs.find(c => c.ConfID === configId); - if (config && confirm(`确定要删除构型"${config.ConfName}"吗?`)) { + if (config && confirm(`确定要删除构型"${config.ConfName}"吗?\n注意:删除后将无法恢复,且会同时删除该构型下的所有模型组、模型和服务。`)) { try { const response = await fetch(`/api/configurations/${configId}`, { method: 'DELETE', credentials: 'include' }); + const responseData = await response.json(); + if (!response.ok) { - throw new Error('删除构型失败'); + throw new Error(responseData.error || '删除构型失败'); } // 重新加载构型列表 this.loadConfigurations(planeName); } catch (error) { console.error('删除构型失败:', error); - alert('删除构型失败,请稍后重试'); + alert(error.message || '删除构型失败,请稍后重试'); } } }); @@ -857,7 +860,7 @@ class ConfigurationConfig extends HTMLElement { return; } - pageTitle.textContent = isNew ? `${planeName} - 新建构型` : `${planeName} - ${configuration.ConfName} 配置`; + pageTitle.textContent = isNew ? `${planeName} - 新建构型` : `${planeName} - ${configuration.ConfName} 构型`; backSection.style.display = 'block'; backButtonText.textContent = '返回构型列表'; contentContainer.style.display = 'none'; @@ -949,6 +952,11 @@ class ConfigurationConfig extends HTMLElement { LogError: this.shadowRoot.getElementById('logError').checked ? 1 : 0 }; + // 如果是新建构型,保留源构型ID + if (this.isNewConfiguration && this.selectedConfiguration.sourceConfId) { + updatedConfig.sourceConfId = this.selectedConfiguration.sourceConfId; + } + try { const url = this.isNewConfiguration ? '/api/configurations' : @@ -965,25 +973,26 @@ class ConfigurationConfig extends HTMLElement { credentials: 'include' }); + const responseData = await response.json(); + if (!response.ok) { - const errorData = await response.json(); - if (errorData.error === '路径验证失败') { - const errorMessages = errorData.details.map(detail => + if (responseData.error === '路径验证失败') { + const errorMessages = responseData.details.map(detail => `${detail.path === 'workPath' ? '工作路径' : detail.path === 'modelsPath' ? '模型路径' : '服务路径'}: ${detail.error}` ).join('\n'); alert(`路径验证失败:\n${errorMessages}`); } else { - throw new Error(errorData.error || '保存配置失败'); + throw new Error(responseData.error || '保存构型失败'); } return; } - this.selectedConfiguration = updatedConfig; + this.selectedConfiguration = responseData; this.showConfigurations(this.selectedPlane); } catch (error) { - console.error('保存配置失败:', error); - alert('保存配置失败,请稍后重试'); + console.error('保存构型失败:', error); + alert(error.message || '保存构型失败,请稍后重试'); } } diff --git a/XNSimHtml/routes/configurations.js b/XNSimHtml/routes/configurations.js index bf8af21..53ac87a 100644 --- a/XNSimHtml/routes/configurations.js +++ b/XNSimHtml/routes/configurations.js @@ -5,48 +5,66 @@ const { getConfigurationById, createConfiguration, updateConfiguration, - deleteConfiguration + deleteConfiguration, + getLoadModelGroups, + getLoadModelGroupById, + createLoadModelGroup, + updateLoadModelGroup, + deleteLoadModelGroup, + deleteLoadModelGroupByConf, + getLoadModels, + getLoadModelById, + createLoadModel, + updateLoadModel, + deleteLoadModel, + deleteLoadModelsByGroup, + getLoadServices, + getLoadServiceById, + createLoadService, + updateLoadService, + deleteLoadService, + deleteLoadServicesByConf } = require('../utils/configuration-utils'); const { validatePaths } = require('../utils/path-utils'); -// 获取所有配置列表 +// 获取所有构型列表 router.get('/configurations', (req, res) => { try { const planeName = req.query.plane; const configs = getConfigurations(planeName); res.json(configs); } catch (error) { - console.error('获取配置列表失败:', error); - res.status(500).json({ error: '获取配置列表失败', details: error.message }); + console.error('获取构型列表失败:', error); + res.status(500).json({ error: '获取构型列表失败', details: error.message }); } }); -// 根据ID获取配置 +// 根据ID获取构型 router.get('/configurations/:id', (req, res) => { try { const config = getConfigurationById(req.params.id); if (!config) { - return res.status(404).json({ error: '配置不存在' }); + return res.status(404).json({ error: '构型不存在' }); } res.json(config); } catch (error) { - console.error('获取配置详情失败:', error); - res.status(500).json({ error: '获取配置详情失败', details: error.message }); + console.error('获取构型详情失败:', error); + res.status(500).json({ error: '获取构型详情失败', details: error.message }); } }); -// 创建新配置 +// 创建新构型 router.post('/configurations', (req, res) => { try { const result = createConfiguration(req.body); res.status(201).json(result); } catch (error) { - console.error('创建配置失败:', error); - res.status(500).json({ error: '创建配置失败', details: error.message }); + console.error('创建构型失败:', error); + res.status(500).json({ error: '创建构型失败', details: error.message }); } }); -// 更新配置 +// 更新构型 router.put('/configurations/:id', async (req, res) => { try { const configData = { ...req.body, ConfID: req.params.id }; @@ -73,7 +91,7 @@ router.put('/configurations/:id', async (req, res) => { }); } - // 使用规范化后的路径更新配置 + // 使用规范化后的路径更新构型 configData.WorkPath = pathValidation.workPath.normalizedPath; configData.ModelsPath = pathValidation.modelsPath.normalizedPath; configData.ServicesPath = pathValidation.servicesPath.normalizedPath; @@ -81,19 +99,243 @@ router.put('/configurations/:id', async (req, res) => { const result = updateConfiguration(configData); res.json(result); } catch (error) { - console.error('更新配置失败:', error); - res.status(500).json({ error: '更新配置失败', details: error.message }); + console.error('更新构型失败:', error); + res.status(500).json({ error: '更新构型失败', details: error.message }); } }); -// 删除配置 +// 删除构型 router.delete('/configurations/:id', (req, res) => { try { const result = deleteConfiguration(req.params.id); res.json(result); } catch (error) { - console.error('删除配置失败:', error); - res.status(500).json({ error: '删除配置失败', details: error.message }); + console.error('删除构型失败:', error); + res.status(500).json({ error: '删除构型失败', details: error.message }); + } +}); + +// 模型组相关路由 +// 获取构型下的所有模型组 +router.get('/configurations/:id/model-groups', (req, res) => { + try { + const groups = getLoadModelGroups(req.params.id); + res.json(groups); + } catch (error) { + console.error('获取模型组列表失败:', error); + res.status(500).json({ error: '获取模型组列表失败', details: error.message }); + } +}); + +// 获取特定模型组 +router.get('/model-groups/:groupId', (req, res) => { + try { + const group = getLoadModelGroupById(req.params.groupId); + if (!group) { + return res.status(404).json({ error: '模型组不存在' }); + } + res.json(group); + } catch (error) { + console.error('获取模型组详情失败:', error); + res.status(500).json({ error: '获取模型组详情失败', details: error.message }); + } +}); + +// 创建新模型组 +router.post('/configurations/:id/model-groups', (req, res) => { + try { + const groupData = { ...req.body, ConfID: req.params.id }; + const result = createLoadModelGroup(groupData); + res.status(201).json(result); + } catch (error) { + console.error('创建模型组失败:', error); + res.status(500).json({ error: '创建模型组失败', details: error.message }); + } +}); + +// 更新模型组 +router.put('/model-groups/:groupId', (req, res) => { + try { + const groupData = { ...req.body, GroupID: req.params.groupId }; + const result = updateLoadModelGroup(groupData); + res.json(result); + } catch (error) { + console.error('更新模型组失败:', error); + res.status(500).json({ error: '更新模型组失败', details: error.message }); + } +}); + +// 删除模型组 +router.delete('/model-groups/:groupId', (req, res) => { + try { + const result = deleteLoadModelGroup(req.params.groupId); + res.json(result); + } catch (error) { + console.error('删除模型组失败:', error); + res.status(500).json({ error: '删除模型组失败', details: error.message }); + } +}); + +// 模型相关路由 +// 获取组下的所有模型 +router.get('/model-groups/:groupId/models', (req, res) => { + try { + const models = getLoadModels(req.params.groupId); + res.json(models); + } catch (error) { + console.error('获取模型列表失败:', error); + res.status(500).json({ error: '获取模型列表失败', details: error.message }); + } +}); + +// 获取特定模型 +router.get('/model-groups/:groupId/models/:className', (req, res) => { + try { + const model = getLoadModelById(req.params.groupId, req.params.className); + if (!model) { + return res.status(404).json({ error: '模型不存在' }); + } + res.json(model); + } catch (error) { + console.error('获取模型详情失败:', error); + res.status(500).json({ error: '获取模型详情失败', details: error.message }); + } +}); + +// 创建新模型 +router.post('/model-groups/:groupId/models', (req, res) => { + try { + const modelData = { ...req.body, GroupID: req.params.groupId }; + const result = createLoadModel(modelData); + res.status(201).json(result); + } catch (error) { + console.error('创建模型失败:', error); + res.status(500).json({ error: '创建模型失败', details: error.message }); + } +}); + +// 更新模型 +router.put('/model-groups/:groupId/models/:className', (req, res) => { + try { + const modelData = { + ...req.body, + GroupID: req.params.groupId, + ClassName: req.params.className + }; + const result = updateLoadModel(modelData); + res.json(result); + } catch (error) { + console.error('更新模型失败:', error); + res.status(500).json({ error: '更新模型失败', details: error.message }); + } +}); + +// 删除模型 +router.delete('/model-groups/:groupId/models/:className', (req, res) => { + try { + const result = deleteLoadModel(req.params.groupId, req.params.className); + res.json(result); + } catch (error) { + console.error('删除模型失败:', error); + res.status(500).json({ error: '删除模型失败', details: error.message }); + } +}); + +// 服务相关路由 +// 获取构型下的所有服务 +router.get('/configurations/:id/services', (req, res) => { + try { + const services = getLoadServices(req.params.id); + res.json(services); + } catch (error) { + console.error('获取服务列表失败:', error); + res.status(500).json({ error: '获取服务列表失败', details: error.message }); + } +}); + +// 获取特定服务 +router.get('/configurations/:id/services/:className', (req, res) => { + try { + const service = getLoadServiceById(req.params.id, req.params.className); + if (!service) { + return res.status(404).json({ error: '服务不存在' }); + } + res.json(service); + } catch (error) { + console.error('获取服务详情失败:', error); + res.status(500).json({ error: '获取服务详情失败', details: error.message }); + } +}); + +// 创建新服务 +router.post('/configurations/:id/services', (req, res) => { + try { + const serviceData = { ...req.body, ConfID: req.params.id }; + const result = createLoadService(serviceData); + res.status(201).json(result); + } catch (error) { + console.error('创建服务失败:', error); + res.status(500).json({ error: '创建服务失败', details: error.message }); + } +}); + +// 更新服务 +router.put('/configurations/:id/services/:className', (req, res) => { + try { + const serviceData = { + ...req.body, + ConfID: req.params.id, + ClassName: req.params.className + }; + const result = updateLoadService(serviceData); + res.json(result); + } catch (error) { + console.error('更新服务失败:', error); + res.status(500).json({ error: '更新服务失败', details: error.message }); + } +}); + +// 删除服务 +router.delete('/configurations/:id/services/:className', (req, res) => { + try { + const result = deleteLoadService(req.params.id, req.params.className); + res.json(result); + } catch (error) { + console.error('删除服务失败:', error); + res.status(500).json({ error: '删除服务失败', details: error.message }); + } +}); + +// 删除构型下的所有模型组 +router.delete('/configurations/:id/model-groups', (req, res) => { + try { + const result = deleteLoadModelGroupByConf(req.params.id); + res.json(result); + } catch (error) { + console.error('删除构型下所有模型组失败:', error); + res.status(500).json({ error: '删除构型下所有模型组失败', details: error.message }); + } +}); + +// 删除组下的所有模型 +router.delete('/model-groups/:groupId/models', (req, res) => { + try { + const result = deleteLoadModelsByGroup(req.params.groupId); + res.json(result); + } catch (error) { + console.error('删除组下所有模型失败:', error); + res.status(500).json({ error: '删除组下所有模型失败', details: error.message }); + } +}); + +// 删除构型下的所有服务 +router.delete('/configurations/:id/services', (req, res) => { + try { + const result = deleteLoadServicesByConf(req.params.id); + res.json(result); + } catch (error) { + console.error('删除构型下所有服务失败:', error); + res.status(500).json({ error: '删除构型下所有服务失败', details: error.message }); } }); diff --git a/XNSimHtml/utils/configuration-utils.js b/XNSimHtml/utils/configuration-utils.js index f9b61de..9a6467d 100644 --- a/XNSimHtml/utils/configuration-utils.js +++ b/XNSimHtml/utils/configuration-utils.js @@ -1,6 +1,7 @@ const { getDBConnection } = require('./file-utils'); +const { deleteDataInterfaceTable, createDataInterfaceTable, copyDataInterfaceTable } = require('./data-interface-utils'); -// 获取所有配置 +// 获取所有构型 function getConfigurations(planeName) { try { const db = getDBConnection(true); @@ -21,12 +22,12 @@ function getConfigurations(planeName) { return configs; } catch (error) { - console.error('获取配置列表失败:', error); + console.error('获取构型列表失败:', error); throw error; } } -// 根据ID获取配置 +// 根据ID获取构型 function getConfigurationById(confId) { try { const db = getDBConnection(true); @@ -38,12 +39,105 @@ function getConfigurationById(confId) { return config; } catch (error) { - console.error(`获取配置ID ${confId} 失败:`, error); + console.error(`获取构型ID ${confId} 失败:`, error); throw error; } } -// 创建新配置 +/** + * 复制模型组及其下的模型 + * @param {number} sourceConfId - 源构型ID + * @param {number} targetConfId - 目标构型ID + */ +function copyModelGroupsAndModels(sourceConfId, targetConfId) { + try { + const db = getDBConnection(); + + // 1. 获取源构型的所有模型组 + const sourceGroups = db.prepare(` + SELECT * FROM LoadModelGroups + WHERE ConfID = ? + `).all(sourceConfId); + + // 2. 复制每个模型组及其下的模型 + for (const group of sourceGroups) { + // 2.1 插入新的模型组 + db.prepare(` + INSERT INTO LoadModelGroups ( + ConfID, GroupName, Freq, Priority, CPUAff + ) VALUES (?, ?, ?, ?, ?) + `).run( + targetConfId, + group.GroupName, + group.Freq, + group.Priority, + group.CPUAff + ); + + // 2.2 获取新插入的模型组ID + const newGroupId = db.prepare('SELECT GroupID FROM LoadModelGroups WHERE rowid = last_insert_rowid()').get().GroupID; + + // 2.3 获取并复制该组下的所有模型 + const sourceModels = db.prepare(` + SELECT * FROM LoadModels + WHERE GroupID = ? + `).all(group.GroupID); + + // 2.4 插入新的模型 + for (const model of sourceModels) { + db.prepare(` + INSERT INTO LoadModels ( + GroupID, ClassName, ModelVersion, ModelName + ) VALUES (?, ?, ?, ?) + `).run( + newGroupId, + model.ClassName, + model.ModelVersion, + model.ModelName + ); + } + } + } catch (error) { + console.error('复制模型组和模型失败:', error); + throw error; + } +} + +/** + * 复制服务 + * @param {number} sourceConfId - 源构型ID + * @param {number} targetConfId - 目标构型ID + */ +function copyServices(sourceConfId, targetConfId) { + try { + const db = getDBConnection(); + + // 1. 获取源构型的所有服务 + const sourceServices = db.prepare(` + SELECT * FROM LoadServices + WHERE ConfID = ? + `).all(sourceConfId); + + // 2. 复制每个服务 + for (const service of sourceServices) { + db.prepare(` + INSERT INTO LoadServices ( + ConfID, ClassName, ServiceVersion, ServiceName + ) VALUES (?, ?, ?, ?) + `).run( + targetConfId, + service.ClassName, + service.ServiceVersion, + service.ServiceName + ); + } + } catch (error) { + console.error('复制服务失败:', error); + throw error; + } +} + +// 创建新构型 function createConfiguration(configData) { try { // 验证必填字段 @@ -83,19 +177,34 @@ function createConfiguration(configData) { configData.LogWarning !== undefined ? configData.LogWarning : 1, configData.LogError !== undefined ? configData.LogError : 1 ); + + const newConfId = result.lastInsertRowid; + + // 处理数据接口表和复制相关数据 + if (configData.sourceConfId) { + // 如果有源构型,复制接口表 + copyDataInterfaceTable(configData.sourceConfId, newConfId); + // 复制模型组和模型 + copyModelGroupsAndModels(configData.sourceConfId, newConfId); + // 复制服务 + copyServices(configData.sourceConfId, newConfId); + } else { + // 如果没有源构型,创建新的接口表 + createDataInterfaceTable(newConfId); + } return { success: true, - confId: result.lastInsertRowid, - message: '配置创建成功' + confId: newConfId, + message: '构型创建成功' }; } catch (error) { - console.error('创建配置失败:', error); + console.error('创建构型失败:', error); throw error; } } -// 更新配置 +// 更新构型 function updateConfiguration(configData) { try { // 验证必填字段 @@ -105,14 +214,14 @@ function updateConfiguration(configData) { const db = getDBConnection(); - // 检查配置是否存在 + // 检查构型是否存在 const existingConfig = db.prepare(` SELECT COUNT(*) as count FROM Configuration WHERE ConfID = ? `).get(configData.ConfID); if (existingConfig.count === 0) { - throw new Error('要更新的配置不存在'); + throw new Error('要更新的构型不存在'); } const result = db.prepare(` @@ -161,36 +270,669 @@ function updateConfiguration(configData) { return { success: true, changes: result.changes, - message: '配置更新成功' + message: '构型更新成功' }; } catch (error) { - console.error('更新配置失败:', error); + console.error('更新构型失败:', error); throw error; } } -// 删除配置 +// 删除构型 function deleteConfiguration(confId) { try { const db = getDBConnection(); + // 1. 删除构型下的所有服务 + deleteLoadServicesByConf(confId); + + // 2. 删除构型下的所有模型组(这会级联删除组下的所有模型) + deleteLoadModelGroupByConf(confId); + + // 3. 删除构型对应的数据接口表 + deleteDataInterfaceTable(confId); + + // 4. 最后删除构型本身 const result = db.prepare('DELETE FROM Configuration WHERE ConfID = ?').run(confId); return { success: true, changes: result.changes, - message: result.changes > 0 ? '配置删除成功' : '配置不存在或已被删除' + message: result.changes > 0 ? '构型删除成功' : '构型不存在或已被删除' }; } catch (error) { - console.error('删除配置失败:', error); + console.error('删除构型失败:', error); throw error; } } +/** + * 获取所有模型组 + * @param {number} confId - 构型ID + * @returns {Array} 模型组列表 + */ +function getLoadModelGroups(confId) { + try { + if (!confId) { + throw new Error('confId 是必填参数'); + } + + const db = getDBConnection(true); + + const query = ` + SELECT * FROM LoadModelGroups + WHERE ConfID = ? + ORDER BY GroupID ASC + `; + + const groups = db.prepare(query).all(confId); + + return groups; + } catch (error) { + console.error('获取模型组列表失败:', error); + throw error; + } +} + +/** + * 根据ID获取模型组 + * @param {number} groupId - 模型组ID + * @returns {Object} 模型组信息 + */ +function getLoadModelGroupById(groupId) { + try { + const db = getDBConnection(true); + + const group = db.prepare(` + SELECT * FROM LoadModelGroups + WHERE GroupID = ? + `).get(groupId); + + return group; + } catch (error) { + console.error(`获取模型组ID ${groupId} 失败:`, error); + throw error; + } +} + +/** + * 创建新模型组 + * @param {Object} groupData - 模型组数据 + * @returns {Object} 创建结果 + */ +function createLoadModelGroup(groupData) { + try { + // 验证必填字段 + const requiredFields = ['ConfID', 'GroupName', 'Freq', 'Priority', 'CPUAff']; + for (const field of requiredFields) { + if (!groupData[field]) { + throw new Error(`${field} 是必填字段`); + } + } + + const db = getDBConnection(); + + const result = db.prepare(` + INSERT INTO LoadModelGroups ( + ConfID, GroupName, Freq, Priority, CPUAff + ) VALUES (?, ?, ?, ?, ?) + `).run( + groupData.ConfID, + groupData.GroupName, + groupData.Freq, + groupData.Priority, + groupData.CPUAff + ); + + return { + success: true, + groupId: result.lastInsertRowid, + message: '模型组创建成功' + }; + } catch (error) { + console.error('创建模型组失败:', error); + throw error; + } +} + +/** + * 更新模型组 + * @param {Object} groupData - 模型组数据 + * @returns {Object} 更新结果 + */ +function updateLoadModelGroup(groupData) { + try { + // 验证必填字段 + if (!groupData.GroupID) { + throw new Error('GroupID 是必填字段'); + } + + const db = getDBConnection(); + + // 检查模型组是否存在 + const existingGroup = db.prepare(` + SELECT COUNT(*) as count FROM LoadModelGroups + WHERE GroupID = ? + `).get(groupData.GroupID); + + if (existingGroup.count === 0) { + throw new Error('要更新的模型组不存在'); + } + + const result = db.prepare(` + UPDATE LoadModelGroups + SET ConfID = ?, + GroupName = ?, + Freq = ?, + Priority = ?, + CPUAff = ? + WHERE GroupID = ? + `).run( + groupData.ConfID, + groupData.GroupName, + groupData.Freq, + groupData.Priority, + groupData.CPUAff, + groupData.GroupID + ); + + return { + success: true, + changes: result.changes, + message: '模型组更新成功' + }; + } catch (error) { + console.error('更新模型组失败:', error); + throw error; + } +} + +/** + * 删除模型组 + * @param {number} groupId - 模型组ID + * @returns {Object} 删除结果 + */ +function deleteLoadModelGroup(groupId) { + try { + const db = getDBConnection(); + + // 1. 先删除组下的所有模型 + deleteLoadModelsByGroup(groupId); + + // 2. 再删除模型组本身 + const result = db.prepare('DELETE FROM LoadModelGroups WHERE GroupID = ?').run(groupId); + + return { + success: true, + changes: result.changes, + message: result.changes > 0 ? '模型组删除成功' : '模型组不存在或已被删除' + }; + } catch (error) { + console.error('删除模型组失败:', error); + throw error; + } +} + +/** + * 获取所有模型 + * @param {number} groupId - 模型组ID + * @returns {Array} 模型列表 + */ +function getLoadModels(groupId) { + try { + if (!groupId) { + throw new Error('groupId 是必填参数'); + } + + const db = getDBConnection(true); + + const query = ` + SELECT * FROM LoadModels + WHERE GroupID = ? + ORDER BY ClassName ASC + `; + + const models = db.prepare(query).all(groupId); + + return models; + } catch (error) { + console.error('获取模型列表失败:', error); + throw error; + } +} + +/** + * 根据组ID和类名获取模型 + * @param {number} groupId - 模型组ID + * @param {string} className - 类名 + * @returns {Object} 模型信息 + */ +function getLoadModelById(groupId, className) { + try { + const db = getDBConnection(true); + + const model = db.prepare(` + SELECT * FROM LoadModels + WHERE GroupID = ? AND ClassName = ? + `).get(groupId, className); + + return model; + } catch (error) { + console.error(`获取模型失败 (GroupID: ${groupId}, ClassName: ${className}):`, error); + throw error; + } +} + +/** + * 创建新模型 + * @param {Object} modelData - 模型数据 + * @returns {Object} 创建结果 + */ +function createLoadModel(modelData) { + try { + // 验证必填字段 + const requiredFields = ['GroupID', 'ClassName', 'ModelVersion']; + for (const field of requiredFields) { + if (!modelData[field]) { + throw new Error(`${field} 是必填字段`); + } + } + + const db = getDBConnection(); + + // 检查是否已存在相同的记录 + const existingModel = db.prepare(` + SELECT COUNT(*) as count FROM LoadModels + WHERE GroupID = ? AND ClassName = ? + `).get(modelData.GroupID, modelData.ClassName); + + if (existingModel.count > 0) { + throw new Error('该组中已存在相同类名的模型'); + } + + const result = db.prepare(` + INSERT INTO LoadModels ( + GroupID, ClassName, ModelVersion, ModelName + ) VALUES (?, ?, ?, ?) + `).run( + modelData.GroupID, + modelData.ClassName, + modelData.ModelVersion, + modelData.ModelName || null + ); + + return { + success: true, + message: '模型创建成功' + }; + } catch (error) { + console.error('创建模型失败:', error); + throw error; + } +} + +/** + * 更新模型 + * @param {Object} modelData - 模型数据 + * @returns {Object} 更新结果 + */ +function updateLoadModel(modelData) { + try { + // 验证必填字段 + const requiredFields = ['GroupID', 'ClassName', 'ModelVersion']; + for (const field of requiredFields) { + if (!modelData[field]) { + throw new Error(`${field} 是必填字段`); + } + } + + const db = getDBConnection(); + + // 检查模型是否存在 + const existingModel = db.prepare(` + SELECT COUNT(*) as count FROM LoadModels + WHERE GroupID = ? AND ClassName = ? + `).get(modelData.GroupID, modelData.ClassName); + + if (existingModel.count === 0) { + throw new Error('要更新的模型不存在'); + } + + const result = db.prepare(` + UPDATE LoadModels + SET ModelVersion = ?, + ModelName = ? + WHERE GroupID = ? AND ClassName = ? + `).run( + modelData.ModelVersion, + modelData.ModelName || null, + modelData.GroupID, + modelData.ClassName + ); + + return { + success: true, + changes: result.changes, + message: '模型更新成功' + }; + } catch (error) { + console.error('更新模型失败:', error); + throw error; + } +} + +/** + * 删除模型 + * @param {number} groupId - 模型组ID + * @param {string} className - 类名 + * @returns {Object} 删除结果 + */ +function deleteLoadModel(groupId, className) { + try { + const db = getDBConnection(); + + const result = db.prepare(` + DELETE FROM LoadModels + WHERE GroupID = ? AND ClassName = ? + `).run(groupId, className); + + return { + success: true, + changes: result.changes, + message: result.changes > 0 ? '模型删除成功' : '模型不存在或已被删除' + }; + } catch (error) { + console.error('删除模型失败:', error); + throw error; + } +} + +/** + * 删除组下的所有模型 + * @param {number} groupId - 模型组ID + * @returns {Object} 删除结果 + */ +function deleteLoadModelsByGroup(groupId) { + try { + const db = getDBConnection(); + + const result = db.prepare(` + DELETE FROM LoadModels + WHERE GroupID = ? + `).run(groupId); + + return { + success: true, + changes: result.changes, + message: result.changes > 0 ? '组内所有模型删除成功' : '组内没有模型或已被删除' + }; + } catch (error) { + console.error('删除组内模型失败:', error); + throw error; + } +} + +/** + * 获取所有服务 + * @param {number} confId - 构型ID + * @returns {Array} 服务列表 + */ +function getLoadServices(confId) { + try { + if (!confId) { + throw new Error('confId 是必填参数'); + } + + const db = getDBConnection(true); + + const query = ` + SELECT * FROM LoadServices + WHERE ConfID = ? + ORDER BY ClassName ASC + `; + + const services = db.prepare(query).all(confId); + + return services; + } catch (error) { + console.error('获取服务列表失败:', error); + throw error; + } +} + +/** + * 根据构型ID和类名获取服务 + * @param {number} confId - 构型ID + * @param {string} className - 类名 + * @returns {Object} 服务信息 + */ +function getLoadServiceById(confId, className) { + try { + const db = getDBConnection(true); + + const service = db.prepare(` + SELECT * FROM LoadServices + WHERE ConfID = ? AND ClassName = ? + `).get(confId, className); + + return service; + } catch (error) { + console.error(`获取服务失败 (ConfID: ${confId}, ClassName: ${className}):`, error); + throw error; + } +} + +/** + * 创建新服务 + * @param {Object} serviceData - 服务数据 + * @returns {Object} 创建结果 + */ +function createLoadService(serviceData) { + try { + // 验证必填字段 + const requiredFields = ['ConfID', 'ClassName', 'ServiceVersion']; + for (const field of requiredFields) { + if (!serviceData[field]) { + throw new Error(`${field} 是必填字段`); + } + } + + const db = getDBConnection(); + + // 检查是否已存在相同的记录 + const existingService = db.prepare(` + SELECT COUNT(*) as count FROM LoadServices + WHERE ConfID = ? AND ClassName = ? + `).get(serviceData.ConfID, serviceData.ClassName); + + if (existingService.count > 0) { + throw new Error('该构型中已存在相同类名的服务'); + } + + const result = db.prepare(` + INSERT INTO LoadServices ( + ConfID, ClassName, ServiceVersion, ServiceName + ) VALUES (?, ?, ?, ?) + `).run( + serviceData.ConfID, + serviceData.ClassName, + serviceData.ServiceVersion, + serviceData.ServiceName || null + ); + + return { + success: true, + message: '服务创建成功' + }; + } catch (error) { + console.error('创建服务失败:', error); + throw error; + } +} + +/** + * 更新服务 + * @param {Object} serviceData - 服务数据 + * @returns {Object} 更新结果 + */ +function updateLoadService(serviceData) { + try { + // 验证必填字段 + const requiredFields = ['ConfID', 'ClassName', 'ServiceVersion']; + for (const field of requiredFields) { + if (!serviceData[field]) { + throw new Error(`${field} 是必填字段`); + } + } + + const db = getDBConnection(); + + // 检查服务是否存在 + const existingService = db.prepare(` + SELECT COUNT(*) as count FROM LoadServices + WHERE ConfID = ? AND ClassName = ? + `).get(serviceData.ConfID, serviceData.ClassName); + + if (existingService.count === 0) { + throw new Error('要更新的服务不存在'); + } + + const result = db.prepare(` + UPDATE LoadServices + SET ServiceVersion = ?, + ServiceName = ? + WHERE ConfID = ? AND ClassName = ? + `).run( + serviceData.ServiceVersion, + serviceData.ServiceName || null, + serviceData.ConfID, + serviceData.ClassName + ); + + return { + success: true, + changes: result.changes, + message: '服务更新成功' + }; + } catch (error) { + console.error('更新服务失败:', error); + throw error; + } +} + +/** + * 删除服务 + * @param {number} confId - 构型ID + * @param {string} className - 类名 + * @returns {Object} 删除结果 + */ +function deleteLoadService(confId, className) { + try { + const db = getDBConnection(); + + const result = db.prepare(` + DELETE FROM LoadServices + WHERE ConfID = ? AND ClassName = ? + `).run(confId, className); + + return { + success: true, + changes: result.changes, + message: result.changes > 0 ? '服务删除成功' : '服务不存在或已被删除' + }; + } catch (error) { + console.error('删除服务失败:', error); + throw error; + } +} + +/** + * 删除构型下的所有服务 + * @param {number} confId - 构型ID + * @returns {Object} 删除结果 + */ +function deleteLoadServicesByConf(confId) { + try { + const db = getDBConnection(); + + const result = db.prepare(` + DELETE FROM LoadServices + WHERE ConfID = ? + `).run(confId); + + return { + success: true, + changes: result.changes, + message: result.changes > 0 ? '构型下所有服务删除成功' : '构型下没有服务或已被删除' + }; + } catch (error) { + console.error('删除构型下服务失败:', error); + throw error; + } +} + +/** + * 删除构型下的所有模型组 + * @param {number} confId - 构型ID + * @returns {Object} 删除结果 + */ +function deleteLoadModelGroupByConf(confId) { + try { + const db = getDBConnection(); + + // 1. 获取该构型下的所有模型组ID + const groups = db.prepare(` + SELECT GroupID FROM LoadModelGroups + WHERE ConfID = ? + `).all(confId); + + // 2. 删除每个模型组下的所有模型 + for (const group of groups) { + db.prepare(` + DELETE FROM LoadModels + WHERE GroupID = ? + `).run(group.GroupID); + } + + // 3. 删除所有模型组 + const result = db.prepare(` + DELETE FROM LoadModelGroups + WHERE ConfID = ? + `).run(confId); + + return { + success: true, + changes: result.changes, + message: result.changes > 0 ? '构型下所有模型组删除成功' : '构型下没有模型组或已被删除' + }; + } catch (error) { + console.error('删除构型下模型组失败:', error); + throw error; + } +} + module.exports = { getConfigurations, getConfigurationById, createConfiguration, updateConfiguration, - deleteConfiguration + deleteConfiguration, + getLoadModelGroups, + getLoadModelGroupById, + createLoadModelGroup, + updateLoadModelGroup, + deleteLoadModelGroup, + deleteLoadModelGroupByConf, + getLoadModels, + getLoadModelById, + createLoadModel, + updateLoadModel, + deleteLoadModel, + deleteLoadModelsByGroup, + getLoadServices, + getLoadServiceById, + createLoadService, + updateLoadService, + deleteLoadService, + deleteLoadServicesByConf }; \ No newline at end of file diff --git a/XNSimHtml/utils/data-interface-utils.js b/XNSimHtml/utils/data-interface-utils.js index b0eacd0..3e4caf1 100644 --- a/XNSimHtml/utils/data-interface-utils.js +++ b/XNSimHtml/utils/data-interface-utils.js @@ -271,10 +271,137 @@ function getDataInterfaceStructs(systemName = 'XNSim', planeName, ataName, confI } } +/** + * 删除指定构型ID的整个接口表 + * @param {number} confID - 构型ID + * @returns {Object} 删除结果 + */ +function deleteDataInterfaceTable(confID) { + try { + if (!confID) { + throw new Error('ConfID 是必填字段'); + } + + const db = getDBConnection(); + const tableName = `DataInterface_${confID}`; + + // 删除整个表 + const result = db.prepare(`DROP TABLE IF EXISTS '${tableName}'`).run(); + + return { + success: true, + message: '接口表删除成功' + }; + } catch (error) { + console.error('删除接口表失败:', error); + throw error; + } +} + +/** + * 创建指定构型ID的接口表 + * @param {number} confID - 构型ID + * @returns {Object} 创建结果 + */ +function createDataInterfaceTable(confID) { + try { + if (!confID) { + throw new Error('ConfID 是必填字段'); + } + + const db = getDBConnection(); + const tableName = `DataInterface_${confID}`; + + // 创建表 + const result = db.prepare(` + CREATE TABLE IF NOT EXISTS '${tableName}' ( + SystemName TEXT NOT NULL, + PlaneName TEXT NOT NULL, + ATAName TEXT NOT NULL, + ModelStructName TEXT NOT NULL, + InterfaceName TEXT NOT NULL PRIMARY KEY, + InterfaceType TEXT NOT NULL, + InterfaceOption TEXT NOT NULL, + InterfaceIsArray INTEGER NOT NULL, + InterfaceArraySize_1 INTEGER NOT NULL, + InterfaceArraySize_2 INTEGER NOT NULL, + InterfaceNotes TEXT + ) + `).run(); + + return { + success: true, + message: '接口表创建成功' + }; + } catch (error) { + console.error('创建接口表失败:', error); + throw error; + } +} + +/** + * 复制接口表 + * @param {number} sourceConfID - 源构型ID + * @param {number} targetConfID - 目标构型ID + * @returns {Object} 复制结果 + */ +function copyDataInterfaceTable(sourceConfID, targetConfID) { + try { + if (!sourceConfID || !targetConfID) { + throw new Error('sourceConfID 和 targetConfID 都是必填字段'); + } + + if (sourceConfID === targetConfID) { + throw new Error('源构型ID和目标构型ID不能相同'); + } + + const db = getDBConnection(); + const sourceTableName = `DataInterface_${sourceConfID}`; + const targetTableName = `DataInterface_${targetConfID}`; + + // 检查源表是否存在 + const sourceTableExists = db.prepare(` + SELECT name FROM sqlite_master + WHERE type='table' AND name=? + `).get(sourceTableName); + + if (!sourceTableExists) { + throw new Error('源接口表不存在'); + } + + // 检查目标表是否存在 + const targetTableExists = db.prepare(` + SELECT name FROM sqlite_master + WHERE type='table' AND name=? + `).get(targetTableName); + + if (targetTableExists) { + throw new Error('目标接口表已存在,请新建新的构型或联系管理员处理'); + } + + // 创建新表并复制数据 + const result = db.prepare(` + CREATE TABLE '${targetTableName}' AS + SELECT * FROM '${sourceTableName}' + `).run(); + + return { + success: true, + message: '接口表复制成功' + }; + } catch (error) { + console.error('复制接口表失败:', error); + throw error; + } +} + module.exports = { getDataInterfaces, addDataInterface, updateDataInterface, deleteDataInterface, - getDataInterfaceStructs + getDataInterfaceStructs, + deleteDataInterfaceTable, + createDataInterfaceTable, + copyDataInterfaceTable }; \ No newline at end of file