Files
Bridge-and-Join-s/internal/lkgateway/web/templates/admin_home.html
T
zuevav da12a9ec1c feat(bj): модуль ЛК на PostgreSQL, обмен с DEPO, боевой ЛК с имитатором НРД, QUIK, НПР
- bj_exchange и «кран» Fancy убраны: данные модуля ЛК в PostgreSQL (схема lk)
- трансферные таблицы FTV_M2M: создание при установке, события, справочник участников
- сверка с DEPO: счёт, ФИО, дата рождения, ИИС по договору, квал-инвестор из опции DEPO
- боевой ЛК ЕСИА Финанс при тестовом ИШ: журнал, отказ через DEPO, статусы в ЛК
- онлайн-лицензирование в bj, план тестирования M2M для контрагента (интерактивный HTML)
- модули QUIK МНП, экспорт QUIK, НПР/УДС; документы и тестовые материалы

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-15 19:41:12 +03:00

151 lines
9.2 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.
{{define "content"}}
{{/* ===== Оператор-дашборд (Apple-стиль): приветствие → статус → плитки задач → сводка ===== */}}
<div class="hero">
<h1 class="hero-greeting">Добрый день</h1>
{{if .AllReady}}
<span class="hero-status ok">● Система готова к работе</span>
{{else}}
<div style="display:flex;align-items:center;gap:14px;flex-wrap:wrap">
<span class="hero-status warn">● Требуется настройка — {{.NotReadyCount}} из {{.TotalCount}} компонентов</span>
<a href="/admin/wizard" class="btn">Открыть мастер настройки →</a>
</div>
{{end}}
</div>
{{if .LKUrl}}
{{/* ===== Первичный тест интеграции с ЛК ===== */}}
<div class="card" style="display:flex;gap:16px;align-items:center;flex-wrap:wrap">
<div style="width:42px;height:42px;border-radius:11px;background:var(--accent-weak);color:var(--accent);display:flex;align-items:center;justify-content:center;flex:none">
<svg viewBox="0 0 24 24" width="21" height="21" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M15 3h6v6"/><path d="M10 14 21 3"/><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/></svg>
</div>
<div style="flex:1;min-width:240px">
<div style="font-weight:640;font-size:15px">Первичный тест с личным кабинетом</div>
<div class="muted" style="margin-top:2px">Откройте ЛК, войдите и подайте заявку M2M — она придёт к нам и появится в разделе <a href="/admin/claims">«Переводы»</a>. Статус вернём в ЛK через callback.</div>
</div>
<a class="btn" href="{{.LKUrl}}" target="_blank" rel="noopener">Открыть тестовый ЛК →</a>
</div>
{{end}}
{{/* ===== Крупные плитки задач ===== */}}
<div class="tiles">
<a href="#" onclick="document.getElementById('sim-modal').style.display='flex';return false" class="tile brand">
<span class="ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 8h12M12 4l4 4-4 4"/><path d="M20 16H8M12 20l-4-4 4-4"/></svg></span>
<span class="t-title">Новый перевод</span>
<span class="t-sub">Симулятор: сценарий робота + кол-во бумаг</span>
<span class="t-arrow"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
</a>
<a href="/admin/claims" class="tile">
<span class="ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M8 6h12M8 12h12M8 18h12"/><path d="M3.5 6h.01M3.5 12h.01M3.5 18h.01"/></svg></span>
<span class="t-title">Переводы</span>
<span class="t-sub">{{.Counts.Total}} всего · {{.Counts.InProgress}} в работе</span>
<span class="t-arrow"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
</a>
<a href="/admin/status" class="tile">
<span class="ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12h4l2.5 7 5-14 2.5 7h4"/></svg></span>
<span class="t-title">Диагностика</span>
<span class="t-sub">Состояние СКЗИ, ИШ и базы</span>
<span class="t-arrow"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
</a>
<a href="/admin/setup" class="tile">
<span class="ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M5 8V3M5 21v-7M12 21v-9M12 8V3M19 21v-4M19 12V3"/><path d="M2.5 14h5M9.5 8h5M16.5 17h5"/></svg></span>
<span class="t-title">Настройка</span>
<span class="t-sub">Криптография, НРД, подключения</span>
<span class="t-arrow"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
</a>
</div>
{{/* ===== Сводка по переводам ===== */}}
<div class="grid">
<div class="stat accent">
<div class="stat-label">Всего переводов</div>
<div class="stat-value">{{.Counts.Total}}</div>
</div>
<div class="stat ok">
<div class="stat-label">Подтверждено</div>
<div class="stat-value" style="color:var(--ok)">{{.Counts.Confirmed}}</div>
</div>
<div class="stat warn">
<div class="stat-label">В ожидании</div>
<div class="stat-value" style="color:var(--warn)">{{.Counts.InProgress}}</div>
</div>
<div class="stat err">
<div class="stat-label">Отказы / таймауты</div>
<div class="stat-value" style="color:var(--err)">{{.Counts.Failed}}</div>
</div>
</div>
{{/* ===== Последние переводы ===== */}}
<div class="section-head">
<h2>Последние переводы</h2>
<a href="/admin/claims">все →</a>
</div>
<div class="card">
{{if .Recent}}
<table>
<thead><tr><th>Время</th><th>ID</th><th>Инвестор</th><th>ЦБ</th><th>Статус</th><th></th></tr></thead>
<tbody>
{{range .Recent}}
<tr>
<td class="num muted" style="white-space:nowrap">{{.CreatedAt.Format "02.01.2006 15:04:05"}}</td>
<td><code>{{short 8 .ID}}</code></td>
<td>{{.Investor.LastName}} {{initial .Investor.FirstName}}</td>
<td class="num">{{len .Securities}}</td>
<td><span class="badge {{.Status}}">{{ruState .Status}}</span></td>
<td><a href="/admin/claims/{{.ID}}">открыть →</a></td>
</tr>
{{end}}
</tbody>
</table>
{{else}}
<p class="muted" style="margin:0">Переводов ещё нет. Нажмите «Новый перевод», чтобы создать первый.</p>
{{end}}
</div>
{{/* ===== События (компактно, если есть) ===== */}}
{{if .News}}
<div class="section-head">
<h2>События</h2>
<a href="/admin/news">все →</a>
</div>
<div class="card">
{{range .News}}
<div style="padding:9px 0;border-bottom:1px solid var(--border)">
<div style="font-weight:600;font-size:13.5px">
{{if eq .Kind "maintenance"}}{{end}}{{if eq .Kind "feature"}}{{end}}{{if eq .Kind "system"}}{{end}}{{if eq .Kind "doc-update"}}{{end}}{{.Title}}
</div>
{{if .Body}}<div class="muted" style="font-size:12px;margin-top:3px">{{.Body}}</div>{{end}}
</div>
{{end}}
</div>
{{end}}
{{/* ===== Модалка-симулятор: тестовый перевод роботу НРД ===== */}}
<div id="sim-modal" style="display:none;position:fixed;inset:0;background:rgba(0,0,0,.45);z-index:1000;align-items:center;justify-content:center"
onclick="if(event.target===this)this.style.display='none'">
<div style="background:var(--card);border:1px solid var(--border);border-radius:14px;padding:24px;max-width:480px;width:92%;box-shadow:var(--shadow-lg)">
<h2 style="margin:0 0 4px">Новый перевод — симулятор</h2>
<p class="muted" style="margin:0 0 16px;font-size:13px">Отправка тестового пакета роботу НРД. Выберите сценарий и количество бумаг. Для сценария 3333 робот пришлёт встречный перевод — он появится во «Входящих» с уведомлением.</p>
<form method="post" action="/admin/setup/test-nsd" style="display:grid;gap:14px">
<label>Сценарий тестирования
<select name="scenario" style="width:100%;margin-top:4px">
<option value="2001">2001 — Принять все бумаги</option>
<option value="2002">2002 — Принять бумаги частично</option>
<option value="1111">1111 — Ответ с отказом</option>
<option value="3333">3333 — Робот принимающая сторона (пришлёт встречный перевод)</option>
</select>
</label>
<label>Количество ценных бумаг
<input type="number" name="securities_count" value="4" min="1" max="20" style="width:100%;margin-top:4px">
<span class="muted" style="font-size:12px">1–20. Эталонный набор — 4 бумаги; больше берётся циклически.</span>
</label>
<input type="hidden" name="channel" value="nsd">
<div style="display:flex;gap:8px;justify-content:flex-end;margin-top:4px">
<button type="button" class="btn btn-secondary" onclick="document.getElementById('sim-modal').style.display='none'">Отмена</button>
<button type="submit" class="btn btn-ok">Отправить</button>
</div>
</form>
</div>
</div>
{{end}}