You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Apache环境:如何通过HTML脚本展示PHP存储的设备活跃下载状态

解决方案:实时展示设备活跃下载状态

第一步:修复后端PHP逻辑(确保正确保存所有设备的活跃状态)

当前你的PHP代码每次上传都会覆盖activeDownloads.json,导致只能保留最后一个设备的数据。我们需要修改代码,让它维护一个所有设备的活跃下载状态集合,并且定期清理已完成的下载(可选)。

修改后的PHP代码:

<?php
// 读取请求体的JSON数据
$body = file_get_contents('php://input');
$data = json_decode($body, true);

// 验证必填字段
$requiredFields = ['userid', 'username', 'gkdevice', 'status', 'TimeRemaining'];
foreach ($requiredFields as $field) {
    if (!isset($data[$field])) {
        http_response_code(400);
        echo json_encode(['error' => "Missing required field: $field"]);
        exit;
    }
}

$userid = $data['userid'];
$username = $data['username'];
$gkdevice = $data['gkdevice'];
$status = $data['status'];
$timeRem = $data['TimeRemaining'];

// 处理设备列表(添加新设备)
$devicesFile = "Gkdevices.json";
$devices = file_exists($devicesFile) ? json_decode(file_get_contents($devicesFile), true) : ['JsonDevices' => []];

// 检查设备是否已存在(用gkdevice作为唯一标识)
$deviceExists = false;
foreach ($devices['JsonDevices'] as $existingDevice) {
    if ($existingDevice['gkdevice'] === $gkdevice) {
        $deviceExists = true;
        break;
    }
}
if (!$deviceExists) {
    $devices['JsonDevices'][] = ['gkdevice' => $gkdevice];
    file_put_contents($devicesFile, json_encode($devices, JSON_PRETTY_PRINT));
}

// 维护活跃下载状态(关键:不要覆盖,而是更新或添加设备条目)
$activeFile = 'activeDownloads.json';
$activeDownloads = file_exists($activeFile) ? json_decode(file_get_contents($activeFile), true) : [];

// 更新当前设备的下载状态
$activeDownloads[$gkdevice] = [
    'username' => $username,
    'userid' => $userid,
    'status' => $status,
    'TimeRemaining' => $timeRem,
    'lastUpdated' => time() // 添加时间戳,用于清理过期状态
];

// 可选:清理已完成(状态不是"下载中")或超过10分钟未更新的条目
$expiryTime = time() - 600; // 10分钟
foreach ($activeDownloads as $deviceId => $deviceData) {
    if ($deviceData['status'] !== '下载中' || $deviceData['lastUpdated'] < $expiryTime) {
        unset($activeDownloads[$deviceId]);
    }
}

// 保存更新后的活跃状态
file_put_contents($activeFile, json_encode($activeDownloads, JSON_PRETTY_PRINT));

// 返回成功响应
http_response_code(200);
echo json_encode(['success' => true]);
?>

第二步:修复前端JavaScript代码(正确渲染设备状态)

原JS代码存在变量未定义、DOM元素创建错误、逻辑判断错误等问题,下面是修复后的版本,它会从activeDownloads.json拉取数据,然后动态渲染到deviceGrid容器中:

