eef6c9d996
- «Подготовить» в мастере (step 3, режим «дать логин администратора») теперь ставит и процедуры обработки bj2depo (CREATE OR ALTER) + GRANT, не только логин/таблицы/джобу. - Скачиваемый скрипт мастера включает процедуры. - Тексты процедур редактируются под клиента (Настройка → Обмен DEPO → Процедуры): сохранённый вариант используется при установке и при «Подготовить». Пусто/совпадение со встроенным — исходная версия. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q7eREaYwUt1i4fNLZcGnjn
251 lines
34 KiB
HTML
251 lines
34 KiB
HTML
{{/* Раздел «Обмен Fancy» — один и тот же в «Настройка → Обмен Fancy» и на шаге 3 мастера
|
||
настройки (данные — SetupData). Правки — только здесь. */}}
|
||
{{define "fancySection"}}
|
||
<div class="card" id="sec-fancy-conn">
|
||
<h2><span class="dot {{if .Settings.Fancy.DepoTablesCheckOK}}ok{{else if .Settings.Fancy.Server}}warn{{else}}err{{end}}"></span>Подключение к серверу БД клиента</h2>
|
||
<p class="muted">Сервер учётной базы Fancy DEPO: картотека лиц, счета и договоры, остатки, опции (признак квалифицированного инвестора), трансферные таблицы обмена. Поддерживаются <strong>Microsoft SQL Server</strong> и <strong>PostgreSQL</strong>. База указывается ниже, в карточке «Трансферные таблицы DEPO».</p>
|
||
<form method="post" action="/admin/setup/fancy" style="margin-top:12px;display:grid;gap:10px;max-width:560px">
|
||
<label>Тип СУБД
|
||
<select name="db_type" id="fancy-dbtype" style="width:100%" onchange="var p=document.getElementById('fancy-port');if(!p.value||p.value=='1433'||p.value=='5432'){p.value=this.value=='postgres'?'5432':'1433';}">
|
||
<option value="mssql" {{if not .Settings.Fancy.IsPostgres}}selected{{end}}>Microsoft SQL Server</option>
|
||
<option value="postgres" {{if .Settings.Fancy.IsPostgres}}selected{{end}}>PostgreSQL</option>
|
||
</select></label>
|
||
<label>Сервер (host или host\instance)
|
||
<input type="text" name="server" value="{{.Settings.Fancy.Server}}" placeholder="10.10.10.x" style="width:100%" required></label>
|
||
<label>Порт
|
||
<input type="number" id="fancy-port" name="port" value="{{if .Settings.Fancy.Port}}{{.Settings.Fancy.Port}}{{else}}{{.Settings.Fancy.DefaultPort}}{{end}}" style="width:100%"></label>
|
||
<label>Пользователь (логин БД)
|
||
<input type="text" name="user" value="{{.Settings.Fancy.User}}" placeholder="bj_user" style="width:100%" required></label>
|
||
<label>Пароль
|
||
<input type="password" name="password" placeholder="{{if .Settings.Fancy.Password}}•••••• — оставьте пустым, чтобы не менять{{else}}пароль SQL-логина{{end}}" autocomplete="off" style="width:100%"></label>
|
||
<label>Шифрование канала
|
||
<select name="encrypt" style="width:100%">
|
||
<option value="disable" {{if eq .Settings.Fancy.Encrypt "disable"}}selected{{end}}>disable — без TLS (типично для LAN)</option>
|
||
<option value="true" {{if eq .Settings.Fancy.Encrypt "true"}}selected{{end}}>true — с TLS</option>
|
||
</select></label>
|
||
<div style="display:flex;gap:8px;flex-wrap:wrap"><button type="submit" class="btn btn-ok">Сохранить</button><button type="submit" formaction="/admin/setup/fancy/test" class="btn">Проверить соединение</button></div>
|
||
</form>
|
||
{{if .Settings.Fancy.Server}}{{template "accPrefix" .}}{{end}}
|
||
</div>
|
||
|
||
<div class="card" id="sec-fancy-depo-tables">
|
||
<h2><span class="dot {{if .Settings.Fancy.DepoTablesCheckOK}}ok{{else if .Settings.Fancy.Server}}warn{{else}}err{{end}}"></span>Трансферные таблицы DEPO</h2>
|
||
<p class="muted">Через эти таблицы bj обменивается с учётной системой DEPO: поручения <code>FTV_M2M</code> и их строки <code>FTV_M2M_LINES</code>, события <code>FTV_M2M_EVENTS</code>, справочник участников НРД <code>FTV_M2M_HANDBOOK</code>. Таблицы создаются в базе DEPO на сервере из подключения выше ({{if .DepoTables.Postgres}}PostgreSQL{{else}}Microsoft SQL Server{{end}}). Создание можно повторять: добавляются только недостающие таблицы, колонки и индексы, данные не меняются.</p>
|
||
<form method="post" action="/admin/setup/fancy/depo-tables" style="margin-top:10px;display:grid;gap:10px;max-width:720px">
|
||
<input type="hidden" name="section" value="sec-fancy-depo-tables">
|
||
<label>База DEPO
|
||
<input type="text" name="depo_database" value="{{.Settings.Fancy.DepoDatabase}}" placeholder="{{.DepoTables.DB}}" pattern="[A-Za-z][A-Za-z0-9_]*" style="width:100%"></label>
|
||
<label>Признак ИИС в названии брокерского договора <span class="muted" style="font-weight:400">(с чего начинается номер договора ИИС в DEPO; несколько — через запятую)</span>
|
||
<input type="text" name="iis_contract_marker" value="{{.Settings.Fancy.IISContractMarker}}" placeholder="БРИИС" style="width:100%"></label>
|
||
<label style="display:flex;gap:8px;align-items:flex-start;font-weight:600"><input type="radio" name="depo_tables_mode" value="auto" {{if eq .Settings.Fancy.DepoTablesMode "auto"}}checked{{end}}> <span>Создаёт bj <span class="muted" style="font-weight:400">— вводите логин с правами на создание таблиц в базе DEPO. Он используется один раз и не сохраняется; bj заодно выдаст права своему логину.</span></span></label>
|
||
<label style="display:flex;gap:8px;align-items:flex-start;font-weight:600"><input type="radio" name="depo_tables_mode" value="script" {{if eq .Settings.Fancy.DepoTablesMode "script"}}checked{{end}}> <span>Создаёт администратор СУБД по скрипту <span class="muted" style="font-weight:400">— скачайте скрипт и передайте администратору, после выполнения нажмите «Проверить таблицы».</span></span></label>
|
||
<div><button type="submit" class="btn">Сохранить</button></div>
|
||
</form>
|
||
|
||
{{if eq .Settings.Fancy.DepoTablesMode "auto"}}
|
||
<form method="post" action="/admin/setup/fancy/depo-tables/create" style="margin-top:12px;display:grid;gap:10px;max-width:720px">
|
||
<input type="hidden" name="section" value="sec-fancy-depo-tables">
|
||
<div><b>Логин с правами на базу {{.DepoTables.DB}}</b><br>
|
||
<span class="muted" style="font-size:12px">{{if .DepoTables.Postgres}}Владелец базы или суперпользователь.{{else}}Роль db_owner в базе (или db_ddladmin + db_securityadmin).{{end}} Если оставить поля пустыми, bj попробует своим логином {{.DepoTables.User}}.</span></div>
|
||
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:10px">
|
||
<label>Логин <input type="text" name="admin_user" autocomplete="off" placeholder="{{if .DepoTables.Postgres}}postgres{{else}}sa{{end}}" style="width:100%"></label>
|
||
<label>Пароль <input type="password" name="admin_password" autocomplete="new-password" style="width:100%"></label>
|
||
</div>
|
||
<div><button type="submit" class="btn btn-ok" onclick="return confirm('Создать трансферные таблицы в базе {{.DepoTables.DB}}?')">⚙ Создать таблицы</button></div>
|
||
</form>
|
||
{{else if eq .Settings.Fancy.DepoTablesMode "script"}}
|
||
<div style="margin-top:12px"><b>Скрипт для администратора СУБД</b> — <a href="/admin/setup/fancy/depo-tables/script.sql">скачать {{.DepoTables.ScriptFile}}</a>
|
||
<pre class="copyable" style="max-height:360px;overflow:auto">{{.DepoTables.Script}}</pre></div>
|
||
{{end}}
|
||
|
||
<div style="display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-top:12px">
|
||
<form method="post" action="/admin/setup/fancy/depo-tables/check" style="margin:0"><input type="hidden" name="section" value="sec-fancy-depo-tables"><button type="submit" class="btn btn-ok">✓ Проверить таблицы</button></form>
|
||
<span class="muted" style="font-size:12px">логином bj: таблицы на месте, колонки совпадают, есть права на чтение и запись</span>
|
||
</div>
|
||
{{if .Settings.Fancy.DepoTablesCheck}}<p style="margin-top:10px;font-size:13px;{{if .Settings.Fancy.DepoTablesCheckOK}}color:var(--ok){{else}}color:var(--err){{end}}">{{if .Settings.Fancy.DepoTablesCheckOK}}✓{{else}}✗{{end}} {{.Settings.Fancy.DepoTablesCheck}} <span class="muted">({{.Settings.Fancy.DepoTablesCheckAt.Format "02.01.2006 15:04"}})</span></p>{{end}}
|
||
</div>
|
||
|
||
<div class="card" id="sec-fancy-depo-job">
|
||
<h2><span class="dot {{if .Settings.Fancy.DepoJobCheckOK}}ok{{else if .Settings.Fancy.DepoJobMode}}warn{{else}}err{{end}}"></span>Где запускается обработка трансферных таблиц DEPO</h2>
|
||
<p class="muted">Поручения и события, которые bj пишет в <code>FTV_M2M*</code>, обрабатывает процедура <code>{{.DepoJob.Proc}}</code> в базе DEPO. Выберите, кто её запускает, выполните инструкцию и нажмите «Проверить готовность» — без зелёной отметки обмен с DEPO работать не будет.</p>
|
||
<form method="post" action="/admin/setup/fancy/depo-job" style="margin-top:10px;display:grid;gap:10px;max-width:720px">
|
||
<input type="hidden" name="section" value="sec-fancy-depo-job">
|
||
<label style="display:flex;gap:8px;align-items:flex-start;font-weight:600"><input type="radio" name="depo_job_mode" value="bj" {{if eq .Settings.Fancy.DepoJobMode "bj"}}checked{{end}}> <span>Внутри bj <span class="muted" style="font-weight:400">— bj сам вызывает процедуру по расписанию. На сервере клиента нужно одно право на процедуру. Для SQL Server Express (там нет SQL Agent) и PostgreSQL.</span></span></label>
|
||
<label style="display:flex;gap:8px;align-items:flex-start;font-weight:600"><input type="radio" name="depo_job_mode" value="sql-auto" {{if or (eq .Settings.Fancy.DepoJobMode "sql-auto") (not .Settings.Fancy.DepoJobMode)}}checked{{end}}> <span>Джоба SQL Agent, создаёт bj <span class="muted" style="font-weight:400">— рекомендуется: работает независимо от bj. bj создаёт джобу кнопкой — логином администратора SQL (вводится один раз и не сохраняется) или своим логином, если ему выдана роль оператора SQL Agent.</span></span></label>
|
||
<label style="display:flex;gap:8px;align-items:flex-start;font-weight:600"><input type="radio" name="depo_job_mode" value="sql-manual" {{if eq .Settings.Fancy.DepoJobMode "sql-manual"}}checked{{end}}> <span>Джоба SQL Agent, настраивает администратор <span class="muted" style="font-weight:400">— передаёте скрипт, bj проверяет, что джоба работает.</span></span></label>
|
||
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:10px">
|
||
<label>Интервал, секунд <input type="number" name="depo_job_every_sec" min="5" max="3600" value="{{.DepoJob.Every}}" style="width:100%"></label>
|
||
<label>Процедура <input type="text" name="depo_job_proc" value="{{.Settings.Fancy.DepoJobProc}}" placeholder="dbo.FTV_M2M_JOB" style="width:100%"></label>
|
||
<label>Работает от имени <input type="text" name="depo_job_run_as" value="{{.Settings.Fancy.DepoJobRunAs}}" placeholder="SYSDBA" style="width:100%"></label>
|
||
</div>
|
||
<p class="muted" style="font-size:12px;margin:0">Процедура обработки выполняется от имени пользователя базы DEPO (у разработчика Fancy это <code>SYSDBA</code>). У клиента такого пользователя может не быть или он называется иначе: «Проверить готовность» проверит, что он есть в базе.</p>
|
||
<div><button type="submit" class="btn">Сохранить способ</button></div>
|
||
</form>
|
||
|
||
{{if eq .Settings.Fancy.DepoJobMode "bj"}}
|
||
<div style="margin-top:12px"><b>Инструкция для администратора SQL клиента</b> — выполнить один раз:
|
||
<pre class="copyable">{{.DepoJob.GrantScript}}</pre></div>
|
||
{{else if eq .Settings.Fancy.DepoJobMode "sql-auto"}}
|
||
<form method="post" action="/admin/setup/fancy/depo-job/create" style="margin-top:12px;display:grid;gap:8px;max-width:720px">
|
||
<input type="hidden" name="section" value="sec-fancy-depo-job">
|
||
<div><b>Создать джобу {{.DepoJob.Name}}</b> <span class="muted" style="font-size:12px">— SQL Server Agent должен быть запущен. Логин администратора SQL (sysadmin, например sa) используется один раз и не сохраняется; пусто — bj попробует своим логином.</span></div>
|
||
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:10px">
|
||
<label>Логин <input type="text" name="admin_user" autocomplete="off" placeholder="sa" style="width:100%"></label>
|
||
<label>Пароль <input type="password" name="admin_password" autocomplete="new-password" style="width:100%"></label>
|
||
</div>
|
||
<div><button type="submit" class="btn btn-ok" onclick="return confirm('Создать джобу SQL Agent {{.DepoJob.Name}} на сервере клиента?')">⚙ Создать джобу и проверить</button></div>
|
||
</form>
|
||
<details style="margin-top:8px"><summary class="muted" style="cursor:pointer;font-size:12px">Без логина администратора: выдать логину bj роль оператора SQL Agent (скрипт)</summary>
|
||
<pre class="copyable">{{.DepoJob.AgentRights}}</pre></details>
|
||
{{else if eq .Settings.Fancy.DepoJobMode "sql-manual"}}
|
||
<div style="margin-top:12px"><b>Инструкция для администратора SQL клиента</b> — создать джобу (SQL Agent должен быть запущен, служебная учётная запись Agent должна иметь право выполнять процедуру):
|
||
<a href="/admin/setup/fancy/depo-job/script.sql">Скачать скрипт bj-depo-job-mssql.sql</a>
|
||
<pre class="copyable">{{.DepoJob.AdminScript}}</pre></div>
|
||
{{end}}
|
||
|
||
{{if .Settings.Fancy.DepoJobMode}}
|
||
<div style="display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-top:12px">
|
||
<form method="post" action="/admin/setup/fancy/depo-job/check" style="margin:0"><input type="hidden" name="section" value="sec-fancy-depo-job"><button type="submit" class="btn btn-ok">✓ Проверить готовность</button></form>
|
||
<span class="muted" style="font-size:12px">для вариантов с джобой bj пишет служебное событие BJ_PING и ждёт до 40 с, пока обработчик его отметит</span>
|
||
</div>
|
||
{{if .Settings.Fancy.DepoJobCheck}}<p style="margin-top:10px;font-size:13px;{{if .Settings.Fancy.DepoJobCheckOK}}color:var(--ok){{else}}color:var(--err){{end}}">{{if .Settings.Fancy.DepoJobCheckOK}}✓{{else}}✗{{end}} {{.Settings.Fancy.DepoJobCheck}} <span class="muted">({{.Settings.Fancy.DepoJobCheckAt.Format "02.01.2006 15:04"}})</span></p>{{end}}
|
||
{{if .Settings.Fancy.DepoProcCheck}}<p style="margin-top:4px;font-size:13px;{{if .Settings.Fancy.DepoProcCheckOK}}color:var(--ok){{else}}color:var(--warn){{end}}">Обработка событий (процедуры): {{if .Settings.Fancy.DepoProcCheckOK}}✓{{else}}⚠{{end}} {{.Settings.Fancy.DepoProcCheck}}</p>{{end}}
|
||
{{if and (eq .Settings.Fancy.DepoJobMode "bj") .Settings.Fancy.DepoJobLast}}<p class="muted" style="font-size:12px;margin-top:6px">Последний вызов процедуры — {{.Settings.Fancy.DepoJobLast}}</p>{{end}}
|
||
{{end}}
|
||
</div>
|
||
|
||
<div class="card" id="sec-fancy-depo-procs">
|
||
<h2><span class="dot {{if .Settings.Fancy.DepoProcCheckOK}}ok{{else}}warn{{end}}"></span>Процедуры обработки bj2depo</h2>
|
||
<p class="muted">Процедуры <code>FTV_M2M_PROCESS_*</code> и <code>FTV_M2M_JOB</code> встроены в bj. Сначала «Проверить возможности» (ничего не меняет), затем «Установить» — bj выполнит их в базе DEPO в порядке WIRING→OPERATION→EVENTS→CREATE→JOB и выдаст логину bj право запуска.</p>
|
||
<form method="post" style="display:grid;gap:10px;max-width:720px">
|
||
<input type="hidden" name="section" value="sec-fancy-depo-procs">
|
||
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:10px">
|
||
<label>Логин администратора SQL <input type="text" name="admin_user" autocomplete="off" placeholder="sa" style="width:100%"></label>
|
||
<label>Пароль <input type="password" name="admin_password" autocomplete="new-password" style="width:100%"></label>
|
||
</div>
|
||
<p class="muted" style="font-size:12px;margin:0">Логин sysadmin (например sa) вводится один раз и не сохраняется. Пусто — bj попробует своим логином (прав на создание процедур у него обычно нет).</p>
|
||
<div style="display:flex;gap:10px;flex-wrap:wrap">
|
||
<button type="submit" class="btn" formaction="/admin/setup/fancy/depo-procs/check">Проверить возможности</button>
|
||
<button type="submit" class="btn btn-ok" formaction="/admin/setup/fancy/depo-procs/install" onclick="return confirm('Установить процедуры обработки в базу DEPO {{.Settings.Fancy.DepoDB}}?')">⚙ Установить процедуры</button>
|
||
</div>
|
||
</form>
|
||
<p style="margin-top:8px"><a href="/admin/setup/fancy/depo-procs/script.sql">Скачать скрипт bj-depo-procs-mssql.sql</a> <span class="muted" style="font-size:12px">— для ручной установки администратором в SSMS</span></p>
|
||
<details style="margin-top:10px"><summary class="muted" style="cursor:pointer">Тексты процедур — изменить под клиента</summary>
|
||
<form method="post" action="/admin/setup/fancy/depo-procs/save-text" style="display:grid;gap:10px;margin-top:10px">
|
||
<input type="hidden" name="section" value="sec-fancy-depo-procs">
|
||
{{range depoProcList}}<label style="font-weight:600;font-size:13px">{{.Name}}<textarea name="proc_{{.Name}}" rows="10" spellcheck="false" style="width:100%;font-family:ui-monospace,monospace;font-size:11.5px">{{depoProcText $.Settings.Fancy .Name}}</textarea></label>{{end}}
|
||
<div><button type="submit" class="btn">Сохранить тексты</button> <span class="muted" style="font-size:12px">пустое поле или совпадение со встроенным — вернуть исходную версию; изменённые ставятся при «Установить» и при «Подготовить» в мастере</span></div>
|
||
</form></details>
|
||
{{if .Settings.Fancy.DepoProcCheck}}<p style="margin-top:6px;font-size:13px;{{if .Settings.Fancy.DepoProcCheckOK}}color:var(--ok){{else}}color:var(--warn){{end}}">{{if .Settings.Fancy.DepoProcCheckOK}}✓{{else}}⚠{{end}} {{.Settings.Fancy.DepoProcCheck}}</p>{{end}}
|
||
</div>
|
||
{{end}}
|
||
|
||
{{define "verline"}}{{if .Title}}<p class="muted" style="font-size:12.5px;margin:-6px 0 12px">{{.Title}}: {{if .Version}}<strong>{{.Version}}</strong>{{else}}не определена{{end}}{{with .Detail}} · {{.}}{{end}}{{with .Err}} · <span style="color:var(--err)">{{.}}</span>{{end}}</p>{{end}}{{end}}
|
||
|
||
{{/* Сводка «Обмен с DEPO» (Настройка): что подключено и проверено — одним взглядом; формы — под «Перенастроить». */}}
|
||
{{define "fancyStatus"}}{{$f := .Settings.Fancy}}{{$ok := and $f.Server $f.DepoTablesCheckOK $f.DepoJobCheckOK}}
|
||
<div class="card" id="sec-fancy-status">
|
||
<div class="stc {{if $ok}}stc-ok{{else if $f.Server}}stc-err{{else}}stc-warn{{end}}"><span class="stc-ic"></span>
|
||
<div class="stc-b"><b>{{if $ok}}Обмен с DEPO работает{{else if $f.Server}}Обмен с DEPO настроен не до конца{{else}}Учёт DEPO не подключён{{end}}</b>
|
||
<small>{{if $ok}}Подключение, трансферные таблицы и обработка проверены — менять ничего не нужно. Если что-то изменилось на сервере DEPO — «Перенастроить» ниже.{{else if $f.Server}}Что не так — в строках ниже с ✗; поправить — в «Перенастроить».{{else}}Подключите базу DEPO — мастером настройки (шаг «Учёт DEPO») или в «Перенастроить».{{end}}</small></div>
|
||
{{if not $f.Server}}<a class="btn" href="/admin/wizard?step=3" style="flex:none">Открыть мастер</a>{{end}}</div>
|
||
{{if $f.Server}}
|
||
<dl class="kv">
|
||
<dt>База DEPO</dt><dd><b>{{$f.DepoDB}}</b> на {{$f.Server}}{{if $f.Port}}:{{$f.Port}}{{end}} · {{if eq $f.DBType "postgres"}}PostgreSQL{{else}}Microsoft SQL Server{{end}}</dd>
|
||
<dt>Логин bj</dt><dd><code>{{$f.User}}</code></dd>
|
||
<dt>Торговые счета клиентов</dt><dd>номер начинается с <code>{{depoAccPrefix}}</code></dd>
|
||
<dt>Признак ИИС</dt><dd>договор начинается с <code>{{if $f.IISContractMarker}}{{$f.IISContractMarker}}{{else}}БРИИС{{end}}</code> — такие переводы отклоняются кодом M2M06</dd>
|
||
<dt>Трансферные таблицы</dt><dd>{{if $f.DepoTablesCheckOK}}<span class="kv-ok">✓</span>{{else}}<span class="kv-no">✗</span>{{end}} {{if $f.DepoTablesCheck}}{{$f.DepoTablesCheck}}{{else}}ещё не проверялись{{end}}{{if not $f.DepoTablesCheckAt.IsZero}} <span class="muted">· {{msk $f.DepoTablesCheckAt}}</span>{{end}}</dd>
|
||
<dt>Обработка событий</dt><dd>{{if $f.DepoJobCheckOK}}<span class="kv-ok">✓</span>{{else}}<span class="kv-no">✗</span>{{end}} {{if eq $f.DepoJobMode "bj"}}запускает bj{{if $f.DepoJobEverySec}} каждые {{$f.DepoJobEverySec}} с{{end}}{{else if eq $f.DepoJobMode "sql-auto"}}задание SQL Server Agent <code>{{depoJobNameOf $f}}</code>{{else if eq $f.DepoJobMode "sql-manual"}}задание SQL Server Agent (создано администратором){{else}}не выбрано, кто запускает{{end}}{{if $f.DepoJobCheck}}<div class="muted" style="font-size:12.5px;margin-top:2px">{{$f.DepoJobCheck}}{{if not $f.DepoJobCheckAt.IsZero}} · {{msk $f.DepoJobCheckAt}}{{end}}</div>{{end}}</dd>
|
||
{{if $f.DepoProcCheck}}<dt>Процедуры обработки</dt><dd>{{if $f.DepoProcCheckOK}}<span class="kv-ok">✓</span>{{else}}<span class="kv-warn">⚠</span>{{end}} {{$f.DepoProcCheck}}{{if not $f.DepoProcCheckAt.IsZero}} <span class="muted">· {{msk $f.DepoProcCheckAt}}</span>{{end}}</dd>{{end}}
|
||
</dl>
|
||
{{end}}
|
||
</div>
|
||
{{end}}
|
||
|
||
{{/* Секция «Обновления»: общий блок для страницы настроек и шага 14 мастера. */}}
|
||
{{define "updateSection"}}
|
||
{{if .InWizard}}<div id="sec-update">{{else}}<section class="settings-section" id="sec-update">{{end}}
|
||
{{if not .InWizard}}<h1>Обновления</h1>{{end}}
|
||
{{template "verline" (.Versions.Get "bj-server")}}
|
||
|
||
<div class="card" id="upd-status" data-last="{{if not .Settings.Update.LastCheck.IsZero}}{{.Settings.Update.LastCheck.Unix}}{{else}}0{{end}}" data-has="{{if .UpdatesAvailable}}1{{else}}0{{end}}">
|
||
{{if .UpdatesAvailable}}
|
||
<div class="stc stc-warn"><span class="stc-ic"></span><div class="stc-b"><b>Доступно обновление{{with .Settings.Update.Available}} {{.}}{{end}}</b><small>{{if .Settings.Update.Notes}}{{.Settings.Update.Notes}}{{else}}новые версии компонентов — список ниже, в «Компоненты и версии»{{end}}</small></div>
|
||
<form method="post" action="/admin/setup/update/apply" style="margin:0" onsubmit="return confirm('Установить обновление? Службы, которые обновляются, перезапустятся на несколько секунд.');"><input type="hidden" name="section" value="sec-update"><button type="submit" class="btn">Установить обновление</button></form></div>
|
||
{{else if and (not .Settings.Update.LastCheck.IsZero) .UpdateFailed}}
|
||
<div class="stc stc-err"><span class="stc-ic"></span><div class="stc-b"><b>Проверить обновления не удалось</b><small>{{.Settings.Update.LastResult}} · {{msk .Settings.Update.LastCheck}}</small></div>
|
||
<button type="button" class="btn btn-secondary" data-upd-check>Проверить ещё раз</button></div>
|
||
{{else}}
|
||
<div class="stc stc-ok"><span class="stc-ic"></span><div class="stc-b"><b>Установлены последние версии</b><small id="upd-when">{{if .Settings.Update.LastCheck.IsZero}}ещё не проверялось{{else}}проверено {{msk .Settings.Update.LastCheck}}{{end}}{{if .Settings.Update.AutoCheck}} · bj проверяет сам каждые 6 часов{{end}}</small></div>
|
||
<button type="button" class="btn btn-secondary" data-upd-check>Проверить сейчас</button></div>
|
||
{{end}}
|
||
{{if and .License.Present (not .License.AllowsUpdates)}}<p class="muted" style="margin-top:6px;font-size:12px;color:var(--warn)">В лицензии нет модуля «Обновления».</p>{{end}}
|
||
</div>
|
||
<script>(function(){
|
||
var box=document.getElementById('upd-status'), sec=document.getElementById('sec-update'), busy=false;
|
||
function check(force){
|
||
if(busy) return; var last=+box.dataset.last||0, now=Date.now()/1000, tried=0;
|
||
try{ tried=+sessionStorage.getItem('bj-upd-auto')||0; }catch(e){}
|
||
if(!force && (now-last<600 || now-tried<600)) return; // проверяли меньше 10 минут назад (или уже пробовали сами)
|
||
try{ sessionStorage.setItem('bj-upd-auto',String(Math.floor(now))); }catch(e){}
|
||
busy=true; var b=box.querySelector('.stc'); if(b){ b.className='stc stc-run'; var t=b.querySelector('b'); if(t) t.textContent='Проверяю обновления…'; }
|
||
fetch('/admin/setup/update/check',{method:'POST',headers:{'X-BJ-Ajax':'1'},cache:'no-store'}).then(function(r){return r.json()}).then(function(d){
|
||
box.dataset.last=String(Math.floor(Date.now()/1000));
|
||
location.reload(); // состояние компонентов — с сервера
|
||
}).catch(function(){ busy=false; location.reload(); });
|
||
}
|
||
box.addEventListener('click',function(e){ if(e.target.closest('[data-upd-check]')) check(true); });
|
||
document.querySelectorAll('.settings-nav [data-sec="update"]').forEach(function(b){ b.addEventListener('click',function(){ setTimeout(function(){ check(false); },0); }); });
|
||
window.addEventListener('load',function(){ if(sec.classList.contains('active')) check(false); });
|
||
})();</script>
|
||
|
||
<div class="card">
|
||
<details class="adv-box" {{if .UpdatesAvailable}}open{{end}}>
|
||
<summary><span class="sum-h">Компоненты и версии</span><span class="muted">что установлено на этом сервере и что есть в выпуске; можно обновить один компонент</span></summary>
|
||
<div style="overflow-x:auto"><table style="margin-top:8px">
|
||
<thead><tr><th>Компонент</th><th>Установлена</th><th>Доступна</th><th>Служба</th><th></th></tr></thead>
|
||
<tbody>
|
||
{{range .Components}}<tr>
|
||
<td><strong>{{.Title}}</strong><div class="muted" style="font-size:11px"><code>{{.Name}}</code>{{if eq .Name "crypto-service.jar"}}{{with $.Versions.Get "validata"}}{{if .Version}} · работает с «Валидата Клиент L» {{.Version}}{{end}}{{end}}{{end}}</div></td>
|
||
<td>{{if .Present}}{{if .Installed}}{{.Installed}}{{else}}<span class="muted">неизвестна</span>{{end}}{{else}}<span class="muted">не установлен</span>{{end}}</td>
|
||
<td>{{if .Available}}{{.Available}}{{if .New}} <span class="hero-status warn">к установке</span>{{else if .Update}} <span class="hero-status warn">новее</span>{{end}}{{if .Blocked}}<div class="muted" style="font-size:11px;color:var(--warn)">{{.Blocked}}</div>{{end}}{{else}}<span class="muted">нет данных</span>{{end}}</td>
|
||
<td><code style="font-size:11px">{{.Unit}}</code></td>
|
||
<td>{{if .Update}}<form method="post" action="/admin/setup/update/apply" style="margin:0" onsubmit="return confirm('{{if .New}}Установить модуль {{.Available}}? Будет включена его служба.{{else}}Обновить компонент до {{.Available}}? Его служба перезапустится.{{end}}');"><input type="hidden" name="section" value="sec-update"><input type="hidden" name="component" value="{{.Name}}"><button type="submit" class="btn btn-ok">{{if .New}}Установить{{else}}Обновить{{end}}</button></form>{{end}}</td>
|
||
</tr>{{end}}
|
||
</tbody>
|
||
</table></div>
|
||
</details>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<details class="adv-box">
|
||
<summary><span class="sum-h">Расширенные настройки</span><span class="muted">источник и канал обновлений, обновление из файла для сервера без выхода в интернет</span></summary>
|
||
<h3 class="adv-h">Обновление из файла</h3>
|
||
<p class="muted" style="margin:0 0 8px;font-size:12.5px"><b>Закрытый контур.</b> Если у сервера нет выхода к серверу обновлений, скачайте пакет обновления на портале клиента (lic.zetit.ru → Установка → «Пакет обновления») и загрузите его кнопкой «Обновить из файла». Система сама распознаёт, что внутри — ядро, модули или всё вместе — и ставит в правильном порядке. Модуль, которому нужно более новое ядро, чем установлено, будет пропущен с подсказкой обновить сначала ядро.</p>
|
||
<div style="display:flex;gap:10px;flex-wrap:wrap">
|
||
<form method="post" action="/admin/setup/update/upload" enctype="multipart/form-data" style="margin:0;display:flex;gap:8px;align-items:center;flex-wrap:wrap" onsubmit="return this.bundle.files.length>0 && confirm('Установить обновление из файла? Подпись пакета будет проверена; поставятся компоненты новее текущих — сначала ядро, затем модули. Службы перезапустятся.');">
|
||
<input type="hidden" name="section" value="sec-update">
|
||
<input type="file" name="bundle" accept=".zip,application/zip" required style="max-width:260px">
|
||
<button type="submit" class="btn btn-secondary" title="Пакет обновления с портала клиента — для сервера без выхода к серверу обновлений">Обновить из файла</button>
|
||
</form>
|
||
</div>
|
||
<h3 class="adv-h">Источник обновлений</h3>
|
||
<form method="post" action="/admin/setup/update" style="margin-top:12px;display:grid;gap:10px;max-width:680px">
|
||
<label>URL артефактории</label>
|
||
<input type="text" name="base_url" value="{{.Settings.Update.BaseURL}}" placeholder="https://lic.zetit.ru/updates (по умолчанию)">
|
||
<label>Канал</label>
|
||
<select name="channel">
|
||
<option value="stable" {{if eq .Settings.Update.Channel "stable"}}selected{{end}}>stable — стабильный</option>
|
||
<option value="beta" {{if eq .Settings.Update.Channel "beta"}}selected{{end}}>beta — предварительный</option>
|
||
</select>
|
||
<label>Публичный ключ издателя (base64 Ed25519)</label>
|
||
<input type="text" name="public_key" value="{{.Settings.Update.PublicKey}}" placeholder="зашит в релиз; переопределить здесь">
|
||
<label style="display:flex;align-items:center;gap:8px;cursor:pointer"><input type="checkbox" name="auto_check" {{if .Settings.Update.AutoCheck}}checked{{end}} style="width:auto"> Проверять автоматически (раз в 6 часов)</label>
|
||
<div><button type="submit" class="btn">Сохранить</button></div>
|
||
</form>
|
||
</details>
|
||
</div>
|
||
{{if .InWizard}}</div>{{else}}</section>{{end}}
|
||
{{end}}
|