const express = require('express'); const router = express.Router(); const systemMonitor = require('../utils/xnCoreService'); // 存储连续注入状态 const continuousInjectStatus = new Map(); /** * @brief 启动数据监控 * @route POST /api/data-monitor/start * @param {string} structName - 结构体名称 * @returns {Object} 返回启动结果 */ router.post('/start', async (req, res) => { try { const { structName } = req.body; if (!structName) { return res.status(400).json({ success: false, message: '结构体名称不能为空' }); } const result = systemMonitor.startDataMonitor(structName); if (result.includes('失败')) { return res.status(500).json({ success: false, message: result }); } res.json({ success: true, message: result }); } catch (error) { res.status(500).json({ success: false, message: `启动数据监控失败: ${error.message}` }); } }); /** * @brief 停止数据监控 * @route POST /api/data-monitor/stop * @param {string} structName - 结构体名称 * @returns {Object} 返回停止结果 */ router.post('/stop', async (req, res) => { try { const { structName } = req.body; if (!structName) { return res.status(400).json({ success: false, message: '结构体名称不能为空' }); } const result = systemMonitor.stopDataMonitor(structName); if (result.includes('失败')) { return res.status(500).json({ success: false, message: result }); } res.json({ success: true, message: result }); } catch (error) { res.status(500).json({ success: false, message: `停止数据监控失败: ${error.message}` }); } }); /** * @brief 获取数据监控信息 * @route GET /api/data-monitor/info * @param {string} structName - 结构体名称 * @param {string} interfaceName - 接口名称 * @param {number} [bufferSize=8192] - 数据缓冲区大小(可选) * @returns {Object} 返回监控信息,data字段包含解析后的JSON对象 */ router.get('/info', async (req, res) => { try { const { structName, interfaceName, bufferSize } = req.query; if (!structName || !interfaceName) { return res.status(400).json({ success: false, message: '结构体名称和接口名称不能为空' }); } const result = systemMonitor.getDataMonitorInfo( structName, interfaceName, bufferSize ? parseInt(bufferSize) : undefined ); if (typeof result === 'string' && result.includes('失败')) { return res.status(500).json({ success: false, message: result }); } // 解析数据字符串为JSON对象 let parsedData; try { parsedData = JSON.parse(result.data); } catch (parseError) { return res.status(500).json({ success: false, message: `数据解析失败: ${parseError.message}` }); } res.json({ success: true, data: parsedData, info: result.info }); } catch (error) { res.status(500).json({ success: false, message: `获取数据监控信息失败: ${error.message}` }); } }); /** * @brief 注入数据接口 * @route POST /api/data-monitor/inject * @param {string} structName - 结构体名称 * @param {string} interfaceNameAndData - 接口名称和数据JSON字符串 * @returns {Object} 返回注入结果 */ router.post('/inject', async (req, res) => { try { const { structName, interfaceNameAndData } = req.body; if (!structName || !interfaceNameAndData) { return res.status(400).json({ success: false, message: '结构体名称和接口数据不能为空' }); } const result = systemMonitor.injectDataInterface(structName, interfaceNameAndData); if (result.includes('失败')) { return res.status(500).json({ success: false, message: result }); } res.json({ success: true, message: result }); } catch (error) { res.status(500).json({ success: false, message: `注入数据接口失败: ${error.message}` }); } }); /** * @brief 启动持续注入数据 * @route POST /api/data-monitor/start-continuous * @param {string} structName - 结构体名称 * @param {string} interfaceNameAndData - 接口名称和数据JSON字符串 * @param {number} frequency - 注入频率 * @returns {Object} 返回启动结果 */ router.post('/start-continuous', async (req, res) => { try { const { structName, interfaceNameAndData, frequency } = req.body; if (!structName || !interfaceNameAndData || frequency === undefined) { return res.status(400).json({ success: false, message: '结构体名称、接口数据和注入频率不能为空' }); } // 检查是否已存在该结构体的注入状态 if (continuousInjectStatus.has(structName)) { const status = continuousInjectStatus.get(structName); // 检查频率是否相同 if (status.frequency !== frequency) { return res.status(400).json({ success: false, message: `该结构体已有其他接口以 ${status.frequency}ms 的频率进行注入,请使用相同的频率` }); } // 合并接口数据 try { const existingData = JSON.parse(status.interfaceNameAndData); const newData = JSON.parse(interfaceNameAndData); const mergedData = { ...existingData, ...newData }; status.interfaceNameAndData = JSON.stringify(mergedData); } catch (error) { return res.status(400).json({ success: false, message: '接口数据格式错误' }); } // 启动注入 const result = systemMonitor.startInjectContinuous(structName, status.interfaceNameAndData, frequency); if (result.includes('失败')) { continuousInjectStatus.delete(structName); return res.status(500).json({ success: false, message: result }); } } else { // 创建新的注入状态 continuousInjectStatus.set(structName, { interfaceNameAndData, frequency, isInjecting: false }); // 启动注入 const result = systemMonitor.startInjectContinuous(structName, interfaceNameAndData, frequency); if (result.includes('失败')) { continuousInjectStatus.delete(structName); return res.status(500).json({ success: false, message: result }); } // 更新注入状态 const status = continuousInjectStatus.get(structName); status.isInjecting = true; } res.json({ success: true, message: '启动持续注入成功', data: { structName, interfaceNameAndData: continuousInjectStatus.get(structName).interfaceNameAndData, frequency } }); } catch (error) { res.status(500).json({ success: false, message: `启动持续注入数据失败: ${error.message}` }); } }); /** * @brief 停止持续注入数据 * @route POST /api/data-monitor/stop-continuous * @param {string} structName - 结构体名称 * @param {string} interfaceName - 要停止的接口名称 * @returns {Object} 返回停止结果 */ router.post('/stop-continuous', async (req, res) => { try { const { structName, interfaceName } = req.body; if (!structName || !interfaceName) { return res.status(400).json({ success: false, message: '结构体名称和接口名称不能为空' }); } // 检查是否存在该结构体的注入状态 if (!continuousInjectStatus.has(structName)) { return res.status(400).json({ success: false, message: '该结构体没有正在进行的注入' }); } const status = continuousInjectStatus.get(structName); try { // 从接口数据中移除指定的接口 const existingData = JSON.parse(status.interfaceNameAndData); delete existingData[interfaceName]; // 如果还有其他接口在注入,更新状态 if (Object.keys(existingData).length > 0) { status.interfaceNameAndData = JSON.stringify(existingData); const result = systemMonitor.startInjectContinuous(structName, status.interfaceNameAndData, status.frequency); if (result.includes('失败')) { return res.status(500).json({ success: false, message: result }); } res.json({ success: true, message: '停止指定接口的注入成功', data: { structName, remainingInterfaces: Object.keys(existingData) } }); } else { // 如果没有其他接口在注入,停止整个结构体的注入 const result = systemMonitor.stopInjectContinuous(structName); if (result.includes('失败')) { return res.status(500).json({ success: false, message: result }); } // 删除注入状态 continuousInjectStatus.delete(structName); res.json({ success: true, message: '停止所有接口的注入成功' }); } } catch (error) { return res.status(400).json({ success: false, message: '接口数据格式错误' }); } } catch (error) { res.status(500).json({ success: false, message: `停止持续注入数据失败: ${error.message}` }); } }); /** * @brief 停止所有持续注入数据 * @route POST /api/data-monitor/stop-all-continuous * @returns {Object} 返回停止结果 */ router.post('/stop-all-continuous', async (req, res) => { try { // 获取所有正在注入的结构体 const injectingStructs = Array.from(continuousInjectStatus.keys()); if (injectingStructs.length === 0) { return res.json({ success: true, message: '当前没有正在进行的注入' }); } // 停止所有结构体的注入 const results = []; for (const structName of injectingStructs) { const result = systemMonitor.stopInjectContinuous(structName); if (result.includes('失败')) { results.push({ structName, success: false, message: result }); } else { results.push({ structName, success: true, message: '停止成功' }); } continuousInjectStatus.delete(structName); } // 检查是否所有结构体都成功停止 const allSuccess = results.every(r => r.success); res.json({ success: allSuccess, message: allSuccess ? '所有持续注入已停止' : '部分持续注入停止失败', details: results }); } catch (error) { res.status(500).json({ success: false, message: `停止所有持续注入数据失败: ${error.message}` }); } }); /** * @brief 从CSV文件注入数据 * @route POST /api/data-monitor/inject-csv * @param {string} structName - 结构体数据JSON字符串,格式为 {structName1: {interfaceName1: [size1, size2], ...}, structName2: ...} * @param {string} csvFilePath - CSV文件路径 * @returns {Object} 返回注入结果 */ router.post('/inject-csv', async (req, res) => { try { const { structName, csvFilePath} = req.body; if (!structName || !csvFilePath) { return res.status(400).json({ success: false, message: '结构体名称、CSV文件路径不能为空' }); } // 解析并验证 structName JSON 字符串 let structData; try { structData = JSON.parse(structName); // 验证数据结构 if (typeof structData !== 'object' || structData === null) { return res.status(400).json({ success: false, message: '结构体数据格式错误:必须是有效的对象' }); } // 验证每个结构体的接口数据 for (const [structName, interfaces] of Object.entries(structData)) { if (typeof interfaces !== 'object' || interfaces === null) { return res.status(400).json({ success: false, message: `结构体 ${structName} 的接口数据格式错误:必须是有效的对象` }); } for (const [interfaceName, sizes] of Object.entries(interfaces)) { if (!Array.isArray(sizes) || sizes.length !== 2 || typeof sizes[0] !== 'number' || typeof sizes[1] !== 'number' || sizes[0] < 0 || sizes[1] < 0) { return res.status(400).json({ success: false, message: `接口 ${interfaceName} 的数据格式错误:必须是包含两个非负数字的数组 [size1, size2]` }); } } } } catch (error) { return res.status(400).json({ success: false, message: `结构体数据解析失败: ${error.message}` }); } const result = systemMonitor.injectDataInterfaceFromCsv(structName, csvFilePath); if (result.includes('失败')) { return res.status(500).json({ success: false, message: result }); } res.json({ success: true, message: result }); } catch (error) { res.status(500).json({ success: false, message: `从CSV文件注入数据失败: ${error.message}` }); } }); /** * @brief 停止CSV数据注入 * @route POST /api/data-monitor/stop-csv-inject * @returns {Object} 返回停止结果 */ router.post('/stop-csv-inject', async (req, res) => { try { const result = systemMonitor.stopCsvDataInject(); if (result.includes('失败')) { return res.status(500).json({ success: false, message: result }); } res.json({ success: true, message: result }); } catch (error) { res.status(500).json({ success: false, message: `停止CSV数据注入失败: ${error.message}` }); } }); /** * @brief 获取CSV数据注入状态 * @route GET /api/data-monitor/csv-inject-status * @returns {Object} 返回CSV数据注入状态 */ router.get('/csv-inject-status', async (req, res) => { try { const result = systemMonitor.getCsvDataInjectStatus(); res.json({ success: true, data: result }); } catch (error) { res.status(500).json({ success: false, message: `获取CSV数据注入状态失败: ${error.message}` }); } }); module.exports = router;