주변 와이파이 관측 화면을 분리
This commit is contained in:
+9
-8
@@ -2919,10 +2919,9 @@ function save_wifi_scan_observations(array $networks): void
|
||||
}
|
||||
}
|
||||
|
||||
function wifi_scan_observed_networks(int $hours, int $limit): array
|
||||
function wifi_scan_observed_networks(int $limit): array
|
||||
{
|
||||
try {
|
||||
$hours = max(1, min(720, $hours));
|
||||
$limit = max(1, min(500, $limit));
|
||||
$stmt = db()->query("
|
||||
SELECT
|
||||
@@ -2945,11 +2944,10 @@ function wifi_scan_observed_networks(int $hours, int $limit): array
|
||||
last_seen_at,
|
||||
TIMESTAMPDIFF(SECOND, last_seen_at, NOW()) AS observed_age_seconds
|
||||
FROM wifi_scan_observations
|
||||
WHERE last_seen_at >= DATE_SUB(NOW(), INTERVAL {$hours} HOUR)
|
||||
ORDER BY
|
||||
FIELD(band, '2.4G', '5G', '6G', '기타'),
|
||||
signal_dbm DESC,
|
||||
last_seen_at DESC
|
||||
last_seen_at DESC,
|
||||
signal_dbm DESC
|
||||
LIMIT {$limit}
|
||||
");
|
||||
} catch (Throwable) {
|
||||
@@ -3033,7 +3031,9 @@ function wifi_scan_data(): array
|
||||
'cached' => false,
|
||||
'generated_at' => null,
|
||||
'interfaces' => [],
|
||||
'networks' => wifi_scan_observed_networks((int)setting_value('wifi.scan_observed_hours'), (int)setting_value('wifi.scan_max_networks')),
|
||||
'networks' => wifi_scan_observed_networks((int)setting_value('wifi.scan_max_networks')),
|
||||
'observed_hours' => null,
|
||||
'observed_mode' => 'all',
|
||||
'errors' => [],
|
||||
];
|
||||
}
|
||||
@@ -3075,7 +3075,7 @@ function wifi_scan_data(): array
|
||||
|
||||
$max = (int)setting_value('wifi.scan_max_networks');
|
||||
save_wifi_scan_observations($networks);
|
||||
$observedNetworks = wifi_scan_observed_networks((int)setting_value('wifi.scan_observed_hours'), $max);
|
||||
$observedNetworks = wifi_scan_observed_networks($max);
|
||||
$mergedNetworks = merge_wifi_scan_networks($networks, $observedNetworks);
|
||||
$payload = [
|
||||
'enabled' => true,
|
||||
@@ -3085,7 +3085,8 @@ function wifi_scan_data(): array
|
||||
'networks' => array_slice($mergedNetworks, 0, $max),
|
||||
'live_found' => count($networks),
|
||||
'total_found' => count($mergedNetworks),
|
||||
'observed_hours' => (int)setting_value('wifi.scan_observed_hours'),
|
||||
'observed_hours' => null,
|
||||
'observed_mode' => 'all',
|
||||
'errors' => $errors,
|
||||
];
|
||||
|
||||
|
||||
+12
-3
@@ -152,6 +152,7 @@
|
||||
wifiScanCached: 'cached',
|
||||
wifiScanFresh: 'fresh',
|
||||
wifiScanDisabledWithHistory: 'scan disabled, showing last observed networks',
|
||||
wifiScanObservedAll: 'all observed BSSID history',
|
||||
observed: 'Observed',
|
||||
ssid: 'SSID',
|
||||
channel: 'Channel',
|
||||
@@ -304,6 +305,7 @@
|
||||
wifiScanCached: '캐시',
|
||||
wifiScanFresh: '실시간',
|
||||
wifiScanDisabledWithHistory: '스캔 꺼짐, 마지막 관측 목록 표시',
|
||||
wifiScanObservedAll: '전체 BSSID 누적 관측',
|
||||
observed: '관측',
|
||||
ssid: 'SSID',
|
||||
channel: '채널',
|
||||
@@ -1345,10 +1347,17 @@
|
||||
}
|
||||
|
||||
const errors = Array.isArray(scan.errors) ? scan.errors : [];
|
||||
const observedMode = scan.observed_mode === 'all' ? t('wifiScanObservedAll') : `${scan.observed_hours || '-'}h`;
|
||||
const status = scan.enabled === false
|
||||
? `${t('wifiScanDisabledWithHistory')} · ${scan.observed_hours || '-'}h`
|
||||
: `${scan.cached ? t('wifiScanCached') : t('wifiScanFresh')} · ${escapeHtml(scan.generated_at || '-')}`;
|
||||
const groups = ['2.4G', '5G'].map(band => {
|
||||
? `${t('wifiScanDisabledWithHistory')} · ${observedMode}`
|
||||
: `${scan.cached ? t('wifiScanCached') : t('wifiScanFresh')} · ${escapeHtml(scan.generated_at || '-')} · ${observedMode}`;
|
||||
const bandOrder = ['2.4G', '5G', '6G', '기타'];
|
||||
const extraBands = networks
|
||||
.map(row => row.band || '기타')
|
||||
.filter(band => !bandOrder.includes(band));
|
||||
const bands = [...bandOrder, ...Array.from(new Set(extraBands))]
|
||||
.filter((band, index) => index < 2 || networks.some(row => (row.band || '기타') === band));
|
||||
const groups = bands.map(band => {
|
||||
const bandRows = networks.filter(row => row.band === band);
|
||||
return `
|
||||
<section class="wifi-scan-band" data-band="${attr(band)}">
|
||||
|
||||
+6
-2
@@ -127,7 +127,7 @@ html[data-theme="light"] .btn.secondary{background:#d9e2ef;color:#172033}html[da
|
||||
.status-list{display:grid;gap:10px}.status-row{display:grid;grid-template-columns:112px minmax(0,1fr);gap:12px;align-items:baseline;padding:10px 12px;background:var(--card2);border-radius:14px}.status-key{color:var(--sub);font-size:13px}.status-value{overflow:visible;white-space:normal;word-break:break-word;font-variant-numeric:tabular-nums}
|
||||
.table-wrap{max-width:100%;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;border-radius:16px;border:1px solid var(--line)}.table-wrap.compact{border-radius:12px}.wifi-table{width:100%;min-width:1080px;table-layout:fixed;border-collapse:collapse}.wifi-table th,.wifi-table td{padding:11px 13px;border-bottom:1px solid rgba(128,145,170,.18);text-align:left;font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.wifi-table th{position:sticky;top:0;background:var(--table-head);z-index:1;font-weight:500}.wifi-table tr:hover{background:rgba(128,145,170,.09)}.wifi-table .col-band{width:72px}.wifi-table .col-host{width:240px}.wifi-table .col-ip{width:132px}.wifi-table .col-mac{width:170px}.wifi-table .col-signal{width:100px}.wifi-table .col-rate{width:120px}.wifi-table .col-time{width:130px}
|
||||
.wifi-host-edit{appearance:none;border:0;background:transparent;color:inherit;font:inherit;max-width:100%;padding:0;margin:0;cursor:pointer;text-align:left;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-decoration:underline;text-decoration-style:dotted;text-underline-offset:3px}.wifi-host-edit:hover{color:var(--blue)}
|
||||
.wifi-signal{font-weight:700;font-variant-numeric:tabular-nums}.wifi-signal.excellent{color:#22c55e}.wifi-signal.good{color:#38bdf8}.wifi-signal.fair{color:#f59e0b}.wifi-signal.weak{color:#fb7185}.wifi-signal.bad{color:#ef4444}.wifi-signal.unknown{color:var(--sub)}.wifi-scan{margin-top:16px;display:grid;gap:12px}.wifi-scan-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px}.wifi-scan-head h3{margin:0;color:var(--text);font-size:15px;font-weight:600}.wifi-scan-head span{color:var(--sub);font-size:12px;font-variant-numeric:tabular-nums}.wifi-scan-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}.wifi-scan-band{min-width:0;display:grid;gap:8px}.wifi-scan-band h3{margin:0;color:var(--sub);font-size:13px;font-weight:600}.wifi-scan-band h3 span{font-weight:500;color:var(--sub)}.wifi-scan-table{width:100%;min-width:1180px;table-layout:fixed;border-collapse:collapse}.wifi-scan-table th,.wifi-scan-table td{padding:9px 10px;border-bottom:1px solid rgba(128,145,170,.16);font-size:12px;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.wifi-scan-table th{background:var(--table-head);color:var(--sub);font-weight:500}.wifi-scan-table th:nth-child(1),.wifi-scan-table td:nth-child(1){width:190px}.wifi-scan-table th:nth-child(2),.wifi-scan-table td:nth-child(2){width:145px}.wifi-scan-table th:nth-child(3),.wifi-scan-table td:nth-child(3){width:112px}.wifi-scan-table th:nth-child(4),.wifi-scan-table td:nth-child(4){width:92px}.wifi-scan-table th:nth-child(5),.wifi-scan-table td:nth-child(5){width:210px}.wifi-scan-table th:nth-child(6),.wifi-scan-table td:nth-child(6){width:90px}.wifi-scan-table th:nth-child(7),.wifi-scan-table td:nth-child(7){width:105px}.wifi-scan-table th:nth-child(8),.wifi-scan-table td:nth-child(8){width:90px}.wifi-scan-table th:nth-child(9),.wifi-scan-table td:nth-child(9){width:150px}.wifi-scan-errors,.wifi-scan-empty{border:1px solid rgba(245,158,11,.35);background:rgba(245,158,11,.1);color:var(--text);border-radius:12px;padding:10px 12px;font-size:13px;line-height:1.5}.wifi-scan-errors{display:grid;gap:5px}.wifi-scan-errors strong{color:#fbbf24;margin-right:5px}
|
||||
.wifi-signal{font-weight:700;font-variant-numeric:tabular-nums}.wifi-signal.excellent{color:#22c55e}.wifi-signal.good{color:#38bdf8}.wifi-signal.fair{color:#f59e0b}.wifi-signal.weak{color:#fb7185}.wifi-signal.bad{color:#ef4444}.wifi-signal.unknown{color:var(--sub)}.wifi-scan{display:grid;gap:12px}.wifi-scan-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px}.wifi-scan-head h3{margin:0;color:var(--text);font-size:15px;font-weight:600}.wifi-scan-head span{color:var(--sub);font-size:12px;font-variant-numeric:tabular-nums}.wifi-scan-grid{display:grid;grid-template-columns:1fr;gap:14px}.wifi-scan-band{min-width:0;display:grid;gap:8px}.wifi-scan-band h3{margin:0;color:var(--sub);font-size:13px;font-weight:600}.wifi-scan-band h3 span{font-weight:500;color:var(--sub)}.wifi-scan-table{width:100%;min-width:1180px;table-layout:fixed;border-collapse:collapse}.wifi-scan-table th,.wifi-scan-table td{padding:9px 10px;border-bottom:1px solid rgba(128,145,170,.16);font-size:12px;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.wifi-scan-table th{background:var(--table-head);color:var(--sub);font-weight:500}.wifi-scan-table th:nth-child(1),.wifi-scan-table td:nth-child(1){width:190px}.wifi-scan-table th:nth-child(2),.wifi-scan-table td:nth-child(2){width:145px}.wifi-scan-table th:nth-child(3),.wifi-scan-table td:nth-child(3){width:112px}.wifi-scan-table th:nth-child(4),.wifi-scan-table td:nth-child(4){width:92px}.wifi-scan-table th:nth-child(5),.wifi-scan-table td:nth-child(5){width:210px}.wifi-scan-table th:nth-child(6),.wifi-scan-table td:nth-child(6){width:150px}.wifi-scan-table th:nth-child(7),.wifi-scan-table td:nth-child(7){width:105px}.wifi-scan-table th:nth-child(8),.wifi-scan-table td:nth-child(8){width:90px}.wifi-scan-table th:nth-child(9),.wifi-scan-table td:nth-child(9){width:150px}.wifi-scan-errors,.wifi-scan-empty{border:1px solid rgba(245,158,11,.35);background:rgba(245,158,11,.1);color:var(--text);border-radius:12px;padding:10px 12px;font-size:13px;line-height:1.5}.wifi-scan-errors{display:grid;gap:5px}.wifi-scan-errors strong{color:#fbbf24;margin-right:5px}
|
||||
.chart-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:14px}.chart-box{height:280px;background:var(--input);border:1px solid rgba(84,101,128,.58);border-radius:16px;padding:12px 12px 18px}.chart-box h3{margin:0 0 8px;color:var(--sub);font-size:13px}.chart-canvas{position:relative;height:calc(100% - 27px);min-height:0}.chart-canvas canvas{width:100%!important;height:100%!important}.chart-secondary{margin-top:14px}
|
||||
.details-panel{border:1px solid rgba(84,101,128,.52);border-radius:16px;background:rgba(128,145,170,.06);padding:0;margin-top:14px;overflow:hidden}.details-panel>summary{cursor:pointer;list-style:none;display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:48px;padding:0 14px;color:var(--text);font-weight:500}.details-panel>summary::-webkit-details-marker{display:none}.details-panel>summary::after{content:"+";display:grid;place-items:center;width:24px;height:24px;border:1px solid var(--line);border-radius:999px;color:var(--sub);font-weight:700}.details-panel[open]>summary::after{content:"-"}.details-body{padding:0 14px 14px}.section-note{margin:0;color:var(--sub);font-size:12px}
|
||||
.resource-card{margin-top:18px}.resource-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin-bottom:12px}.resource-head h2{margin:0}.baseline-pill{color:var(--sub);font-size:12px;font-variant-numeric:tabular-nums;text-align:right;white-space:nowrap}.spike-log-box{margin-top:16px}.spike-log-box h3{margin:0 0 9px;color:var(--text);font-size:14px;font-weight:500}.spike-log-list{display:grid;gap:8px;max-height:260px;overflow:auto;padding-right:4px}.spike-log-list.compact{max-height:180px}.spike-log-item{display:grid;gap:4px;padding:10px 12px;border:1px solid var(--notice-border);background:var(--notice-bg);border-radius:12px}.spike-log-item.latest{border:1px solid var(--notice-border-strong);background:var(--notice-bg-strong);box-shadow:0 0 0 1px var(--notice-border) inset;}.spike-log-item.alert{border-color:rgba(255,95,87,.58);background:rgba(150,38,38,.18)}.spike-log-item.alert strong{color:#ffb4ad}.spike-log-item strong{font-size:13px;font-weight:500;color:var(--notice-title)}.spike-log-item span{font-size:12px;color:var(--notice-copy);font-variant-numeric:tabular-nums}.spike-log-empty{padding:10px 12px;border-radius:12px;background:var(--card2);color:var(--sub);font-size:13px}.service-list{display:grid;gap:10px;max-height:520px;overflow:auto;padding-right:4px}.service-item{border:1px solid var(--line);border-radius:12px;background:var(--card2);padding:12px;display:grid;gap:9px}.service-head{display:flex;justify-content:space-between;gap:10px;align-items:flex-start}.service-title{display:grid;gap:3px;min-width:0}.service-name{font-size:14px;color:var(--text);font-weight:600;word-break:break-word}.service-desc,.service-meta{font-size:12px;color:var(--sub);font-variant-numeric:tabular-nums;word-break:break-word}.service-state{border:1px solid var(--line);border-radius:999px;padding:4px 9px;font-size:12px;color:var(--sub);white-space:nowrap}.service-state.active{color:#bbf7d0;border-color:rgba(34,197,94,.35);background:rgba(22,163,74,.14)}.service-state.failed{color:#fecaca;border-color:rgba(239,68,68,.4);background:rgba(185,28,28,.16)}.service-log{margin:0;max-height:160px;overflow:auto;border:1px solid var(--line);border-radius:10px;background:var(--code-bg);color:var(--mono-text);padding:10px;font:11px/1.45 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;white-space:pre-wrap;word-break:break-word}.dmesg-head{display:flex;align-items:center;justify-content:space-between;gap:10px}.dmesg-meta{font-size:12px;color:var(--sub);font-variant-numeric:tabular-nums}.dmesg-log{margin:10px 0 0;max-height:420px;overflow:auto;border:1px solid var(--line);border-radius:12px;background:var(--code-bg);color:var(--mono-text);padding:12px;font:12px/1.45 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;white-space:pre-wrap;word-break:break-word}.dmesg-log[hidden]{display:none}
|
||||
@@ -270,6 +270,10 @@ html[data-theme="light"] .details-panel{background:#edf3fa;border-color:#b8c7da}
|
||||
<tbody id="wifiTable"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2 data-i18n="wifiScan">Nearby WiFi Scan</h2>
|
||||
<div id="wifiScan" class="wifi-scan"></div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -373,7 +377,7 @@ html[data-theme="light"] .details-panel{background:#edf3fa;border-color:#b8c7da}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/assets/app.js?v=20260626_wifi_observe_scroll1"></script>
|
||||
<script src="/assets/app.js?v=20260627_wifi_scan_split1"></script>
|
||||
<script src="/assets/wakelock.js?v=20260607_prefs1"></script>
|
||||
<?php endif; ?>
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user