Форма ввода по 15 колонкам из Google Sheets + экспорт/импорт CSV
This commit is contained in:
parent
2477e26c30
commit
d2ea436d89
190
index.html
190
index.html
@ -1147,35 +1147,34 @@ body {
|
||||
<div class="toggle-panel active" id="panel-input">
|
||||
<div class="form-grid">
|
||||
<div class="form-group">
|
||||
<label>Дата проверки</label>
|
||||
<label>№</label>
|
||||
<input type="number" id="fNum" placeholder="Авто">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Дата</label>
|
||||
<input type="date" id="fDate" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>№ указания</label>
|
||||
<input type="text" id="fDirective" placeholder="Номер указания">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Филиал</label>
|
||||
<select id="fFilial">
|
||||
<option value="">Выберите...</option>
|
||||
<option>ОДС</option>
|
||||
<option>ДРБ</option>
|
||||
<option>ДИТ</option>
|
||||
<option>Сервисная фабрика</option>
|
||||
<option>ДКБ</option>
|
||||
<option>ДУП</option>
|
||||
<option>ДТК</option>
|
||||
<option>СФ</option>
|
||||
<option>ЦТО СФ</option>
|
||||
<option>ЦЭиК</option>
|
||||
<option>ОДС</option><option>ДРБ</option><option>ДИТ</option>
|
||||
<option>Сервисная фабрика</option><option>ДКБ</option>
|
||||
<option>ДУП</option><option>ДТК</option><option>СФ</option>
|
||||
<option>ЦТО СФ</option><option>ЦЭиК</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Область</label>
|
||||
<select id="fRegion">
|
||||
<option value="">Выберите...</option>
|
||||
<option>Акмолинская</option>
|
||||
<option>Астана</option>
|
||||
<option>Карагандинская</option>
|
||||
<option>Улытауская</option>
|
||||
<option>Костанайская</option>
|
||||
<option>Павлодарская</option>
|
||||
<option>Акмолинская</option><option>Астана</option>
|
||||
<option>Карагандинская</option><option>Улытауская</option>
|
||||
<option>Костанайская</option><option>Павлодарская</option>
|
||||
<option>СКО</option>
|
||||
</select>
|
||||
</div>
|
||||
@ -1187,10 +1186,6 @@ body {
|
||||
<label>Объект с адресом</label>
|
||||
<input type="text" id="fAddr" placeholder="Например: ул. Казахстанская 100а">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Кому выдано</label>
|
||||
<input type="text" id="fIssuedTo" placeholder="Например: Начальник ЛТЦ">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Категория нарушения</label>
|
||||
<select id="fCat">
|
||||
@ -1204,27 +1199,38 @@ body {
|
||||
<option>Санитарно-бытовые условия</option>
|
||||
<option>организационные требования БиОТ</option>
|
||||
<option>Производственная санитария</option>
|
||||
<option>Инструкция по проведению 4-х ступенчатого контроля</option>
|
||||
<option>Наряды-допуски</option>
|
||||
<option>Инструкция по проведению 4-х ступенчатого контроля</option>
|
||||
<option>Не обеспечение СИЗ</option>
|
||||
<option>Политика в области ТСС</option>
|
||||
<option>Требовании по организации в управлении транспортных средств</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group full">
|
||||
<label>Категория нарушения (описание)</label>
|
||||
<textarea id="fDesc" placeholder="Подробное описание выявленного нарушения..."></textarea>
|
||||
</div>
|
||||
<div class="form-group full">
|
||||
<label>Ссылка на законодательство</label>
|
||||
<textarea id="fLaw" rows="2" placeholder="Например: пп.4, п.2 статьи 182 Трудового кодекса РК..."></textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Статус</label>
|
||||
<label>Срок исполнения</label>
|
||||
<input type="text" id="fDeadline" placeholder="Например: 14.01.2026г.">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Исполнено</label>
|
||||
<select id="fStatus">
|
||||
<option value="на контроле">На контроле</option>
|
||||
<option value="исполнено">Исполнено</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group full">
|
||||
<label>Описание нарушения</label>
|
||||
<textarea id="fDesc" placeholder="Кратко опишите нарушение..."></textarea>
|
||||
<label>Примечание</label>
|
||||
<input type="text" id="fNote" placeholder="Примечание (необязательно)">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Срок исполнения</label>
|
||||
<input type="date" id="fDeadline">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Проверяющий (кто выдал)</label>
|
||||
<label>Кто выдал</label>
|
||||
<select id="fInspector">
|
||||
<option value="">Выберите...</option>
|
||||
<option>Инженер по БиОТ Семидоцкий С.А.</option>
|
||||
@ -1235,8 +1241,13 @@ body {
|
||||
<option>Инженер ОБиОТ Садыков М.Ф.</option>
|
||||
<option>Ведущий инженер ОБиОТ Тумабаева С.А.</option>
|
||||
<option>Инженер по БиОТ Джусупова А.Т.</option>
|
||||
<option>Ведущий инженер ОБиОТ Федоськин А.Н.</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Кому выдано</label>
|
||||
<input type="text" id="fIssuedTo" placeholder="Например: Начальник ЛТЦ">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<button class="btn btn-blue" id="btnAdd">Добавить запись</button>
|
||||
@ -1625,13 +1636,13 @@ body {
|
||||
var fixed = isFixed(r.status);
|
||||
html += '<div class="entry-card">' +
|
||||
'<span class="entry-date">' + escHtml(r.date || '—') + '</span>' +
|
||||
'<span class="entry-cat">' + escHtml(normalizeCategory(r.category || r.cat || '')) + '</span>' +
|
||||
'<span class="entry-cat">' + escHtml(normalizeCategory(r.cat || r.category || '')) + '</span>' +
|
||||
'<span class="entry-desc">' + escHtml((r.desc || r.description || '').slice(0, 80)) + '</span>' +
|
||||
'<span class="entry-status ' + (fixed ? 'fixed' : 'pending') + '">' + (fixed ? 'Исполнено' : 'На контроле') + '</span>' +
|
||||
'<button class="entry-del" data-id="' + r.id + '" title="Удалить">×</button>' +
|
||||
'</div>';
|
||||
});
|
||||
if (data.length === 0) html = '<p style="color:var(--gray-500);text-align:center;padding:40px">Нет записей. Добавьте через форму «Ввод данных».</p>';
|
||||
if (data.length === 0) html = '<p style="color:var(--gray-500);text-align:center;padding:40px">Нет записей. Добавьте через вкладку «Ввод данных».</p>';
|
||||
if (data.length > 200) html += '<p style="font-size:13px;color:var(--gray-500);text-align:center">Показаны последние 200 из ' + data.length + '</p>';
|
||||
document.getElementById('entriesList').innerHTML = html;
|
||||
|
||||
@ -1646,32 +1657,39 @@ body {
|
||||
// ---- Form handling ----
|
||||
function submitForm() {
|
||||
var entry = {
|
||||
num: document.getElementById('fNum').value,
|
||||
date: document.getElementById('fDate').value,
|
||||
directive: document.getElementById('fDirective').value,
|
||||
filial: document.getElementById('fFilial').value,
|
||||
region: document.getElementById('fRegion').value,
|
||||
city: document.getElementById('fCity').value,
|
||||
addr: document.getElementById('fAddr').value,
|
||||
issuedTo: document.getElementById('fIssuedTo').value,
|
||||
cat: document.getElementById('fCat').value,
|
||||
status: document.getElementById('fStatus').value,
|
||||
desc: document.getElementById('fDesc').value,
|
||||
law: document.getElementById('fLaw').value,
|
||||
deadline: document.getElementById('fDeadline').value,
|
||||
inspector: document.getElementById('fInspector').value
|
||||
status: document.getElementById('fStatus').value,
|
||||
note: document.getElementById('fNote').value,
|
||||
inspector: document.getElementById('fInspector').value,
|
||||
issuedTo: document.getElementById('fIssuedTo').value
|
||||
};
|
||||
|
||||
if (!entry.date || !entry.filial || !entry.cat || !entry.desc) {
|
||||
showMsg('Заполните обязательные поля: дата, филиал, категория, описание', 'err');
|
||||
showMsg('Заполните обязательные поля: Дата, Филиал, Категория, Описание', 'err');
|
||||
return;
|
||||
}
|
||||
|
||||
addEntry(entry);
|
||||
showMsg('Запись добавлена!', 'ok');
|
||||
document.getElementById('fDesc').value = '';
|
||||
// Clear text fields, keep dropdowns
|
||||
document.getElementById('fNum').value = '';
|
||||
document.getElementById('fDate').value = '';
|
||||
document.getElementById('fIssuedTo').value = '';
|
||||
document.getElementById('fAddr').value = '';
|
||||
document.getElementById('fCity').value = '';
|
||||
document.getElementById('fDirective').value = '';
|
||||
document.getElementById('fDesc').value = '';
|
||||
document.getElementById('fLaw').value = '';
|
||||
document.getElementById('fDeadline').value = '';
|
||||
document.getElementById('fNote').value = '';
|
||||
document.getElementById('fIssuedTo').value = '';
|
||||
renderAll();
|
||||
setTimeout(function() { showMsg('', ''); }, 2500);
|
||||
}
|
||||
@ -1686,13 +1704,14 @@ body {
|
||||
function exportCSV() {
|
||||
var data = loadData();
|
||||
if (data.length === 0) { alert('Нет данных для экспорта.'); return; }
|
||||
var header = 'Дата,Филиал,Область,Город/Район,Объект,Категория нарушения,Описание,Статус,Срок,Проверяющий,Кому выдано';
|
||||
var header = '№,Дата,№ указания,Филиал,Область,Город/Район,Объект с адресом,Категория нарушения,Категория нарушения,Ссылка на законодательство,Срок исполнения,исполнено,Примечание,кто выдал,кому выдано';
|
||||
var lines = [header];
|
||||
data.forEach(function(r) {
|
||||
lines.push([
|
||||
r.date || '', r.filial || '', r.region || '', r.city || '',
|
||||
r.addr || '', r.cat || r.category || '', r.desc || r.description || '',
|
||||
r.status || '', r.deadline || '', r.inspector || r.issuedBy || '', r.issuedTo || ''
|
||||
r.num || '', r.date || '', r.directive || '', r.filial || '', r.region || '',
|
||||
r.city || '', r.addr || '', r.cat || r.category || '', r.desc || r.description || '',
|
||||
r.law || '', r.deadline || '', r.status || '', r.note || '',
|
||||
r.inspector || r.issuedBy || '', r.issuedTo || ''
|
||||
].map(function(v) { return '"' + String(v).replace(/"/g, '""') + '"'; }).join(','));
|
||||
});
|
||||
var blob = new Blob(['\uFEFF' + lines.join('\n')], { type: 'text/csv;charset=utf-8' });
|
||||
@ -1740,36 +1759,47 @@ body {
|
||||
return -1;
|
||||
}
|
||||
|
||||
var ciNum = idx(['№']);
|
||||
var ciDate = idx(['дата']);
|
||||
var ciDirective = idx(['указания','№ указания']);
|
||||
var ciFilial = idx(['филиал']);
|
||||
var ciRegion = idx(['область','регион']);
|
||||
var ciCity = idx(['город','район']);
|
||||
var ciCity = idx(['город','район','населен']);
|
||||
var ciAddr = idx(['объект','адрес']);
|
||||
var ciCat = idx(['категор','нарушен']);
|
||||
|
||||
// Second "Категория нарушения" = description
|
||||
var ciDesc = -1;
|
||||
for (var hi = 0; hi < headers.length; hi++) {
|
||||
if (headers[hi].indexOf('категор') !== -1 && hi !== ciCat) { ciDesc = hi; break; }
|
||||
if (headers[hi].indexOf('описан') !== -1 || headers[hi].indexOf('суть') !== -1) { ciDesc = hi; break; }
|
||||
if (headers[hi].indexOf('описан') !== -1) { ciDesc = hi; break; }
|
||||
}
|
||||
if (ciDesc < 0) ciDesc = ciCat >= 0 ? ciCat + 1 : -1;
|
||||
var ciStatus = idx(['исполнен','статус','устран']);
|
||||
if (ciDesc < 0 && ciCat >= 0) ciDesc = ciCat + 1;
|
||||
|
||||
var ciLaw = idx(['законодательств','ссылка','основание']);
|
||||
var ciDeadline = idx(['срок']);
|
||||
var ciInspector = idx(['выдал','кто выдал','проверяющ']);
|
||||
var ciStatus = idx(['исполнен','статус','устран']);
|
||||
var ciNote = idx(['примечан']);
|
||||
var ciInspector = idx(['выдал','кто выдал']);
|
||||
var ciIssued = idx(['кому','выдано']);
|
||||
|
||||
var entries = [];
|
||||
data.forEach(function(r) {
|
||||
if (r.length < 2) return;
|
||||
entries.push({
|
||||
num: ciNum >= 0 ? r[ciNum] || '' : '',
|
||||
date: ciDate >= 0 ? r[ciDate] || '' : '',
|
||||
directive: ciDirective >= 0 ? r[ciDirective] || '' : '',
|
||||
filial: ciFilial >= 0 ? r[ciFilial] || '' : '',
|
||||
region: ciRegion >= 0 ? r[ciRegion] || '' : '',
|
||||
city: ciCity >= 0 ? r[ciCity] || '' : '',
|
||||
addr: ciAddr >= 0 ? r[ciAddr] || '' : '',
|
||||
cat: ciCat >= 0 ? r[ciCat] || '' : '',
|
||||
desc: ciDesc >= 0 && ciDesc < r.length ? r[ciDesc] || '' : '',
|
||||
status: ciStatus >= 0 ? r[ciStatus] || '' : '',
|
||||
law: ciLaw >= 0 ? r[ciLaw] || '' : '',
|
||||
deadline: ciDeadline >= 0 ? r[ciDeadline] || '' : '',
|
||||
status: ciStatus >= 0 ? r[ciStatus] || '' : '',
|
||||
note: ciNote >= 0 ? r[ciNote] || '' : '',
|
||||
inspector: ciInspector >= 0 ? r[ciInspector] || '' : '',
|
||||
issuedTo: ciIssued >= 0 ? r[ciIssued] || '' : ''
|
||||
});
|
||||
@ -1804,21 +1834,40 @@ body {
|
||||
}
|
||||
|
||||
function generateSampleCSV() {
|
||||
var header = 'Дата,Филиал,Область,Город/Район,Объект с адресом,Категория нарушения,Описание нарушения,Срок исполнения,исполнено,кто выдал,кому выдано';
|
||||
var header = '№,Дата,№ указания,Филиал,Область,Город/Район,Объект с адресом,Категория нарушения,Категория нарушения,Ссылка на законодательство,Срок исполнения,исполнено,Примечание,кто выдал,кому выдано';
|
||||
var filials = ['ОДС','ДРБ','ДИТ','Сервисная фабрика','ДКБ','ДУП','ЦТО СФ','ЦЭиК'];
|
||||
var oblasts = ['Акмолинская','Карагандинская','Астана','Астана','Улытауская','Карагандинская','Акмолинская'];
|
||||
var oblasts = ['Акмолинская','Карагандинская','Астана','Улытауская'];
|
||||
var cities = ['Шахтинск','Астана','Караганда','Темиртау','Щучинск','Атбасар','Балхаш','Кокшетау'];
|
||||
var inspectors = [
|
||||
'Инженер по БиОТ Семидоцкий С.А.','Ведущий инженер ОБиОТ Туржанов А.Т.',
|
||||
'Инженер ОБиОТ Бачинская Н.В.','Ведущий инженер ОБиОТ Ажакметов М.З.',
|
||||
'Ведущий инженер ОБиОТ Баяхметова Ж.Т.','Инженер ОБиОТ Садыков М.Ф.'
|
||||
];
|
||||
var realCats = ['основные док-ты по БиОТ','Пожарная безопасность','Электробезопасность','СИЗ','Транспортная безопасность','Промышленная безопасность','Санитарно-бытовые условия','организационные требования БиОТ'];
|
||||
var cats = ['основные док-ты по БиОТ','Пожарная безопасность','Электробезопасность','СИЗ','Транспортная безопасность','Промышленная безопасность','Санитарно-бытовые условия','организационные требования БиОТ'];
|
||||
var descs = [
|
||||
'Отсутствует журнал инструктажа','Не проведён повторный инструктаж','Работники не ознакомлены с регламентом СИЗ',
|
||||
'Просроченные диэлектрические перчатки','Неактуальные инструкции по ТБ','Отсутствует аптечка',
|
||||
'Пожарный кран не проверялся','Работники без касок','Прошёл срок поверки инструмента',
|
||||
'Аварийный выход заблокирован','На территории скопление снега'
|
||||
'Отсутствует журнал инструктажа на рабочем месте',
|
||||
'Не проведён повторный инструктаж за 1 квартал 2026',
|
||||
'Работники не ознакомлены с регламентом обеспечения СИЗ',
|
||||
'Форма журнала наряд-допусков не соответствует правилам',
|
||||
'Просроченные диэлектрические перчатки',
|
||||
'Неактуальные инструкции по ТБ по видам работ',
|
||||
'Отсутствует аптечка для оказания первой помощи',
|
||||
'Пожарный кран не проверялся на работоспособность',
|
||||
'Работники не применяли СИЗ (без касок, пояса)',
|
||||
'Прошёл срок поверки инструмента',
|
||||
'Аварийный выход заблокирован',
|
||||
'На территории скопление снега, требуется вывоз'
|
||||
];
|
||||
var laws = [
|
||||
'пп.4, п.2 статьи 182 Трудового кодекса РК',
|
||||
'Приказ №55 МЧС РК от 21.02.2022',
|
||||
'Приказ Министра энергетики РК от 19.03.2015 №222',
|
||||
'Распоряжение №253 от 31.10.2025',
|
||||
'Распоряжение №271 от 19.11.2025',
|
||||
'Приказ №262 от 14.11.2018'
|
||||
];
|
||||
var inspectors = [
|
||||
'Инженер по БиОТ Семидоцкий С.А.',
|
||||
'Ведущий инженер ОБиОТ Туржанов А.Т.',
|
||||
'Инженер ОБиОТ Бачинская Н.В.',
|
||||
'Ведущий инженер ОБиОТ Ажакметов М.З.',
|
||||
'Ведущий инженер ОБиОТ Баяхметова Ж.Т.',
|
||||
'Инженер ОБиОТ Садыков М.Ф.'
|
||||
];
|
||||
var statuses = ['исполнено','исполнено','исполнено','на контроле','на контроле','исполнено','на контроле'];
|
||||
var months = ['01','02','03','04','05','06'];
|
||||
@ -1826,11 +1875,18 @@ body {
|
||||
var lines = [header];
|
||||
for (var i = 0; i < 200; i++) {
|
||||
var d = String(Math.floor(Math.random()*28)+1).padStart(2,'0') + '.' + months[Math.floor(Math.random()*months.length)] + '.2026';
|
||||
lines.push([d, filials[Math.floor(Math.random()*filials.length)], oblasts[Math.floor(Math.random()*oblasts.length)],
|
||||
cities[Math.floor(Math.random()*cities.length)], 'ул. Примерная '+(Math.floor(Math.random()*50)+1),
|
||||
realCats[Math.floor(Math.random()*realCats.length)], descs[Math.floor(Math.random()*descs.length)],
|
||||
'', statuses[Math.floor(Math.random()*statuses.length)],
|
||||
inspectors[Math.floor(Math.random()*inspectors.length)], ''].join(','));
|
||||
lines.push([
|
||||
i+1, d, Math.floor(Math.random()*20)+1,
|
||||
filials[Math.floor(Math.random()*filials.length)],
|
||||
oblasts[Math.floor(Math.random()*oblasts.length)],
|
||||
cities[Math.floor(Math.random()*cities.length)],
|
||||
'ул. Примерная ' + (Math.floor(Math.random()*50)+1),
|
||||
cats[Math.floor(Math.random()*cats.length)],
|
||||
descs[Math.floor(Math.random()*descs.length)],
|
||||
laws[Math.floor(Math.random()*laws.length)],
|
||||
d, statuses[Math.floor(Math.random()*statuses.length)],
|
||||
'', inspectors[Math.floor(Math.random()*inspectors.length)], ''
|
||||
].join(','));
|
||||
}
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user