Files
CoRE.Vision/frontend/settings.html
T
2026-06-03 16:09:49 +05:00

280 lines
16 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CoRE.Vizion+ — Настройки</title>
<link rel="stylesheet" href="/static/style.css">
</head>
<body data-page="settings">
<div class="layout">
<aside>
<a class="nav-item" href="/" data-nav="live"><span class="ico"></span>Live view</a>
<a class="nav-item" href="/archive" data-nav="archive"><span class="ico">🗄</span>Архив</a>
<div class="aside-spacer"></div>
<a class="nav-item active" href="/settings" data-nav="settings"><span class="ico"></span>Настройки</a>
</aside>
<main class="settings-main">
<div class="tabs">
<button class="tab active" data-tab="cams" data-min-role="admin">Камеры</button>
<button class="tab" data-tab="storage" data-min-role="admin">Хранилища</button>
<button class="tab" data-tab="layout">Раскладка</button>
<button class="tab" data-tab="player" data-min-role="operator">Плеер</button>
<button class="tab" data-tab="users" data-min-role="superadmin">Пользователи</button>
<button class="tab" data-tab="general" data-min-role="operator">Система</button>
<button class="tab" data-tab="optim" data-min-role="superadmin">Доп настройки</button>
</div>
<!-- ВКЛАДКА 1: Камеры -->
<div class="tab-panel" data-panel="cams" data-min-role="admin">
<div class="card">
<div class="card-head">
<h2>Камеры — 64 слота</h2>
<div style="display:flex;gap:8px">
<button id="bulk-edit">Изменить</button>
<button id="bulk-cancel" hidden>Отмена</button>
</div>
</div>
<table class="cams cams-fixed">
<thead>
<tr><th style="width:48px">ID</th><th>Камера</th><th>IP</th><th>Потоки</th><th style="width:56px">Вкл</th><th style="width:64px">Запись</th><th style="width:150px">Хранилище</th><th data-bulk-label="Логин / пароль">Статус</th><th style="width:62px"></th></tr>
</thead>
<tbody id="cam-rows"></tbody>
</table>
</div>
</div>
<!-- ВКЛАДКА: Хранилища (управление записью) -->
<div class="tab-panel" data-panel="storage" data-min-role="admin" hidden>
<div class="card">
<div class="card-head">
<h2>Хранилища записи</h2>
<button id="stor-add">+ Добавить хранилище</button>
</div>
<div class="muted" style="margin-bottom:12px">
Активное хранилище — куда пишутся новые записи. Квота задаётся на каждое хранилище
(0 = без лимита) и правится прямо в таблице. После смены активного старые записи
остаются доступны в Архиве. Удаление хранилища убирает его из списка — файлы записей
НЕ удаляются.
</div>
<table class="cams">
<thead>
<tr>
<th style="width:74px">Активно</th>
<th style="width:90px">ID</th>
<th>Название</th>
<th style="width:56px">Тип</th>
<th>Путь</th>
<th style="width:130px">Квота, ГБ</th>
<th style="width:150px">Занято / диск</th>
<th style="width:130px">Статус</th>
<th style="width:48px"></th>
</tr>
</thead>
<tbody id="stor-rows"></tbody>
</table>
<div class="muted" id="stor-msg" style="margin-top:10px;font-size:12px"></div>
</div>
<!-- форма добавления (скрыта по умолчанию) -->
<div class="card" id="stor-form-card" hidden>
<h2>Новое хранилище</h2>
<div class="cam-edit-grid">
<label>ID<input type="text" id="sf-id" placeholder="arch2"></label>
<label>Название<input type="text" id="sf-name" placeholder="Архив 2"></label>
<label>Тип
<select id="sf-type">
<option value="local">Локальное (папка)</option>
<option value="nas">NAS (SMB)</option>
</select>
</label>
<label>Квота, ГБ (0 = без лимита)<input type="number" id="sf-quota" min="0" value="0"></label>
<label class="sf-local">Папка<input type="text" id="sf-path" placeholder="/storages/arch2 (по умолчанию)"></label>
<label class="sf-nas" hidden>SMB сервер (IP)<input type="text" id="sf-server" placeholder="192.168.1.10"></label>
<label class="sf-nas" hidden>Шара (share)<input type="text" id="sf-share" placeholder="cctv"></label>
<label class="sf-nas" hidden>Логин<input type="text" id="sf-user"></label>
<label class="sf-nas" hidden>Пароль<input type="password" id="sf-pass"></label>
<label class="sf-nas" hidden>Подпапка (необяз.)<input type="text" id="sf-subpath" placeholder="cam-archive"></label>
</div>
<div class="cam-edit-foot">
<span class="err" id="sf-err"></span>
<button id="sf-save" class="primary">Создать</button>
<button id="sf-cancel">Отмена</button>
</div>
<div class="muted" id="sf-mount" style="margin-top:10px;font-size:12px;white-space:pre-wrap"></div>
</div>
<div class="card">
<h2>Политика записи <span class="muted" style="font-weight:400;font-size:12px">— общая для всех хранилищ</span></h2>
<div class="cam-edit-grid">
<label>Длина сегмента
<select id="pol-segment">
<option value="60">1 минута</option>
<option value="120">2 минуты</option>
<option value="300">5 минут</option>
<option value="600">10 минут</option>
<option value="900">15 минут</option>
</select>
</label>
<label>Срок хранения, дней (0 = не удалять по возрасту)<input type="number" id="pol-retention" min="0" max="3650"></label>
</div>
<div style="margin-top:12px"><button id="pol-save">Сохранить</button></div>
<div class="muted" id="pol-saved" style="margin-top:8px;font-size:12px"></div>
</div>
<div class="card">
<h2>Активное хранилище <span class="muted" style="font-weight:400;font-size:12px">— сводка</span></h2>
<div class="kv" id="storage-kv"><div class="muted">загрузка…</div></div>
</div>
</div>
<!-- ВКЛАДКА 2: Система -->
<div class="tab-panel" data-panel="general" data-min-role="operator" hidden>
<div class="wrap">
<div class="card">
<h2>Система</h2>
<div class="kv" id="system-kv"><div class="muted">загрузка…</div></div>
</div>
</div>
</div>
<!-- ВКЛАДКА: Плеер и перекодирование (этот браузер) -->
<div class="tab-panel" data-panel="player" data-min-role="operator" hidden>
<div class="wrap">
<div class="card">
<h2>Live view <span class="muted" style="font-weight:400;font-size:12px">— настройки этого браузера</span></h2>
<label style="display:flex;align-items:center;gap:10px;cursor:pointer">
<input type="checkbox" id="pref-autostart">
<span>Показывать камеры сразу при входе в Live view
<span class="muted">— иначе просмотр стартует после нажатия Play (по умолчанию)</span></span>
</label>
</div>
<div class="card">
<h2>Плеер и перекодирование <span class="muted" style="font-weight:400;font-size:12px">— настройки этого браузера</span></h2>
<div class="muted" style="margin-top:-4px;margin-bottom:16px;font-size:12px">
Для каждого потока выберите способ воспроизведения: <b>встроенный плеер</b>
декодирует поток прямо в браузере без нагрузки на сервер (ffmpeg -c copy):
H.265/H.265+ — софтом (WASM hevc.js в Web Worker), H.264/H.264+ — средствами
браузера; тянет и основной поток (3200×1800, включая тайлы), и субпоток
(декод нагружает CPU клиента); <b>перекодировать</b> — сервер транскодирует
в H.264 / VP9 (нагрузка на CPU сервера, для слабых клиентов).
</div>
<!-- 3 независимых профиля: 1 поток / 2 поток / архив -->
<div class="tr-block" data-tr="1">
<h3>1 поток (основной)</h3>
<div class="seg-toggle">
<label><input type="radio" name="mode-1" value="player"><span>Встроенный плеер</span></label>
<label><input type="radio" name="mode-1" value="transcode"><span>Перекодировать</span></label>
</div>
<div class="tr-row"></div>
</div>
<div class="tr-block" data-tr="2">
<h3>2 поток (суб)</h3>
<div class="seg-toggle">
<label><input type="radio" name="mode-2" value="player"><span>Встроенный плеер</span></label>
<label><input type="radio" name="mode-2" value="transcode"><span>Перекодировать</span></label>
</div>
<div class="tr-row"></div>
</div>
<div class="tr-block" data-tr="a">
<h3>Архив</h3>
<div class="seg-toggle">
<label><input type="radio" name="mode-a" value="player"><span>Встроенный плеер</span></label>
<label><input type="radio" name="mode-a" value="transcode"><span>Перекодировать</span></label>
</div>
<div class="tr-row"></div>
</div>
<div style="margin-top:16px"><button id="prefs-save">Сохранить</button></div>
<div class="muted" id="prefs-saved" style="margin-top:8px;font-size:12px">Сохраняется в этом браузере</div>
</div>
</div>
</div>
<!-- ВКЛАДКА: Раскладка (назначение камер по ячейкам, этот браузер) -->
<div class="tab-panel" data-panel="layout" hidden>
<div class="card">
<div class="card-head">
<h2>Настройка раскладки</h2>
<div style="display:flex;align-items:center;gap:10px">
<label class="muted">Раскладка:</label>
<select id="layout-dim">
<option value="2">4 (2×2)</option>
<option value="3">9 (3×3)</option>
<option value="4">16 (4×4)</option>
<option value="5">25 (5×5)</option>
<option value="6">36 (6×6)</option>
<option value="7">49 (7×7)</option>
<option value="8">64 (8×8)</option>
</select>
<button id="layout-save">Сохранить</button>
</div>
</div>
<div class="muted" style="margin-bottom:12px">Назначьте камеру в каждую ячейку раскладки. Сохраняется в этом браузере.</div>
<div id="layout-grid" class="layout-grid"></div>
<div class="muted" id="layout-saved" style="margin-top:12px;font-size:12px"></div>
</div>
</div>
<!-- ВКЛАДКА: Доп настройки (только суперадмин) -->
<div class="tab-panel" data-panel="optim" data-min-role="superadmin" hidden>
<div class="wrap">
<div class="card">
<h2>Live view <span class="muted" style="font-weight:400;font-size:12px">— общая политика для всех клиентов</span></h2>
<label class="toggle" style="color:var(--text)">
<input type="checkbox" id="single-main">
Не более одного основного потока в режиме Live view
</label>
<div class="muted" style="margin-top:8px;font-size:12px">
Включено по умолчанию. Основной (HD) поток можно держать одновременно
только в одной ячейке — при переключении другой ячейки на «1»
предыдущая вернётся на субпоток. Снижает нагрузку на сеть и камеры.
</div>
<label class="toggle" style="color:var(--text);margin-top:18px">
<input type="checkbox" id="mode-16plus">
Режим 16+
</label>
<div class="muted" style="margin-top:8px;font-size:12px">
По умолчанию в Live view доступно не более 16 камер (сетки до 4×4).
Включите «16+», чтобы открыть раскладки 25 / 36 / 49 / 64.
</div>
<div class="muted" style="margin-top:12px;font-size:12px">
<b>Менять может только суперадмин с подтверждением пароля.</b>
</div>
<div style="margin-top:14px"><button id="optim-save">Сохранить</button></div>
<div class="muted" id="optim-saved" style="margin-top:8px;font-size:12px">Смена требует пароль</div>
</div>
</div>
</div>
<!-- ВКЛАДКА 4: Пользователи (только суперадмин) -->
<div class="tab-panel" data-panel="users" data-min-role="superadmin" hidden>
<div class="card">
<h2>Учётная запись</h2>
<div class="muted" id="me-info" style="margin-bottom:10px;font-size:13px"></div>
<button id="logout">Выйти из системы</button>
</div>
<div class="card">
<div class="card-head">
<h2>Пользователи и роли</h2>
<button id="add-user">+ Добавить пользователя</button>
</div>
<table class="cams">
<thead>
<tr><th>Логин</th><th style="width:160px">Роль</th><th style="width:220px">Пароль</th><th style="width:120px"></th></tr>
</thead>
<tbody id="user-rows"></tbody>
</table>
<div class="muted" id="users-msg" style="margin-top:10px;font-size:12px"></div>
</div>
</div>
</main>
</div>
<script src="/static/app.js"></script>
</body>
</html>