Files
cockpit_avm/lj360/lj360.js

233 lines
8.4 KiB
JavaScript
Raw Normal View History

2026-04-21 15:38:57 +08:00
const SCRIPT = "/home/ztl/LJ360/bash/video_tool.sh";
const SERVICE = "lj360_camera";
const LOG_FILE = "/home/ztl/LJ360/lj360_camera_keepalive.log";
const WEBPY = "/home/ztl/LJ360/web.py";
// DOM 元素
let statusIcon, statusText, outputBox, autostartSwitch;
function initElements() {
statusIcon = document.getElementById("status-icon");
statusText = document.getElementById("status-text");
outputBox = document.getElementById("output");
autostartSwitch = document.getElementById("autostart-switch");
}
function setOutput(text) {
if (outputBox) {
outputBox.textContent = text;
outputBox.scrollTop = outputBox.scrollHeight;
}
}
function setStatus(text, isActive) {
if (statusText) {
statusText.textContent = text;
}
const panel = document.getElementById("status-panel");
if (panel) {
// 移除现有状态类
panel.classList.remove("status-success", "status-danger", "status-warning");
if (isActive === true) {
panel.classList.add("status-success");
} else if (isActive === false) {
panel.classList.add("status-danger");
} else if (isActive === undefined) {
panel.classList.add("status-warning");
}
}
if (statusIcon) {
if (isActive === true) {
statusIcon.innerHTML = '<i class="fa fa-check-circle" style="color:#3f9c35"></i>';
} else if (isActive === false) {
statusIcon.innerHTML = '<i class="fa fa-exclamation-circle" style="color:#c00"></i>';
} else {
statusIcon.innerHTML = '<i class="fa fa-refresh fa-spin"></i>';
}
}
}
function runCommand(args, callback) {
const proc = cockpit.spawn(args, { superuser: "require", err: "out" });
let output = "";
proc.stream(data => { output += data; });
proc.then(() => callback(output, null));
proc.catch(err => callback(output, err));
}
// 获取服务状态和开机自启状态
function refreshStatus() {
setStatus("正在获取服务状态...", undefined);
setOutput("⏳ 正在刷新状态...");
// 获取服务运行状态
runCommand(["systemctl", "is-active", SERVICE + ".service"], (outActive, errActive) => {
const isRunning = (outActive.trim() === "active");
// 获取开机自启状态
runCommand(["systemctl", "is-enabled", SERVICE + ".service"], (outEnabled, errEnabled) => {
let isEnabled = false;
if (!errEnabled) {
const enabledOut = outEnabled.trim();
isEnabled = (enabledOut === "enabled" || enabledOut === "static");
}
// 更新开关状态不触发change事件
if (autostartSwitch) {
autostartSwitch.checked = isEnabled;
}
// 更新状态文本
if (isRunning) {
setStatus("服务正在运行" + (isEnabled ? " (开机自启已启用)" : " (开机自启未启用)"), true);
} else {
setStatus("服务未运行" + (isEnabled ? " (开机自启已启用但未运行)" : " (开机自启未启用)"), false);
}
// 获取详细状态输出
runCommand(["systemctl", "status", SERVICE + ".service", "--no-pager", "-l"], (outDetail) => {
setOutput(outDetail || "无状态信息");
});
});
});
}
// 设置开机自启(通过开关)
function setAutostart(enabled) {
setOutput("⏳ " + (enabled ? "正在启用开机自启..." : "正在禁用开机自启..."));
const action = enabled ? "enable_autostart" : "disable_autostart";
runCommand(["bash", SCRIPT, action], (out, err) => {
if (err) {
setOutput("❌ 错误: " + (err.message || err) + "\n" + (out || ""));
// 恢复开关状态
setTimeout(() => refreshStatus(), 500);
} else {
setOutput((enabled ? "✅ 开机自启已启用" : "✅ 开机自启已禁用") + "\n" + (out || ""));
setTimeout(() => refreshStatus(), 300);
}
});
}
// 启动服务
function startService() {
setOutput("⏳ 正在启动服务...");
runCommand(["systemctl", "start", SERVICE + ".service"], (out, err) => {
if (err) {
setOutput("❌ 启动失败: " + (err.message || err) + "\n" + out);
} else {
setOutput("✅ 服务已启动\n" + out);
}
setTimeout(() => refreshStatus(), 500);
});
}
// 停止服务
function stopService() {
setOutput("⏳ 正在停止服务...");
runCommand(["systemctl", "stop", SERVICE + ".service"], (out, err) => {
if (err) {
setOutput("❌ 停止失败: " + (err.message || err) + "\n" + out);
} else {
setOutput("✅ 服务已停止\n" + out);
}
setTimeout(() => refreshStatus(), 500);
});
}
// 重启服务
function restartService() {
setOutput("⏳ 正在重启服务...");
runCommand(["systemctl", "restart", SERVICE + ".service"], (out, err) => {
if (err) {
setOutput("❌ 重启失败: " + (err.message || err) + "\n" + out);
} else {
setOutput("✅ 服务已重启\n" + out);
}
setTimeout(() => refreshStatus(), 800);
});
}
// 查看日志
function viewLog() {
setOutput("⏳ 读取日志文件...");
runCommand(["tail", "-n", "80", LOG_FILE], (out, err) => {
if (err) {
setOutput("❌ 无法读取日志: " + (err.message || err) + "\n尝试查看服务日志...");
// 备用:查看 journalctl
runCommand(["journalctl", "-u", SERVICE + ".service", "-n", "50", "--no-pager"], (out2, err2) => {
if (err2) {
setOutput("📭 日志为空或无法读取\n" + (out2 || ""));
} else {
setOutput("📋 系统日志 (journalctl):\n" + (out2 || "无日志"));
}
});
} else {
setOutput("📋 服务日志 (最近80行):\n" + (out || "日志为空"));
}
});
}
// 单独启动 web.py
function startWebPy() {
setOutput("⏳ 正在启动 web.py...");
runCommand([
"bash", "-c",
"export DISPLAY=:0 && cd /home/ztl/LJ360 && sudo -u ztl python3 /home/ztl/LJ360/web.py >> /home/ztl/LJ360/web.log 2>&1 &"
], (out, err) => {
if (err) {
setOutput("❌ 启动 web.py 失败: " + (err.message || err));
} else {
setOutput("✅ web.py 已在后台启动\n可通过 'ps aux | grep web.py' 查看进程");
}
});
}
// 停止 web.py
function stopWebPy() {
setOutput("⏳ 正在关闭 web.py...");
runCommand(["bash", "-c", "pkill -f /home/ztl/LJ360/web.py"], (out, err) => {
if (err) {
// pkill 没有找到进程也会返回错误,这是正常的
if (err.message && err.message.includes("exit code 1")) {
setOutput("⚠️ 未找到运行中的 web.py 进程");
} else {
setOutput("❌ 关闭失败: " + (err.message || err));
}
} else {
setOutput("✅ web.py 已关闭");
}
});
}
// 事件绑定
function bindEvents() {
const btnStart = document.getElementById("btn-start");
const btnStop = document.getElementById("btn-stop");
const btnRestart = document.getElementById("btn-restart");
const btnStatus = document.getElementById("btn-status");
const btnLog = document.getElementById("btn-log");
const btnPyon = document.getElementById("btn-pyon");
const btnPyoff = document.getElementById("btn-pyoff");
if (btnStart) btnStart.addEventListener("click", startService);
if (btnStop) btnStop.addEventListener("click", stopService);
if (btnRestart) btnRestart.addEventListener("click", restartService);
if (btnStatus) btnStatus.addEventListener("click", refreshStatus);
if (btnLog) btnLog.addEventListener("click", viewLog);
if (btnPyon) btnPyon.addEventListener("click", startWebPy);
if (btnPyoff) btnPyoff.addEventListener("click", stopWebPy);
// 开关事件:开机自启变更
if (autostartSwitch) {
autostartSwitch.addEventListener("change", function(e) {
setAutostart(e.target.checked);
});
}
}
// 页面初始化
document.addEventListener("DOMContentLoaded", function() {
initElements();
bindEvents();
refreshStatus();
});