Files
Bridge-and-Join-s/internal/lkgateway/participant_reg.go
T
fontvielle 07866526eb Анкета участника: ловить ответ НРД (M2MER с нулевым GUID) и показывать отправку/ответ
Ответ НРД на анкету приходит как M2MTransferResponse (M2MER) с нулевым GUID —
раньше он уходил в обработку перевода, «сделка не найдена», и отбрасывался.
Теперь нулевой GUID распознаётся как ответ на регистрацию участника:
- сырой XML сохраняется (captureNSDReply → nsd-replies);
- отправка анкеты и ответ НРД пишутся в participant-reg.json (время, пакет,
  наименование, статус, коды, текст НРД);
- на странице «Регистрация участника M2M» показываем: когда отправили и вердикт
  НРД («принял»/«отклонил» с текстом, напр. M2M37 «Некорректно указано
  наименование участника в анкете»).
Текст берётся из самого ответа (serviceErrorTexts) — карту кодов не трогаем.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q7eREaYwUt1i4fNLZcGnjn
2026-10-21 18:01:50 +03:00

83 lines
2.6 KiB
Go
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.
package lkgateway
// participant_reg.go — учёт регистрации участника M2M: что и когда отправили
// анкетой (#M2MPF) и какой ответ дал НРД (сервис МОСТ, M2MTransferResponse с
// нулевым GUID — он не относится к переводу). Показывается на странице анкеты.
import (
"encoding/json"
"os"
"strings"
"sync"
"time"
"git.zetit.ru/zuevav/Bridge-and-Join-s/internal/m2m"
)
const participantRegFile = "/var/lib/bj/.bj/participant-reg.json"
// participantReg — последняя отправка анкеты и ответ НРД на неё.
type participantReg struct {
SentAt time.Time `json:"sent_at,omitempty"`
PkgID string `json:"pkg_id,omitempty"`
Name string `json:"name,omitempty"` // отправленное полное наименование
Channel string `json:"channel,omitempty"`
RespAt time.Time `json:"resp_at,omitempty"`
Status string `json:"status,omitempty"` // OK | ERROR
Codes []string `json:"codes,omitempty"`
RespText string `json:"resp_text,omitempty"`
RawFile string `json:"raw_file,omitempty"`
}
var participantRegMu sync.Mutex
func loadParticipantReg() participantReg {
participantRegMu.Lock()
defer participantRegMu.Unlock()
var r participantReg
if b, err := os.ReadFile(participantRegFile); err == nil {
_ = json.Unmarshal(b, &r)
}
return r
}
// saveParticipantReg читает текущую запись, даёт изменить и атомарно пишет назад.
func saveParticipantReg(mut func(*participantReg)) {
participantRegMu.Lock()
defer participantRegMu.Unlock()
var r participantReg
if b, err := os.ReadFile(participantRegFile); err == nil {
_ = json.Unmarshal(b, &r)
}
mut(&r)
b, err := json.MarshalIndent(&r, "", " ")
if err != nil {
return
}
tmp := participantRegFile + ".tmp"
if os.WriteFile(tmp, b, 0o640) == nil {
_ = os.Rename(tmp, participantRegFile)
}
}
// recordParticipantReply сохраняет ответ НРД на анкету (статус, коды, тексты, файл XML).
func recordParticipantReply(status string, resp *m2m.M2MTransferResponse, rawFile string) {
var codes []string
seen := map[string]bool{}
for _, rr := range resp.Responses {
c := strings.TrimSpace(rr.Code)
if c != "" && !seen[c] {
seen[c] = true
codes = append(codes, c)
}
}
text := strings.Join(serviceErrorTexts(resp), "; ")
saveParticipantReg(func(r *participantReg) {
r.RespAt = time.Now()
r.Status = status
r.Codes = codes
r.RespText = text
r.RawFile = rawFile
})
}