Files
Bridge-and-Join-s/internal/lkgateway/web/templates/part_quik.html
T
zuevav 56068af897 QUIK и НРД в настройках — простой вид и расширенный под раскрытием; выбор «Кто отвечает на переводы M2M»
- QUIK: в карточке режима — одна галочка «Клиенты подают поручения из QUIK (терминал и мобильное приложение)», сохраняется сразу; предупреждение, если режим изменён в расширенных; «Расширенные настройки» (отдельно исходящие/входящие, инструменты МНП, коды клиентов) свёрнуты, без дубля счёта и галочки терминала; формы цикла не сбрасывают поля, которых не прислали.
- НРД: организация — код, ИНН, наименование в ряд; реквизиты в НРД — общий блок с мастером (nsdRequisites), «Определить из DEPO» видна (была белым по белому); блок шлюза из мастера (контуры, доступ к папкам по сети) — и в настройках; ручная настройка шлюза — под «Расширенными настройками».
- Автоматический режим M2M: вместо галочки с «Сохранить» — выбор плиткой «bj сам — автоматически / Оператор», сохраняется сразу (m2mAutoCard); тот же выбор — в мастере на шаге «Проверка»; подробности — под раскрытием.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014FsEKyJrYF69Cj9ZXzFLRi
2026-10-07 08:15:06 +03:00

