Мониторинг связи с НРД: участки Шлюз/НРД/M2M/Отправка, сквозная проверка справочником раз в 10 мин, история за сутки на «Статусе», цепочка в шапке (30 с), автоповтор недоставленных до 24 ч, баннер и статус «ожидает отправки» в кабинете клиента

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014FsEKyJrYF69Cj9ZXzFLRi
This commit is contained in:
zuevav
2026-09-25 16:17:25 +03:00
parent a0f6ce9f7b
commit 4cbefa41d5
18 changed files with 1075 additions and 62 deletions
+31
View File
@@ -55,6 +55,34 @@ type Server struct {
handlerOnce sync.Once
handler http.Handler
nsdMu sync.Mutex // состояние обмена с НРД для баннера (кэш 30 с)
nsdAt time.Time
nsdNotice string
}
// nsdBanner — предупреждение «обмен с НРД недоступен» для вошедшего клиента (пусто — всё работает).
// Спрашивает ядро не чаще раза в 30 с; ядро недоступно — баннер не показываем (об этом скажет сама страница).
func (s *Server) nsdBanner(r *http.Request) string {
sess := session(r)
if sess == "" {
return ""
}
s.nsdMu.Lock()
defer s.nsdMu.Unlock()
if time.Since(s.nsdAt) < 30*time.Second {
return s.nsdNotice
}
var out struct {
Notice string `json:"notice"`
}
ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
defer cancel()
if err := s.bj().call(ctx, http.MethodGet, "/api/lk/nsd-status", sess, nil, &out); err == nil {
s.nsdNotice = out.Notice
}
s.nsdAt = time.Now()
return s.nsdNotice
}
// New — кабинет с разобранными шаблонами.
@@ -734,6 +762,9 @@ func (s *Server) render(w http.ResponseWriter, r *http.Request, name string, dat
data["AsClient"] = c.Value
}
data["CSRF"] = csrfToken(w, r)
if _, ok := data["NSDNotice"]; !ok {
data["NSDNotice"] = s.nsdBanner(r)
}
if _, ok := data["Flash"]; !ok {
if f := takeFlash(w, r); f != "" {
data["Flash"] = f