From 6a68dc927f14a32151c16de339294dc52755bc1f Mon Sep 17 00:00:00 2001 From: zuevav Date: Tue, 6 Oct 2026 11:58:58 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9C=D0=B0=D1=81=D1=82=D0=B5=D1=80=20=D0=BD?= =?UTF-8?q?=D0=B0=D1=81=D1=82=D1=80=D0=BE=D0=B9=D0=BA=D0=B8=20=D0=BF=D1=80?= =?UTF-8?q?=D0=BE=D1=89=D0=B5:=20=D0=BE=D0=B4=D0=B8=D0=BD=20=D0=B2=D0=BE?= =?UTF-8?q?=D0=BF=D1=80=D0=BE=D1=81=20=D0=BD=D0=B0=20=D1=8D=D0=BA=D1=80?= =?UTF-8?q?=D0=B0=D0=BD,=20=D0=BF=D0=BE=D0=B4=D1=80=D0=BE=D0=B1=D0=BD?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D0=B8=20=E2=80=94=20=D0=BF=D0=BE=D0=B4=20?= =?UTF-8?q?=C2=AB=D0=9F=D0=BE=D0=B4=D1=80=D0=BE=D0=B1=D0=BD=D0=B5=D0=B5?= =?UTF-8?q?=C2=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - «Время и сеть»: пояс компьютера пользователя предлагается одной кнопкой, пояс применяется сразу при выборе; сервер времени — только если не синхронизируется; «сделано установщиком» — строкой внизу. - «Лицензия»: модули словами, а не кодами (quik-mnp → «QUIK: неторговые поручения…»); пояснения — только пока ключа нет; поле ключа крупное, одно. - «Учёт DEPO»: главный вопрос «Как подготовить базу» первым, короткие подписи; кружки переключателей больше не сплющиваются длинным текстом. - «QUIK»: одна кнопка «Сохранить и проверить»; база и шифрование — под «Дополнительно», без «true/disable» и TrustServerCertificate; автоматический цикл и справочник получателей в мастере свёрнуты. - «Организация»: без логотипа (он в «Оформлении»), кнопки одного цвета. «Шлюз НРД», «Ключ», «Оповещения»: по одному абзацу, письма и устройство автообновления сертификатов — под раскрытием. - Мастер и «Подготовка модулей» — без меню системы; подзаголовок не повторяет названия глав. - Подсказка о восстановлении из копии ведёт на первую страницу (в мастере его больше нет). Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_014FsEKyJrYF69Cj9ZXzFLRi --- internal/lkgateway/admin.go | 1 + internal/lkgateway/auth.go | 11 + internal/lkgateway/onboarding_test.go | 80 ++++++++ internal/lkgateway/quikdb_handlers.go | 4 + internal/lkgateway/setup.go | 4 +- .../web/templates/admin_prepare.html | 2 +- .../lkgateway/web/templates/admin_wizard.html | 190 +++++++++--------- internal/lkgateway/web/templates/layout.html | 3 +- .../lkgateway/web/templates/part_alerts.html | 2 +- .../lkgateway/web/templates/part_backup.html | 2 +- .../lkgateway/web/templates/part_igate.html | 2 +- .../lkgateway/web/templates/part_org.html | 2 +- .../lkgateway/web/templates/part_quik.html | 64 +++--- 13 files changed, 234 insertions(+), 133 deletions(-) diff --git a/internal/lkgateway/admin.go b/internal/lkgateway/admin.go index 5e90ee1..4efe903 100644 --- a/internal/lkgateway/admin.go +++ b/internal/lkgateway/admin.go @@ -95,6 +95,7 @@ var templateFuncs = template.FuncMap{ "devOn": authTemplateFuncs["devOn"], "devLicensed": authTemplateFuncs["devLicensed"], "mod": func(f string) bool { return globalRC == nil || moduleAllowed(globalRC, f) }, // модуль в лицензии + "modTitle": moduleTitle, // название признака лицензии по-человечески "isIIS": incomingIsIIS, // входящий перевод на ИИС "depoSubs": func() any { return depoWizardSubs }, // экраны шага 3 мастера "authOpen": authOpen, diff --git a/internal/lkgateway/auth.go b/internal/lkgateway/auth.go index 0627b6f..63d3b1c 100644 --- a/internal/lkgateway/auth.go +++ b/internal/lkgateway/auth.go @@ -905,6 +905,17 @@ func moduleForPath(p string) string { var moduleTitles = map[string]string{"esia-finance": "ЕСИА Финанс", "quik-mnp": "QUIK: неторговые поручения и обмен с DEPO", "quik-export": "Экспорт биржевой информации QUIK", "web-cabinet": "Личный кабинет клиента", "npr": "Риск-монитор НПР / УДС"} +// moduleTitle — признак лицензии словами (в мастере и на странице лицензии — не коды вроде quik-mnp). +func moduleTitle(f string) string { + if t, ok := moduleTitles[f]; ok { + return t + } + if f == "updates" { + return "обновления" + } + return f +} + func moduleNotLicensed(w http.ResponseWriter, f string) { w.Header().Set("Content-Type", "text/html; charset=utf-8") w.WriteHeader(http.StatusForbidden) diff --git a/internal/lkgateway/onboarding_test.go b/internal/lkgateway/onboarding_test.go index 14442bd..08b3833 100644 --- a/internal/lkgateway/onboarding_test.go +++ b/internal/lkgateway/onboarding_test.go @@ -377,3 +377,83 @@ func TestDepoSetupScript(t *testing.T) { t.Fatalf("пароль: %q", p) } } + +// Шаги мастера отрисовываются без ошибок шаблона: лицензия, учёт DEPO одним шагом, время и сеть, проверка. +func TestWizardStepsRender(t *testing.T) { + a, err := newAdmin() + if err != nil { + t.Fatal(err) + } + priv := testLicenseKey(t) + rc := testRC(t) + now := time.Now().UTC() + tok := signTestLicense(t, priv, &license.License{Schema: 1, ID: "lic-1", Tenant: "Тест", Product: "bj-server", Plan: license.PlanPro, + IssuedAt: now, ExpiresAt: now.Add(30 * 24 * time.Hour), ContractUntil: now.AddDate(1, 0, 0), Features: []string{"updates", "quik-mnp"}}) + if err := rc.SaveLicense(LicenseSettings{Key: tok}); err != nil { + t.Fatal(err) + } + h := &setupHandlers{rc: rc, tpl: &adminTemplates{a: a}} + for step, want := range map[string]string{"1": "QUIK: неторговые поручения", "3": "wiz-depo", "5": "Сохранить и проверить", "12": "wiz-tz-suggest", "10": "Проверка"} { + w := httptest.NewRecorder() + h.renderWizard(w, httptest.NewRequest(http.MethodGet, "/admin/wizard?step="+step, nil)) + body := w.Body.String() + if d := os.Getenv("BJ_DUMP_PAGES"); d != "" { + _ = os.WriteFile(filepath.Join(d, "wizard-"+step+".html"), []byte(body), 0o644) + } + if w.Code != http.StatusOK || !strings.Contains(body, want) { + i := strings.Index(body, " go test -run TestDumpOnboardingPages. +func TestDumpOnboardingPages(t *testing.T) { + dir := os.Getenv("BJ_DUMP_PAGES") + if dir == "" { + t.Skip("BJ_DUMP_PAGES не задан") + } + priv := testLicenseKey(t) + a, err := newAdmin() + if err != nil { + t.Fatal(err) + } + rc := testRC(t) + now := time.Now().UTC() + tok := signTestLicense(t, priv, &license.License{Schema: 1, ID: "lic-1", Tenant: "АО «Пример Инвест»", Product: "bj-server", Plan: license.PlanEnterprise, + IssuedAt: now, ExpiresAt: now.Add(365 * 24 * time.Hour), ContractUntil: now.AddDate(1, 0, 0), Features: []string{"updates", "quik-mnp", "web-cabinet", "npr", "quik-export"}}) + if err := rc.SaveLicense(LicenseSettings{Key: tok}); err != nil { + t.Fatal(err) + } + h := &setupHandlers{rc: rc, tpl: &adminTemplates{a: a}} + for step := 1; step <= wizardSteps; step++ { + w := httptest.NewRecorder() + h.renderWizard(w, httptest.NewRequest(http.MethodGet, fmt.Sprintf("/admin/wizard?step=%d", step), nil)) + _ = os.WriteFile(filepath.Join(dir, fmt.Sprintf("wizard-%02d.html", step)), w.Body.Bytes(), 0o644) + } + var b strings.Builder + d := PrepareData{page: page{Title: "Подготовка модулей", Active: "wizard"}, Tenant: "АО «Пример Инвест»", Plan: "enterprise", Until: "поддержка до 06.10.2027", Next: "/admin/wizard?step=12", Flash: "Администратор создан."} + if err := a.prepare.ExecuteTemplate(&b, "layout", d); err != nil { + t.Fatal(err) + } + _ = os.WriteFile(filepath.Join(dir, "prepare.html"), []byte(b.String()), 0o644) +} + +// Первая страница (администратор) — для снимка в TestDumpOnboardingPages. +func TestDumpFirstRunPage(t *testing.T) { + dir := os.Getenv("BJ_DUMP_PAGES") + if dir == "" { + t.Skip("BJ_DUMP_PAGES не задан") + } + var b strings.Builder + if err := firstRunTpl.Execute(&b, firstRunData{NeedKey: true}); err != nil { + t.Fatal(err) + } + _ = os.WriteFile(filepath.Join(dir, "first-run.html"), []byte(b.String()), 0o644) +} diff --git a/internal/lkgateway/quikdb_handlers.go b/internal/lkgateway/quikdb_handlers.go index 7546230..43833ef 100644 --- a/internal/lkgateway/quikdb_handlers.go +++ b/internal/lkgateway/quikdb_handlers.go @@ -161,6 +161,10 @@ func (h *setupHandlers) saveQuik(w http.ResponseWriter, r *http.Request) { setupFlash(w, r, "QUIK МНП: ошибка сохранения: "+err.Error()) return } + if r.FormValue("check") != "" { // «Сохранить и проверить» — одной кнопкой + h.testQuik(w, r) + return + } setupFlash(w, r, fmt.Sprintf("QUIK МНП: настройки сохранены (%s:%d, логин %s)", s.Server, s.Port, s.User)) } diff --git a/internal/lkgateway/setup.go b/internal/lkgateway/setup.go index e5d23cc..3b9510b 100644 --- a/internal/lkgateway/setup.go +++ b/internal/lkgateway/setup.go @@ -296,10 +296,10 @@ func (h *setupHandlers) renderWizard(w http.ResponseWriter, r *http.Request) { } d.ChaptersLine = wizChaptersLine(d.Chapters) if done[2] { - d.AutoDone = append(d.AutoDone, "База bj создана установщиком"+pickStr(" — "+d.PGSummary, "")) + d.AutoDone = append(d.AutoDone, "база bj") } if done[6] { - d.AutoDone = append(d.AutoDone, "СКЗИ «Валидата Клиент L» "+d.ValidataVer+" установлена вместе с bj") + d.AutoDone = append(d.AutoDone, "СКЗИ «Валидата» "+d.ValidataVer) } if step == 4 && strings.TrimSpace(s.Fancy.Server) != "" && !doneOrg(s) && depoDetectResult() == nil { // организация ещё не задана, а база DEPO подключена — определяем реквизиты сами: карточка diff --git a/internal/lkgateway/web/templates/admin_prepare.html b/internal/lkgateway/web/templates/admin_prepare.html index 63dfbf4..dbc7335 100644 --- a/internal/lkgateway/web/templates/admin_prepare.html +++ b/internal/lkgateway/web/templates/admin_prepare.html @@ -22,7 +22,7 @@
{{if .Flash}}

✓ {{.Flash}}

{{end}} -

Лицензия: план {{.Plan}}, {{.Until}}

+

Лицензия активна · {{.Until}}

Проверяю обновления и состав лицензии…

diff --git a/internal/lkgateway/web/templates/admin_wizard.html b/internal/lkgateway/web/templates/admin_wizard.html index 4ef7ca5..c49ee3e 100644 --- a/internal/lkgateway/web/templates/admin_wizard.html +++ b/internal/lkgateway/web/templates/admin_wizard.html @@ -27,11 +27,16 @@ a.wstep:hover .bub { box-shadow:0 0 0 4px var(--accent-weak); } .wiz-sub a.cur { background:var(--accent); color:#fff; border-color:var(--accent); } .wiz-nav { margin-top:20px; display:flex; justify-content:space-between; gap:8px; flex-wrap:wrap; } .wiz-card * { min-width:0; } +.wiz-row { display:flex; align-items:center; gap:10px 14px; flex-wrap:wrap; } +.wiz-row-l { font-weight:600; font-size:15px; min-width:130px; margin:0; } +.wiz-opt { display:flex; gap:8px; align-items:flex-start; font-weight:400; margin:0 0 6px; } +.wiz-opt .muted { font-size:13px; } +.wiz-card input[type=radio], .wiz-card input[type=checkbox] { flex:none; width:auto; margin-top:3px; }

Настройка Bridge&Join

-

{{.ChaptersLine}} Всё сохраняется сразу — можно прерваться и вернуться.

+

Всё сохраняется сразу — можно прерваться и продолжить позже.

@@ -39,7 +44,7 @@ a.wstep:hover .bub { box-shadow:0 0 0 4px var(--accent-weak); } {{end}}
{{range .Chapters}}{{if and .Current (gt (len .Steps) 1)}}
{{range .Steps}}{{if .Done}}✓ {{end}}{{.Title}}{{end}}
{{end}}{{end}} -

Пропустить мастер и перейти в систему → — вернуться к нему можно из «Настройка → Мастер настройки»

+

Настроить позже и перейти в систему →

{{if .Flash}}

{{.Flash}}

{{end}} @@ -52,10 +57,10 @@ a.wstep:hover .bub { box-shadow:0 0 0 4px var(--accent-weak); } {{/* восстановление из резервной копии — только на первой странице (/first-run), в мастере его нет */}}

Лицензия

-
Что это. Ключ продукта (BJ-XXXX-XXXX-XXXX) привязывает этот сервер к вашей лицензии.
- Зачем. От лицензии зависят модули (обмен с DEPO и QUIK, личный кабинет, НПР/УДС) и получение обновлений: bj скачает и поставит модули, входящие в лицензию, автоматически.
- Где взять. Портал клиента lic.zetit.ru/portal или письмо от ZETIT.
- {{if .Done.License}}

✓ Ключ продукта введён, лицензия активна: {{.Lic.Tenant}}, {{if eq .Lic.Plan "enterprise"}}полная лицензия (все модули){{else}}базовая лицензия{{end}}, модули: {{if .Lic.Features}}{{range $i, $f := .Lic.Features}}{{if $i}}, {{end}}{{$f}}{{end}}{{else}}только ядро{{end}}; {{.Lic.Message}}

{{end}} + {{if .Done.License}}

✓ Лицензия активна — {{.Lic.Tenant}}

+

{{if eq .Lic.Plan "enterprise"}}Все модули{{else if .Lic.Features}}Входит: {{range $i, $f := .Lic.Features}}{{if $i}}, {{end}}{{modTitle $f}}{{end}}{{else}}Только ядро: обмен с НРД и переводы M2M{{end}} · {{.Lic.Message}}

+ {{else}}

Введите ключ продукта — bj сам скачает и поставит модули вашей лицензии.

+

Ключ вида BJ-XXXX-XXXX-XXXX — в портале клиента lic.zetit.ru/portal или в письме от ZETIT.

{{end}} {{with .Update}}{{if .HasUpdate}}

На сервере лицензий есть что поставить (выпуск {{.Available}})

@@ -65,7 +70,7 @@ a.wstep:hover .bub { box-shadow:0 0 0 4px var(--accent-weak); }
- {{else}}

✓ Установлена последняя версия bj ({{.Available}}).

{{end}}{{end}} + {{else}}

✓ Установлена последняя версия bj

{{end}}{{end}} {{if .Done.License}}
Сменить ключ продукта (обычно не нужно)
@@ -74,11 +79,10 @@ a.wstep:hover .bub { box-shadow:0 0 0 4px var(--accent-weak); }
{{else}} -
+ - - - + +
{{end}} {{template "wizNav" .}}
@@ -93,44 +97,42 @@ a.wstep:hover .bub { box-shadow:0 0 0 4px var(--accent-weak); } {{else}} {{$sub := .Sub}} {{if eq $sub "setup"}} -
Что это. bj подключается к базе учёта DEPO (Fancy): сверяет с учётом каждый перевод (клиент, счёт, остаток, квалификация) и передаёт в DEPO поручения и их исполнение — документы в учёте создаются сами.
- Что понадобится. Адрес сервера базы DEPO. Имя базы знать не нужно — bj найдёт её сам. Подготовить базу (логин bj, таблицы обмена, задание обработки) можно одним действием: логином администратора SQL — он используется один раз и не сохраняется, — или администратор выполнит один готовый скрипт.
+

bj сверяет каждый перевод с учётом DEPO и сам создаёт в нём поручения. Нужен только адрес сервера — базу DEPO bj найдёт сам.

{{$mode := .Settings.Fancy.DepoJobMode}}
-
- - - +
+ + +
{{if .DepoCands}}{{end}} -
Обработку обмена в DEPO запускает
- - -
-
Как подготовить базу
- +
- +
- + - +
- {{if not .DepoCands}}
Дополнительно: указать базу DEPO вручную (обычно не нужно) +
Кто запускает обработку обмена
+ + +
+ {{if not .DepoCands}}
Указать базу DEPO вручную (обычно не нужно)
{{end}} -
+
{{else if eq $sub "done"}} - +
Подключение к базе DEPO{{if .Settings.Fancy.Server}}✓ {{.Settings.Fancy.Server}}, база {{.DepoTables.DB}}{{else}}не настроено{{end}}
Таблицы обмена FTV_M2M{{if .Settings.Fancy.DepoTablesCheckOK}}✓ на месте{{else}}✗ {{.Settings.Fancy.DepoTablesCheck}}{{end}}
Запуск обработки (джоба){{if .Settings.Fancy.DepoJobCheckOK}}✓ {{.Settings.Fancy.DepoJobCheck}}{{else}}✗ {{.Settings.Fancy.DepoJobCheck}}{{end}}
Запуск обработки{{if .Settings.Fancy.DepoJobCheckOK}}✓ {{.Settings.Fancy.DepoJobCheck}}{{else}}✗ {{.Settings.Fancy.DepoJobCheck}}{{end}}
Обработка событий (процедуры){{if .Settings.Fancy.DepoProcCheckOK}}✓ {{.Settings.Fancy.DepoProcCheck}}{{else if .Settings.Fancy.DepoProcCheck}}⚠ {{.Settings.Fancy.DepoProcCheck}}{{else}}не проверялась — «Перепроверить всё»{{end}}
{{if .Settings.Fancy.Server}}{{template "accPrefix" .}}{{end}} @@ -200,13 +202,12 @@ a.wstep:hover .bub { box-shadow:0 0 0 4px var(--accent-weak); } {{if eq .Step 4}}

Наша организация

-
Что это. Депозитарий — участник MOEX МОСТ, от имени которого bj отправляет и принимает переводы: код участника, ИНН и наименование попадают в пакеты НРД{{if .DepoLicensed}} и в поручения QUIK{{end}}.
- Откуда взять. {{if .DepoLicensed}}Если подключена база DEPO (раздел «Учёт DEPO»), bj сам определяет реквизиты по учёту — проверьте их и сохраните. Иначе выберите{{else}}Выберите{{end}} себя из справочника участников НРД или введите вручную.
+

От имени вашей организации bj отправляет и принимает переводы. {{if .DepoLicensed}}Реквизиты bj берёт из DEPO — проверьте и сохраните.{{else}}Найдите себя в справочнике участников НРД.{{end}}

{{if .Suggest}}{{if .Suggest.OrgName}}{{if not .Done.Org}}

✓ Определено из DEPO: {{.Suggest.OrgName}}, ИНН {{.Suggest.OrgINN}}, код {{.Suggest.OrgCode}}{{if .Suggest.AccountID}}, счёт НРД {{.Suggest.AccountID}}{{end}}. Поля ниже заполнены — проверьте и нажмите «Сохранить».

{{end}}{{end}}{{end}} {{with .Fancy}}{{template "orgSection" .}}{{end}}

Депозитарные реквизиты в НРД

-

Где в НРД учитываются бумаги вашей организации: место хранения указывается в каждом пакете перевода. Берутся из договора с НРД{{if .Settings.Fancy.Server}} — или кнопкой «Определить из DEPO»{{end}}.

+

Где в НРД учитываются бумаги организации — из договора с НРД{{if .Settings.Fancy.Server}} или кнопкой «Определить из DEPO»{{end}}.

{{if .Suggest}}{{if .Suggest.AccountID}}
Найдено в DEPO: счёт {{.Suggest.AccountID}}, код {{.Suggest.DeponentCode}}, раздел {{.Suggest.SectionID}}.{{range .Suggest.Notes}}
⚠ {{.}}{{end}}
{{end}}{{end}}
@@ -218,16 +219,6 @@ a.wstep:hover .bub { box-shadow:0 0 0 4px var(--accent-weak); }
{{if .Settings.Fancy.Server}}{{end}}
-
-

Логотип организации (необязательно)

-

Показывается справа в шапке отчётов для регулятора. Можно загрузить сейчас или позже в «Настройка → Оформление».

- {{if .Settings.Branding.LogoDataURI}}

логотип

{{end}} -
- - - -
-
{{template "wizNav" .}}
{{end}} @@ -235,16 +226,15 @@ a.wstep:hover .bub { box-shadow:0 0 0 4px var(--accent-weak); } {{/* ============= ШАГ 5: QUIK МНП ============= */}} {{if eq .Step 5}}
-

QUIK — модуль неторговых поручений

-
Что это. Модуль неторговых поручений QUIK (МНП) — продукт компании ARQA Technologies, разработчика QUIK. Через него bj блокирует бумаги клиента в QUIK на время перевода, снимает блокировку при отказе и после исполнения проводит поручение.
- Если МНП у вас ещё нет. Обратитесь в ARQA Technologies (arqatech.com, служба поддержки QUIK) и попросите подключить модуль неторговых поручений для работы с внешней системой. После подключения ARQA выдаст адрес сервера МНП и учётные данные — их и нужно ввести ниже.
- Если МНП уже есть. Адрес сервера и учётные данные — у вашего администратора QUIK.
+

QUIK

+

Адрес и логин модуля неторговых поручений — у вашего администратора QUIK. Если модуля ещё нет, его подключает ARQA Technologies — письмо для них готово ниже.

{{if .DepoLicensed}}{{template "letterCard" (letter "arqa")}}{{end}} {{if not .DepoLicensed}}

Модуль неторговых поручений не входит в текущую лицензию — шаг пропускается.

{{else}}{{with .Fancy}}{{template "quikSection" .}}{{end}} {{if .Settings.Quik.Server}}{{template "mnpCheck" .}}{{end}} {{if .Settings.Quik.M2MMissing}}

✗ Подключение есть, но под этим логином не видно объектов M2M: {{.Settings.Quik.M2MMissing}}. Проверьте имя базы МНП и права логина (роль InstrEu) и нажмите «Проверить» ещё раз.

{{end}} -
Справочник депозитариев-получателей. Чтобы QUIK принимал поручения M2M, в МНП должен быть справочник депозитариев-получателей (M2MDepoRecipients): bj заполняет его сам по справочнику участников НРД. Модуль МНП читает справочник только при запуске — после первого заполнения попросите администратора QUIK перезапустить модуль неторговых поручений, иначе QUIK ответит «Неизвестный депозитарий получателя».
{{quikRecipientsInfo}}
{{end}} +
Справочник депозитариев-получателей — bj заполняет сам +

Чтобы QUIK принимал поручения M2M, bj ведёт в МНП справочник депозитариев-получателей (M2MDepoRecipients) по справочнику участников НРД. МНП читает его только при запуске — после первого заполнения попросите администратора QUIK перезапустить модуль, иначе QUIK ответит «Неизвестный депозитарий получателя».
{{quikRecipientsInfo}}

{{end}} {{template "wizNav" .}}
{{end}} @@ -275,14 +265,13 @@ a.wstep:hover .bub { box-shadow:0 0 0 4px var(--accent-weak); } {{/* ============= ШАГ 7: Шлюз НРД (до ключа: ключ ставится в профиль ИШ) ============= */}} {{if eq .Step 7}}
-

Интеграционный шлюз НРД (ИШ)

-
- Что это. Интеграционный шлюз — программа НРД на этом же сервере: через неё bj отправляет пакеты M2M в НРД и получает ответы. bj работает со шлюзом по его адресу на сервере (обычно http://localhost:8090).
- К кому обратиться. Дистрибутив ИШ выпускает НРД (nsd.ru/workflow/system/programs). Доступ к контурам — сначала тестовому TEST3, затем боевому — НРД открывает по заявке: обратитесь к своему менеджеру НРД или в поддержку электронного документооборота. -
+

Шлюз НРД

+

Через интеграционный шлюз НРД (ИШ) на этом сервере bj отправляет переводы и получает ответы. bj ставит и настраивает шлюз сам; доступ к тестовому и боевому контуру НРД открывает по заявке — письма готовы.

+ {{template "igateInstall" .}} +
Письма в НРД о доступе к контурам {{template "letterCard" (letter "nsd-test")}} {{template "letterCard" (letter "nsd-prod")}} - {{template "igateInstall" .}} +
Дополнительно: адрес шлюза (обычно не нужно)
@@ -307,24 +296,17 @@ a.wstep:hover .bub { box-shadow:0 0 0 4px var(--accent-weak); } {{if eq .Step 8}}

Ключ и сертификаты

-

Здесь две части: ключ и сертификат вашей организации (ставите вы) и сертификаты НРД и удостоверяющих центров (bj ведёт их сам).

- {{if not .Done.NSD}}

Ключ устанавливается в профиль интеграционного шлюза — сначала установите шлюз в разделе «Шлюз НРД».

{{end}} +

Ключ электронной подписи организации для обмена с НРД. Его выдаёт Удостоверяющий центр Московской биржи: вам передадут архив ключа и пароль.

+ {{if not .Done.NSD}}

Ключ ставится в шлюз НРД — сначала установите шлюз.

{{end}} +

{{if .Certs}}Установить другой ключ{{else}}Установить ключ{{end}} архив → носитель → справочник → проверка подписи

-

1. Ключ и сертификат организации

-
Что это. Ключ электронной подписи вашей организации для обмена с НРД и его сертификат.
- К кому обратиться. Ключ выдаёт Удостоверяющий центр Московской биржи; оформляется по заявке в рамках подключения к электронному документообороту НРД. Вам передадут архив ключа и пароль к нему — его и загружают в мастере установки ключа.
- Как поставить. Мастер установки ключа: загрузить архив → запись на носитель → справочник сертификатов → проверка подписи Валидатой.
- Открыть мастер установки ключа → - -

2. Сертификаты НРД и УЦ — автоматически

-

✓ Автоматическое обновление {{if .Settings.NSDCerts.Manual}}выключено (включается в «Настройка → Криптография»){{else}}включено{{end}}. Делать на этом шаге ничего не нужно.

-
- Как это работает. Действующие сертификаты НРД и удостоверяющих центров Московской биржи поставляются вместе с bj и приезжают с обновлениями. Каждые 6 часов bj сверяет их со справочником сертификатов ИШ: добавляет недостающие, а заменённые НРД убирает строго после срока, который НРД объявил в уведомлении. Перед каждым изменением делается резервная копия и проверка подписи, при ошибке всё откатывается.
- Тестовые и боевые. Сертификат попадает только в справочник своего контура: боевые (издатель «Корневой УЦ») — только к боевому ключу, тестовые (издатель «Тестовый УЦ») — только к тестовому. Поэтому смешать контуры нельзя.
- Откуда берутся. НРД и Московская биржа публикуют сертификаты в постоянных местах: комплект ГОСТ МБ, НКЦ и НРД — https://fs.moex.com/cdp/sert/GOST.zip, сертификаты УЦ — https://fs.moex.com/cdp/. Когда там появляется новый сертификат, мы добавляем его в комплект bj, и он приезжает к вам с обновлением.
- Состояние, ручная проверка и выключение — «Настройка → Криптография → Сертификаты НРД в справочнике ИШ». +
+ Сертификаты НРД + {{if .Settings.NSDCerts.Manual}}⚠ автообновление выключено — «Настройка → Криптография»{{else}}✓ bj обновляет их сам{{end}}
- {{if .Settings.NSDCerts.LastRows}}

Последняя сверка: {{.Settings.NSDCerts.LastRun.Format "02.01.2006 15:04"}}{{if .Settings.NSDCerts.LastProfile}}, профиль ИШ {{.Settings.NSDCerts.LastProfile}}{{end}}.

{{else}}

Первая сверка пройдёт сразу после установки ключа.

{{end}} +
Как это работает +

Действующие сертификаты НРД и удостоверяющих центров Московской биржи приезжают вместе с bj и его обновлениями. Каждые 6 часов bj сверяет их со справочником шлюза: добавляет недостающие, а заменённые убирает строго после срока, объявленного НРД. Перед изменением — резервная копия и проверка подписи, при ошибке всё откатывается. Тестовые сертификаты попадают только к тестовому ключу, боевые — только к боевому.

+ {{if .Settings.NSDCerts.LastRows}}

Последняя сверка: {{.Settings.NSDCerts.LastRun.Format "02.01.2006 15:04"}}{{if .Settings.NSDCerts.LastProfile}}, профиль ИШ {{.Settings.NSDCerts.LastProfile}}{{end}}.

{{else}}{{end}} {{if .Certs}}

Установленные сертификаты ({{len .Certs}})

@@ -343,7 +325,7 @@ a.wstep:hover .bub { box-shadow:0 0 0 4px var(--accent-weak); } {{else}} -

Ключ организации ещё не установлен. Можно пропустить этот шаг и вернуться к нему, когда будет архив ключа.

+

Архива ключа ещё нет — шаг можно пропустить и вернуться позже.

{{end}} {{template "wizNav" .}} @@ -353,27 +335,46 @@ a.wstep:hover .bub { box-shadow:0 0 0 4px var(--accent-weak); } {{/* ============= ШАГ 12: Время и сеть (глава «Сервер») ============= */}} {{if eq .Step 12}}
-

Время и сеть сервера

- {{if .AutoDone}}
Сделано автоматически.{{range .AutoDone}}
✓ {{.}}{{end}}
{{end}} -

Часовой пояс

-

По нему — время в журналах, уведомлениях и сроках поручений. Время НРД — московское; если сервер в другом поясе, выберите свой.

+

Время и сеть

{{$tz := serverTimeZone}} - + - - - сейчас: {{$tz}} + + -

Сервер времени

-

{{if .Done.Server}}✓ время синхронизируется{{else}}⚠ время не синхронизируется — укажите сервер времени вашей сети (обычно контроллер домена или маршрутизатор){{end}}

-
+

По нему — время в журналах, уведомлениях и сроках поручений. Время НРД — московское.

+ + +
+ Точное время + {{if .Done.Server}}✓ синхронизируется{{else}}⚠ не синхронизируется{{end}} +
+
{{if .Done.Server}}Свой сервер времени (обычно не нужно){{else}}Укажите сервер времени вашей сети — обычно контроллер домена или маршрутизатор{{end}} + - - + + -

Адрес и HTTPS

-

Сервер: {{serverAddrs}}. Вход по HTTPS: https://{{serverIP}}:8443/.

-

Чтобы адрес не менялся, задайте постоянный — на консоли сервера: sudo bj-network. Перенаправление на HTTPS и сертификат организации — в «Настройка → Сервер».

+
+ +
+ Адрес bj + https://{{serverIP}}:8443/ +
+

Чтобы адрес не менялся, задайте постоянный: на консоли сервера — sudo bj-network.

+ {{if .AutoDone}}

Уже сделано установщиком: {{range $i, $a := .AutoDone}}{{if $i}} · {{end}}✓ {{$a}}{{end}}

{{end}} + {{template "wizNav" .}}
{{end}} @@ -381,13 +382,13 @@ a.wstep:hover .bub { box-shadow:0 0 0 4px var(--accent-weak); } {{/* ============= ШАГ 11: Модули по лицензии (глава «Запуск») ============= */}} {{if eq .Step 11}}
-

Модули по лицензии

-

Здесь только модули, которые входят в вашу лицензию. Каждый настраивается в своём разделе — кнопка «Настроить» откроет его, а вернуться в мастер можно ссылкой вверху раздела.

+

Модули

+

Модули вашей лицензии уже установлены. Каждый настраивается в своём разделе — сейчас или позже.

{{range .Modules}}

{{.What}}

{{if .Ready}}✓{{else}}⚠{{end}} {{.Status}}

@@ -401,15 +402,14 @@ a.wstep:hover .bub { box-shadow:0 0 0 4px var(--accent-weak); } {{if eq .Step 9}}

Оповещения и резервные копии

-
Зачем. bj сам следит за обменом: НРД не отвечает, перевод не доставлен{{if .DepoLicensed}}, ошибка обработки в DEPO{{end}}, истекает сертификат ключа. Чтобы об этом узнали сразу, а не открыв bj, — укажите почту. Резервные копии позволят восстановить сервер целиком (настройки, заявки, шлюз НРД) после сбоя или переустановки.
- Можно позже. Шаг необязательный — обмен работает и без него, но мы настоятельно советуем настроить оба пункта.
+

bj напишет на почту, если НРД не отвечает, перевод застрял{{if .DepoLicensed}}, DEPO не обработал поручение{{end}} или истекает ключ, — и будет сам делать копии сервера. Обмен работает и без этого, но мы советуем настроить оба пункта.

{{with .Fancy}} -

Почта для оповещений

{{template "smtpCard" .}} +
Разослать уведомления отделам — депозитарий, бэк-офис, мидл-офис (необязательно) {{template "notifyGroupsCard" .}} -

Резервные копии

+
{{template "backupCard" .}} {{end}}
diff --git a/internal/lkgateway/web/templates/layout.html b/internal/lkgateway/web/templates/layout.html index 9fa620a..69a83f0 100644 --- a/internal/lkgateway/web/templates/layout.html +++ b/internal/lkgateway/web/templates/layout.html @@ -61,6 +61,7 @@ body { .brand svg { width:26px; height:26px; display:block; flex:none; } .brand b { font-weight:730; } .brand .brand-j { color:var(--muted); font-weight:600; } .nav { display:flex; align-items:center; gap:1px; margin-left:6px; flex:1 1 auto; min-width:0; flex-wrap:wrap; } +.nav[hidden] { visibility:hidden; } .nav::-webkit-scrollbar { display:none; } .user-chip { display:inline-flex; flex-direction:column; line-height:1.15; margin-right:6px; max-width:180px; } .user-chip .user-name { font-size:12.5px; font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; } @@ -336,7 +337,7 @@ details:has(> pre.copyable) { min-width:0; max-width:100%; } Bridge&Join -