v3: авто-режим — шаблон отметок + автоприменение + автовыгрузка

This commit is contained in:
Dauren777 2026-06-24 05:41:04 +00:00
parent 7e68575be5
commit 5c2a822f2d

View File

@ -123,6 +123,16 @@ tbody tr.marked:hover{background:var(--green-bg)}
</label> </label>
</div> </div>
<div style="display:flex;flex-wrap:wrap;gap:8px;margin-bottom:12px;padding:12px 16px;background:var(--white);border-radius:12px;border:2px solid var(--cyan)">
<label class="check-filter" style="padding:0">
<input type="checkbox" id="autoMode"> 🤖 Авто-режим (применить шаблон и скачать)
</label>
<span style="flex:1"></span>
<button class="btn btn-sm btn-outline" id="saveTemplateBtn">💾 Сохранить шаблон</button>
<button class="btn btn-sm btn-outline" id="loadTemplateBtn">📂 Применить шаблон</button>
<span id="templateStatus" style="font-size:13px;color:var(--gray-500);align-self:center"></span>
</div>
<div class="actions" id="batchActions" style="margin-bottom:16px"> <div class="actions" id="batchActions" style="margin-bottom:16px">
<button class="btn btn-sm" id="markAllBtn">✅ Отметить все в фильтре</button> <button class="btn btn-sm" id="markAllBtn">✅ Отметить все в фильтре</button>
<button class="btn btn-sm btn-outline" id="unmarkAllBtn">✕ Снять все</button> <button class="btn btn-sm btn-outline" id="unmarkAllBtn">✕ Снять все</button>
@ -349,6 +359,48 @@ function toggleGroup(groupName) {
renderTable(); renderTable();
} }
const TEMPLATE_KEY = 'snp_marked_template';
function saveTemplate() {
if (markedIds.size === 0) { alert('Нет отмеченных пунктов. Сначала отметьте.'); return; }
const arr = [...markedIds].filter(id => !id.startsWith('row_'));
if (arr.length === 0) { alert('Не найдены КАТО-коды. Отметка работает только если в файле есть колонка КАТО.'); return; }
localStorage.setItem(TEMPLATE_KEY, JSON.stringify(arr));
document.getElementById('templateStatus').textContent = `✅ Шаблон сохранён (${arr.length} кодов)`;
setTimeout(() => document.getElementById('templateStatus').textContent = '', 3000);
}
function loadTemplate() {
const raw = localStorage.getItem(TEMPLATE_KEY);
if (!raw) { alert('Нет сохранённого шаблона. Сначала отметьте пункты и сохраните.'); return; }
const saved = JSON.parse(raw);
let found = 0;
allData.forEach(r => {
if (saved.includes(r._id)) { markedIds.add(r._id); found++; }
});
renderTable();
document.getElementById('templateStatus').textContent = `📂 Применено: ${found} совпадений`;
setTimeout(() => document.getElementById('templateStatus').textContent = '', 3000);
}
function autoProcess() {
const raw = localStorage.getItem(TEMPLATE_KEY);
if (!raw) return;
const saved = JSON.parse(raw);
let found = 0;
allData.forEach(r => {
if (saved.includes(r._id)) { markedIds.add(r._id); found++; }
});
renderTable();
if (found > 0) {
setTimeout(() => {
document.getElementById('exportBtn').click();
document.getElementById('templateStatus').textContent = `🤖 Авто: отмечено ${found}, файл скачан`;
setTimeout(() => document.getElementById('templateStatus').textContent = '', 4000);
}, 500);
}
}
function handleFile(file) { function handleFile(file) {
const reader = new FileReader(); const reader = new FileReader();
reader.onload = function(e) { reader.onload = function(e) {
@ -370,8 +422,8 @@ function handleFile(file) {
}); });
allData.columns = headers; allData.columns = headers;
// init marked from localStorage
markedIds = new Set(); markedIds = new Set();
updateTemplateStatus();
const zone = document.getElementById('dropZone'); const zone = document.getElementById('dropZone');
zone.classList.add('has-file'); zone.classList.add('has-file');
@ -381,6 +433,10 @@ function handleFile(file) {
renderFilters(); renderFilters();
applyFilter(); applyFilter();
document.getElementById('resultArea').classList.remove('hidden'); document.getElementById('resultArea').classList.remove('hidden');
if (document.getElementById('autoMode').checked) {
autoProcess();
}
} catch(err) { } catch(err) {
alert('Ошибка: ' + err.message); alert('Ошибка: ' + err.message);
} }
@ -388,6 +444,17 @@ function handleFile(file) {
reader.readAsArrayBuffer(file); reader.readAsArrayBuffer(file);
} }
function updateTemplateStatus() {
const raw = localStorage.getItem(TEMPLATE_KEY);
const el = document.getElementById('templateStatus');
if (raw) {
const saved = JSON.parse(raw);
el.textContent = `📁 Шаблон: ${saved.length} кодов`;
} else {
el.textContent = '';
}
}
document.getElementById('fileInput').onchange = e => { if (e.target.files[0]) handleFile(e.target.files[0]); }; document.getElementById('fileInput').onchange = e => { if (e.target.files[0]) handleFile(e.target.files[0]); };
const dz = document.getElementById('dropZone'); const dz = document.getElementById('dropZone');
dz.onclick = () => document.getElementById('fileInput').click(); dz.onclick = () => document.getElementById('fileInput').click();
@ -395,6 +462,10 @@ dz.ondragover = e => { e.preventDefault(); dz.classList.add('dragover'); };
dz.ondragleave = () => dz.classList.remove('dragover'); dz.ondragleave = () => dz.classList.remove('dragover');
dz.ondrop = e => { e.preventDefault(); dz.classList.remove('dragover'); if (e.dataTransfer.files[0]) handleFile(e.dataTransfer.files[0]); }; dz.ondrop = e => { e.preventDefault(); dz.classList.remove('dragover'); if (e.dataTransfer.files[0]) handleFile(e.dataTransfer.files[0]); };
document.getElementById('saveTemplateBtn').onclick = saveTemplate;
document.getElementById('loadTemplateBtn').onclick = loadTemplate;
updateTemplateStatus();
document.getElementById('markAllBtn').onclick = () => { document.getElementById('markAllBtn').onclick = () => {
const btn = document.getElementById('markAllBtn'); const btn = document.getElementById('markAllBtn');
const allMarked = filteredData.length > 0 && filteredData.every(r => markedIds.has(r._id)); const allMarked = filteredData.length > 0 && filteredData.every(r => markedIds.has(r._id));