Дашборд: готовность по шагам мастера настройки (с учётом лицензии) и список невыполненных шагов со ссылками
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014FsEKyJrYF69Cj9ZXzFLRi
This commit is contained in:
@@ -382,6 +382,7 @@ type homeData struct {
|
||||
AllReady bool
|
||||
NotReadyCount int
|
||||
TotalCount int
|
||||
NotReady []SetupStep // невыполненные шаги мастера — ссылками на них
|
||||
|
||||
// LKUrl — адрес тестового ЛК (для первичного теста интеграции).
|
||||
LKUrl string
|
||||
@@ -494,15 +495,12 @@ func (a *admin) renderHome(w http.ResponseWriter, r *http.Request, svc *Service,
|
||||
News: topNews(visibleNews(rc, rc.Snapshot().News.Items), 3),
|
||||
LKUrl: rc.Snapshot().LK.PublicURL,
|
||||
}
|
||||
// Готовность системы считаем ТОЛЬКО по обязательным компонентам.
|
||||
// Опциональные (напр. callback в ЛК) не влияют на «готовность».
|
||||
for _, c := range status.Checks {
|
||||
if c.Optional {
|
||||
continue
|
||||
}
|
||||
// Готовность — по тем же шагам, что в мастере настройки (с учётом лицензии).
|
||||
for _, st := range setupSteps(rc) {
|
||||
data.TotalCount++
|
||||
if !c.OK {
|
||||
if !st.Done {
|
||||
data.NotReadyCount++
|
||||
data.NotReady = append(data.NotReady, st)
|
||||
}
|
||||
}
|
||||
data.AllReady = data.TotalCount > 0 && data.NotReadyCount == 0
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
package lkgateway
|
||||
|
||||
// Шаги настройки — одни и те же для мастера и дашборда: дашборд пишет «Требуется настройка — N из M»
|
||||
// ровно по шагам мастера (с учётом лицензии), а не по отдельному списку проверок.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"git.zetit.ru/zuevav/Bridge-and-Join-s/internal/cryptocli"
|
||||
)
|
||||
|
||||
type SetupStep struct {
|
||||
Step int
|
||||
Title string
|
||||
Done bool
|
||||
}
|
||||
|
||||
var setupProbeCache = struct {
|
||||
sync.Mutex
|
||||
at time.Time
|
||||
validata string
|
||||
certs int
|
||||
}{}
|
||||
|
||||
// setupProbes — версия Валидаты и число сертификатов (внешние вызовы) с кэшем на минуту.
|
||||
func setupProbes(rc *RuntimeConfig) (string, int) {
|
||||
setupProbeCache.Lock()
|
||||
defer setupProbeCache.Unlock()
|
||||
if time.Since(setupProbeCache.at) < time.Minute {
|
||||
return setupProbeCache.validata, setupProbeCache.certs
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 4*time.Second)
|
||||
defer cancel()
|
||||
setupProbeCache.validata, _, _ = validataVersion(ctx)
|
||||
setupProbeCache.certs = 0
|
||||
s := rc.Snapshot()
|
||||
if s.Crypto.Provider != "" && s.Crypto.Provider != "stub" {
|
||||
cli := cryptocli.New(cryptocli.Config{Provider: cryptocli.Provider(s.Crypto.Provider), SocketPath: s.Crypto.SocketPath, ModulePath: s.Crypto.ModulePath})
|
||||
if certs, err := cli.FindCertificates(ctx); err == nil {
|
||||
setupProbeCache.certs = len(certs)
|
||||
}
|
||||
cli.Close()
|
||||
}
|
||||
setupProbeCache.at = time.Now()
|
||||
return setupProbeCache.validata, setupProbeCache.certs
|
||||
}
|
||||
|
||||
// setupSteps — шаги мастера, которые относятся к этой установке (по лицензии), и выполнены ли они.
|
||||
func setupSteps(rc *RuntimeConfig) []SetupStep {
|
||||
s := rc.Snapshot()
|
||||
mnp := moduleAllowed(rc, "quik-mnp")
|
||||
validata, certs := setupProbes(rc)
|
||||
steps := []SetupStep{
|
||||
{1, "Лицензия", licenseStatus(rc).Valid},
|
||||
{2, "База bj", s.Postgres.DSN != ""},
|
||||
}
|
||||
if mnp {
|
||||
steps = append(steps, SetupStep{3, "Учёт DEPO", strings.TrimSpace(s.Fancy.Server) != "" && s.Fancy.DepoTablesCheckOK && s.Fancy.DepoJobCheckOK})
|
||||
}
|
||||
steps = append(steps, SetupStep{4, "Наша организация", orgCode(s) != "" && orgINN(s) != ""})
|
||||
if mnp {
|
||||
steps = append(steps, SetupStep{5, "QUIK МНП", s.Quik.Verified})
|
||||
}
|
||||
steps = append(steps,
|
||||
SetupStep{6, "Валидата", validata != "" || (s.Crypto.Provider != "" && s.Crypto.Provider != "stub" && s.Crypto.ModulePath != "")},
|
||||
SetupStep{7, "Сертификаты", certs > 0},
|
||||
SetupStep{8, "Шлюз НРД", s.NSD.IGWBaseURL != "" && s.NSD.Profile != ""},
|
||||
)
|
||||
return steps
|
||||
}
|
||||
@@ -7,9 +7,10 @@
|
||||
<span class="hero-status ok">● Система готова к работе</span>
|
||||
{{else}}
|
||||
<div style="display:flex;align-items:center;gap:14px;flex-wrap:wrap">
|
||||
<span class="hero-status warn">● Требуется настройка — {{.NotReadyCount}} из {{.TotalCount}} компонентов</span>
|
||||
<span class="hero-status warn">● Требуется настройка — не выполнено {{.NotReadyCount}} из {{.TotalCount}} шагов</span>
|
||||
<a href="/admin/wizard" class="btn">Открыть мастер настройки →</a>
|
||||
</div>
|
||||
<p class="muted" style="margin:8px 0 0;font-size:13px">Осталось: {{range $i, $s := .NotReady}}{{if $i}}, {{end}}<a href="/admin/wizard?step={{$s.Step}}">{{$s.Title}}</a>{{end}}</p>
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user