Списки: период, сортировка, подгрузка; анкета участника — строкой исходящих

«Исходящие», «Входящие», «Журнал обмена»: быстрые периоды (сегодня, 7, 30
дней, всё время), даты с–по, сортировка (время, инвестор/контрагент,
направление, статус), первые 50 строк и подгрузка при прокрутке
(part=rows&offset=N). Раньше показывались только последние 200/100.

Анкета участника — исходящий пакет в НРД: строка в «Исходящих» и
«Журнале» с ответом НРД (принята / отклонена с кодом / ждёт), вместо
плашки над списком. Отправки копятся в participant-regs.json (прежний
participant-reg.json подхватывается). userTemplate — функции текущего
пользователя и для порций строк.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q7eREaYwUt1i4fNLZcGnjn
This commit is contained in:
fontvielle
2026-10-22 10:50:43 +03:00
parent 890e575d3d
commit 60b4d46277
13 changed files with 522 additions and 92 deletions
+36 -7
View File
@@ -68,11 +68,15 @@ func incomingStatusOf(it *IncomingTransfer) incomingStatusVM {
}
// buildJournalRows — объединённая лента (исходящие + входящие), отсортированная от новых к старым.
func buildJournalRows(ctx context.Context, svc *Service, store *IncomingStore) []journalRow {
func buildJournalRows(ctx context.Context, svc *Service, store *IncomingStore, from time.Time) []journalRow {
var rows []journalRow
// Исходящие (наши заявки в НРД).
if page, err := svc.ListClaims(ctx, m2mcore.Filter{Limit: 100}); err == nil {
// Исходящие (наши заявки в НРД); from — с какого времени (нулевое — все).
f := m2mcore.Filter{Limit: 100000}
if !from.IsZero() {
f.CreatedFrom = &from
}
if page, err := svc.ListClaims(ctx, f); err == nil {
for _, c := range page.Items {
party := m2mPartyName(c.ReceivingDepositoryINN)
if party != "" {
@@ -109,6 +113,16 @@ func buildJournalRows(ctx context.Context, svc *Service, store *IncomingStore) [
LiveKey: "in:" + it.ID, Live: liveIncoming(it),
})
}
// Анкеты участника M2M — исходящие пакеты в НРД с ответом на них.
for _, rg := range loadParticipantRegs() {
rows = append(rows, journalRow{
Time: rg.SentAt, Dir: "Исходящий", DirKind: "out",
Party: "НРД · анкета участника M2M",
Status: rg.StatusClass(), StatusText: rg.StatusText(),
Href: "/admin/setup/participant-form",
LiveKey: "pf:" + rg.PkgID,
})
}
sort.Slice(rows, func(i, j int) bool { return rows[i].Time.After(rows[j].Time) })
return rows
}
@@ -117,22 +131,37 @@ func buildJournalRows(ctx context.Context, svc *Service, store *IncomingStore) [
func registerJournal(mux *http.ServeMux, a *admin, svc *Service, store *IncomingStore) {
registerLiveStatus(mux, svc, store) // «чего ждёт заявка» для строк в работе
mux.HandleFunc("/admin/journal", func(w http.ResponseWriter, r *http.Request) {
rows := buildJournalRows(r.Context(), svc, store)
q := parseListQ(r, []string{"time", "dir", "party", "status"})
var items []listItem
for _, row := range buildJournalRows(r.Context(), svc, store, q.From) {
items = append(items, listItem{T: row.Time, V: row, Keys: map[string]string{"dir": row.Dir, "party": row.Party, "status": row.StatusText}})
}
rows, total, more := listApply(items, q)
if r.URL.Query().Get("part") == "rows" {
listRowsPart(w, a.journal, "journalrow", rows, q, more)
return
}
data := struct {
page
Rows []journalRow
}{nowPage("Журнал обмена", "journal"), rows}
Rows []any
List listView
}{nowPage("Журнал обмена", "journal"), listVals(rows),
newListView("/admin/journal", "journal-body", q, total, more, "time", "по времени", "dir", "по направлению", "party", "по контрагенту", "status", "по статусу")}
render(w, a.journal, data)
})
// /admin/journal/rows — только новые строки (появившиеся после since, unix-наносекунды).
// Страница подставляет их сверху без перезагрузки. count — общее число строк (для счётчика).
mux.HandleFunc("/admin/journal/rows", func(w http.ResponseWriter, r *http.Request) {
rows := buildJournalRows(r.Context(), svc, store)
var since int64
if s := r.URL.Query().Get("since"); s != "" {
since, _ = strconv.ParseInt(s, 10, 64)
}
var from time.Time
if since > 0 {
from = time.Unix(0, since)
}
rows := buildJournalRows(r.Context(), svc, store, from)
type rowJSON struct {
Key string `json:"key"`
T int64 `json:"t"`