V0.21.11.250611_alpha:数据监控连续注入功能已可用
This commit is contained in:
parent
1e2581a239
commit
2fe987f44a
Binary file not shown.
@ -53,6 +53,7 @@ class DataMonitor extends HTMLElement {
|
|||||||
this.initializeComponent();
|
this.initializeComponent();
|
||||||
// 重新启动定时器
|
// 重新启动定时器
|
||||||
this.startDataUpdateTimer();
|
this.startDataUpdateTimer();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async initializeComponent() {
|
async initializeComponent() {
|
||||||
@ -185,13 +186,17 @@ class DataMonitor extends HTMLElement {
|
|||||||
InterfaceName: item.InterfaceName,
|
InterfaceName: item.InterfaceName,
|
||||||
ModelStructName: item.ModelStructName,
|
ModelStructName: item.ModelStructName,
|
||||||
InjectValue: '',
|
InjectValue: '',
|
||||||
|
InjectFrequency: 100,
|
||||||
monitorData: '',
|
monitorData: '',
|
||||||
isMonitoring: false
|
isMonitoring: false,
|
||||||
|
isInjecting: false
|
||||||
});
|
});
|
||||||
|
|
||||||
// 创建新行
|
// 创建新行
|
||||||
const tbody = this.shadowRoot.querySelector('.data-table tbody');
|
const tbody = this.shadowRoot.querySelector('.data-table tbody');
|
||||||
const tr = document.createElement('tr');
|
const tr = document.createElement('tr');
|
||||||
|
tr.setAttribute('data-interface', item.InterfaceName);
|
||||||
|
tr.setAttribute('data-struct', item.ModelStructName);
|
||||||
tr.innerHTML = `
|
tr.innerHTML = `
|
||||||
<td title="${item.InterfaceName}">${item.InterfaceName}</td>
|
<td title="${item.InterfaceName}">${item.InterfaceName}</td>
|
||||||
<td title="${item.ModelStructName}">${item.ModelStructName}</td>
|
<td title="${item.ModelStructName}">${item.ModelStructName}</td>
|
||||||
@ -204,146 +209,27 @@ class DataMonitor extends HTMLElement {
|
|||||||
data-interface="${item.InterfaceName}"
|
data-interface="${item.InterfaceName}"
|
||||||
data-struct="${item.ModelStructName}">
|
data-struct="${item.ModelStructName}">
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
<input type="number"
|
||||||
|
class="frequency-input"
|
||||||
|
value="100"
|
||||||
|
min="10"
|
||||||
|
max="10000"
|
||||||
|
step="10"
|
||||||
|
placeholder="输入频率"
|
||||||
|
data-interface="${item.InterfaceName}"
|
||||||
|
data-struct="${item.ModelStructName}">
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="action-buttons">
|
<div class="action-buttons">
|
||||||
<button class="action-button plot" data-interface="${item.InterfaceName}" data-struct="${item.ModelStructName}">绘图</button>
|
<button class="action-button plot" data-interface="${item.InterfaceName}" data-struct="${item.ModelStructName}">绘图</button>
|
||||||
<button class="action-button inject-once" data-interface="${item.InterfaceName}" data-struct="${item.ModelStructName}">注入一次</button>
|
<button class="action-button inject-once" data-interface="${item.InterfaceName}" data-struct="${item.ModelStructName}">注入一次</button>
|
||||||
<button class="action-button inject-continuous" data-interface="${item.ModelStructName}" data-struct="${item.ModelStructName}">连续注入</button>
|
<button class="action-button inject-continuous" data-interface="${item.InterfaceName}" data-struct="${item.ModelStructName}">连续注入</button>
|
||||||
<button class="action-button delete" data-interface="${item.InterfaceName}" data-struct="${item.ModelStructName}">删除</button>
|
<button class="action-button delete" data-interface="${item.InterfaceName}" data-struct="${item.ModelStructName}">删除</button>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// 为输入框绑定事件
|
|
||||||
const input = tr.querySelector('.inject-input');
|
|
||||||
input.addEventListener('input', (e) => {
|
|
||||||
const value = e.target.value;
|
|
||||||
const interfaceName = e.target.dataset.interface;
|
|
||||||
const modelStructName = e.target.dataset.struct;
|
|
||||||
|
|
||||||
// 检查接口类型
|
|
||||||
const isArray = this.isInterfaceArray(interfaceName, modelStructName);
|
|
||||||
|
|
||||||
// 只允许数字、小数点、负号和逗号
|
|
||||||
const validValue = value.replace(/[^0-9.,-]/g, '');
|
|
||||||
if (value !== validValue) {
|
|
||||||
e.target.value = validValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 验证格式
|
|
||||||
const isValid = this.validateInjectValue(validValue, isArray, interfaceName, modelStructName);
|
|
||||||
e.target.classList.toggle('invalid', !isValid);
|
|
||||||
|
|
||||||
// 实时更新表格数据
|
|
||||||
const row = this.tableData.find(r =>
|
|
||||||
r.InterfaceName === interfaceName &&
|
|
||||||
r.ModelStructName === modelStructName
|
|
||||||
);
|
|
||||||
if (row) {
|
|
||||||
row.InjectValue = validValue;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
input.addEventListener('change', (e) => {
|
|
||||||
const interfaceName = e.target.dataset.interface;
|
|
||||||
const modelStructName = e.target.dataset.struct;
|
|
||||||
const value = e.target.value;
|
|
||||||
|
|
||||||
// 检查接口类型
|
|
||||||
const isArray = this.isInterfaceArray(interfaceName, modelStructName);
|
|
||||||
|
|
||||||
// 验证格式
|
|
||||||
if (!this.validateInjectValue(value, isArray, interfaceName, modelStructName)) {
|
|
||||||
e.target.value = '';
|
|
||||||
// 清空表格数据中的注入值
|
|
||||||
const row = this.tableData.find(r =>
|
|
||||||
r.InterfaceName === interfaceName &&
|
|
||||||
r.ModelStructName === modelStructName
|
|
||||||
);
|
|
||||||
if (row) {
|
|
||||||
row.InjectValue = '';
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新表格数据
|
|
||||||
const row = this.tableData.find(r =>
|
|
||||||
r.InterfaceName === interfaceName &&
|
|
||||||
r.ModelStructName === modelStructName
|
|
||||||
);
|
|
||||||
if (row) {
|
|
||||||
row.InjectValue = value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 为按钮绑定事件
|
|
||||||
const deleteButton = tr.querySelector('.action-button.delete');
|
|
||||||
deleteButton.addEventListener('click', () => {
|
|
||||||
this.handleDelete(item.InterfaceName, item.ModelStructName);
|
|
||||||
});
|
|
||||||
|
|
||||||
const plotButton = tr.querySelector('.action-button.plot');
|
|
||||||
plotButton.addEventListener('click', () => {
|
|
||||||
this.handlePlot(item.InterfaceName, item.ModelStructName);
|
|
||||||
});
|
|
||||||
|
|
||||||
const injectButton = tr.querySelector('.action-button.inject-once');
|
|
||||||
injectButton.addEventListener('click', async () => {
|
|
||||||
// 检查监控状态
|
|
||||||
const statusIndicator = this.shadowRoot.getElementById('statusIndicator');
|
|
||||||
if (!statusIndicator || !statusIndicator.classList.contains('active')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const row = this.tableData.find(r =>
|
|
||||||
r.InterfaceName === item.InterfaceName &&
|
|
||||||
r.ModelStructName === item.ModelStructName
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!row) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!row.InjectValue || row.InjectValue.trim() === '') {
|
|
||||||
alert('请先输入注入值');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查接口类型和注入值格式
|
|
||||||
const isArray = this.isInterfaceArray(item.InterfaceName, item.ModelStructName);
|
|
||||||
if (!this.validateInjectValue(row.InjectValue, isArray, item.InterfaceName, item.ModelStructName)) {
|
|
||||||
alert(isArray ? '请输入正确格式的数组数据(用逗号分隔的数字)' : '请输入单个数字');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 构造接口数据
|
|
||||||
const interfaceData = {
|
|
||||||
[item.InterfaceName]: row.InjectValue
|
|
||||||
};
|
|
||||||
|
|
||||||
// 调用注入接口
|
|
||||||
const response = await fetch('/api/data-monitor/inject', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
structName: item.ModelStructName,
|
|
||||||
interfaceNameAndData: JSON.stringify(interfaceData)
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
const result = await response.json();
|
|
||||||
if (!result.success) {
|
|
||||||
throw new Error(result.message);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('注入失败:', error);
|
|
||||||
alert(`注入失败: ${error.message}`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
tbody.appendChild(tr);
|
tbody.appendChild(tr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1069,6 +955,33 @@ class DataMonitor extends HTMLElement {
|
|||||||
box-shadow: 0 0 0 2px rgba(255, 77, 79, 0.2);
|
box-shadow: 0 0 0 2px rgba(255, 77, 79, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.frequency-input {
|
||||||
|
width: 100%;
|
||||||
|
padding: 4px 8px;
|
||||||
|
border: 1px solid #d9d9d9;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.frequency-input:focus {
|
||||||
|
border-color: #1890ff;
|
||||||
|
outline: none;
|
||||||
|
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.frequency-input:disabled {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-button:disabled {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
color: #d9d9d9;
|
||||||
|
border-color: #d9d9d9;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
.floating-chart-window {
|
.floating-chart-window {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
width: 400px;
|
width: 400px;
|
||||||
@ -1140,6 +1053,22 @@ class DataMonitor extends HTMLElement {
|
|||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
height: 100% !important;
|
height: 100% !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.action-button.active {
|
||||||
|
background-color: #ff4d4f;
|
||||||
|
color: white;
|
||||||
|
border-color: #ff4d4f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-button.active:hover {
|
||||||
|
background-color: #ff7875;
|
||||||
|
border-color: #ff7875;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inject-input:disabled {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<div class="toolbar">
|
<div class="toolbar">
|
||||||
<div class="toolbar-left">
|
<div class="toolbar-left">
|
||||||
@ -1184,13 +1113,14 @@ class DataMonitor extends HTMLElement {
|
|||||||
<th style="width: 200px">结构体名<div class="resizer"></div></th>
|
<th style="width: 200px">结构体名<div class="resizer"></div></th>
|
||||||
<th style="width: 200px">数据<div class="resizer"></div></th>
|
<th style="width: 200px">数据<div class="resizer"></div></th>
|
||||||
<th style="width: 200px">注入值<div class="resizer"></div></th>
|
<th style="width: 200px">注入值<div class="resizer"></div></th>
|
||||||
|
<th style="width: 120px">注入频率(Hz)<div class="resizer"></div></th>
|
||||||
<th>操作</th>
|
<th>操作</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
${this.tableData.map(row => {
|
${this.tableData.map(row => {
|
||||||
return `
|
return `
|
||||||
<tr>
|
<tr data-interface="${row.InterfaceName}" data-struct="${row.ModelStructName}">
|
||||||
<td title="${row.InterfaceName}">${row.InterfaceName}</td>
|
<td title="${row.InterfaceName}">${row.InterfaceName}</td>
|
||||||
<td title="${row.ModelStructName}">${row.ModelStructName}</td>
|
<td title="${row.ModelStructName}">${row.ModelStructName}</td>
|
||||||
<td class="data-cell" title="${this.formatMonitorData(row.monitorData)}">${this.formatMonitorData(row.monitorData)}</td>
|
<td class="data-cell" title="${this.formatMonitorData(row.monitorData)}">${this.formatMonitorData(row.monitorData)}</td>
|
||||||
@ -1200,14 +1130,27 @@ class DataMonitor extends HTMLElement {
|
|||||||
value="${row.InjectValue || ''}"
|
value="${row.InjectValue || ''}"
|
||||||
placeholder="输入注入值"
|
placeholder="输入注入值"
|
||||||
data-interface="${row.InterfaceName}"
|
data-interface="${row.InterfaceName}"
|
||||||
data-struct="${row.ModelStructName}">
|
data-struct="${row.ModelStructName}"
|
||||||
|
${row.isInjecting ? 'disabled' : ''}>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input type="number"
|
||||||
|
class="frequency-input"
|
||||||
|
value="${row.InjectFrequency || 100}"
|
||||||
|
min="10"
|
||||||
|
max="10000"
|
||||||
|
step="10"
|
||||||
|
placeholder="输入频率"
|
||||||
|
data-interface="${row.InterfaceName}"
|
||||||
|
data-struct="${row.ModelStructName}"
|
||||||
|
${row.isInjecting ? 'disabled' : ''}>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="action-buttons">
|
<div class="action-buttons">
|
||||||
<button class="action-button plot" data-interface="${row.InterfaceName}" data-struct="${row.ModelStructName}">绘图</button>
|
<button class="action-button plot" data-interface="${row.InterfaceName}" data-struct="${row.ModelStructName}">绘图</button>
|
||||||
<button class="action-button inject-once" data-interface="${row.InterfaceName}" data-struct="${row.ModelStructName}">注入一次</button>
|
<button class="action-button inject-once" data-interface="${row.InterfaceName}" data-struct="${row.ModelStructName}" ${row.isInjecting ? 'disabled' : ''}>注入一次</button>
|
||||||
<button class="action-button inject-continuous" data-interface="${row.InterfaceName}" data-struct="${row.ModelStructName}">连续注入</button>
|
<button class="action-button inject-continuous ${row.isInjecting ? 'active' : ''}" data-interface="${row.InterfaceName}" data-struct="${row.ModelStructName}">${row.isInjecting ? '停止注入' : '连续注入'}</button>
|
||||||
<button class="action-button delete" data-interface="${row.InterfaceName}" data-struct="${row.ModelStructName}">删除</button>
|
<button class="action-button delete" data-interface="${row.InterfaceName}" data-struct="${row.ModelStructName}" ${row.isInjecting ? 'disabled' : ''}>删除</button>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -1336,6 +1279,31 @@ class DataMonitor extends HTMLElement {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 添加频率输入框的事件处理
|
||||||
|
const frequencyInputs = this.shadowRoot.querySelectorAll('.frequency-input');
|
||||||
|
frequencyInputs.forEach(input => {
|
||||||
|
input.addEventListener('change', (e) => {
|
||||||
|
const interfaceName = e.target.dataset.interface;
|
||||||
|
const modelStructName = e.target.dataset.struct;
|
||||||
|
const value = parseInt(e.target.value);
|
||||||
|
|
||||||
|
// 验证频率范围
|
||||||
|
if (value < 0 || value > 1000) {
|
||||||
|
e.target.value = 100; // 默认值
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新表格数据
|
||||||
|
const row = this.tableData.find(r =>
|
||||||
|
r.InterfaceName === interfaceName &&
|
||||||
|
r.ModelStructName === modelStructName
|
||||||
|
);
|
||||||
|
if (row) {
|
||||||
|
row.InjectFrequency = value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// 添加注入一次按钮的事件委托
|
// 添加注入一次按钮的事件委托
|
||||||
table.addEventListener('click', async (e) => {
|
table.addEventListener('click', async (e) => {
|
||||||
const injectButton = e.target.closest('.action-button.inject-once');
|
const injectButton = e.target.closest('.action-button.inject-once');
|
||||||
@ -1420,6 +1388,134 @@ class DataMonitor extends HTMLElement {
|
|||||||
this.handlePlot(interfaceName, modelStructName);
|
this.handlePlot(interfaceName, modelStructName);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 添加连续注入按钮的事件委托
|
||||||
|
table.addEventListener('click', async (e) => {
|
||||||
|
const continuousInjectButton = e.target.closest('.action-button.inject-continuous');
|
||||||
|
if (continuousInjectButton) {
|
||||||
|
// 检查监控状态
|
||||||
|
const statusIndicator = this.shadowRoot.getElementById('statusIndicator');
|
||||||
|
if (!statusIndicator || !statusIndicator.classList.contains('active')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const interfaceName = continuousInjectButton.getAttribute('data-interface');
|
||||||
|
const modelStructName = continuousInjectButton.getAttribute('data-struct');
|
||||||
|
|
||||||
|
if (!interfaceName || !modelStructName) {
|
||||||
|
console.error('按钮缺少必要的数据属性');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const row = this.tableData.find(r =>
|
||||||
|
r.InterfaceName === interfaceName &&
|
||||||
|
r.ModelStructName === modelStructName
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!row) {
|
||||||
|
console.error('未找到对应的行数据:', { interfaceName, modelStructName });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果正在连续注入,则停止注入
|
||||||
|
if (continuousInjectButton.classList.contains('active')) {
|
||||||
|
try {
|
||||||
|
// 调用停止注入接口
|
||||||
|
const response = await fetch('/api/data-monitor/stop-continuous', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
structName: modelStructName,
|
||||||
|
interfaceName: interfaceName
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
if (!result.success) {
|
||||||
|
throw new Error(result.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新按钮和输入框状态
|
||||||
|
continuousInjectButton.textContent = '连续注入';
|
||||||
|
continuousInjectButton.classList.remove('active');
|
||||||
|
const tr = continuousInjectButton.closest('tr');
|
||||||
|
const input = tr.querySelector('.inject-input');
|
||||||
|
const injectButton = tr.querySelector('.action-button.inject-once');
|
||||||
|
const frequencyInput = tr.querySelector('.frequency-input');
|
||||||
|
const deleteButton = tr.querySelector('.action-button.delete');
|
||||||
|
input.disabled = false;
|
||||||
|
injectButton.disabled = false;
|
||||||
|
frequencyInput.disabled = false;
|
||||||
|
deleteButton.disabled = false;
|
||||||
|
|
||||||
|
// 更新表格数据状态
|
||||||
|
row.isInjecting = false;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('停止注入失败:', error);
|
||||||
|
alert(`停止注入失败: ${error.message}`);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!row.InjectValue || row.InjectValue.trim() === '') {
|
||||||
|
alert('请先输入注入值');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查接口类型和注入值格式
|
||||||
|
const isArray = this.isInterfaceArray(interfaceName, modelStructName);
|
||||||
|
if (!this.validateInjectValue(row.InjectValue, isArray, interfaceName, modelStructName)) {
|
||||||
|
alert(isArray ? '请输入正确格式的数组数据(用逗号分隔的数字)' : '请输入单个数字');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 构造接口数据
|
||||||
|
const interfaceData = {
|
||||||
|
[interfaceName]: row.InjectValue
|
||||||
|
};
|
||||||
|
|
||||||
|
// 调用连续注入接口
|
||||||
|
const response = await fetch('/api/data-monitor/start-continuous', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
structName: modelStructName,
|
||||||
|
interfaceNameAndData: JSON.stringify(interfaceData),
|
||||||
|
frequency: row.InjectFrequency || 100
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
if (!result.success) {
|
||||||
|
throw new Error(result.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新按钮和输入框状态
|
||||||
|
continuousInjectButton.textContent = '停止注入';
|
||||||
|
continuousInjectButton.classList.add('active');
|
||||||
|
const tr = continuousInjectButton.closest('tr');
|
||||||
|
const input = tr.querySelector('.inject-input');
|
||||||
|
const injectButton = tr.querySelector('.action-button.inject-once');
|
||||||
|
const frequencyInput = tr.querySelector('.frequency-input');
|
||||||
|
const deleteButton = tr.querySelector('.action-button.delete');
|
||||||
|
input.disabled = true;
|
||||||
|
injectButton.disabled = true;
|
||||||
|
frequencyInput.disabled = true;
|
||||||
|
deleteButton.disabled = true;
|
||||||
|
|
||||||
|
// 更新表格数据状态
|
||||||
|
row.isInjecting = true;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('连续注入失败:', error);
|
||||||
|
alert(`连续注入失败: ${error.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2,6 +2,9 @@ const express = require('express');
|
|||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
const systemMonitor = require('../utils/xnCoreService');
|
const systemMonitor = require('../utils/xnCoreService');
|
||||||
|
|
||||||
|
// 存储连续注入状态
|
||||||
|
const continuousInjectStatus = new Map();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 启动数据监控
|
* @brief 启动数据监控
|
||||||
* @route POST /api/data-monitor/start
|
* @route POST /api/data-monitor/start
|
||||||
@ -141,11 +144,66 @@ router.post('/start-continuous', async (req, res) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = systemMonitor.startInjectContinuous(structName, interfaceNameAndData, frequency);
|
// 检查是否已存在该结构体的注入状态
|
||||||
if (result.includes('失败')) {
|
if (continuousInjectStatus.has(structName)) {
|
||||||
return res.status(500).json({ success: false, message: result });
|
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: result });
|
|
||||||
|
res.json({
|
||||||
|
success: true,
|
||||||
|
message: '启动持续注入成功',
|
||||||
|
data: {
|
||||||
|
structName,
|
||||||
|
interfaceNameAndData: continuousInjectStatus.get(structName).interfaceNameAndData,
|
||||||
|
frequency
|
||||||
|
}
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).json({ success: false, message: `启动持续注入数据失败: ${error.message}` });
|
res.status(500).json({ success: false, message: `启动持续注入数据失败: ${error.message}` });
|
||||||
}
|
}
|
||||||
@ -155,20 +213,69 @@ router.post('/start-continuous', async (req, res) => {
|
|||||||
* @brief 停止持续注入数据
|
* @brief 停止持续注入数据
|
||||||
* @route POST /api/data-monitor/stop-continuous
|
* @route POST /api/data-monitor/stop-continuous
|
||||||
* @param {string} structName - 结构体名称
|
* @param {string} structName - 结构体名称
|
||||||
|
* @param {string} interfaceName - 要停止的接口名称
|
||||||
* @returns {Object} 返回停止结果
|
* @returns {Object} 返回停止结果
|
||||||
*/
|
*/
|
||||||
router.post('/stop-continuous', async (req, res) => {
|
router.post('/stop-continuous', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { structName } = req.body;
|
const { structName, interfaceName } = req.body;
|
||||||
if (!structName) {
|
if (!structName || !interfaceName) {
|
||||||
return res.status(400).json({ success: false, message: '结构体名称不能为空' });
|
return res.status(400).json({
|
||||||
|
success: false,
|
||||||
|
message: '结构体名称和接口名称不能为空'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = systemMonitor.stopInjectContinuous(structName);
|
// 检查是否存在该结构体的注入状态
|
||||||
if (result.includes('失败')) {
|
if (!continuousInjectStatus.has(structName)) {
|
||||||
return res.status(500).json({ success: false, message: result });
|
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: '接口数据格式错误'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
res.json({ success: true, message: result });
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).json({ success: false, message: `停止持续注入数据失败: ${error.message}` });
|
res.status(500).json({ success: false, message: `停止持续注入数据失败: ${error.message}` });
|
||||||
}
|
}
|
||||||
|
@ -68,13 +68,26 @@ try {
|
|||||||
// 注册进程退出时的清理函数
|
// 注册进程退出时的清理函数
|
||||||
function performCleanup() {
|
function performCleanup() {
|
||||||
console.log('正在执行清理操作...');
|
console.log('正在执行清理操作...');
|
||||||
if (loginLib) {
|
try {
|
||||||
try {
|
// 清理 loginLib
|
||||||
|
if (loginLib) {
|
||||||
loginLib.cleanup();
|
loginLib.cleanup();
|
||||||
console.log('清理操作完成');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('清理操作失败:', error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 清理 monitorLib
|
||||||
|
if (monitorLib) {
|
||||||
|
// 停止所有监控
|
||||||
|
stopMonitorSystemInfo();
|
||||||
|
stopMonitorModelInfo();
|
||||||
|
// 停止所有数据监控和注入
|
||||||
|
stopDataMonitor('');
|
||||||
|
stopInjectContinuous('');
|
||||||
|
// 清理监控服务器资源
|
||||||
|
monitorLib.XN_Cleanup();
|
||||||
|
}
|
||||||
|
console.log('清理操作完成');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('清理操作失败:', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user