Загрузить файлы в «/»
This commit is contained in:
533
Шаблон_запроса_РК.html
Normal file
533
Шаблон_запроса_РК.html
Normal file
@@ -0,0 +1,533 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Шаблон запроса на резервное копирование</title>
|
||||
<style>
|
||||
:root {
|
||||
--primary: #1a56db;
|
||||
--bg: #f8fafc;
|
||||
--border: #d1d5db;
|
||||
--radius: 8px;
|
||||
}
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
|
||||
background: var(--bg);
|
||||
padding: 30px;
|
||||
color: #1f2937;
|
||||
}
|
||||
.container { max-width: 1000px; margin: 0 auto; }
|
||||
h1 {
|
||||
font-size: 22px; margin-bottom: 4px; color: #111827;
|
||||
}
|
||||
.subtitle {
|
||||
color: #6b7280; font-size: 13px; margin-bottom: 24px;
|
||||
}
|
||||
.doc-ref {
|
||||
font-size: 12px; color: #9ca3af; margin-bottom: 20px;
|
||||
}
|
||||
.card {
|
||||
background: #fff;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius);
|
||||
padding: 20px 24px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.card h2 {
|
||||
font-size: 15px; font-weight: 600; margin-bottom: 14px;
|
||||
color: var(--primary); text-transform: uppercase; letter-spacing: 0.5px;
|
||||
}
|
||||
.row { display: flex; gap: 16px; flex-wrap: wrap; margin-bottom: 12px; }
|
||||
.field { flex: 1; min-width: 200px; }
|
||||
.field label {
|
||||
display: block; font-size: 12px; font-weight: 500;
|
||||
color: #374151; margin-bottom: 4px;
|
||||
}
|
||||
.field input, .field select, .field textarea {
|
||||
width: 100%; padding: 8px 10px; font-size: 14px;
|
||||
border: 1px solid var(--border); border-radius: 6px;
|
||||
background: #fff; transition: border-color 0.2s;
|
||||
}
|
||||
.field input:focus, .field select:focus { outline: none; border-color: var(--primary); }
|
||||
.field input[readonly] { background: #f3f4f6; color: #4b5563; cursor: default; }
|
||||
.field textarea { resize: vertical; min-height: 60px; font-family: monospace; font-size: 13px; }
|
||||
.field .hint {
|
||||
font-size: 11px; color: #9ca3af; margin-top: 3px;
|
||||
}
|
||||
.auto-badge {
|
||||
display: inline-block; font-size: 10px; background: #dbeafe; color: var(--primary);
|
||||
padding: 1px 6px; border-radius: 4px; margin-left: 6px; font-weight: 500;
|
||||
}
|
||||
.params-grid {
|
||||
display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
|
||||
gap: 10px; margin-top: 8px;
|
||||
}
|
||||
.param-card {
|
||||
background: #f0f4ff; border-radius: 6px; padding: 10px 14px;
|
||||
border-left: 3px solid var(--primary);
|
||||
}
|
||||
.param-card .label { font-size: 11px; color: #6b7280; text-transform: uppercase; }
|
||||
.param-card .value { font-size: 16px; font-weight: 700; color: var(--primary); margin-top: 2px; }
|
||||
.param-card .value.green { color: #059669; }
|
||||
.param-card .value.orange { color: #d97706; }
|
||||
.param-card .value.red { color: #dc2626; }
|
||||
.gen-name {
|
||||
font-family: 'Courier New', monospace; font-size: 13px;
|
||||
background: #1f2937; color: #e5e7eb; padding: 10px 14px;
|
||||
border-radius: 6px; word-break: break-all; margin-top: 6px;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.btn-group { display: flex; gap: 10px; margin-top: 20px; }
|
||||
.btn {
|
||||
padding: 10px 24px; border: none; border-radius: 6px;
|
||||
font-size: 14px; font-weight: 500; cursor: pointer; transition: 0.2s;
|
||||
}
|
||||
.btn-primary { background: var(--primary); color: #fff; }
|
||||
.btn-primary:hover { background: #1d4ed8; }
|
||||
.btn-secondary { background: #e5e7eb; color: #374151; }
|
||||
.btn-secondary:hover { background: #d1d5db; }
|
||||
.btn-danger { background: #fee2e2; color: #dc2626; }
|
||||
.btn-danger:hover { background: #fecaca; }
|
||||
.output-section { margin-top: 12px; }
|
||||
.output-section textarea { min-height: 120px; font-family: monospace; font-size: 13px; }
|
||||
.warning {
|
||||
background: #fffbeb; border: 1px solid #fde68a; border-radius: 6px;
|
||||
padding: 10px 14px; font-size: 13px; color: #92400e; margin-top: 8px;
|
||||
}
|
||||
@media print {
|
||||
body { background: #fff; padding: 0; }
|
||||
.btn-group, .doc-ref { display: none; }
|
||||
.card { border: 1px solid #ddd; break-inside: avoid; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Шаблон запроса на резервное копирование ИТ-системы</h1>
|
||||
<p class="subtitle">М НСП-НТ-03-02 26-09-2025 «Методика резервного копирования ИТ-систем»</p>
|
||||
<p class="doc-ref">Номер заявки: <span id="reqId"></span> | Дата: <span id="reqDate"></span></p>
|
||||
|
||||
<!-- 1. Общая информация -->
|
||||
<div class="card">
|
||||
<h2>1. Общая информация об ИТ-системе</h2>
|
||||
<div class="row">
|
||||
<div class="field">
|
||||
<label>Наименование ИТ-системы</label>
|
||||
<input type="text" id="sysName" placeholder="Введите наименование">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Идентификатор в EATool</label>
|
||||
<input type="text" id="eaToolId" placeholder="IS000XXXX" maxlength="10">
|
||||
<div class="hint">Формат: IS000XXXX. Для систем без ID — IS0000000</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="field">
|
||||
<label>Ответственный за эксплуатацию ИТ-системы</label>
|
||||
<input type="text" id="responsible" placeholder="ФИО / должность">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Подразделение</label>
|
||||
<input type="text" id="department" placeholder="Наименование подразделения">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="field">
|
||||
<label>Класс критичности ИТ-системы</label>
|
||||
<select id="criticality" onchange="autoFill()">
|
||||
<option value="">— Выберите класс критичности —</option>
|
||||
<option value="max">Максимальный</option>
|
||||
<option value="high">Высокий</option>
|
||||
<option value="medium">Средний</option>
|
||||
<option value="low">Низкий</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Тип данных</label>
|
||||
<select id="dataType" onchange="autoFill()">
|
||||
<option value="">— Выберите тип данных —</option>
|
||||
<option value="vm">Виртуальная машина</option>
|
||||
<option value="fs">Файловая система</option>
|
||||
<option value="db">База данных / Приложение</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 2. Класс резервирования (авто) -->
|
||||
<div class="card" id="classCard" style="display:none">
|
||||
<h2>2. Класс резервирования и параметры восстановления <span class="auto-badge">авто</span></h2>
|
||||
<div class="params-grid" id="paramsGrid"></div>
|
||||
</div>
|
||||
|
||||
<!-- 3. Параметры резервного копирования -->
|
||||
<div class="card" id="backupParamsCard" style="display:none">
|
||||
<h2>3. Параметры резервного копирования</h2>
|
||||
|
||||
<div class="row">
|
||||
<div class="field">
|
||||
<label>Класс резервирования (КР)</label>
|
||||
<input type="text" id="krClass" readonly>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Периодичность резервного копирования</label>
|
||||
<input type="text" id="backupPeriod" readonly>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="field">
|
||||
<label>RTO (целевое время восстановления)</label>
|
||||
<input type="text" id="rto" readonly>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>RPO (целевая точка восстановления)</label>
|
||||
<input type="text" id="rpo" readonly>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="field">
|
||||
<label>Срок хранения — ежедневные копии (S)</label>
|
||||
<input type="text" id="storeDaily" readonly>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Срок хранения — еженедельные копии (F)</label>
|
||||
<input type="text" id="storeWeekly" readonly>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Срок хранения — ежемесячные копии (G)</label>
|
||||
<input type="text" id="storeMonthly" readonly>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="field">
|
||||
<label>Место хранения резервных копий</label>
|
||||
<input type="text" id="storageLocation" readonly>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Наличие удалённой реплики</label>
|
||||
<input type="text" id="hasReplica" readonly>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" id="dbDetailsRow" style="display:none">
|
||||
<div class="field">
|
||||
<label>Периодичность копирования транзакционных журналов БД</label>
|
||||
<input type="text" id="tlogPeriod" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field" style="margin-top:8px">
|
||||
<label>Согласованное изменение параметров (если применимо)</label>
|
||||
<textarea id="agreedChanges" placeholder="Решение ответственного за эксплуатацию ИТ-системы и ответственного за эксплуатацию СРК (если периодичность/сроки изменены)"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 4. Детали объекта -->
|
||||
<div class="card" id="detailsCard" style="display:none">
|
||||
<h2>4. Детали объекта резервирования</h2>
|
||||
<div class="row">
|
||||
<div class="field">
|
||||
<label>Тип объекта РК</label>
|
||||
<select id="rkType">
|
||||
<option value="">— Выберите —</option>
|
||||
<option value="zVirt">zVirt</option>
|
||||
<option value="HyperV">Hyper-V</option>
|
||||
<option value="VMware">VMware</option>
|
||||
<option value="File">File</option>
|
||||
<option value="Block">Block</option>
|
||||
<option value="MSSQL">MSSQL</option>
|
||||
<option value="PSQL">Postgres</option>
|
||||
<option value="Mongo">Mongo</option>
|
||||
<option value="DB2">DB2</option>
|
||||
<option value="Exchange">Exchange</option>
|
||||
<option value="SP">SharePoint</option>
|
||||
<option value="Oracle">Oracle</option>
|
||||
<option value="SAP">SAP HANA</option>
|
||||
<option value="Sybase">Sybase</option>
|
||||
<option value="K8s">Kubernetes</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Схема резервного копирования (F-I-D)</label>
|
||||
<select id="fidScheme" onchange="toggleF1Warning()">
|
||||
<option value="">— Выберите —</option>
|
||||
<option value="F">F — только полное</option>
|
||||
<option value="F1">F1 — разовое полное</option>
|
||||
<option value="I">I — всегда инкрементальное</option>
|
||||
<option value="FI">FI — полное + инкрементальное</option>
|
||||
<option value="FD">FD — полное + дифференциальное</option>
|
||||
<option value="SF">SF — синтетическое полное</option>
|
||||
<option value="FDI">FDI — полное + дифференциальное + инкрементальное</option>
|
||||
<option value="TLB">TLB — транзакционные логи</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div id="f1Warning" class="warning" style="display:none">
|
||||
Внимание! Для схемы F1 требуется ежеквартальная ревизия актуальности. По итогам ревизии план защиты и соответствующие файлы РК могут быть удалены.
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="field">
|
||||
<label>Имя сервера / ресурса (Hostname/FQDN)</label>
|
||||
<input type="text" id="hostname" placeholder="server-name.domain.local">
|
||||
<div class="hint">Верхний регистр — Windows, нижний — Unix. Группа серверов: GrSrv-<NAME></div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Объём резервируемых данных (Гб)</label>
|
||||
<input type="number" id="volumeGb" placeholder="0" min="0" step="0.1">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="field">
|
||||
<label>Допустимое окно резервного копирования</label>
|
||||
<input type="text" id="backupWindow" placeholder="например: 22:00–06:00">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Порядковый номер политики (X)</label>
|
||||
<input type="text" id="policyNum" placeholder="1, 2, ... (опционально)">
|
||||
<div class="hint">При одинаковых названиях, но разных расписаниях</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="field">
|
||||
<label>Прогнозируемый объём на конец года (Гб)</label>
|
||||
<input type="number" id="volumeMaxGb" placeholder="0" min="0" step="0.1">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Коэффициент дедупликации</label>
|
||||
<input type="text" id="dedupFactor" placeholder="Например: 2:1, 3:1">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 5. Сгенерированное наименование плана защиты -->
|
||||
<div class="card" id="nameCard" style="display:none">
|
||||
<h2>5. Наименование плана защиты / политики РК <span class="auto-badge">авто</span></h2>
|
||||
<p style="font-size:12px; color:#6b7280; margin-bottom:6px;">
|
||||
Шаблон: <code><IS000XXXX>_<Объект-РК>_<Тип РК>_<F-I-D>_<X></code>
|
||||
</p>
|
||||
<div class="gen-name" id="generatedName">—</div>
|
||||
<div class="field" style="margin-top:8px">
|
||||
<label>Примечание (для служебных / тестовых политик)</label>
|
||||
<select id="policyNote" onchange="updateGeneratedName()">
|
||||
<option value="">— Стандартная политика —</option>
|
||||
<option value="Test">Test — тестовая политика</option>
|
||||
<option value="System">System — служебная (сбор логов, скрипты) — для КиберБэкап</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 6. Полный вывод -->
|
||||
<div class="card" id="outputCard" style="display:none">
|
||||
<h2>6. Спецификация резервного копирования (сводка)</h2>
|
||||
<div class="output-section">
|
||||
<textarea id="fullOutput" readonly></textarea>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-primary" onclick="copyOutput()">Копировать спецификацию</button>
|
||||
<button class="btn btn-secondary" onclick="window.print()">Печать</button>
|
||||
<button class="btn btn-danger" onclick="resetForm()">Сбросить</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const KR_CONFIG = {
|
||||
max: {
|
||||
kr: 1, period: '2 ч.', rto: '2 ч.', rpo: '2 ч.',
|
||||
storeDaily: '1 нед.', storeWeekly: '1 м.', storeMonthly: '1 г.',
|
||||
location: 'ОЦОД + РЦОД + ЛБ', replica: 'Да',
|
||||
tlog: '2 ч.', color: 'red'
|
||||
},
|
||||
high: {
|
||||
kr: 2, period: '8 ч.', rto: '8 ч.', rpo: '8 ч.',
|
||||
storeDaily: '1 нед.', storeWeekly: '1 м.', storeMonthly: '1 г.',
|
||||
location: 'ОЦОД + РЦОД + ЛБ', replica: 'Да',
|
||||
tlog: '8 ч.', color: 'orange'
|
||||
},
|
||||
medium: {
|
||||
kr: 3, period: '16 ч.', rto: '16 ч.', rpo: '16 ч.',
|
||||
storeDaily: '1 нед.', storeWeekly: '1 м.', storeMonthly: '1 г.',
|
||||
location: 'ОЦОД', replica: 'Нет',
|
||||
tlog: '16 ч.', color: 'green'
|
||||
},
|
||||
low: {
|
||||
kr: 4, period: '24 ч.', rto: '24 ч.', rpo: '24 ч.',
|
||||
storeDaily: '1 нед.', storeWeekly: '1 м.', storeMonthly: '1 г.',
|
||||
location: 'ОЦОД', replica: 'Нет',
|
||||
tlog: '24 ч.', color: 'green'
|
||||
}
|
||||
};
|
||||
|
||||
const CRIT_NAMES = { max: 'Максимальный', high: 'Высокий', medium: 'Средний', low: 'Низкий' };
|
||||
const DATA_TYPES = { vm: 'Виртуальная машина', fs: 'Файловая система', db: 'База данных / Приложение' };
|
||||
|
||||
function get(id) { return document.getElementById(id); }
|
||||
|
||||
function autoFill() {
|
||||
const crit = get('criticality').value;
|
||||
const dt = get('dataType').value;
|
||||
|
||||
if (!crit || !dt) return;
|
||||
|
||||
const cfg = KR_CONFIG[crit];
|
||||
|
||||
get('classCard').style.display = 'block';
|
||||
get('backupParamsCard').style.display = 'block';
|
||||
get('detailsCard').style.display = 'block';
|
||||
get('nameCard').style.display = 'block';
|
||||
get('outputCard').style.display = 'block';
|
||||
|
||||
// Параметры восстановления
|
||||
const labels = {
|
||||
max: { label: 'КР 1 — Максимальный', desc: 'RTO 2ч / RPO 2ч' },
|
||||
high: { label: 'КР 2 — Высокий', desc: 'RTO 8ч / RPO 8ч' },
|
||||
medium: { label: 'КР 3 — Средний', desc: 'RTO 16ч / RPO 16ч' },
|
||||
low: { label: 'КР 4 — Низкий', desc: 'RTO 24ч / RPO 24ч' }
|
||||
};
|
||||
|
||||
get('paramsGrid').innerHTML = `
|
||||
<div class="param-card"><div class="label">Класс резервирования</div><div class="value ${cfg.color}">КР ${cfg.kr}</div></div>
|
||||
<div class="param-card"><div class="label">Периодичность</div><div class="value">${cfg.period}</div></div>
|
||||
<div class="param-card"><div class="label">RTO</div><div class="value">${cfg.rto}</div></div>
|
||||
<div class="param-card"><div class="label">RPO</div><div class="value">${cfg.rpo}</div></div>
|
||||
<div class="param-card"><div class="label">Хранение (ежедн/еженед/ежемес)</div><div class="value">${cfg.storeDaily} / ${cfg.storeWeekly} / ${cfg.storeMonthly}</div></div>
|
||||
<div class="param-card"><div class="label">Место хранения</div><div class="value">${cfg.location}</div></div>
|
||||
<div class="param-card"><div class="label">Удалённая реплика</div><div class="value ${cfg.replica === 'Да' ? 'red' : 'green'}">${cfg.replica}</div></div>
|
||||
`;
|
||||
|
||||
get('krClass').value = 'КР ' + cfg.kr;
|
||||
get('backupPeriod').value = cfg.period;
|
||||
get('rto').value = cfg.rto;
|
||||
get('rpo').value = cfg.rpo;
|
||||
get('storeDaily').value = cfg.storeDaily;
|
||||
get('storeWeekly').value = cfg.storeWeekly;
|
||||
get('storeMonthly').value = cfg.storeMonthly;
|
||||
get('storageLocation').value = cfg.location;
|
||||
get('hasReplica').value = cfg.replica;
|
||||
|
||||
// Показываем/скрываем строку TLog
|
||||
get('dbDetailsRow').style.display = (dt === 'db') ? 'flex' : 'none';
|
||||
if (dt === 'db') {
|
||||
get('tlogPeriod').value = 'каждые ' + cfg.tlog;
|
||||
}
|
||||
|
||||
updateGeneratedName();
|
||||
updateFullOutput();
|
||||
}
|
||||
|
||||
function toggleF1Warning() {
|
||||
get('f1Warning').style.display = (get('fidScheme').value === 'F1') ? 'block' : 'none';
|
||||
updateGeneratedName();
|
||||
}
|
||||
|
||||
function updateGeneratedName() {
|
||||
const eaId = get('eaToolId').value || 'IS0000000';
|
||||
const host = get('hostname').value || '<Имя_сервера>';
|
||||
const rkType = get('rkType').value || '<Тип_РК>';
|
||||
const fid = get('fidScheme').value || '<F-I-D>';
|
||||
const num = get('policyNum').value;
|
||||
const note = get('policyNote').value;
|
||||
|
||||
let base = eaId + '_' + host + '_' + rkType + '_' + fid;
|
||||
if (num) base += '_' + num;
|
||||
if (note) base = note + '_' + base;
|
||||
|
||||
get('generatedName').textContent = base;
|
||||
updateFullOutput();
|
||||
}
|
||||
|
||||
function updateFullOutput() {
|
||||
const crit = get('criticality').value;
|
||||
const cfg = crit ? KR_CONFIG[crit] : null;
|
||||
const dt = get('dataType').value;
|
||||
|
||||
let o = '=== СПЕЦИФИКАЦИЯ РЕЗЕРВНОГО КОПИРОВАНИЯ ИТ-СИСТЕМЫ ===\n';
|
||||
o += 'Методика: М НСП-НТ-03-02 26-09-2025\n\n';
|
||||
|
||||
o += '1. ИТ-СИСТЕМА\n';
|
||||
o += ' Наименование: ' + (get('sysName').value || '(не указано)') + '\n';
|
||||
o += ' ID EATool: ' + (get('eaToolId').value || 'IS0000000') + '\n';
|
||||
o += ' Ответственный: ' + (get('responsible').value || '(не указано)') + '\n';
|
||||
o += ' Подразделение: ' + (get('department').value || '(не указано)') + '\n';
|
||||
o += ' Класс критичности: ' + (CRIT_NAMES[crit] || '(не выбран)') + '\n';
|
||||
o += ' Тип данных: ' + (DATA_TYPES[dt] || '(не выбран)') + '\n\n';
|
||||
|
||||
if (cfg) {
|
||||
o += '2. КЛАСС РЕЗЕРВИРОВАНИЯ\n';
|
||||
o += ' КР: КР ' + cfg.kr + '\n';
|
||||
o += ' Периодичность: ' + cfg.period + '\n';
|
||||
o += ' RTO: ' + cfg.rto + '\n';
|
||||
o += ' RPO: ' + cfg.rpo + '\n\n';
|
||||
|
||||
o += '3. ХРАНЕНИЕ\n';
|
||||
o += ' Ежедневные (S): ' + cfg.storeDaily + '\n';
|
||||
o += ' Еженедельные (F): ' + cfg.storeWeekly + '\n';
|
||||
o += ' Ежемесячные (G): ' + cfg.storeMonthly + '\n\n';
|
||||
|
||||
o += '4. РАЗМЕЩЕНИЕ\n';
|
||||
o += ' Место хранения: ' + cfg.location + '\n';
|
||||
o += ' Удалённая реплика: ' + cfg.replica + '\n';
|
||||
if (dt === 'db') {
|
||||
o += ' Транзакционные логи: каждые ' + cfg.tlog + '\n';
|
||||
}
|
||||
o += '\n';
|
||||
}
|
||||
|
||||
o += '5. ОБЪЕКТ РЕЗЕРВИРОВАНИЯ\n';
|
||||
o += ' Тип объекта РК: ' + (get('rkType').value || '(не выбран)') + '\n';
|
||||
o += ' Схема F-I-D: ' + (get('fidScheme').value || '(не выбрана)') + '\n';
|
||||
o += ' Hostname/FQDN: ' + (get('hostname').value || '(не указан)') + '\n';
|
||||
o += ' Объём (текущий): ' + (get('volumeGb').value || '0') + ' Гб\n';
|
||||
o += ' Объём (прогноз): ' + (get('volumeMaxGb').value || '0') + ' Гб\n';
|
||||
o += ' Дедупликация: ' + (get('dedupFactor').value || '(не указан)') + '\n';
|
||||
o += ' Окно РК: ' + (get('backupWindow').value || '(не указано)') + '\n\n';
|
||||
|
||||
o += '6. ПЛАН ЗАЩИТЫ / ПОЛИТИКА РК\n';
|
||||
o += ' Наименование: ' + get('generatedName').textContent + '\n\n';
|
||||
|
||||
if (get('agreedChanges').value.trim()) {
|
||||
o += '7. СОГЛАСОВАННЫЕ ИЗМЕНЕНИЯ\n';
|
||||
o += ' ' + get('agreedChanges').value + '\n\n';
|
||||
}
|
||||
|
||||
o += '=== КОНЕЦ СПЕЦИФИКАЦИИ ===';
|
||||
|
||||
get('fullOutput').value = o;
|
||||
}
|
||||
|
||||
// Автообновление сводки при любых изменениях
|
||||
document.querySelectorAll('input, select, textarea').forEach(el => {
|
||||
el.addEventListener('change', () => { updateGeneratedName(); updateFullOutput(); });
|
||||
el.addEventListener('input', () => { updateGeneratedName(); updateFullOutput(); });
|
||||
});
|
||||
|
||||
function copyOutput() {
|
||||
const ta = get('fullOutput');
|
||||
ta.select();
|
||||
document.execCommand('copy');
|
||||
const btn = event.target;
|
||||
const orig = btn.textContent;
|
||||
btn.textContent = 'Скопировано!';
|
||||
setTimeout(() => btn.textContent = orig, 2000);
|
||||
}
|
||||
|
||||
function resetForm() {
|
||||
if (!confirm('Сбросить все поля?')) return;
|
||||
document.querySelectorAll('input, textarea').forEach(el => el.value = '');
|
||||
document.querySelectorAll('select').forEach(el => el.selectedIndex = 0);
|
||||
['classCard','backupParamsCard','detailsCard','nameCard','outputCard','f1Warning','dbDetailsRow'].forEach(id => {
|
||||
get(id).style.display = 'none';
|
||||
});
|
||||
}
|
||||
|
||||
// Инициализация
|
||||
(function() {
|
||||
const now = new Date();
|
||||
const pad = n => String(n).padStart(2, '0');
|
||||
get('reqDate').textContent = now.getFullYear() + '-' + pad(now.getMonth()+1) + '-' + pad(now.getDate());
|
||||
get('reqId').textContent = 'ЗРК-' + now.getFullYear() + pad(now.getMonth()+1) + pad(now.getDate()) + '-' + pad(Math.floor(Math.random()*999)+1);
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user