Files
Bridge-and-Join-s/internal/lkgateway/web/templates/admin_handbook.html
T
fontvielle e4b164c6e5 Справочник участников: показывать результат обработки джобой Fancy
На странице «Справочник участников M2M» теперь выводится итог обработки
справочника джобой bj2depo — STATE/COMMENT последнего события HANDBOOK
из FTV_M2M_EVENTS (поле COMMENT пишет Fancy). Расхождения/предупреждения
выделяются цветом и значком: КРИТИЧ/ОШИБКА — красным, ПРЕДУПРЕЖДЕНИЕ —
жёлтым, «изменений нет» — зелёным, чтобы оператор видел, что проверить.

Только чтение (fsql.QEv11, TOP 1 по EVENT_DATE), короткий таймаут 4с,
страница не висит если DEPO недоступна.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-14 11:16:19 +03:00

124 lines
6.3 KiB
HTML

{{define "content"}}
<div class="card">
<h2>Справочник участников M2M</h2>
<p class="muted">Актуальная карта участников сервиса MOEX МОСТ (получена от НРД пакетом <code>#M2MTH</code>): ИНН, код участника (MC/EC/…), тип и наименование. Используется для сопоставления контрагента с кодом участника.
{{if .At}}<br><span style="font-size:12px">Справочник обновлён: <strong>{{.At}}</strong>.</span>{{end}}
</p>
{{if not .Participants}}
<div style="margin-top:12px;padding:14px;background:var(--warn-weak,#f6eed8);border-radius:10px">
<strong>Справочник ещё не загружен.</strong>
<p class="muted" style="margin:6px 0 0">Запросите его у НРД: <a href="/admin/setup">Настройка → Диагностика → «Запросить справочник у НРД»</a>. Ответ придёт во входящие ИШ (~30–60 сек) и появится здесь.</p>
</div>
{{end}}
</div>
{{if or .Result.Found .Result.Err}}
<div class="card">
<h2 style="margin-top:0">Результат обработки в Fancy</h2>
<p class="muted" style="margin-top:0">Итог сверки справочника юрлиц Fancy с данными НРД (джоба bj2depo, поле COMMENT последнего события HANDBOOK).</p>
{{if .Result.Err}}
<p class="muted">Результат пока недоступен: {{.Result.Err}}.</p>
{{else}}
<div style="padding:12px 14px;border-radius:10px;background:{{if eq .Result.Severity "err"}}var(--err-weak,#f7dede){{else if eq .Result.Severity "warn"}}var(--warn-weak,#f6eed8){{else}}var(--ok-weak,#e3f2e3){{end}}">
<div style="font-weight:600;margin-bottom:6px">
{{if eq .Result.Severity "err"}}⛔ Обнаружены ошибки — проверьте и исправьте{{else if eq .Result.Severity "warn"}}⚠ Есть предупреждения — проверьте{{else}}✓ Справочник обработан, расхождений нет{{end}}
<span class="muted" style="font-weight:400;font-size:12px">· обработано {{.Result.AtText}}{{with .Result.State}} · статус {{.}}{{end}}</span>
</div>
{{with .Result.Comment}}<pre style="white-space:pre-wrap;word-break:break-word;margin:0;font-size:13px;line-height:1.5;font-family:inherit">{{.}}</pre>{{else}}<span class="muted">джоба отработала, но COMMENT пуст</span>{{end}}
</div>
{{end}}
</div>
{{end}}
{{if .Participants}}
<div class="card">
<div style="display:flex;gap:12px;flex-wrap:wrap;align-items:center;justify-content:space-between">
<div style="flex:1;min-width:220px">
<input id="hb-search" type="text" placeholder="Поиск по наименованию, ИНН или коду…" autocomplete="off"
style="width:100%;max-width:520px" oninput="hbFilter()">
</div>
<div style="display:flex;gap:8px;align-items:center">
<select id="hb-kind" onchange="hbFilter()" style="max-width:200px">
<option value="">Все типы</option>
<option value="depo">Депозитарии</option>
<option value="broker">Брокеры</option>
<option value="place">Места расчётов</option>
</select>
<span class="muted" id="hb-count" style="font-size:13px;white-space:nowrap"></span>
</div>
</div>
<div class="tw" style="margin-top:14px">
<table id="hb-table">
<thead>
<tr>
<th style="width:150px">Код участника</th>
<th style="width:140px">ИНН</th>
<th style="width:120px">Тип</th>
<th>Наименование</th>
</tr>
</thead>
<tbody>
{{range .Participants}}
<tr class="hb-row" data-kind="{{.Kind}}"
data-s="{{.Code}} {{.INN}} {{.Name}}">
<td class="mono">{{if .Code}}{{.Code}}{{else}}—{{end}}</td>
<td class="mono">{{.INN}}</td>
<td>
{{if eq .Kind "depo"}}<span class="pill p-depo">депозитарий</span>
{{else if eq .Kind "broker"}}<span class="pill p-broker">брокер</span>
{{else if eq .Kind "place"}}<span class="pill p-place">место расчётов</span>
{{else}}{{.Kind}}{{end}}
</td>
<td>{{.Name}}</td>
</tr>
{{end}}
</tbody>
</table>
</div>
<p class="muted" id="hb-empty" style="display:none;margin-top:12px">Ничего не найдено по запросу.</p>
</div>
<style>
#hb-table td{vertical-align:middle}
.pill{font-family:var(--mono,monospace);font-size:11px;font-weight:600;padding:3px 9px;border-radius:999px;white-space:nowrap;display:inline-block}
.p-depo{background:var(--accent-weak,#e8ecfb);color:var(--accent,#1e4fd8)}
.p-broker{background:var(--warn-weak,#f6eed8);color:var(--warn-ink,#8a5806)}
.p-place{background:var(--ok-weak,#e2f1eb);color:var(--good-ink,#0c6144)}
mark{background:var(--accent-weak,#e8ecfb);color:inherit;padding:0 1px;border-radius:3px}
</style>
<script>
(function(){
var rows=[].slice.call(document.querySelectorAll('.hb-row'));
window.hbFilter=function(){
var q=(document.getElementById('hb-search').value||'').trim().toLowerCase();
var kind=document.getElementById('hb-kind').value;
var shown=0;
rows.forEach(function(r){
var s=(r.getAttribute('data-s')||'').toLowerCase();
var okQ=!q || s.indexOf(q)>=0;
var okK=!kind || r.getAttribute('data-kind')===kind;
var vis=okQ&&okK;
r.style.display=vis?'':'none';
if(vis)shown++;
});
document.getElementById('hb-count').textContent='Показано: '+shown+' из '+rows.length;
document.getElementById('hb-empty').style.display=shown?'none':'block';
};
hbFilter();
// Enter в поиске не отправляет форму
var inp=document.getElementById('hb-search');
inp.addEventListener('keydown',function(e){if(e.key==='Enter')e.preventDefault();});
inp.focus();
})();
</script>
{{end}}
<div class="card">
<details>
<summary style="cursor:pointer;font-weight:600;font-size:15px">Коды ошибок и отказов M2M — справка</summary>
<div style="margin-top:10px">{{.CodesHTML}}</div>
</details>
</div>
{{end}}