«Диагностика» объединена со «Статусом системы»

Службы (с перезапуском), здоровье фоновых компонентов, запрос справочника
участников и тестовые прогоны переехали из «Настройка → Диагностика» в
«Статус системы» — одно место про состояние bj. Раздел «Диагностика» и
пункт меню убраны, старые ссылки (#tests, #units) ведут в «Статус».
«Настройка» больше не опрашивает systemctl при каждом открытии.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q7eREaYwUt1i4fNLZcGnjn
This commit is contained in:
fontvielle
2026-10-22 11:05:24 +03:00
parent 077e542c1a
commit f50b338294
7 changed files with 92 additions and 92 deletions
@@ -72,6 +72,89 @@
<p class="muted" style="margin-top: 16px">Проверка выполнена в {{.CheckedAt.Format "15:04:05 02.01.2006"}}.</p>
</div>
{{/* Диагностика: службы, здоровье фоновых компонентов, справочник, тестовые прогоны (раньше — Настройка → Диагностика) */}}
<div class="card" id="sec-units"><a id="diag"></a>
<h2><span class="dot {{$bad := 0}}{{range .Units}}{{if not .OK}}{{$bad = 1}}{{end}}{{end}}{{if eq $bad 1}}err{{else}}ok{{end}}"></span>Службы</h2>
<p class="muted">Ядро и модули работают отдельными службами: если служба модуля не запущена, его раздел в bj отвечает ошибкой связи. Здесь видно состояние и можно перезапустить службу, не заходя на сервер.</p>
<div class="tw" style="margin-top:8px"><table>
<thead><tr>{{if devOn}}<th>Служба</th>{{end}}<th>Что делает</th><th>Состояние</th><th>С</th><th></th></tr></thead>
<tbody>{{range .Units}}<tr>
{{if devOn}}<td style="white-space:nowrap"><code>{{.Unit}}</code></td>{{end}}
<td>{{.Title}}</td>
<td>{{if .OK}}<span class="badge ok">работает</span>{{else}}<span class="badge err">не работает{{if devOn}}: {{.State}}{{with .Sub}} / {{.}}{{end}}{{with .Result}} ({{.}}){{end}}{{end}}</span>{{end}}</td>
<td class="muted">{{if .Since}}{{.Since}}{{else}}—{{end}}</td>
<td style="white-space:nowrap"><form method="post" action="/admin/setup/units/restart" style="margin:0" onsubmit="return confirm('{{if .Core}}Перезапустить bj? Страница настроек на несколько секунд станет недоступна.{{else}}Перезапустить «{{.Title}}»?{{end}}');">
<input type="hidden" name="section" value="sec-units"><input type="hidden" name="unit" value="{{.Unit}}">
<button type="submit" class="btn btn-secondary">Перезапустить</button></form></td>
</tr>{{end}}</tbody></table></div>
</div>
<div class="card">
<h2>Здоровье сервиса</h2>
<p class="muted">Фоновые компоненты под самоконтролем: при сбое перезапускаются автоматически, при зависании — перезапуск всего сервиса и запись в «Новости». Ниже — живой статус.</p>
{{if .Health}}
<div class="tw" style="margin-top:12px">
<table>
<thead><tr><th>Компонент</th><th>Состояние</th><th>Последняя отметка</th><th>Последняя ошибка</th></tr></thead>
<tbody>
{{range .Health}}
<tr>
<td>{{healthLabel .Name}}</td>
<td>{{if .Healthy}}<span class="sys-status" style="--dot:#16a34a">работает</span>{{else}}<span class="sys-status" style="--dot:#dc2626">не отвечает</span>{{end}}</td>
<td class="mono">{{dur .Age}} назад</td>
<td class="muted">{{if .LastErr}}{{.LastErr}}{{else}}—{{end}}</td>
</tr>
{{end}}
</tbody>
</table>
</div>
{{else}}
<p class="muted" style="margin-top:10px">Компоненты ещё не зарегистрированы (сервис только запущен).</p>
{{end}}
</div>
<div class="card">
<h2>Справочник участников M2M</h2>
<p class="muted">Справочник участников M2M из НРД: по нему bj узнаёт код участника по ИНН контрагента. bj запрашивает его сам; кнопка — запросить сейчас.</p>
<form method="post" action="/admin/setup/handbook-request" style="margin-top:12px"><button type="submit" class="btn">Запросить справочник у НРД</button></form>
<p class="muted" style="font-size:12px;margin-top:8px">Ответ НРД приходит через 30–60 секунд.</p>
</div>
{{if devOn}} <div class="card">
<h2>Тестовый пакет роботу НРД</h2>
<p class="muted">Робот <code>MC0012500000</code> эмулирует вторую сторону перевода. Выберите сценарий — bj-server отправит эталонный запрос через шлюз НРД, ответ придёт во входящие. Требуется настроенный шлюз НРД и ключ подписи.</p>
<form method="post" action="/admin/setup/test-nsd" style="margin-top:12px;display:flex;gap:8px;flex-wrap:wrap;align-items:center">
<select name="scenario">
<option value="2001">2001 — Принять все бумаги</option>
<option value="2002">2002 — Принять частично</option>
<option value="1111">1111 — Ответ с отказом</option>
<option value="3333">3333 — Робот принимающая сторона</option>
</select>
<button type="submit" class="btn">Отправить роботу</button>
</form>
<p class="muted" style="margin-top:6px;font-size:12px">Ответ робота — асинхронно (~30-60 сек) во входящие шлюза НРД.</p>
</div>
<div class="card">
<h2>Сквозной тестовый прогон (mock/реальный)</h2>
<p class="muted">Заявка с предзаполненными данными через всю цепочку до финального статуса.</p>
<form method="post" action="/admin/setup/test-run" style="margin-top:12px"><button type="submit" class="btn">Запустить тестовую заявку</button></form>
{{if .LastTest}}
<div style="margin-top:16px;padding:14px;background:var(--card-2);border:1px solid var(--border);border-radius:10px">
<strong>Последний прогон</strong>
<table style="margin-top:8px">
<tbody>
<tr><td style="width:160px" class="muted">Статус</td><td>{{if .LastTest.OK}}<span style="color:var(--ok)">✓ успешно</span>{{else}}<span style="color:var(--err)">✗ не прошёл</span>{{end}}</td></tr>
<tr><td class="muted">FSM-статус</td><td><code>{{.LastTest.FinalStatus}}</code></td></tr>
<tr><td class="muted">ClaimID</td><td><code>{{.LastTest.ClaimID}}</code> {{if .LastTest.ClaimID}}<a href="/admin/claims/{{.LastTest.ClaimID}}">→ карточка</a>{{end}}</td></tr>
<tr><td class="muted">Сообщение</td><td>{{.LastTest.Message}}</td></tr>
</tbody>
</table>
</div>
{{end}}
</div>{{end}}
{{if devOn}}{{/* дорожная карта разработки — только в режиме разработки */}}
<div class="card">
<h2>Что подключается на следующих этапах</h2>