<section>
    <div class="container-fluid pt-5 pb-5 bg-main">
        <div class="container rounded pt-3 pb-3 content-box">
            <div class="container">
                <div class="row fw-bold border-bottom pb-2 mb-2">
                    <div class="col-2">Gerät</div>
                    <div class="col-4">Status</div>
                    <div class="col-6">Info</div>
                </div>
                <div id="deviceGrid"></div>
                <script>
                    const activeDownloadsUrl = "api/activeDownloads.json"; // 确保路径正确
                    const refreshInterval = 1000; // 1秒刷新一次,可根据需求调整
                    let firstLoad = true;

                    // 格式化剩余时间(毫秒转时分)
                    function formatTimeRemaining(ms) {
                        const hours = Math.floor(ms / 3600000);
                        const minutes = Math.floor((ms % 3600000) / 60000);
                        const parts = [];
                        if (hours > 0) parts.push(`${hours} Std.`);
                        if (minutes > 0) parts.push(`${minutes} Min.`);
                        return parts.length > 0 ? parts.join(' ') : "Kurz";
                    }

                    async function loadAndRenderDevices() {
                        try {
                            // 添加时间戳避免缓存
                            const response = await fetch(`${activeDownloadsUrl}?_=${Date.now()}`);
                            if (!response.ok) throw new Error(`HTTP-Fehler: ${response.status}`);
                            
                            const activeDownloads = await response.json();
                            const deviceGrid = document.getElementById("deviceGrid");
                            deviceGrid.innerHTML = ""; // 清空之前的内容

                            // 遍历每个活跃设备
                            Object.entries(activeDownloads).forEach(([deviceId, deviceData]) => {
                                // 创建行容器
                                const row = document.createElement("div");
                                row.className = "row align-items-center border-bottom py-2";

                                // 1. 设备编号列
                                const colDevice = document.createElement("div");
                                colDevice.className = "col-2";
                                colDevice.textContent = deviceId;
                                row.appendChild(colDevice);

                                // 2. 状态列(带图标)
                                const colStatus = document.createElement("div");
                                colStatus.className = "col-4 d-flex align-items-center gap-2";
                                if (deviceData.status === "下载中") {
                                    colStatus.innerHTML = `
                                        <img src="pictures/reject.png" alt="Download aktiv">
                                        <span class="text-danger">Download aktiv</span>
                                    `;
                                } else {
                                    colStatus.innerHTML = `
                                        <img src="pictures/approved.png" alt="Kein Download">
                                        <span class="text-success">Keine Downloads</span>
                                    `;
                                }
                                row.appendChild(colStatus);

                                // 3. 信息列(用户名、剩余时间)
                                const colInfo = document.createElement("div");
                                colInfo.className = "col-6";
                                colInfo.innerHTML = `
                                    <div>Benutzer: ${deviceData.username} (ID: ${deviceData.userid})</div>
                                    <div>Verbleibende Zeit: ${formatTimeRemaining(deviceData.TimeRemaining)}</div>
                                `;
                                row.appendChild(colInfo);

                                // 将行添加到网格
                                deviceGrid.appendChild(row);
                            });

                            // 如果没有活跃设备,显示提示
                            if (Object.keys(activeDownloads).length === 0) {
                                deviceGrid.innerHTML = '<div class="text-center py-4">Keine aktiven Downloads</div>';
                            }

                            firstLoad = false;
                        } catch (error) {
                            console.error("Laden der Daten fehlgeschlagen:", error);
                            if (firstLoad) {
                                document.getElementById("deviceGrid").innerHTML = `<div class="text-center py-4 text-danger">Fehler beim Laden der Daten: ${error.message}</div>`;
                            }
                        }
                    }

                    // 初始化加载+定时刷新
                    loadAndRenderDevices();
                    setInterval(loadAndRenderDevices, refreshInterval);
                </script>
            </div>
        </div>
    </div>
</section>

关键修复点说明

后端PHP

  • 不再覆盖activeDownloads.json,而是以gkdevice为键维护所有设备的状态
  • 添加了必填字段验证,返回合适的HTTP状态码
  • 新增了过期状态清理逻辑,避免无效数据堆积
  • 优化了设备列表的存在性检查(原代码用in_array对比整个数组,现在只检查gkdevice)

前端JavaScript

  • 修正了变量未定义问题(比如原代码的devicesFile)
  • 修复了DOM元素创建错误(原代码重复给同一个colDevice设置不同的className,现在为每个列创建独立元素)
  • 修正了逻辑判断错误(原代码if (downloadActive = true)是赋值,现在正确判断状态字段)
  • 添加了时间格式化函数,把毫秒转换为易读的时分格式
  • 处理了无活跃设备的空状态提示
  • 避免了缓存问题,每次请求添加时间戳参数

部署注意事项

  1. 确保存放PHP和JSON文件的目录有写权限,让PHP能创建和修改JSON文件
  2. 验证浏览器插件上传的JSON格式是否和PHP预期一致(所有必填字段都存在)
  3. 根据实际需求调整刷新间隔(refreshInterval),不要设置太频繁避免服务器压力

内容的提问来源于stack exchange,提问作者user32421586

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 10:32:36