162 lines
18 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.
{{/* «QUIK — модуль неторговых поручений» — один и тот же в настройках и в мастере (данные — SetupData). */}}
{{define "quikSection"}}
{{template "verline" (.Versions.Get "quik-mnp")}}
<div class="card">
<h2><span class="dot {{if .Settings.Quik.Verified}}ok{{else if .Settings.Quik.Server}}warn{{else}}err{{end}}"></span>Подключение к модулю неторговых поручений</h2>
<p class="muted">{{if not .InWizard}}bj блокирует бумаги клиента в QUIK на время перевода через модуль неторговых поручений (МНП). {{end}}Нужен логин SQL с ролью <code>InstrEu</code> — его выдаёт администратор QUIK.</p>
{{template "quikMemo" .}}
<form method="post" action="/admin/setup/quik" style="margin-top:12px;display:grid;gap:10px;max-width:560px">
<input type="hidden" name="check" value="1">
<div style="display:grid;grid-template-columns:2.2fr .8fr 1.6fr;gap:10px">
<label>Сервер QUIK МНП
<input type="text" name="server" data-need="адрес сервера QUIK МНП" value="{{.Settings.Quik.Server}}" placeholder="адрес или имя\экземпляр" style="width:100%" required></label>
<label>Порт
<input type="number" name="port" value="{{if .Settings.Quik.Port}}{{.Settings.Quik.Port}}{{else}}1433{{end}}" style="width:100%"></label>
<label>База МНП{{/* без имени базы модуль не подключается — обязательно */}}
<input type="text" name="database" data-need="имя базы модуля неторговых поручений" value="{{.Settings.Quik.Database}}" placeholder="имя базы модуля" style="width:100%" required spellcheck="false"></label>
</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:10px">
<label>Логин
<input type="text" name="user" data-need="логин SQL для QUIK" value="{{.Settings.Quik.User}}" style="width:100%" required autocomplete="off"></label>
<label>Пароль
<input type="password" name="password" {{if not .Settings.Quik.Password}}data-need="пароль SQL для QUIK"{{end}} placeholder="{{if .Settings.Quik.Password}}сохранён — пусто, чтобы не менять{{end}}" autocomplete="new-password" style="width:100%"></label>
</div>
<details {{if quikNeedsTrust .Settings.Quik}}open{{end}}><summary style="cursor:pointer;color:var(--accent);font-size:13px">Дополнительно: шифрование</summary>
<div style="display:grid;gap:10px;margin-top:8px">
<label>Шифрование
<select name="encrypt" style="width:100%">
<option value="true" {{if ne .Settings.Quik.Encrypt "disable"}}selected{{end}}>Шифровать соединение (обычно требуется)</option>
<option value="disable" {{if eq .Settings.Quik.Encrypt "disable"}}selected{{end}}>Без шифрования</option>
</select></label>
<label style="display:flex;gap:8px;align-items:center;font-weight:400">
<input type="checkbox" name="trust" value="1" {{if or .Settings.Quik.Trust (not .Settings.Quik.Server)}}checked{{end}}>{{/* по умолчанию — да: у QUIK сертификат свой */}}
Доверять сертификату сервера, даже самоподписанному</label>
</div>
</details>
<div><button type="submit" class="btn">Сохранить и проверить</button> <span class="muted" style="font-size:12.5px;margin-left:6px">проверка только читает — в QUIK ничего не меняется</span></div>
</form>
<p class="muted" style="margin-top:12px">Статус: {{if .Settings.Quik.Verified}}<span style="color:var(--ok)">✓ подключение проверено</span>{{else}}<span class="muted">не проверено</span>{{end}}</p>
</div>
{{if not .InWizard}}{{/* в мастере вместо этой карточки — выбор «Как bj работает с QUIK» (шаг QUIK) */}}
{{if .Settings.Quik.Verified}}{{template "quikModeCard" (withRet . "")}}{{end}}
<div class="card" id="sec-quik-cycle-more">
<details class="adv-box" {{if quikModeCustom .Settings.Quik}}open{{end}}>
<summary><span class="sum-h">Расширенные настройки</span><span class="muted">отдельно исходящие и входящие, инструменты МНП, коды клиентов — нужны, только если QUIK настроен необычно</span></summary>
<div id="sec-quik-cycle">
<h3 class="adv-h"><span class="dot {{if .Settings.Quik.Emulate}}warn{{else if not .Settings.Quik.WritesEnabled}}warn{{else if or .Settings.Quik.AutoOut .Settings.Quik.AutoIn}}ok{{else}}warn{{end}}"></span>Автоматический цикл M2M в МНП{{if .Settings.Quik.Emulate}} <span class="hero-status warn">{{if devOn}}имитация{{else}}остановлен{{end}}</span>{{end}}</h3>
<p class="muted">Обычно всё задаёт выбор «Только чтение / Чтение и запись» выше. Здесь — если нужно иначе: например, исходящие вести автоматически, а входящие зачислять вручную; или инструменты МНП в QUIK названы не по умолчанию.</p>
<form method="post" action="/admin/setup/quik/cycle" style="margin-top:12px;display:grid;gap:10px;max-width:640px">
<input type="hidden" name="section" value="sec-quik-cycle">
<label style="display:flex;gap:8px;align-items:center;font-weight:600">
<input type="checkbox" name="writes_enabled" value="1" {{if .Settings.Quik.WritesEnabled}}checked{{end}}>
Разрешить записи в МНП (главный выключатель: без него bj в QUIK ничего не меняет)</label>
{{if devOn}} <label style="display:flex;gap:8px;align-items:center;font-weight:600">
<input type="checkbox" name="emulate" value="1" {{if .Settings.Quik.Emulate}}checked{{end}}>
Имитация: шаги цикла (блокировка, подпись, снятие, зачисление) проходят и отмечаются «имитация», в МНП ничего не пишется — пока нет пользователя QUIK для блокировок и лимитов. Имеет приоритет над записью.</label>{{end}}
<label style="display:flex;gap:8px;align-items:center;font-weight:400;margin-left:22px">
<input type="checkbox" name="auto_out" value="1" {{if .Settings.Quik.AutoOut}}checked{{end}}>
Исходящие переводы: регистрировать при отправке, подписывать / снимать по ответу автоматически</label>
<label style="display:flex;gap:8px;align-items:center;font-weight:400;margin-left:22px">
<input type="checkbox" name="auto_in" value="1" {{if .Settings.Quik.AutoIn}}checked{{end}}>
Входящие переводы: зачислять в QUIK после приёма поручения НРД автоматически</label>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:10px">
<label>МНП-инструмент вывода
<input type="text" name="sec_out" value="{{.Settings.Quik.SecOut}}" placeholder="пусто — по классу INSTROUTM2M" style="width:100%"></label>
<label>МНП-инструмент ввода
<input type="text" name="sec_in" value="{{.Settings.Quik.SecIn}}" placeholder="пусто — по классу INSTRINM2M" style="width:100%"></label>
</div>
<label>Исключения кодов клиентов <span class="muted">— обычно не нужны: номер портфеля «БР-001» сам становится кодом «BR001»; иначе строкой «номер портфеля=код QUIK»</span>
<textarea name="client_code_map" rows="3" style="width:100%;font-family:ui-monospace,monospace;font-size:12px" placeholder="БР-12-3=BR123">{{quikCodeMap .Settings.Quik.ClientCodeMap}}</textarea></label>
<div style="display:flex;gap:8px;flex-wrap:wrap"><button type="submit" class="btn">Сохранить</button></div>
</form>
</div>
</details>
</div>
{{end}}
{{if .Settings.Quik.LastReport}}
<div class="card">
<h2>Полный ответ сервера (последняя проверка)</h2>
<p class="muted">Можно выделить и скопировать целиком — для отправки коллегам/аутсорсеру QUIK.
{{if not .Settings.Quik.LastAt.IsZero}}Проверка от {{.Settings.Quik.LastAt.Format "02.01.2006 15:04:05"}} UTC.{{end}}</p>
<div style="display:flex;gap:8px;margin:8px 0">
<button type="button" class="btn" onclick="var t=document.getElementById('quik-report').textContent;window.bjCopy(t);this.textContent='Скопировано ✓';setTimeout(()=>this.textContent='Скопировать отчёт',1500)">Скопировать отчёт</button>
</div>
<pre id="quik-report" style="white-space:pre-wrap;word-break:break-word;background:var(--surface-2,#0d1117);color:var(--code-fg,#c9d1d9);padding:14px;border-radius:8px;font-size:12.5px;line-height:1.5;overflow:auto;max-height:420px;user-select:all">{{.Settings.Quik.LastReport}}</pre>
</div>
{{end}}
{{end}}
{{define "mnpCheck"}}
<div class="card" id="mnp-check">
<h2><span class="dot" id="mnp-dot"></span>Проверка модуля неторговых поручений</h2>
<p class="muted" style="margin:0 0 8px">Только чтение: всё, без чего цикл M2M в МНП не работает. Ничего в QUIK не меняет.</p>
<table style="width:100%"><tbody id="mnp-rows"></tbody></table>
<p style="margin-top:8px"><button type="button" class="btn" id="mnp-run">Проверить МНП</button> <span class="muted" id="mnp-at" style="font-size:12px"></span></p>
</div>
<script>
(function(){
var rows=document.getElementById('mnp-rows'), dot=document.getElementById('mnp-dot');
function esc(s){return String(s).replace(/[&<>"]/g,function(c){return{'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;'}[c]})}
var ic={ok:'<span style="color:var(--ok)">✓</span>',info:'<span style="color:var(--accent)">ℹ</span>',warn:'<span style="color:var(--warn)">⚠</span>',err:'<span style="color:var(--err)">✗</span>'};
function run(){ rows.innerHTML='<tr><td class="muted">Проверяю…</td></tr>';
fetch('/admin/setup/quik/mnp-check',{cache:'no-store'}).then(function(r){return r.json()}).then(function(d){
rows.innerHTML=d.checks.map(function(c){return '<tr><td style="width:22px;vertical-align:top">'+(ic[c.state]||'')+'</td><td style="vertical-align:top;padding-right:10px;white-space:nowrap"><b>'+esc(c.title)+'</b></td><td style="vertical-align:top">'+esc(c.detail)+'</td></tr>'}).join('');
dot.className='dot '+d.state; document.getElementById('mnp-at').textContent='проверено '+d.at;
}).catch(function(){ rows.innerHTML='<tr><td>Проверка не выполнилась</td></tr>'; }); }
document.getElementById('mnp-run').onclick=run;
{{if .Settings.Quik.Server}}run();{{end}}
})();
</script>
{{end}}
{{/* Памятка администратору QUIK — в мастере и в «Настройке». Без ссылок на техническую справку (её нет в
рабочей сборке) и на документы ARQA (их у клиента нет на сервере bj — они у администратора QUIK). */}}
{{define "quikMemo"}}
<details style="margin:2px 0 10px;font-size:13.5px"><summary style="cursor:pointer;color:var(--accent)">Памятка администратору QUIK — что настроить</summary>
<p style="margin:6px 0 4px">Всё это описано в документации ARQA на модуль неторговых поручений («Руководство администратора», «Таблицы и процедуры БД») — она есть у администратора QUIK:</p>
<ul style="margin:0 0 6px;padding-left:20px">
<li>в QAdmin — классы <code>INSTROUTM2M</code> (вывод ценных бумаг) и <code>INSTRINM2M</code> (ввод), типы неторговых поручений M2M;</li>
<li>SQL-логин для bj с ролью <code>InstrEu</code> — его логин и пароль вписываются в поля ниже;</li>
<li>справочник депозитариев-получателей <code>M2MDepoRecipients</code> заполняет bj; после первого заполнения модуль нужно перезапустить — QUIK читает справочник только при запуске.</li>
</ul>
{{if internalDocs}}<a href="/admin/help/quik">Подробная внутренняя справка →</a>{{end}}
</details>
{{end}}
{{/* Как bj работает с QUIK: только чтение или чтение и запись (боевая работа) — одинаково в мастере (шаг 5) и в
Настройка → QUIK МНП. Данные — withRet: .D — данные страницы (нужно .D.Settings), .Ret — куда вернуться без JS. */}}
{{define "quikModeCard"}}
<div class="card" id="quik-mode">
<h2>Как bj работает с QUIK</h2>
<form method="post" action="/admin/setup/quik/mode" id="quik-mode-form" class="dq">
{{if .Ret}}<input type="hidden" name="return_to" value="{{.Ret}}">{{end}}
<div class="dq-tiles">
<label class="dq-tile"><input type="radio" name="mode" value="check" {{if not .D.Settings.Quik.WritesEnabled}}checked{{end}}><span><b>Только чтение</b><small>bj подключён к QUIK и читает данные, но ничего в нём не меняет: не блокирует и не разблокирует бумаги, не меняет лимиты. Для настройки и проверки — когда будете готовы, включите «Чтение и запись».</small></span></label>
<label class="dq-tile"><input type="radio" name="mode" value="auto" {{if .D.Settings.Quik.WritesEnabled}}checked{{end}}><span><b>Чтение и запись</b><small>Боевая работа: bj сам блокирует бумаги в QUIK при отправке перевода, списывает или снимает блокировку по ответу НРД, зачисляет входящие.</small></span></label>
</div>
<div class="dq-jobname" id="quik-acc">
<label>Торговый счёт для поручений<input type="text" name="account" value="{{.D.Settings.Quik.Account}}" placeholder="торговый счёт фирмы в QUIK" spellcheck="false" class="dq-mono"></label>
</div>
<label class="dq-alt quik-term"><input type="checkbox" name="terminal" value="1" {{if .D.Settings.Quik.PollTerminal}}checked{{end}}><span><b>Клиенты подают поручения на перевод из QUIK</b> — из терминала или мобильного приложения («Вывод ЦБ (M2M)»). bj сам замечает такие поручения (раз в 30 секунд) и сообщает оператору; бумаги QUIK блокирует сразу при подаче. Если клиенты подают поручения только через депозитарий — оставьте выключенным.</span></label>
<input type="hidden" name="terminal_set" value="1">
{{with quikModeCustom .D.Settings.Quik}}<p class="dq-warn">{{.}} — изменено в «Расширенных настройках» ниже.</p>{{end}}
<p class="dq-note" id="quik-mode-st" aria-live="polite">Выбор сохраняется сразу.{{if .Ret}} Тонкая настройка — инструменты МНП, коды клиентов, поручения из терминала — в «Настройка → QUIK».{{end}}</p>
<noscript><button type="submit" class="btn">Сохранить</button></noscript>
</form>
<p class="dq-note">{{quikRecipientsInfo}} После первого заполнения справочника депозитариев-получателей попросите администратора QUIK перезапустить модуль неторговых поручений — QUIK читает справочник только при запуске.</p>
</div>
<script>(function(){
var f=document.getElementById('quik-mode-form'), st=document.getElementById('quik-mode-st'), acc=document.getElementById('quik-acc');
function sync(){ acc.hidden=f.mode.value!=='auto'; }
f.addEventListener('change', function(){ sync();
fetch(f.action,{method:'POST',body:new URLSearchParams(new FormData(f)),headers:{'Content-Type':'application/x-www-form-urlencoded','X-BJ-Ajax':'1'},cache:'no-store'})
.then(function(r){ return r.text().then(function(t){ st.textContent=(r.ok?'✓ Сохранено: ':'✗ ')+t; }); })
.catch(function(){ st.textContent='✗ Не сохранилось — обновите страницу и выберите ещё раз.'; });
});
f.addEventListener('submit', function(e){ if(window.fetch) e.preventDefault(); });
sync();
})();</script>
{{end}}