feat(admin): вкладка «Инструкции» + русификация статусов в UI
В admin-панели lk-gateway добавлен раздел /admin/help — справка по основным интеграциям, читается прямо на сервере, без выхода во внешнюю документацию. Состав /admin/help: - /admin/help — hub-страница с 4 карточками-ссылками - /admin/help/database — подключение PostgreSQL, схемы fansy/fansy_staging/m2m_core, что подгружается через ETL Fansy и что пишет сама система, роли, миграции, полезные запросы - /admin/help/lk-api — REST-контракт ESIA Finance V1: аутентификация, POST/GET/PATCH/list, формат callback'ов и ошибок, эмулятор для тестов, примеры curl - /admin/help/cryptopro — установка КриптоПро CSP на РЕД ОС и Ubuntu, ввод серийного номера лицензии (cpconfig), путь к PKCS#11 модулю libcppkcs11.so, подключение Рутокен ЭЦП 2.0 для подписи оператора, тестирование подписи через csptest и cryptcp - /admin/help/systems — Интеграционный шлюз НРД (профили guest/test3/prod), команда Fansy (порядок согласования контракта), уведомления (SMTP/Yandex Messenger/Telegram), контакты команд Русификация статусов: - Добавлены template-функции ruState и ruOutcome (в lkgateway и lkemulator) - "draft" → "Черновик", "confirmed" → "Подтверждена", "rejected" → "Отклонена" и т.д. - CSS-классы бейджей сохраняются (по исходному state), меняется только отображаемый текст. Технические термины (PostgreSQL, ИНН, GUID, REST) остаются как есть — они являются именами программного обеспечения. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -19,12 +19,65 @@ var templatesFS embed.FS
|
||||
// конкретный content-шаблон). Так html/template не путается с несколькими
|
||||
// {{define "content"}} в разных файлах.
|
||||
type admin struct {
|
||||
home, claims, claim, status, setup *template.Template
|
||||
home, claims, claim, status, setup *template.Template
|
||||
help, helpDatabase, helpLK, helpCryptoPro, helpSystems *template.Template
|
||||
}
|
||||
|
||||
// templateFuncs — функции, доступные внутри шаблонов. Главная задача —
|
||||
// русификация статусов и других технических обозначений (см. требование
|
||||
// «всё UI на русском, кроме программных терминов»).
|
||||
var templateFuncs = template.FuncMap{
|
||||
"ru": russianText,
|
||||
"ruState": russianState,
|
||||
"ruOutcome": russianOutcome,
|
||||
}
|
||||
|
||||
// russianState переводит технический FSM-state в человекочитаемый
|
||||
// русский, сохраняя CSS-класс для бейджа.
|
||||
func russianState(s string) string {
|
||||
switch s {
|
||||
case "draft":
|
||||
return "Черновик"
|
||||
case "validated":
|
||||
return "Валидирована"
|
||||
case "submitted_to_nsd":
|
||||
return "Отправлена в НРД"
|
||||
case "awaiting_decision":
|
||||
return "Ожидает решение"
|
||||
case "confirmed":
|
||||
return "Подтверждена"
|
||||
case "awaiting_sub16":
|
||||
return "Ожидает SUB16"
|
||||
case "done":
|
||||
return "Завершена"
|
||||
case "rejected":
|
||||
return "Отклонена"
|
||||
case "timed_out":
|
||||
return "Таймаут SLA"
|
||||
case "manual_approval":
|
||||
return "На ручном разборе"
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// russianOutcome — для NSDDecisionSecurity.Outcome.
|
||||
func russianOutcome(o string) string {
|
||||
switch o {
|
||||
case "confirmed":
|
||||
return "Подтверждено"
|
||||
case "rejected":
|
||||
return "Отказ"
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
// russianText — fallback функция для произвольных строк (на случай
|
||||
// будущих расширений). Сейчас возвращает строку без изменений.
|
||||
func russianText(s string) string { return s }
|
||||
|
||||
func newAdmin() (*admin, error) {
|
||||
parse := func(content string) (*template.Template, error) {
|
||||
return template.ParseFS(templatesFS,
|
||||
return template.New("layout.html").Funcs(templateFuncs).ParseFS(templatesFS,
|
||||
"web/templates/layout.html",
|
||||
"web/templates/"+content)
|
||||
}
|
||||
@@ -48,7 +101,30 @@ func newAdmin() (*admin, error) {
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parse admin_setup: %w", err)
|
||||
}
|
||||
return &admin{home: home, claims: claims, claim: claim, status: status, setup: setup}, nil
|
||||
help, err := parse("admin_help.html")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parse admin_help: %w", err)
|
||||
}
|
||||
helpDB, err := parse("admin_help_database.html")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parse admin_help_database: %w", err)
|
||||
}
|
||||
helpLK, err := parse("admin_help_lk.html")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parse admin_help_lk: %w", err)
|
||||
}
|
||||
helpCP, err := parse("admin_help_cryptopro.html")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parse admin_help_cryptopro: %w", err)
|
||||
}
|
||||
helpSys, err := parse("admin_help_systems.html")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parse admin_help_systems: %w", err)
|
||||
}
|
||||
return &admin{
|
||||
home: home, claims: claims, claim: claim, status: status, setup: setup,
|
||||
help: help, helpDatabase: helpDB, helpLK: helpLK, helpCryptoPro: helpCP, helpSystems: helpSys,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// page — общий "конверт" данных для всех шаблонов.
|
||||
@@ -111,6 +187,16 @@ func RegisterAdmin(mux *http.ServeMux, svc *Service, getOpts func() CheckOptions
|
||||
a.renderClaim(w, r, svc, id)
|
||||
case p == "status":
|
||||
a.renderStatus(w, r, getOpts())
|
||||
case p == "help":
|
||||
render(w, a.help, nowPage("Инструкции", "help"))
|
||||
case p == "help/database":
|
||||
render(w, a.helpDatabase, nowPage("База данных", "help"))
|
||||
case p == "help/lk-api":
|
||||
render(w, a.helpLK, nowPage("API ЛК", "help"))
|
||||
case p == "help/cryptopro":
|
||||
render(w, a.helpCryptoPro, nowPage("КриптоПро", "help"))
|
||||
case p == "help/systems":
|
||||
render(w, a.helpSystems, nowPage("Внешние системы", "help"))
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user