Справочник M2M: ручная загрузка файла в формате НРД

Форма «Загрузка справочника из файла» на /admin/handbook принимает
подлинный формат НРД (hk:M2MTransferHandbook, windows-1251 — тот же,
что приходит пакетом #M2MTH и который отдаёт кнопка «XML»). Разбор и
сохранение идут тем же путём, что у поллера при ответе НРД:
nsdxml.Unmarshal → writeHandbookRawXML (сырой XML для байт-в-байт
выгрузки) → saveHandbookEx (плоский JSON) → перезапись FTV_M2M_HANDBOOK
в DEPO → синхронизация получателей в МНП. На сервер лицензий ручной файл
НЕ рассылается (saveHandbookEx push=false): справочник одного стенда не
должен становиться облачным для всех клиентов. Нужно для закрытого
контура и когда шлюз к НРД недоступен.

- handbook_import.go: обработчик importHandbook (POST /admin/handbook/import)
- nsdpoller.go: saveHandbook → saveHandbookEx(hb, push)
- admin.go: маршрут import, поле Flash, renderHandbook читает ?flash=
- admin_handbook.html: карточка загрузки + вывод flash

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XG3zNMMf2LMoDpXo22mwMX
This commit is contained in:
fontvielle
2026-10-15 11:18:50 +03:00
parent ba3ae22c49
commit 5beb726e5b
4 changed files with 114 additions and 6 deletions
+9 -2
View File
@@ -305,7 +305,12 @@ type HandbookEntry struct {
// saveHandbook раскладывает справочник в плоский список и пишет в файл. Возвращает, изменился ли
// состав: справочник запрашивается раз в 10 минут (сквозная проверка связи, nsdhealth.go), и без
// изменений его не нужно ни рассылать, ни переписывать в DEPO.
func saveHandbook(hb *m2m.M2MTransferHandbook) (changed bool) {
func saveHandbook(hb *m2m.M2MTransferHandbook) (changed bool) { return saveHandbookEx(hb, true) }
// saveHandbookEx — как saveHandbook, но push управляет рассылкой справочника на сервер
// лицензий. Ручная загрузка файла (handbook_import.go) идёт с push=false: справочник
// одного стенда не должен становиться облачным для всех клиентов.
func saveHandbookEx(hb *m2m.M2MTransferHandbook, push bool) (changed bool) {
out := struct {
At string `json:"at"`
Participants []HandbookEntry `json:"participants"`
@@ -350,7 +355,9 @@ func saveHandbook(hb *m2m.M2MTransferHandbook) (changed bool) {
for _, e := range out.Participants {
log.Printf("lk-gateway: справочник M2M: ИНН %s → %s [%s] %s", e.INN, e.Code, e.Kind, e.Name)
}
pushHandbookAsync(globalRC, raw) // свежий справочник — на сервер лицензий для всех клиентов
if push {
pushHandbookAsync(globalRC, raw) // свежий справочник — на сервер лицензий для всех клиентов
}
}
}
return changed