Справочник участников: показывать результат обработки джобой Fancy

На странице «Справочник участников M2M» теперь выводится итог обработки
справочника джобой bj2depo — STATE/COMMENT последнего события HANDBOOK
из FTV_M2M_EVENTS (поле COMMENT пишет Fancy). Расхождения/предупреждения
выделяются цветом и значком: КРИТИЧ/ОШИБКА — красным, ПРЕДУПРЕЖДЕНИЕ —
жёлтым, «изменений нет» — зелёным, чтобы оператор видел, что проверить.

Только чтение (fsql.QEv11, TOP 1 по EVENT_DATE), короткий таймаут 4с,
страница не висит если DEPO недоступна.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
fontvielle
2026-10-14 11:16:19 +03:00
parent c73f6120d3
commit e4b164c6e5
4 changed files with 97 additions and 1 deletions
+72
View File
@@ -13,6 +13,7 @@ import (
"context"
"database/sql"
"encoding/json"
"errors"
"fmt"
"git.zetit.ru/zuevav/Bridge-and-Join-s/internal/lkgateway/fsql"
"log"
@@ -551,6 +552,77 @@ func depoPollOrders(ctx context.Context, db *sql.DB, rc *RuntimeConfig) {
}
}
// HandbookResult — результат обработки справочника участников джобой Fancy bj2depo
// (STATE/COMMENT последнего события HANDBOOK в FTV_M2M_EVENTS). bj только читает.
type HandbookResult struct {
Found bool
At time.Time
AtText string
State string
Comment string
Severity string // ok | warn | err
Err string
}
// handbookSeverity — важность результата обработки справочника по STATE/COMMENT.
func handbookSeverity(state, comment string) string {
s := strings.ToUpper(state)
u := strings.ToUpper(comment)
switch {
case strings.Contains(s, "ERROR") || strings.Contains(u, "ОШИБКА") || strings.Contains(u, "КРИТИЧ"):
return "err"
case strings.Contains(s, "WARN") || strings.Contains(u, "ПРЕДУПРЕЖД"):
return "warn"
default:
return "ok"
}
}
// depoHandbookResult читает результат последней обработки справочника участников: событие
// HANDBOOK, в COMMENT/STATE которого джоба Fancy bj2depo пишет итог сверки своего справочника
// юрлиц с данными НРД (расхождения, предупреждения). Только чтение, короткий таймаут.
func depoHandbookResult(rc *RuntimeConfig) HandbookResult {
var res HandbookResult
if rc == nil {
res.Err = "настройки недоступны"
return res
}
fs := rc.Snapshot().Fancy
if strings.TrimSpace(fs.Server) == "" {
res.Err = "подключение к DEPO (Обмен Fancy) не настроено"
return res
}
db, err := fancyOpen(fs, fs.DepoDB())
if err != nil {
res.Err = "DEPO недоступна: " + err.Error()
return res
}
defer db.Close()
ctx, cancel := context.WithTimeout(context.Background(), 4*time.Second)
defer cancel()
if !depoTableExists(ctx, db, "FTV_M2M_EVENTS") {
res.Err = "таблицы FTV_M2M_EVENTS нет"
return res
}
var at time.Time
var state, comment string
err = db.QueryRowContext(ctx, fsql.QEv11).Scan(&at, &state, &comment)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return res // событий HANDBOOK ещё нет
}
res.Err = err.Error()
return res
}
res.Found = true
res.At = at
res.AtText = at.Format("02.01.2006 15:04")
res.State = strings.TrimSpace(state)
res.Comment = strings.TrimSpace(comment)
res.Severity = handbookSeverity(res.State, res.Comment)
return res
}
// ---- справочник участников → FTV_M2M_HANDBOOK (полная перезапись) ----
var depoHandbookWritten time.Time