Мастер настройки — 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:
@@ -7,6 +7,7 @@ package lkgateway
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -59,3 +60,71 @@ func asString(v any) string {
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// wizTimeZones — часовые пояса России для выбора (время НРД — московское).
|
||||
var wizTimeZones = []struct{ Zone, Title string }{
|
||||
{"Europe/Kaliningrad", "Калининград (UTC+2)"},
|
||||
{"Europe/Moscow", "Москва (UTC+3)"},
|
||||
{"Europe/Samara", "Самара (UTC+4)"},
|
||||
{"Asia/Yekaterinburg", "Екатеринбург (UTC+5)"},
|
||||
{"Asia/Omsk", "Омск (UTC+6)"},
|
||||
{"Asia/Novosibirsk", "Новосибирск (UTC+7)"},
|
||||
{"Asia/Krasnoyarsk", "Красноярск (UTC+7)"},
|
||||
{"Asia/Irkutsk", "Иркутск (UTC+8)"},
|
||||
{"Asia/Yakutsk", "Якутск (UTC+9)"},
|
||||
{"Asia/Vladivostok", "Владивосток (UTC+10)"},
|
||||
{"Asia/Magadan", "Магадан (UTC+11)"},
|
||||
{"Asia/Kamchatka", "Камчатка (UTC+12)"},
|
||||
}
|
||||
|
||||
// serverTimeZone — часовой пояс сервера (timedatectl; запасной — /etc/timezone).
|
||||
func serverTimeZone() string {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
if out, err := exec.CommandContext(ctx, "timedatectl", "show", "-p", "Timezone", "--value").Output(); err == nil {
|
||||
if z := strings.TrimSpace(string(out)); z != "" {
|
||||
return z
|
||||
}
|
||||
}
|
||||
if b, err := os.ReadFile("/etc/timezone"); err == nil {
|
||||
return strings.TrimSpace(string(b))
|
||||
}
|
||||
return time.Local.String()
|
||||
}
|
||||
|
||||
func registerTimeZone(mux *http.ServeMux) {
|
||||
mux.HandleFunc("/admin/setup/timezone", func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "method", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
zone := strings.TrimSpace(r.FormValue("zone"))
|
||||
known := false
|
||||
for _, z := range wizTimeZones {
|
||||
if z.Zone == zone {
|
||||
known = true
|
||||
}
|
||||
}
|
||||
if !known {
|
||||
setupFlash(w, r, "Часовой пояс: выберите из списка")
|
||||
return
|
||||
}
|
||||
if zone == serverTimeZone() {
|
||||
setupFlash(w, r, "Часовой пояс уже "+zone)
|
||||
return
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(r.Context(), time.Minute)
|
||||
defer cancel()
|
||||
res, err := runKeymediaOp(ctx, "system-tz", map[string]string{"extra": zone})
|
||||
if err != nil || res["ok"] != true {
|
||||
setupFlash(w, r, "Часовой пояс не изменён: "+pickStr(asString(res["error"]), errStr(err)))
|
||||
return
|
||||
}
|
||||
// время процесса bj берётся при запуске — перезапускаем, чтобы журналы и сроки шли по новому поясу
|
||||
go func() {
|
||||
time.Sleep(2 * time.Second)
|
||||
_, _ = restartUnit(context.Background(), "bj-server")
|
||||
}()
|
||||
setupFlash(w, r, asString(res["output"])+". bj перезапускается — обновите страницу через 15 секунд. Шлюз НРД перейдёт на новый пояс при своём следующем перезапуске.")
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user