8 changed files with 728 additions and 762 deletions
@ -1,353 +0,0 @@ |
|||
@{ |
|||
ViewData["Title"] = "统计测试"; |
|||
} |
|||
|
|||
<div class="container-fluid"> |
|||
<div class="row"> |
|||
<div class="col-12"> |
|||
<div class="card"> |
|||
<div class="card-header"> |
|||
<h3 class="card-title">统计功能测试</h3> |
|||
</div> |
|||
<div class="card-body"> |
|||
<div class="row"> |
|||
<div class="col-md-6"> |
|||
<h5>API测试</h5> |
|||
<button class="btn btn-primary mb-2" onclick="testGetAllStats()">获取所有统计数据</button> |
|||
<button class="btn btn-info mb-2" onclick="testGetLatestStats()">获取最新统计数据</button> |
|||
<button class="btn btn-success mb-2" onclick="testGetSummary()">获取统计摘要</button> |
|||
<button class="btn btn-warning mb-2" onclick="testClearStats()">清空统计数据</button> |
|||
</div> |
|||
<div class="col-md-6"> |
|||
<h5>SSE测试</h5> |
|||
<button class="btn btn-primary mb-2" onclick="testSSE()">测试SSE连接</button> |
|||
<button class="btn btn-danger mb-2" onclick="stopSSE()">停止SSE</button> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="row mt-3"> |
|||
<div class="col-12"> |
|||
<h5>统计配置管理</h5> |
|||
<div class="row"> |
|||
<div class="col-md-6"> |
|||
<div class="card"> |
|||
<div class="card-header"> |
|||
<h6>全局统计配置</h6> |
|||
</div> |
|||
<div class="card-body"> |
|||
<div class="form-group"> |
|||
<label>默认Samples:</label> |
|||
<div class="form-check"> |
|||
<input class="form-check-input" type="checkbox" id="globalSamples"> |
|||
<label class="form-check-label" for="globalSamples">启用Samples</label> |
|||
</div> |
|||
</div> |
|||
<div class="form-group"> |
|||
<label>默认RF:</label> |
|||
<div class="form-check"> |
|||
<input class="form-check-input" type="checkbox" id="globalRf"> |
|||
<label class="form-check-label" for="globalRf">启用RF</label> |
|||
</div> |
|||
</div> |
|||
<button class="btn btn-primary btn-sm" onclick="loadGlobalConfig()">加载配置</button> |
|||
<button class="btn btn-success btn-sm" onclick="saveGlobalConfig()">保存配置</button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="col-md-6"> |
|||
<div class="card"> |
|||
<div class="card-header"> |
|||
<h6>客户端特定配置</h6> |
|||
</div> |
|||
<div class="card-body"> |
|||
<div class="form-group"> |
|||
<label>客户端名称:</label> |
|||
<input type="text" class="form-control" id="clientName" placeholder="输入客户端名称"> |
|||
</div> |
|||
<div class="form-group"> |
|||
<label>IP地址:</label> |
|||
<input type="text" class="form-control" id="clientIp" placeholder="输入IP地址"> |
|||
</div> |
|||
<div class="form-group"> |
|||
<label>配置选项:</label> |
|||
<div class="form-check"> |
|||
<input class="form-check-input" type="checkbox" id="clientSamples"> |
|||
<label class="form-check-label" for="clientSamples">启用Samples</label> |
|||
</div> |
|||
<div class="form-check"> |
|||
<input class="form-check-input" type="checkbox" id="clientRf"> |
|||
<label class="form-check-label" for="clientRf">启用RF</label> |
|||
</div> |
|||
<div class="form-check"> |
|||
<input class="form-check-input" type="checkbox" id="clientEnabled" checked> |
|||
<label class="form-check-label" for="clientEnabled">启用配置</label> |
|||
</div> |
|||
</div> |
|||
<div class="form-group"> |
|||
<label>描述:</label> |
|||
<input type="text" class="form-control" id="clientDescription" placeholder="配置描述"> |
|||
</div> |
|||
<button class="btn btn-primary btn-sm" onclick="loadClientConfig()">加载配置</button> |
|||
<button class="btn btn-success btn-sm" onclick="saveClientConfig()">保存配置</button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="row mt-3"> |
|||
<div class="col-12"> |
|||
<h5>配置列表</h5> |
|||
<button class="btn btn-info btn-sm mb-2" onclick="loadAllClientConfigs()">刷新配置列表</button> |
|||
<div id="configList" class="table-responsive"> |
|||
<table class="table table-striped"> |
|||
<thead> |
|||
<tr> |
|||
<th>客户端名称</th> |
|||
<th>IP地址</th> |
|||
<th>Samples</th> |
|||
<th>RF</th> |
|||
<th>启用</th> |
|||
<th>描述</th> |
|||
<th>操作</th> |
|||
</tr> |
|||
</thead> |
|||
<tbody id="configTableBody"> |
|||
</tbody> |
|||
</table> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="row mt-3"> |
|||
<div class="col-12"> |
|||
<h5>测试结果</h5> |
|||
<pre id="testResult" style="background-color: #f8f9fa; padding: 10px; border-radius: 5px; max-height: 400px; overflow-y: auto;"></pre> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
@section Scripts { |
|||
<script> |
|||
let sseConnection = null; |
|||
|
|||
function logResult(message) { |
|||
const result = document.getElementById('testResult'); |
|||
const timestamp = new Date().toLocaleTimeString(); |
|||
result.textContent += `[${timestamp}] ${message}\n`; |
|||
result.scrollTop = result.scrollHeight; |
|||
} |
|||
|
|||
function testGetAllStats() { |
|||
logResult('测试获取所有统计数据...'); |
|||
$.get('/Statistics/GetAllStats', function(response) { |
|||
logResult('响应: ' + JSON.stringify(response, null, 2)); |
|||
}).fail(function(xhr, status, error) { |
|||
logResult('错误: ' + error); |
|||
}); |
|||
} |
|||
|
|||
function testGetLatestStats() { |
|||
logResult('测试获取最新统计数据...'); |
|||
$.get('/Statistics/GetLatestStats', function(response) { |
|||
logResult('响应: ' + JSON.stringify(response, null, 2)); |
|||
}).fail(function(xhr, status, error) { |
|||
logResult('错误: ' + error); |
|||
}); |
|||
} |
|||
|
|||
function testGetSummary() { |
|||
logResult('测试获取统计摘要...'); |
|||
$.get('/Statistics/GetSummary', function(response) { |
|||
logResult('响应: ' + JSON.stringify(response, null, 2)); |
|||
}).fail(function(xhr, status, error) { |
|||
logResult('错误: ' + error); |
|||
}); |
|||
} |
|||
|
|||
function testClearStats() { |
|||
logResult('测试清空统计数据...'); |
|||
$.post('/Statistics/ClearStats', function(response) { |
|||
logResult('响应: ' + JSON.stringify(response, null, 2)); |
|||
}).fail(function(xhr, status, error) { |
|||
logResult('错误: ' + error); |
|||
}); |
|||
} |
|||
|
|||
function testSSE() { |
|||
logResult('测试SSE连接...'); |
|||
if (sseConnection) { |
|||
sseConnection.close(); |
|||
} |
|||
|
|||
sseConnection = new EventSource('/Statistics/SSEStats'); |
|||
|
|||
sseConnection.onopen = function(event) { |
|||
logResult('SSE连接已建立'); |
|||
}; |
|||
|
|||
sseConnection.onmessage = function(event) { |
|||
logResult('SSE消息: ' + event.data); |
|||
}; |
|||
|
|||
sseConnection.onerror = function(event) { |
|||
logResult('SSE错误: ' + JSON.stringify(event)); |
|||
}; |
|||
} |
|||
|
|||
function stopSSE() { |
|||
logResult('停止SSE连接...'); |
|||
if (sseConnection) { |
|||
sseConnection.close(); |
|||
sseConnection = null; |
|||
logResult('SSE连接已关闭'); |
|||
} |
|||
} |
|||
|
|||
// 统计配置相关函数 |
|||
function loadGlobalConfig() { |
|||
logResult('加载全局统计配置...'); |
|||
$.get('/Statistics/GetGlobalStatisticsConfig', function(response) { |
|||
if (response.success) { |
|||
const config = response.data; |
|||
document.getElementById('globalSamples').checked = config.defaultSamples; |
|||
document.getElementById('globalRf').checked = config.defaultRf; |
|||
logResult('全局配置已加载: ' + JSON.stringify(config, null, 2)); |
|||
} else { |
|||
logResult('加载全局配置失败: ' + response.message); |
|||
} |
|||
}).fail(function(xhr, status, error) { |
|||
logResult('加载全局配置错误: ' + error); |
|||
}); |
|||
} |
|||
|
|||
function saveGlobalConfig() { |
|||
const config = { |
|||
defaultSamples: document.getElementById('globalSamples').checked, |
|||
defaultRf: document.getElementById('globalRf').checked, |
|||
clientConfigs: [] |
|||
}; |
|||
|
|||
logResult('保存全局统计配置...'); |
|||
$.ajax({ |
|||
url: '/Statistics/SetGlobalStatisticsConfig', |
|||
type: 'POST', |
|||
contentType: 'application/json', |
|||
data: JSON.stringify(config), |
|||
success: function(response) { |
|||
logResult('响应: ' + JSON.stringify(response, null, 2)); |
|||
}, |
|||
error: function(xhr, status, error) { |
|||
logResult('错误: ' + error); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
function loadClientConfig() { |
|||
const clientName = document.getElementById('clientName').value; |
|||
if (!clientName) { |
|||
logResult('请输入客户端名称'); |
|||
return; |
|||
} |
|||
|
|||
logResult('加载客户端统计配置: ' + clientName); |
|||
$.get('/Statistics/GetClientStatisticsConfig', { clientName: clientName }, function(response) { |
|||
if (response.success && response.data) { |
|||
const config = response.data; |
|||
document.getElementById('clientName').value = config.clientName; |
|||
document.getElementById('clientIp').value = config.ipAddress; |
|||
document.getElementById('clientSamples').checked = config.enableSamples; |
|||
document.getElementById('clientRf').checked = config.enableRf; |
|||
document.getElementById('clientEnabled').checked = config.isEnabled; |
|||
document.getElementById('clientDescription').value = config.description; |
|||
logResult('客户端配置已加载: ' + JSON.stringify(config, null, 2)); |
|||
} else { |
|||
logResult('客户端配置未找到或加载失败'); |
|||
} |
|||
}).fail(function(xhr, status, error) { |
|||
logResult('加载客户端配置错误: ' + error); |
|||
}); |
|||
} |
|||
|
|||
function saveClientConfig() { |
|||
const config = { |
|||
clientName: document.getElementById('clientName').value, |
|||
ipAddress: document.getElementById('clientIp').value, |
|||
enableSamples: document.getElementById('clientSamples').checked, |
|||
enableRf: document.getElementById('clientRf').checked, |
|||
isEnabled: document.getElementById('clientEnabled').checked, |
|||
description: document.getElementById('clientDescription').value |
|||
}; |
|||
|
|||
if (!config.clientName) { |
|||
logResult('请输入客户端名称'); |
|||
return; |
|||
} |
|||
|
|||
logResult('保存客户端统计配置...'); |
|||
$.ajax({ |
|||
url: '/Statistics/SetClientStatisticsConfig', |
|||
type: 'POST', |
|||
contentType: 'application/json', |
|||
data: JSON.stringify(config), |
|||
success: function(response) { |
|||
logResult('响应: ' + JSON.stringify(response, null, 2)); |
|||
loadAllClientConfigs(); // 刷新配置列表 |
|||
}, |
|||
error: function(xhr, status, error) { |
|||
logResult('错误: ' + error); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
function loadAllClientConfigs() { |
|||
logResult('加载所有客户端配置...'); |
|||
$.get('/Statistics/GetAllClientStatisticsConfigs', function(response) { |
|||
if (response.success) { |
|||
const configs = response.data; |
|||
const tbody = document.getElementById('configTableBody'); |
|||
tbody.innerHTML = ''; |
|||
|
|||
configs.forEach(function(config) { |
|||
const row = document.createElement('tr'); |
|||
row.innerHTML = ` |
|||
<td>${config.clientName}</td> |
|||
<td>${config.ipAddress}</td> |
|||
<td>${config.enableSamples ? '是' : '否'}</td> |
|||
<td>${config.enableRf ? '是' : '否'}</td> |
|||
<td>${config.isEnabled ? '是' : '否'}</td> |
|||
<td>${config.description}</td> |
|||
<td> |
|||
<button class="btn btn-sm btn-primary" onclick="editConfig('${config.clientName}')">编辑</button> |
|||
</td> |
|||
`; |
|||
tbody.appendChild(row); |
|||
}); |
|||
|
|||
logResult('配置列表已更新,共 ' + configs.length + ' 个配置'); |
|||
} else { |
|||
logResult('加载配置列表失败: ' + response.message); |
|||
} |
|||
}).fail(function(xhr, status, error) { |
|||
logResult('加载配置列表错误: ' + error); |
|||
}); |
|||
} |
|||
|
|||
function editConfig(clientName) { |
|||
document.getElementById('clientName').value = clientName; |
|||
loadClientConfig(); |
|||
} |
|||
|
|||
// 页面加载时初始化 |
|||
$(document).ready(function() { |
|||
document.getElementById('testResult').textContent = ''; |
|||
loadGlobalConfig(); |
|||
loadAllClientConfigs(); |
|||
}); |
|||
</script> |
|||
} |
@ -0,0 +1,564 @@ |
|||
@{ |
|||
ViewData["Title"] = "统计配置管理"; |
|||
} |
|||
|
|||
<style> |
|||
/* 页面整体布局 */ |
|||
.config-container { |
|||
max-height: calc(100vh - 280px); |
|||
display: flex; |
|||
flex-direction: column; |
|||
overflow: hidden; |
|||
} |
|||
|
|||
/* 表单容器 */ |
|||
.config-form { |
|||
flex: 1; |
|||
overflow-y: auto; |
|||
overflow-x: hidden; |
|||
padding: 0.75rem; |
|||
} |
|||
|
|||
/* 自定义滚动条 */ |
|||
.config-form::-webkit-scrollbar { |
|||
width: 6px; |
|||
} |
|||
|
|||
.config-form::-webkit-scrollbar-track { |
|||
background: #f1f1f1; |
|||
border-radius: 3px; |
|||
} |
|||
|
|||
.config-form::-webkit-scrollbar-thumb { |
|||
background: #c1c1c1; |
|||
border-radius: 3px; |
|||
} |
|||
|
|||
.config-form::-webkit-scrollbar-thumb:hover { |
|||
background: #a8a8a8; |
|||
} |
|||
|
|||
/* 表单样式 */ |
|||
.form-group { |
|||
margin-bottom: 0.75rem; |
|||
} |
|||
|
|||
.form-group label { |
|||
font-weight: 600; |
|||
color: #495057; |
|||
margin-bottom: 0.25rem; |
|||
font-size: 0.9rem; |
|||
} |
|||
|
|||
.form-control { |
|||
border-radius: 0.375rem; |
|||
border: 1px solid #ced4da; |
|||
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; |
|||
padding: 0.375rem 0.75rem; |
|||
} |
|||
|
|||
.form-control:focus { |
|||
border-color: #80bdff; |
|||
box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); |
|||
} |
|||
|
|||
/* 表格样式 */ |
|||
.table-responsive { |
|||
border-radius: 0.5rem; |
|||
overflow: hidden; |
|||
box-shadow: 0 2px 4px rgba(0,0,0,0.1); |
|||
} |
|||
|
|||
.table { |
|||
margin-bottom: 0; |
|||
font-size: 0.85rem; |
|||
} |
|||
|
|||
.table th { |
|||
background-color: #343a40; |
|||
color: white; |
|||
font-weight: 600; |
|||
border: none; |
|||
padding: 0.5rem; |
|||
} |
|||
|
|||
.table td { |
|||
vertical-align: middle; |
|||
border-color: #dee2e6; |
|||
padding: 0.5rem; |
|||
} |
|||
|
|||
/* 按钮样式 */ |
|||
.btn { |
|||
border-radius: 0.375rem; |
|||
font-weight: 500; |
|||
transition: all 0.2s; |
|||
padding: 0.375rem 0.75rem; |
|||
font-size: 0.9rem; |
|||
} |
|||
|
|||
.btn:hover { |
|||
transform: translateY(-1px); |
|||
box-shadow: 0 2px 4px rgba(0,0,0,0.1); |
|||
} |
|||
|
|||
.form-check { |
|||
margin-bottom: 0.5rem; |
|||
} |
|||
|
|||
.form-check-input:checked { |
|||
background-color: #007bff; |
|||
border-color: #007bff; |
|||
} |
|||
|
|||
.section-title { |
|||
color: #495057; |
|||
font-weight: 600; |
|||
margin-bottom: 0.5rem; |
|||
padding-bottom: 0.25rem; |
|||
border-bottom: 2px solid #e9ecef; |
|||
font-size: 1rem; |
|||
} |
|||
|
|||
/* 按钮区域 */ |
|||
.button-area { |
|||
flex-shrink: 0; |
|||
background: white; |
|||
border-top: 1px solid #dee2e6; |
|||
padding: 0.5rem 0.75rem; |
|||
display: flex; |
|||
gap: 0.5rem; |
|||
flex-wrap: wrap; |
|||
} |
|||
|
|||
/* 配置卡片样式 */ |
|||
.config-card { |
|||
border: 1px solid #e9ecef; |
|||
border-radius: 0.5rem; |
|||
background: #f8f9fa; |
|||
padding: 1rem; |
|||
margin-bottom: 1rem; |
|||
} |
|||
|
|||
.config-card-header { |
|||
display: flex; |
|||
justify-content: between; |
|||
align-items: center; |
|||
margin-bottom: 1rem; |
|||
padding-bottom: 0.5rem; |
|||
border-bottom: 1px solid #dee2e6; |
|||
} |
|||
|
|||
.config-card-title { |
|||
font-weight: 600; |
|||
color: #495057; |
|||
margin: 0; |
|||
font-size: 1rem; |
|||
} |
|||
|
|||
.config-options { |
|||
display: flex; |
|||
gap: 1rem; |
|||
align-items: center; |
|||
flex-wrap: wrap; |
|||
} |
|||
|
|||
.config-option { |
|||
display: flex; |
|||
align-items: center; |
|||
gap: 0.5rem; |
|||
} |
|||
|
|||
/* 响应式调整 */ |
|||
@@media (max-width: 768px) { |
|||
.config-container { |
|||
max-height: calc(100vh - 240px); |
|||
} |
|||
|
|||
.button-area { |
|||
padding: 0.4rem 0.6rem; |
|||
} |
|||
|
|||
.config-form { |
|||
padding: 0.6rem; |
|||
} |
|||
|
|||
.config-options { |
|||
flex-direction: column; |
|||
align-items: flex-start; |
|||
} |
|||
} |
|||
|
|||
@@media (max-width: 576px) { |
|||
.config-container { |
|||
max-height: calc(100vh - 220px); |
|||
} |
|||
|
|||
.button-area { |
|||
padding: 0.3rem 0.5rem; |
|||
} |
|||
|
|||
.config-form { |
|||
padding: 0.5rem; |
|||
} |
|||
|
|||
.btn { |
|||
font-size: 0.8rem; |
|||
padding: 0.3rem 0.6rem; |
|||
} |
|||
} |
|||
</style> |
|||
|
|||
<div class="container"> |
|||
<div class="row"> |
|||
<div class="col-12"> |
|||
<div class="card"> |
|||
<div class="card-header"> |
|||
<h3 class="card-title"> |
|||
<i class="fas fa-cogs"></i> 统计配置管理 |
|||
</h3> |
|||
</div> |
|||
<div class="card-body p-0"> |
|||
<div class="config-container"> |
|||
<div class="config-form"> |
|||
<!-- 客户端配置 --> |
|||
<div class="row mb-4"> |
|||
<div class="col-12"> |
|||
<div class="card"> |
|||
<div class="card-header"> |
|||
<h5 class="card-title mb-0"> |
|||
<i class="fas fa-server"></i> 客户端统计配置 |
|||
</h5> |
|||
</div> |
|||
<div class="card-body"> |
|||
<div class="d-flex justify-content-between align-items-center mb-3"> |
|||
<div> |
|||
<span class="badge bg-info" id="clientCount">0</span> 个客户端 |
|||
</div> |
|||
<button class="btn btn-sm btn-outline-primary" onclick="loadClientList()"> |
|||
<i class="fas fa-sync-alt"></i> 重新加载客户端 |
|||
</button> |
|||
</div> |
|||
<div class="table-responsive"> |
|||
<table class="table table-striped table-hover"> |
|||
<thead class="table-dark"> |
|||
<tr> |
|||
<th>客户端名称</th> |
|||
<th>IP地址</th> |
|||
<th>Samples</th> |
|||
<th>RF</th> |
|||
<th>状态</th> |
|||
<th>描述</th> |
|||
<th>操作</th> |
|||
</tr> |
|||
</thead> |
|||
<tbody id="clientConfigTableBody"> |
|||
<!-- 客户端配置数据将通过JavaScript动态填充 --> |
|||
</tbody> |
|||
</table> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- 配置信息 --> |
|||
<div class="row"> |
|||
<div class="col-12"> |
|||
<div class="card"> |
|||
<div class="card-header"> |
|||
<h5 class="card-title mb-0"> |
|||
<i class="fas fa-info-circle"></i> 配置说明 |
|||
</h5> |
|||
</div> |
|||
<div class="card-body"> |
|||
<div class="row"> |
|||
<div class="col-md-6"> |
|||
<h6>配置优先级:</h6> |
|||
<ol> |
|||
<li><strong>客户端特定配置</strong> - 如果客户端有特定的配置且启用,则使用该配置</li> |
|||
<li><strong>系统默认值</strong> - 如果客户端没有特定配置,则使用系统默认值(samples=false, rf=false)</li> |
|||
</ol> |
|||
</div> |
|||
<div class="col-md-6"> |
|||
<h6>参数说明:</h6> |
|||
<ul> |
|||
<li><strong>Samples</strong> - 控制是否收集详细的采样数据,可能影响性能</li> |
|||
<li><strong>RF</strong> - 控制是否收集射频相关数据,包含信号质量等信息</li> |
|||
<li><strong>启用配置</strong> - 控制该客户端配置是否生效</li> |
|||
</ul> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
@section Scripts { |
|||
<script> |
|||
// 页面加载时初始化 |
|||
$(document).ready(function() { |
|||
loadClientList(); |
|||
}); |
|||
|
|||
// 加载客户端列表并生成配置表格 |
|||
function loadClientList() { |
|||
console.log('加载客户端列表...'); |
|||
$.get('/api/config', function(response) { |
|||
if (response && response.length > 0) { |
|||
const tbody = document.getElementById('clientConfigTableBody'); |
|||
tbody.innerHTML = ''; |
|||
|
|||
response.forEach(function(client) { |
|||
const row = document.createElement('tr'); |
|||
row.innerHTML = ` |
|||
<td><strong>${client.name}</strong></td> |
|||
<td><code>${client.address}</code></td> |
|||
<td> |
|||
<div class="form-check d-flex justify-content-center"> |
|||
<input class="form-check-input" type="checkbox" id="samples_${client.name}" |
|||
onchange="updateConfig('${client.name}', 'samples', this.checked)"> |
|||
</div> |
|||
</td> |
|||
<td> |
|||
<div class="form-check d-flex justify-content-center"> |
|||
<input class="form-check-input" type="checkbox" id="rf_${client.name}" |
|||
onchange="updateConfig('${client.name}', 'rf', this.checked)"> |
|||
</div> |
|||
</td> |
|||
<td> |
|||
<div class="form-check d-flex justify-content-center"> |
|||
<input class="form-check-input" type="checkbox" id="enabled_${client.name}" checked |
|||
onchange="updateConfig('${client.name}', 'enabled', this.checked)"> |
|||
</div> |
|||
</td> |
|||
<td> |
|||
<input type="text" class="form-control form-control-sm" id="desc_${client.name}" |
|||
placeholder="配置描述" onblur="updateConfig('${client.name}', 'description', this.value)"> |
|||
</td> |
|||
<td> |
|||
<div class="btn-group btn-group-sm"> |
|||
<button class="btn btn-success" onclick="saveClientConfig('${client.name}')" title="保存"> |
|||
<i class="fas fa-save"></i> |
|||
</button> |
|||
<button class="btn btn-info" onclick="loadClientConfig('${client.name}')" title="加载"> |
|||
<i class="fas fa-download"></i> |
|||
</button> |
|||
</div> |
|||
</td> |
|||
`; |
|||
tbody.appendChild(row); |
|||
}); |
|||
|
|||
document.getElementById('clientCount').textContent = response.length; |
|||
console.log('客户端列表已加载,共', response.length, '个客户端'); |
|||
|
|||
// 加载所有客户端的现有配置 |
|||
loadAllClientConfigs(); |
|||
} else { |
|||
console.log('没有找到客户端配置'); |
|||
document.getElementById('clientCount').textContent = '0'; |
|||
} |
|||
}).fail(function(xhr, status, error) { |
|||
console.error('加载客户端列表错误:', error); |
|||
showAlert('danger', '加载客户端列表失败: ' + error); |
|||
}); |
|||
} |
|||
|
|||
// 更新配置(实时保存到服务器) |
|||
function updateConfig(clientName, field, value) { |
|||
console.log(`更新配置: ${clientName} - ${field} = ${value}`); |
|||
|
|||
if (field === 'samples') { |
|||
// 更新Samples参数 |
|||
$.ajax({ |
|||
url: `/api/config/statistics/${encodeURIComponent(clientName)}/samples`, |
|||
type: 'POST', |
|||
contentType: 'application/json', |
|||
data: JSON.stringify(value), |
|||
success: function(response) { |
|||
if (response.success) { |
|||
console.log(`客户端 ${clientName} Samples参数已更新`); |
|||
} else { |
|||
console.error('更新Samples参数失败:', response.message); |
|||
showAlert('danger', `更新Samples参数失败: ${response.message}`); |
|||
} |
|||
}, |
|||
error: function(xhr, status, error) { |
|||
console.error('更新Samples参数错误:', error); |
|||
showAlert('danger', `更新Samples参数错误: ${error}`); |
|||
} |
|||
}); |
|||
} else if (field === 'rf') { |
|||
// 更新RF参数 |
|||
$.ajax({ |
|||
url: `/api/config/statistics/${encodeURIComponent(clientName)}/rf`, |
|||
type: 'POST', |
|||
contentType: 'application/json', |
|||
data: JSON.stringify(value), |
|||
success: function(response) { |
|||
if (response.success) { |
|||
console.log(`客户端 ${clientName} RF参数已更新`); |
|||
} else { |
|||
console.error('更新RF参数失败:', response.message); |
|||
showAlert('danger', `更新RF参数失败: ${response.message}`); |
|||
} |
|||
}, |
|||
error: function(xhr, status, error) { |
|||
console.error('更新RF参数错误:', error); |
|||
showAlert('danger', `更新RF参数错误: ${error}`); |
|||
} |
|||
}); |
|||
} else if (field === 'enabled') { |
|||
// 更新启用状态 |
|||
saveClientConfig(clientName); |
|||
} else if (field === 'description') { |
|||
// 更新描述 |
|||
saveClientConfig(clientName); |
|||
} |
|||
} |
|||
|
|||
// 加载客户端配置 |
|||
function loadClientConfig(clientName) { |
|||
console.log('加载客户端统计配置:', clientName); |
|||
$.get(`/api/config/statistics/${encodeURIComponent(clientName)}`, function(response) { |
|||
if (response.success && response.data) { |
|||
const config = response.data; |
|||
document.getElementById(`samples_${clientName}`).checked = config.enableSamples; |
|||
document.getElementById(`rf_${clientName}`).checked = config.enableRf; |
|||
document.getElementById(`enabled_${clientName}`).checked = config.isEnabled; |
|||
document.getElementById(`desc_${clientName}`).value = config.description || ''; |
|||
console.log('客户端配置已加载:', config); |
|||
showAlert('success', `客户端 ${clientName} 配置已加载`); |
|||
} else { |
|||
console.log('客户端配置未找到,使用默认值'); |
|||
// 使用默认值 |
|||
document.getElementById(`samples_${clientName}`).checked = false; |
|||
document.getElementById(`rf_${clientName}`).checked = false; |
|||
document.getElementById(`enabled_${clientName}`).checked = true; |
|||
document.getElementById(`desc_${clientName}`).value = ''; |
|||
showAlert('info', `客户端 ${clientName} 使用默认配置`); |
|||
} |
|||
}).fail(function(xhr, status, error) { |
|||
console.error('加载客户端配置错误:', error); |
|||
showAlert('danger', `加载客户端 ${clientName} 配置失败: ${error}`); |
|||
}); |
|||
} |
|||
|
|||
// 保存客户端配置 |
|||
function saveClientConfig(clientName) { |
|||
const config = { |
|||
clientName: clientName, |
|||
ipAddress: '', // 将从客户端列表获取 |
|||
enableSamples: document.getElementById(`samples_${clientName}`).checked, |
|||
enableRf: document.getElementById(`rf_${clientName}`).checked, |
|||
isEnabled: document.getElementById(`enabled_${clientName}`).checked, |
|||
description: document.getElementById(`desc_${clientName}`).value |
|||
}; |
|||
|
|||
// 从已加载的客户端列表中获取IP地址 |
|||
const tbody = document.getElementById('clientConfigTableBody'); |
|||
const rows = tbody.getElementsByTagName('tr'); |
|||
for (let row of rows) { |
|||
const nameCell = row.querySelector('td:first-child strong'); |
|||
if (nameCell && nameCell.textContent === clientName) { |
|||
const ipCell = row.querySelector('td:nth-child(2) code'); |
|||
if (ipCell) { |
|||
config.ipAddress = ipCell.textContent; |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
|
|||
console.log('保存客户端统计配置:', config); |
|||
$.ajax({ |
|||
url: `/api/config/statistics/${encodeURIComponent(clientName)}`, |
|||
type: 'POST', |
|||
contentType: 'application/json', |
|||
data: JSON.stringify(config), |
|||
success: function(response) { |
|||
console.log('客户端配置保存响应:', response); |
|||
if (response.success) { |
|||
showAlert('success', `客户端 ${clientName} 配置已保存`); |
|||
} else { |
|||
showAlert('danger', `保存失败: ${response.message}`); |
|||
} |
|||
}, |
|||
error: function(xhr, status, error) { |
|||
console.error('保存客户端配置错误:', error); |
|||
showAlert('danger', `保存失败: ${error}`); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
// 加载所有客户端配置 |
|||
function loadAllClientConfigs() { |
|||
console.log('加载所有客户端配置...'); |
|||
// 从WebSocketManagerService获取所有统计配置 |
|||
$.get('/Statistics/GetAllClientStatisticsConfigs', function(response) { |
|||
if (response.success) { |
|||
const configs = response.data; |
|||
const configDict = {}; |
|||
|
|||
// 将配置转换为字典,方便查找 |
|||
configs.forEach(function(config) { |
|||
configDict[config.clientName] = config; |
|||
}); |
|||
|
|||
// 更新表格中的配置 |
|||
const tbody = document.getElementById('clientConfigTableBody'); |
|||
const rows = tbody.getElementsByTagName('tr'); |
|||
|
|||
for (let row of rows) { |
|||
const nameCell = row.querySelector('td:first-child strong'); |
|||
if (nameCell) { |
|||
const clientName = nameCell.textContent; |
|||
const config = configDict[clientName]; |
|||
|
|||
if (config) { |
|||
row.querySelector(`#samples_${clientName}`).checked = config.enableSamples; |
|||
row.querySelector(`#rf_${clientName}`).checked = config.enableRf; |
|||
row.querySelector(`#enabled_${clientName}`).checked = config.isEnabled; |
|||
row.querySelector(`#desc_${clientName}`).value = config.description || ''; |
|||
} |
|||
} |
|||
} |
|||
|
|||
console.log('所有客户端配置已加载,共', configs.length, '个配置'); |
|||
} else { |
|||
console.error('加载配置列表失败:', response.message); |
|||
} |
|||
}).fail(function(xhr, status, error) { |
|||
console.error('加载配置列表错误:', error); |
|||
}); |
|||
} |
|||
|
|||
// 显示提示信息 |
|||
function showAlert(type, message) { |
|||
const alertHtml = ` |
|||
<div class="alert alert-${type} alert-dismissible fade show" role="alert"> |
|||
${message} |
|||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button> |
|||
</div> |
|||
`; |
|||
|
|||
// 移除现有的提示 |
|||
$('.alert').remove(); |
|||
|
|||
// 添加新提示到页面顶部 |
|||
$('.container').prepend(alertHtml); |
|||
|
|||
// 3秒后自动消失 |
|||
setTimeout(function() { |
|||
$('.alert').fadeOut(); |
|||
}, 3000); |
|||
} |
|||
</script> |
|||
} |
@ -1,22 +1,5 @@ |
|||
{ |
|||
"defaultSamples": false, |
|||
"defaultRf": false, |
|||
"clientConfigs": [ |
|||
{ |
|||
"ipAddress": "192.168.13.12", |
|||
"clientName": "TestClient1", |
|||
"enableSamples": true, |
|||
"enableRf": false, |
|||
"isEnabled": true, |
|||
"description": "测试客户端1 - 启用samples" |
|||
}, |
|||
{ |
|||
"ipAddress": "192.168.13.13", |
|||
"clientName": "TestClient2", |
|||
"enableSamples": false, |
|||
"enableRf": true, |
|||
"isEnabled": true, |
|||
"description": "测试客户端2 - 启用rf" |
|||
} |
|||
] |
|||
} |
|||
"defaultSamples": true, |
|||
"defaultRf": true, |
|||
"clientConfigs": [] |
|||
} |
Loading…
Reference in new issue