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 }) }