You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

564 lines
23 KiB

@{
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>
}