генератор фронта завершен

This commit is contained in:
2025-01-14 17:42:38 +03:00
parent 25a3b11ba8
commit 5a94f9a4fd
7 changed files with 310 additions and 269 deletions

View File

@@ -47,6 +47,7 @@
<a href="#monitoring" class="tabs-btn" @click="activeTab = 'monitoring'" :class="{ active: activeTab === 'monitoring' }">Мониторинг</a>
<a href="#setup" class="tabs-btn" @click="activeTab = 'setup'" :class="{ active: activeTab === 'setup' }">Настройки</a>
<a href="#qos" class="tabs-btn" @click="activeTab = 'qos'" :class="{ active: activeTab === 'qos' }">QoS</a>
<a href="#admin" class="tabs-btn" @click="activeTab = 'admin'" :class="{ active: activeTab === 'admin' }">Администрирование</a>
<a href="/logout" class="tabs-btn">Выход</a>
</div>
</header>
@@ -172,6 +173,13 @@
<option :value="25">0.25</option>
</select>
</label>
<label>
<span>Номер последовательности Голда</span>
<select v-model="paramRxtx.txGoldan">
<option :value="0">0</option>
<option :value="1">1</option>
</select>
</label>
<label><span>Ослабление, дБ</span><input type="number" v-model="paramRxtx.txAttenuation" step="1"/></label>
</div>
<div class="settings-set-container">
@@ -276,6 +284,13 @@
<option :value="25">0.25</option>
</select>
</label>
<label>
<span>Номер последовательности Голда</span>
<select v-model="paramRxtx.rxGoldan">
<option :value="0">0</option>
<option :value="1">1</option>
</select>
</label>
</div>
</div>
<button class="action-button" @click="settingsSubmitRxtx()">Сохранить <span class="submit-spinner" v-show="submitStatus.rxtx"></span></button>
@@ -289,6 +304,13 @@
</select>
</label>
<label><span>Полоса поиска, КГц ±</span><input type="number" v-model="paramCinc.cincSearchBandwidth" max="100" step="1"/></label>
<h2 v-show="paramCinc.cincIsPositional === true">Настройки позиционирования</h2>
<label v-show="paramCinc.cincIsPositional === true"><span>Широта станции</span><input type="number" v-model="paramCinc.cincPositionStationLatitude" min="-180" max="180" step="1e-06"/></label>
<label v-show="paramCinc.cincIsPositional === true"><span>Долгота станции</span><input type="number" v-model="paramCinc.cincPositionStationLongitude" min="-180" max="180" step="1e-06"/></label>
<label v-show="paramCinc.cincIsPositional === true"><span>Подспутниковая точка</span><input type="number" v-model="paramCinc.cincPositionSatelliteLongitude" min="-180" max="180" step="1e-06"/></label>
<h2 v-show="paramCinc.cincIsPositional === false">Задержка до спутника</h2>
<label v-show="paramCinc.cincIsPositional === false"><span>от, мс</span><input type="number" v-model="paramCinc.cincDelayMin" max="400" step="0.1"/></label>
<label v-show="paramCinc.cincIsPositional === false"><span>до, мс</span><input type="number" v-model="paramCinc.cincDelayMax" max="400" step="0.1"/></label>
</div>
<button class="action-button" @click="settingsSubmitCinc()" v-show="paramRxtx.isCinC">Сохранить <span class="submit-spinner" v-show="submitStatus.cinc"></span></button>
<h2>Настройки питания и опорного генератора</h2>
@@ -448,13 +470,62 @@
<label><span>Максимальное количество соединений</span><input type="number" v-model="paramTcpaccel.accelMaxConnections" max="4000" step="1"/></label>
</div>
<button class="action-button" @click="settingsSubmitTcpaccel()">Сохранить <span class="submit-spinner" v-show="submitStatus.tcpaccel"></span></button>
</div>
</div> <div class="tabs-body-item" v-if="activeTab === 'admin' && settingFetchComplete">
<h2>Настройки сети</h2>
<div class="settings-set-container">
<h3>Настройки интерфейса управления</h3>
<label>
<span>Интерфейс управления (/24)</span>
<input v-model="paramNetwork.netManagementIp" required type="text" pattern="^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$">
</label>
<label>
<span>Режим сети</span>
<select v-model="paramNetwork.netIsL2">
<option :value="false">Маршрутизатор</option>
<option :value="true">Коммутатор</option>
</select>
</label>
<label v-show="paramNetwork.netIsL2 === false">
<span>Интерфейс данных (/24)</span>
<input v-model="paramNetwork.netDataIp" required type="text" pattern="^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$">
</label>
<label><span>MTU интерфейса данных</span><input type="number" v-model="paramNetwork.netDataMtu" min="1500" max="2000" step="1"/></label>
</div>
<button class="action-button" @click="settingsSubmitNetwork()">Сохранить <span class="submit-spinner" v-show="submitStatus.network"></span></button>
<h2>Система</h2>
<div class="settings-set-container">
<table>
<tbody>
<tr><th>Версия ПО</th><td>{{ about.firmwareVersion }}</td></tr>
<tr><th>ID модема</th><td>{{ about.modemUid }}</td></tr>
<tr><th>Серийный номер</th><td>{{ about.modemSn }}</td></tr>
<tr><th>MAC интерфейса управления</th><td>{{ about.macManagement }}</td></tr>
<tr><th>MAC интерфейса управления</th><td>{{ about.macData }}</td></tr>
</tbody>
</table>
<div>
<button class="dangerous-button" @click="doModemReboot()">Перезагрузить модем <span class="submit-spinner" v-show="submitStatus.modemReboot !== null"></span></button>
</div>
<div>
<button class="dangerous-button" onclick="fetch('/api/resetSettings', { method: 'POST' }).then((r) => { window.location.reload(); })">Сбросить модем до заводских настроек</button>
</div>
<h3>Обновление ПО</h3>
<label>
<span>Файл {{ this.uploadFw.progress !== null ? `(${this.uploadFw.progress}%)` : '' }}</span>
<input type="file" accept="application/zip" @change="(e) => { this.uploadFw.filename = e.target.files[0] }">
<span v-if="uploadFw.sha256 !== null">SHA256: {{ uploadFw.sha256 }}</span>
</label>
<button class="action-button" @click="settingsUploadUpdate()">Загрузить<span class="submit-spinner" v-show="submitStatus.firmwareUpload"></span></button>
<button class="dangerous-button" v-show="uploadFw.sha256 !== null" @click="settingsPerformFirmwareUpgrade()">Обновить встроенное ПО <span class="submit-spinner" v-show="submitStatus.firmwareUpgrade"></span></button>
</div> </div>
<p>Последнее обновление статистики: {{ lastUpdateTime }}</p>
</div>
</div>
<script src="/js/vue.js"></script>
<script>
const availableTabs = ['monitoring', 'setup', 'qos']
const availableTabs = ['monitoring', 'setup', 'qos', 'admin']
// для обновления высоты хидера
function updateHeaderHeight() { const header = document.querySelector('header'); document.body.style.setProperty('--header-height', `${header.offsetHeight}px`); }
@@ -477,6 +548,7 @@
cinc: false,
buclnb: false,
tcpaccel: false,
network: false,
firmwareUpload: false,
firmwareUpgrade: false,
// когда модем перезагружается, тут должен быть счетчик. Направление счета - к нулю
@@ -502,6 +574,7 @@
rxAgcEn: false,
rxBaudrate: 0,
rxCentralFreq: 900000,
rxGoldan: 0,
rxManualGain: -40,
rxRolloff: 2,
rxSpectrumInversion: false,
@@ -511,12 +584,18 @@
txCentralFreq: 900000,
txEn: false,
txFrameSizeNormal: true,
txGoldan: 0,
txIsTestInput: false,
txModulatorIsTest: false,
txRolloff: 2,
},
paramCinc: {
cincDelayMax: 0,
cincDelayMin: 0,
cincIsPositional: true,
cincPositionSatelliteLongitude: -180,
cincPositionStationLatitude: -180,
cincPositionStationLongitude: -180,
cincSearchBandwidth: 0,
},
paramBuclnb: {
@@ -531,6 +610,12 @@
accelEn: false,
accelMaxConnections: 0,
},
paramNetwork: {
netDataIp: null,
netDataMtu: 1500,
netIsL2: false,
netManagementIp: null,
},
// ========== include end from 'common/all-params-data.js.j2'
// ========== include from 'common/monitoring-data.js.j2'
@@ -589,6 +674,9 @@
cd: [],
}, // ========== include end from 'common/qos-data.js.j2'
// ========== include from 'common/admin-data.js.j2'
// ========== include end from 'common/admin-data.js.j2'
uploadFw: {
progress: null,
filename: null,
@@ -666,6 +754,7 @@
"rxAgcEn": this.paramRxtx.rxAgcEn,
"rxBaudrate": this.paramRxtx.rxBaudrate,
"rxCentralFreq": this.paramRxtx.rxCentralFreq,
"rxGoldan": this.paramRxtx.rxGoldan,
"rxManualGain": this.paramRxtx.rxManualGain,
"rxRolloff": this.paramRxtx.rxRolloff,
"rxSpectrumInversion": this.paramRxtx.rxSpectrumInversion,
@@ -675,6 +764,7 @@
"txCentralFreq": this.paramRxtx.txCentralFreq,
"txEn": this.paramRxtx.txEn,
"txFrameSizeNormal": this.paramRxtx.txFrameSizeNormal,
"txGoldan": this.paramRxtx.txGoldan,
"txIsTestInput": this.paramRxtx.txIsTestInput,
"txModulatorIsTest": this.paramRxtx.txModulatorIsTest,
"txRolloff": this.paramRxtx.txRolloff,
@@ -690,7 +780,12 @@
if (this.submitStatus.cinc) { return }
let query = {
"cincDelayMax": this.paramCinc.cincDelayMax,
"cincDelayMin": this.paramCinc.cincDelayMin,
"cincIsPositional": this.paramCinc.cincIsPositional,
"cincPositionSatelliteLongitude": this.paramCinc.cincPositionSatelliteLongitude,
"cincPositionStationLatitude": this.paramCinc.cincPositionStationLatitude,
"cincPositionStationLongitude": this.paramCinc.cincPositionStationLongitude,
"cincSearchBandwidth": this.paramCinc.cincSearchBandwidth,
}
@@ -702,6 +797,7 @@
},
settingsSubmitBuclnb() {
if (this.submitStatus.buclnb) { return }
{ if (!confirm("Применение неправильных настроек может вывести из строя оборудование! Продолжить?")) return }
let query = {
"bucLnbAutoStart": this.paramBuclnb.bucLnbAutoStart,
@@ -732,6 +828,23 @@
.catch((reason) => { alert(`Ошибка при применении настроек: ${reason}`) })
.finally(() => { this.submitStatus.tcpaccel = false })
},
settingsSubmitNetwork() {
if (this.submitStatus.network) { return }
{ if (!confirm("Применение этих настроек может сделать модем недоступным! Продолжить?")) return }
let query = {
"netDataIp": this.paramNetwork.netDataIp,
"netDataMtu": this.paramNetwork.netDataMtu,
"netIsL2": this.paramNetwork.netIsL2,
"netManagementIp": this.paramNetwork.netManagementIp,
}
this.submitStatus.network = true
fetch('/api/set/network', {method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(query) })
.then(async (resp) => { this.updateNetworkSettings(await resp.json()) })
.catch((reason) => { alert(`Ошибка при применении настроек: ${reason}`) })
.finally(() => { this.submitStatus.network = false })
},
updateRxtxSettings(vals) {
this.submitStatus.rxtx = false
@@ -752,6 +865,7 @@
this.paramRxtx.rxAgcEn = vals["settings"]["rxAgcEn"]
this.paramRxtx.rxBaudrate = vals["settings"]["rxBaudrate"]
this.paramRxtx.rxCentralFreq = vals["settings"]["rxCentralFreq"]
this.paramRxtx.rxGoldan = vals["settings"]["rxGoldan"]
this.paramRxtx.rxManualGain = vals["settings"]["rxManualGain"]
this.paramRxtx.rxRolloff = vals["settings"]["rxRolloff"]
this.paramRxtx.rxSpectrumInversion = vals["settings"]["rxSpectrumInversion"]
@@ -761,13 +875,19 @@
this.paramRxtx.txCentralFreq = vals["settings"]["txCentralFreq"]
this.paramRxtx.txEn = vals["settings"]["txEn"]
this.paramRxtx.txFrameSizeNormal = vals["settings"]["txFrameSizeNormal"]
this.paramRxtx.txGoldan = vals["settings"]["txGoldan"]
this.paramRxtx.txIsTestInput = vals["settings"]["txIsTestInput"]
this.paramRxtx.txModulatorIsTest = vals["settings"]["txModulatorIsTest"]
this.paramRxtx.txRolloff = vals["settings"]["txRolloff"]
},
updateCincSettings(vals) {
this.submitStatus.cinc = false
this.paramCinc.cincDelayMax = vals["settings"]["cincDelayMax"]
this.paramCinc.cincDelayMin = vals["settings"]["cincDelayMin"]
this.paramCinc.cincIsPositional = vals["settings"]["cincIsPositional"]
this.paramCinc.cincPositionSatelliteLongitude = vals["settings"]["cincPositionSatelliteLongitude"]
this.paramCinc.cincPositionStationLatitude = vals["settings"]["cincPositionStationLatitude"]
this.paramCinc.cincPositionStationLongitude = vals["settings"]["cincPositionStationLongitude"]
this.paramCinc.cincSearchBandwidth = vals["settings"]["cincSearchBandwidth"]
},
updateBuclnbSettings(vals) {
@@ -784,6 +904,13 @@
this.paramTcpaccel.accelEn = vals["settings"]["accelEn"]
this.paramTcpaccel.accelMaxConnections = vals["settings"]["accelMaxConnections"]
},
updateNetworkSettings(vals) {
this.submitStatus.network = false
this.paramNetwork.netDataIp = vals["settings"]["netDataIp"]
this.paramNetwork.netDataMtu = vals["settings"]["netDataMtu"]
this.paramNetwork.netIsL2 = vals["settings"]["netIsL2"]
this.paramNetwork.netManagementIp = vals["settings"]["netManagementIp"]
},
// ========== include end from 'common/all-params-methods.js.j2'
// ========== include from 'common/monitoring-methods.js.j2'
@@ -1085,6 +1212,70 @@
},
// ========== include end from 'common/qos-methods.js.j2'
// ========== include from 'common/admin-methods.js.j2'
async settingsUploadUpdate() {
if (!this.uploadFw.filename) {
alert('Выберите файл для загрузки');
return;
}
async function readFileAsArrayBuffer(fileName) {
return new Promise((resolve, reject) => {
if (!fileName) { reject(`Файл не выбран`); return }
const reader = new FileReader();
reader.onload = (e) => { resolve(reader.result) }
reader.onerror = (e) => { reject(e) }
reader.readAsArrayBuffer(fileName)
})
}
try {
this.submitStatus.firmwareUpload = true
this.uploadFw.progress = 0
const blob = await readFileAsArrayBuffer(this.uploadFw.filename)
const xhr = new XMLHttpRequest();
await new Promise((resolve) => {
xhr.upload.addEventListener("progress", (event) => {
if (event.lengthComputable) {
this.uploadFw.progress = Math.round((event.loaded / event.total) * 1000) / 10;
}
});
xhr.addEventListener("loadend", () => {
this.uploadFw.progress = 100
const rep = JSON.parse(xhr.responseText);
this.uploadFw.sha256 = rep['sha256']
resolve(xhr.readyState === 4 && xhr.status === 200);
});
xhr.open("PUT", "/api/firmwareUpdate", true);
xhr.setRequestHeader("Content-Type", "application/octet-stream");
xhr.send(blob);
});
} catch (e) {
alert(`Ошибка загрузки файла: ${e}`);
}
this.submitStatus.firmwareUpload = false
},
async settingsPerformFirmwareUpgrade() {
if (this.submitStatus.firmwareUpgrade) { return }
this.submitStatus.firmwareUpgrade = true
try {
await fetch('/api/doFirmwareUpgrade', { method: 'POST' })
} catch (e) {
console.log("failed to perform upgrade firmware: ", e)
}
this.submitStatus.firmwareUpgrade = false
},
doModemReboot() {
if (this.submitStatus.modemReboot !== null) {
return
}
this.submitStatus.modemReboot = 30
fetch('/api/reboot', { method: 'POST' }).then((r) => {})
}, // ========== include end from 'common/admin-methods.js.j2'
performUpdateSettings() {
const doFetchSettings = async () => {
@@ -1095,6 +1286,7 @@
this.updateCincSettings(vals)
this.updateBuclnbSettings(vals)
this.updateTcpaccelSettings(vals)
this.updateNetworkSettings(vals)
this.updateQosSettings(vals)
}