diff --git a/Release/database/XNSim.db b/Release/database/XNSim.db index fb6ee21..17cf1d6 100644 Binary files a/Release/database/XNSim.db and b/Release/database/XNSim.db differ diff --git a/Release/lib/libQt6Core.so.6 b/Release/lib/libQt6Core.so.6 deleted file mode 120000 index 2f814d5..0000000 --- a/Release/lib/libQt6Core.so.6 +++ /dev/null @@ -1 +0,0 @@ -libQt6Core.so.6.9.0 \ No newline at end of file diff --git a/Release/lib/libQt6Core.so.6.9.0 b/Release/lib/libQt6Core.so.6.9.0 deleted file mode 100755 index e211213..0000000 Binary files a/Release/lib/libQt6Core.so.6.9.0 and /dev/null differ diff --git a/Release/lib/libQt6DBus.so.6 b/Release/lib/libQt6DBus.so.6 deleted file mode 120000 index 1e829e7..0000000 --- a/Release/lib/libQt6DBus.so.6 +++ /dev/null @@ -1 +0,0 @@ -libQt6DBus.so.6.9.0 \ No newline at end of file diff --git a/Release/lib/libQt6DBus.so.6.9.0 b/Release/lib/libQt6DBus.so.6.9.0 deleted file mode 100755 index 90d57ce..0000000 Binary files a/Release/lib/libQt6DBus.so.6.9.0 and /dev/null differ diff --git a/Release/lib/libQt6Gui.so.6 b/Release/lib/libQt6Gui.so.6 deleted file mode 120000 index 385b0e7..0000000 --- a/Release/lib/libQt6Gui.so.6 +++ /dev/null @@ -1 +0,0 @@ -libQt6Gui.so.6.9.0 \ No newline at end of file diff --git a/Release/lib/libQt6Gui.so.6.9.0 b/Release/lib/libQt6Gui.so.6.9.0 deleted file mode 100755 index 555dfc0..0000000 Binary files a/Release/lib/libQt6Gui.so.6.9.0 and /dev/null differ diff --git a/Release/lib/libQt6Network.so.6 b/Release/lib/libQt6Network.so.6 deleted file mode 120000 index 2d8d752..0000000 --- a/Release/lib/libQt6Network.so.6 +++ /dev/null @@ -1 +0,0 @@ -libQt6Network.so.6.9.0 \ No newline at end of file diff --git a/Release/lib/libQt6Network.so.6.9.0 b/Release/lib/libQt6Network.so.6.9.0 deleted file mode 100755 index 9d7d95a..0000000 Binary files a/Release/lib/libQt6Network.so.6.9.0 and /dev/null differ diff --git a/Release/lib/libQt6OpenGL.so.6 b/Release/lib/libQt6OpenGL.so.6 deleted file mode 120000 index 4cebb83..0000000 --- a/Release/lib/libQt6OpenGL.so.6 +++ /dev/null @@ -1 +0,0 @@ -libQt6OpenGL.so.6.9.0 \ No newline at end of file diff --git a/Release/lib/libQt6OpenGL.so.6.9.0 b/Release/lib/libQt6OpenGL.so.6.9.0 deleted file mode 100755 index 24cf6e7..0000000 Binary files a/Release/lib/libQt6OpenGL.so.6.9.0 and /dev/null differ diff --git a/Release/lib/libQt6PrintSupport.so.6 b/Release/lib/libQt6PrintSupport.so.6 deleted file mode 120000 index 389dfcb..0000000 --- a/Release/lib/libQt6PrintSupport.so.6 +++ /dev/null @@ -1 +0,0 @@ -libQt6PrintSupport.so.6.9.0 \ No newline at end of file diff --git a/Release/lib/libQt6PrintSupport.so.6.9.0 b/Release/lib/libQt6PrintSupport.so.6.9.0 deleted file mode 100755 index 0777c85..0000000 Binary files a/Release/lib/libQt6PrintSupport.so.6.9.0 and /dev/null differ diff --git a/Release/lib/libQt6WaylandClient.so.6 b/Release/lib/libQt6WaylandClient.so.6 deleted file mode 120000 index 40477fe..0000000 --- a/Release/lib/libQt6WaylandClient.so.6 +++ /dev/null @@ -1 +0,0 @@ -libQt6WaylandClient.so.6.9.0 \ No newline at end of file diff --git a/Release/lib/libQt6WaylandClient.so.6.9.0 b/Release/lib/libQt6WaylandClient.so.6.9.0 deleted file mode 100755 index f10fc0c..0000000 Binary files a/Release/lib/libQt6WaylandClient.so.6.9.0 and /dev/null differ diff --git a/Release/lib/libQt6Widgets.so.6 b/Release/lib/libQt6Widgets.so.6 deleted file mode 120000 index 0ff79f2..0000000 --- a/Release/lib/libQt6Widgets.so.6 +++ /dev/null @@ -1 +0,0 @@ -libQt6Widgets.so.6.9.0 \ No newline at end of file diff --git a/Release/lib/libQt6Widgets.so.6.9.0 b/Release/lib/libQt6Widgets.so.6.9.0 deleted file mode 100755 index 0c95687..0000000 Binary files a/Release/lib/libQt6Widgets.so.6.9.0 and /dev/null differ diff --git a/Release/lib/libQt6XcbQpa.so.6 b/Release/lib/libQt6XcbQpa.so.6 deleted file mode 120000 index 192df9d..0000000 --- a/Release/lib/libQt6XcbQpa.so.6 +++ /dev/null @@ -1 +0,0 @@ -libQt6XcbQpa.so.6.9.0 \ No newline at end of file diff --git a/Release/lib/libQt6XcbQpa.so.6.9.0 b/Release/lib/libQt6XcbQpa.so.6.9.0 deleted file mode 100755 index 24f69d6..0000000 Binary files a/Release/lib/libQt6XcbQpa.so.6.9.0 and /dev/null differ diff --git a/Release/lib/libQt6Xml.so.6 b/Release/lib/libQt6Xml.so.6 deleted file mode 120000 index b9e23ce..0000000 --- a/Release/lib/libQt6Xml.so.6 +++ /dev/null @@ -1 +0,0 @@ -libQt6Xml.so.6.9.0 \ No newline at end of file diff --git a/Release/lib/libQt6Xml.so.6.9.0 b/Release/lib/libQt6Xml.so.6.9.0 deleted file mode 100755 index 4a873df..0000000 Binary files a/Release/lib/libQt6Xml.so.6.9.0 and /dev/null differ diff --git a/Release/lib/libxcb.so.1 b/Release/lib/libxcb.so.1 deleted file mode 120000 index e858d46..0000000 --- a/Release/lib/libxcb.so.1 +++ /dev/null @@ -1 +0,0 @@ -libxcb.so.1.1.0 \ No newline at end of file diff --git a/Release/lib/libxcb.so.1.1.0 b/Release/lib/libxcb.so.1.1.0 deleted file mode 100755 index 949b9f9..0000000 Binary files a/Release/lib/libxcb.so.1.1.0 and /dev/null differ diff --git a/XNSimHtml/assets/icons/png/git.png b/XNSimHtml/assets/icons/png/git.png new file mode 100644 index 0000000..dfd1f71 Binary files /dev/null and b/XNSimHtml/assets/icons/png/git.png differ diff --git a/XNSimHtml/components/data-monitor.js b/XNSimHtml/components/data-monitor.js index eaa208c..2e2b89a 100644 --- a/XNSimHtml/components/data-monitor.js +++ b/XNSimHtml/components/data-monitor.js @@ -1,227 +1,324 @@ +/** + * @class DataMonitor + * @extends HTMLElement + * @description 数据监控组件的基础类 + */ class DataMonitor extends HTMLElement { constructor() { super(); this.attachShadow({ mode: 'open' }); - this.currentMode = 'udp'; // 默认显示UDP模式 - this.udpPort = 54321; // 默认UDP端口 - this.udpIp = '127.0.0.1'; // 默认监听所有接口 - this.isMonitoring = false; // 监控状态 - this.udpData = []; // 存储接收到的UDP数据 - - // UDP数据注入默认值 - this.injectIp = '127.0.0.1'; - this.injectPort = 12345; - this.injectData = '{"message": "测试数据"}'; + this.interfaces = []; // 存储接口数据 + this.filteredInterfaces = []; // 存储过滤后的接口数据 + this.searchText = ''; // 搜索文本 + this.searchTimeout = null; // 用于防抖的定时器 + this.cursorPosition = 0; // 存储光标位置 + this.tableData = []; // 表格数据,存储已添加的接口 + this.chart = null; // Chart.js 实例 + this.tableHeight = 220; // 表格初始高度(px) + this.isResizing = false; // 是否正在拖动分隔线 + this.startY = 0; // 拖动起始Y + this.startTableHeight = 0; // 拖动起始表格高度 + this.activeChartIndexes = []; // 当前绘图的行索引 + // 列宽数组,初始为像素 + this.colWidths = [160, 160, 120, 180, 320]; // px + this.dragColIndex = null; + this.dragStartX = 0; + this.dragStartWidth = 0; + this._colWidthInited = false; + this._resizeEventBinded = false; } connectedCallback() { - this.render(); - } - - switchMode(mode) { - this.currentMode = mode; - this.render(); - } - - async startMonitoring() { - if (this.isMonitoring) return; - - try { - const response = await fetch('/api/udp-monitor/start', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - port: this.udpPort, - ip: this.udpIp - }), - }); - - const data = await response.json(); - - if (data.success) { - this.isMonitoring = true; - this.updateMonitoringStatus(); - this.setupDataFetch(); - } else { - this.showError(data.error || '启动监控失败'); + this.loadInterfaces(); + // 延迟多次尝试,直到拿到有效宽度 + const tryInitColWidth = (tryCount = 0) => { + const section = this.shadowRoot && this.shadowRoot.querySelector('.table-section'); + if (section && section.clientWidth > 0) { + const totalWidth = section.clientWidth; + const ratios = [0.17, 0.17, 0.13, 0.19, 0.34]; + this.colWidths = ratios.map(r => Math.floor(totalWidth * r)); + this._colWidthInited = true; + this.render(); + } else if (tryCount < 10) { + setTimeout(() => tryInitColWidth(tryCount + 1), 50); } - } catch (error) { - this.showError('无法连接到服务器'); - console.error('启动UDP监控失败:', error); - } - } - - async stopMonitoring() { - if (!this.isMonitoring) return; - - try { - const response = await fetch('/api/udp-monitor/stop', { - method: 'POST', - }); - - const data = await response.json(); - - if (data.success) { - this.isMonitoring = false; - this.updateMonitoringStatus(); - if (this.dataFetchInterval) { - clearInterval(this.dataFetchInterval); - this.dataFetchInterval = null; + }; + tryInitColWidth(); + // 只绑定一次全局拖动事件 + if (!this._resizeEventBinded) { + window.addEventListener('mousemove', this._onWindowMouseMove = (e) => { + if (this.isResizing) { + const delta = e.clientY - this.startY; + let newHeight = this.startTableHeight + delta; + const minHeight = 60; + const maxHeight = Math.max(120, this.offsetHeight - 180); + if (newHeight < minHeight) newHeight = minHeight; + if (newHeight > maxHeight) newHeight = maxHeight; + this.tableHeight = newHeight; + this.render(); } - } else { - this.showError(data.error || '停止监控失败'); - } - } catch (error) { - this.showError('无法连接到服务器'); - console.error('停止UDP监控失败:', error); + }); + window.addEventListener('mouseup', this._onWindowMouseUp = () => { + if (this.isResizing) { + this.isResizing = false; + const divider = this.shadowRoot.querySelector('.divider'); + if (divider) divider.classList.remove('active'); + document.body.style.cursor = ''; + document.body.style.userSelect = ''; + } + }); + this._resizeEventBinded = true; } } - async injectUdpData() { + /** + * @description 从localStorage获取当前选择的配置 + * @returns {Object} 包含plane和configurationId的对象 + */ + getCurrentSelection() { + const selection = localStorage.getItem('xnsim-selection'); + return selection ? JSON.parse(selection) : { plane: '', configurationId: '' }; + } + + /** + * @description 加载接口数据 + */ + async loadInterfaces() { try { - // 验证数据格式 - let parsedData; - try { - parsedData = JSON.parse(this.injectData); - } catch (e) { - this.showError('数据格式无效,请输入有效的JSON'); + const { configurationId } = this.getCurrentSelection(); + if (!configurationId) { + console.warn('未找到配置ID'); return; } - - const response = await fetch('/api/udp-monitor/inject', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - targetIp: this.injectIp, - targetPort: this.injectPort, - data: parsedData - }), - }); - + + const response = await fetch(`/api/interface/list?systemName=XNSim&confID=${configurationId}`); const data = await response.json(); - - if (data.success) { - this.showSuccess('数据已成功发送'); - } else { - this.showError(data.error || '发送数据失败'); - } + this.interfaces = data; + this.filteredInterfaces = this.filterInterfaces(this.searchText); + this.render(); } catch (error) { - this.showError('无法连接到服务器'); - console.error('发送UDP数据失败:', error); + console.error('加载接口数据失败:', error); } } - setupDataFetch() { - // 清除可能存在的之前的定时器 - if (this.dataFetchInterval) { - clearInterval(this.dataFetchInterval); + /** + * @description 根据搜索文本过滤接口 + * @param {string} searchText - 搜索文本 + * @returns {Array} 过滤后的接口数据 + */ + filterInterfaces(searchText) { + if (!searchText) return this.interfaces; + + return this.interfaces.filter(item => + item.InterfaceName.toLowerCase().includes(searchText.toLowerCase()) || + item.ModelStructName.toLowerCase().includes(searchText.toLowerCase()) + ); + } + + /** + * @description 处理搜索输入 + * @param {Event} event - 输入事件 + */ + handleSearch(event) { + this.searchText = event.target.value; + this.cursorPosition = event.target.selectionStart; + + // 清除之前的定时器 + if (this.searchTimeout) { + clearTimeout(this.searchTimeout); } - // 每秒拉取一次新数据 - this.dataFetchInterval = setInterval(async () => { - try { - const response = await fetch('/api/udp-monitor/data'); - const data = await response.json(); - - if (data.success && data.data) { - this.updateDataDisplay(data.data); + // 设置新的定时器,300ms后执行搜索 + this.searchTimeout = setTimeout(() => { + this.filteredInterfaces = this.filterInterfaces(this.searchText); + this.render(); + + // 在下一个事件循环中恢复焦点和光标位置 + requestAnimationFrame(() => { + const searchInput = this.shadowRoot.querySelector('.search-input'); + if (searchInput) { + searchInput.focus(); + searchInput.setSelectionRange(this.cursorPosition, this.cursorPosition); + } + }); + }, 300); + } + + /** + * @description 处理树节点双击事件,将接口添加到表格 + * @param {Object} item - 接口对象 + */ + handleTreeItemDblClick(item) { + // 防止重复添加 + if (!this.tableData.some(row => row.InterfaceName === item.InterfaceName && row.ModelStructName === item.ModelStructName)) { + this.tableData.push({ + InterfaceName: item.InterfaceName, + ModelStructName: item.ModelStructName, + InjectValue: '', + Drawing: false, + color: this.getRandomColor() + }); + this.renderTable(); + } + } + + /** + * @description 渲染表格内容 + */ + renderTable() { + const tableBody = this.shadowRoot.querySelector('#monitor-table-body'); + if (tableBody) { + tableBody.innerHTML = this.tableData.map((row, idx) => ` +
接口名称 | +结构体名 | +数据 | +注入值 | +操作 | +
---|