Мастер настройки — 4 главы (Сервер, Учёт и организация, НРД, Запуск) вместо 10 шагов: в пути только нужное этой установке — без лицензии учёта DEPO, QUIK и модулей их шагов нет, сделанное установщиком (база, Валидата) показано строкой; общая навигация «Назад/Далее»; раздел «Время и сеть» с часовым поясом; модули по лицензии (кабинет, ЕСИА Финанс, экспорт QUIK, НПР) с переходом в раздел и возвратом в мастер; «Проверить всю цепочку» (DEPO, QUIK, пробная блокировка по желанию, подпись, НРД); готовые письма в НРД, ARQA и администратору DEPO; ИШ с образа без интернета
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014FsEKyJrYF69Cj9ZXzFLRi
This commit is contained in:
+46
-35
@@ -179,6 +179,15 @@ type WizardData struct {
|
||||
AutoDone []string // шаги до текущего, уже выполненные без участия пользователя, — с пояснением
|
||||
Certs []cryptocli.Certificate
|
||||
Flash string
|
||||
// главы мастера (wizchapters.go): путь этой установки, соседние шаги, шапка
|
||||
Path []int
|
||||
Chapters []WizChapter
|
||||
Prev, Next int
|
||||
StepDone bool
|
||||
StepRequired bool
|
||||
StepTitle string
|
||||
ChapterTitle string
|
||||
Modules []WizModule // глава «Запуск»: модули по лицензии
|
||||
Done struct {
|
||||
License bool
|
||||
Depo bool
|
||||
@@ -190,6 +199,8 @@ type WizardData struct {
|
||||
NSD bool
|
||||
TestRun bool
|
||||
Alerts bool // оповещения настроены и резервные копии включены
|
||||
Modules bool // модули по лицензии настроены
|
||||
Server bool // время сервера синхронизируется
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,23 +258,43 @@ func (h *setupHandlers) renderWizard(w http.ResponseWriter, r *http.Request) {
|
||||
d.Done.NSD = doneNSD(s)
|
||||
d.Done.TestRun = s.LastTest != nil || (!d.DevMode && readinessDone()) // вне режима разработки — итоговая проверка готовности пройдена
|
||||
|
||||
// Мастер идёт по порядку: каждый шаг показывается, даже если он уже выполнен (установщиком,
|
||||
// лицензией) — на нём написано, что сделано, и пользователь сам нажимает «Далее». Без ?step
|
||||
// продолжаем со следующего за последним пройденным шагом.
|
||||
progress := wizardProgress()
|
||||
step := progress + 1
|
||||
d.Done.Org = doneOrg(s)
|
||||
d.Done.Alerts = doneAlerts(s)
|
||||
d.Done.Quik = !d.DepoLicensed || doneQuik(s)
|
||||
d.Modules = wizModuleViews(h.rc, s)
|
||||
d.Done.Server, _ = timeStatus(r.Context())
|
||||
d.Done.Modules = true
|
||||
for _, m := range d.Modules {
|
||||
if !m.Ready {
|
||||
d.Done.Modules = false
|
||||
}
|
||||
}
|
||||
// Главы (wizchapters.go): в пути только шаги, нужные этой установке — по лицензии и без сделанного
|
||||
// установщиком. Без ?step — первый несделанный обязательный шаг, а если всё сделано — проверка.
|
||||
done := map[int]bool{1: d.Done.License, 2: d.Done.Postgres, 3: d.Done.Depo, 4: d.Done.Org, 5: d.Done.Quik, 6: d.Done.Crypto,
|
||||
7: d.Done.NSD, 8: d.Done.Certs, 9: d.Done.Alerts, 10: d.Done.TestRun, 11: d.Done.Modules, 12: d.Done.Server}
|
||||
path, _ := wizPath(h.rc, done, 0)
|
||||
step := wizDefaultStep(path, done)
|
||||
if v := r.URL.Query().Get("step"); v != "" {
|
||||
if n, err := strconv.Atoi(v); err == nil && n >= 1 && n <= wizardSteps {
|
||||
step = n
|
||||
if n-1 > progress {
|
||||
setWizardProgress(n - 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
if step > wizardSteps {
|
||||
step = wizardSteps
|
||||
}
|
||||
d.Step = step
|
||||
d.Path, d.Chapters = wizPath(h.rc, done, step)
|
||||
d.Prev, d.Next = wizNeighbours(d.Path, step)
|
||||
d.StepDone, d.StepRequired, d.StepTitle = done[step], wizRequired[step], wizStepTitles[step]
|
||||
for _, c := range d.Chapters {
|
||||
if c.Current {
|
||||
d.ChapterTitle = c.Title
|
||||
}
|
||||
}
|
||||
if done[2] {
|
||||
d.AutoDone = append(d.AutoDone, "База bj создана установщиком"+pickStr(" — "+d.PGSummary, ""))
|
||||
}
|
||||
if done[6] {
|
||||
d.AutoDone = append(d.AutoDone, "СКЗИ «Валидата Клиент L» "+d.ValidataVer+" установлена вместе с bj")
|
||||
}
|
||||
if step == 4 && strings.TrimSpace(s.Fancy.Server) != "" && !doneOrg(s) && depoDetectResult() == nil {
|
||||
// организация ещё не задана, а база DEPO подключена — определяем реквизиты сами: карточка
|
||||
// покажет их заполненными, пользователю остаётся проверить и сохранить
|
||||
@@ -278,7 +309,7 @@ func (h *setupHandlers) renderWizard(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
cancel()
|
||||
}
|
||||
if (step >= 3 && step <= 5) || step == 9 { // DEPO, организация, QUIK МНП, оповещения и копии — общие блоки из «Настройки»
|
||||
if (step >= 3 && step <= 5) || step == 9 || step == 11 { // DEPO, организация, QUIK МНП, оповещения и копии, модули — общие блоки из «Настройки»
|
||||
fd := h.setupData(w, r, "")
|
||||
d.Fancy = &fd
|
||||
}
|
||||
@@ -288,9 +319,6 @@ func (h *setupHandlers) renderWizard(w http.ResponseWriter, r *http.Request) {
|
||||
d.Sub = "done"
|
||||
}
|
||||
}
|
||||
d.Done.Org = doneOrg(s)
|
||||
d.Done.Alerts = doneAlerts(s)
|
||||
d.Done.Quik = !d.DepoLicensed || doneQuik(s)
|
||||
if step == 3 && d.DepoLicensed && strings.TrimSpace(s.Fancy.Server) != "" {
|
||||
// Есть ли у сервера SQL Agent: у Express его нет, у PostgreSQL — тоже; тогда обработку
|
||||
// запускает сам bj. Иначе по умолчанию джобу SQL Agent создаёт bj.
|
||||
@@ -334,26 +362,7 @@ func depoServerEdition(ctx context.Context, f FancyMSSQLSettings) (string, bool)
|
||||
// wizardSteps — шагов в мастере: 1 лицензия, 2 база bj, 3 учёт DEPO, 4 наша организация, 5 QUIK МНП,
|
||||
// 6 Валидата, 7 шлюз НРД, 8 ключ и сертификаты (ключ ставится в профиль ИШ — после шлюза),
|
||||
// 9 оповещения и резервные копии, 10 проверка готовности.
|
||||
const wizardSteps = 10
|
||||
|
||||
// wizardProgressFile — номер последнего пройденного шага мастера (переход «Далее» на шаг N
|
||||
// означает, что шаги до N пройдены).
|
||||
const wizardProgressFile = "/var/lib/bj/.bj/wizard-progress"
|
||||
|
||||
func wizardProgress() int {
|
||||
b, err := os.ReadFile(wizardProgressFile)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
n, _ := strconv.Atoi(strings.TrimSpace(string(b)))
|
||||
return n
|
||||
}
|
||||
|
||||
func setWizardProgress(n int) {
|
||||
if err := os.WriteFile(wizardProgressFile, []byte(strconv.Itoa(n)+"\n"), 0o600); err != nil {
|
||||
log.Printf("wizard: прогресс мастера не сохранён: %v", err)
|
||||
}
|
||||
}
|
||||
const wizardSteps = 12 // 11 — модули по лицензии (глава «Запуск»), 12 — время и сеть (глава «Сервер»)
|
||||
|
||||
// dsnSummary — «host:port, база name» из строки подключения PostgreSQL, без логина и пароля.
|
||||
func dsnSummary(dsn string) string {
|
||||
@@ -448,6 +457,7 @@ func (h *setupHandlers) testSignCrypto(w http.ResponseWriter, r *http.Request) {
|
||||
// SetupData — данные для шаблона admin_setup.html.
|
||||
type SetupData struct {
|
||||
page
|
||||
FromWizard bool // раздел открыт из мастера (настройка модуля) — показать «Вернуться в мастер»
|
||||
Settings Settings
|
||||
Suggest *DepoRequisites // предложение реквизитов из DEPO
|
||||
Readiness []Readiness
|
||||
@@ -537,6 +547,7 @@ func (h *setupHandlers) setupData(w http.ResponseWriter, req *http.Request, flas
|
||||
License: licenseStatus(h.rc),
|
||||
Health: HealthSnapshot(),
|
||||
AdvancedUnlocked: advancedUnlocked(req),
|
||||
FromWizard: req.URL.Query().Get("from") == "wizard",
|
||||
NSDCerts: nsdCertsView(s),
|
||||
Participants: handbookParticipants(),
|
||||
OrgINN: orgINN(s),
|
||||
|
||||
Reference in New Issue
Block a user