v1.0.20: Полный цикл + промпт-редактор
This commit is contained in:
@@ -64,7 +64,7 @@
|
|||||||
<body>
|
<body>
|
||||||
<div class="topbar">
|
<div class="topbar">
|
||||||
<img src="/nubes-logo.svg" alt="Nubes">
|
<img src="/nubes-logo.svg" alt="Nubes">
|
||||||
<span class="title">Сверка договоров <span style="font-weight:400;color:var(--muted);font-size:12px;">v1.0.19 — Lucee</span></span>
|
<span class="title">Сверка договоров <span style="font-weight:400;color:var(--muted);font-size:12px;">v1.0.20 — Lucee</span></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
@@ -99,10 +99,14 @@
|
|||||||
Обработка
|
Обработка
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
<div style="margin-bottom:8px;">
|
||||||
|
<textarea id="promptEditor" style="width:100%;height:120px;font-family:monospace;font-size:11px;border:1px solid var(--brand-gray);border-radius:6px;padding:8px;" placeholder="Промпт для LLM (оставьте пустым для стандартного)..."></textarea>
|
||||||
|
</div>
|
||||||
<div class="flex-row">
|
<div class="flex-row">
|
||||||
<button class="btn btn-primary" id="btnParse">Парсинг</button>
|
<button class="btn btn-primary" id="btnParse">Парсинг</button>
|
||||||
<button class="btn btn-primary" id="btnExtract">LLM-извлечение</button>
|
<button class="btn btn-primary" id="btnExtract">LLM-извлечение</button>
|
||||||
<button class="btn btn-primary" id="btnDiffer">Сравнить</button>
|
<button class="btn btn-primary" id="btnDiffer">Сравнить</button>
|
||||||
|
<button class="btn btn-primary" id="btnFull" style="background:var(--green);border-color:var(--green);">⚡ Полный цикл</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="log"></div>
|
<div id="log"></div>
|
||||||
</div>
|
</div>
|
||||||
@@ -370,6 +374,68 @@ document.getElementById('btnDiffer').addEventListener('click', async function()
|
|||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ── Полный цикл: парсинг → LLM → сравнение ────────────────
|
||||||
|
document.getElementById('btnFull').addEventListener('click', async function() {
|
||||||
|
var btn = this; btn.disabled = true; log('⚡ Полный цикл...');
|
||||||
|
// 1. Парсинг
|
||||||
|
for (var i = 0; i < fileQueue.length; i++) {
|
||||||
|
var f = fileQueue[i];
|
||||||
|
if (!f.doc_id || f.parsed) continue;
|
||||||
|
try {
|
||||||
|
var resp = await fetch('/parser.cfm?doc_id=' + f.doc_id);
|
||||||
|
var d = await resp.json();
|
||||||
|
if (d.OK) { f.element_count = d.ELEMENT_COUNT; f.parsed = true; f.status = 'parsed (' + d.ELEMENT_COUNT + ')'; log('📄 ' + f.name + ': ' + d.ELEMENT_COUNT + ' эл.'); }
|
||||||
|
else { log('❌ ' + f.name + ': ' + (d.ERROR||'')); }
|
||||||
|
} catch(e) { log('❌ ' + f.name + ': ' + e.message); }
|
||||||
|
renderTable();
|
||||||
|
}
|
||||||
|
// 2. LLM-извлечение
|
||||||
|
try {
|
||||||
|
var resp = await fetch('/api.cfm?action=query&sql=' + encodeURIComponent("SELECT s.id,d.filename FROM supplements s JOIN documents d ON s.document_id=d.id WHERE s.contract_id='" + contractId + "' ORDER BY s.created_at"));
|
||||||
|
var data = await resp.json();
|
||||||
|
if (data.OK && data.ROWS) {
|
||||||
|
for (var i = 0; i < data.ROWS.length; i++) {
|
||||||
|
var row = data.ROWS[i];
|
||||||
|
try {
|
||||||
|
var er = await fetch('/extractor.cfm?supplement_id=' + row.id);
|
||||||
|
var ed = await er.json();
|
||||||
|
if (ed.OK) { log('🤖 ' + row.filename + ': ' + ed.ROWS_SAVED + ' строк'); }
|
||||||
|
else { log('❌ ' + row.filename + ': ' + (ed.ERROR||'')); }
|
||||||
|
} catch(e) { log('❌ ' + row.filename + ': ' + e.message); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(e) { log('❌ ' + e.message); }
|
||||||
|
// 3. Сравнение
|
||||||
|
try {
|
||||||
|
var resp = await fetch('/differ.cfm?contract_id=' + contractId);
|
||||||
|
var data = await resp.json();
|
||||||
|
if (data.OK) {
|
||||||
|
var s = data.SUMMARY;
|
||||||
|
log('🔍 Изменено: ' + (s.CHANGED||0) + ', Добавлено: ' + (s.ADDED||0) + ', Удалено: ' + (s.DELETED||0));
|
||||||
|
var html = '<p style="margin-bottom:8px;"><b>Изменено:</b> ' + (s.CHANGED||0) + ' <b>Добавлено:</b> ' + (s.ADDED||0) + ' <b>Удалено:</b> ' + (s.DELETED||0) + ' <b>Без изменений:</b> ' + (s.UNCHANGED||0) + '</p>';
|
||||||
|
html += '<table><tr><th>#</th><th>Тип</th><th>Услуга</th><th>Цена</th><th>Кол-во</th><th>Сумма</th></tr>';
|
||||||
|
for (var i = 0; i < data.CHANGES.length; i++) {
|
||||||
|
var c = data.CHANGES[i];
|
||||||
|
var cls = c.CHANGE_TYPE === 'added' ? 'diff-added' : (c.CHANGE_TYPE === 'deleted' ? 'diff-deleted' : (c.CHANGE_TYPE === 'changed' ? 'diff-changed' : ''));
|
||||||
|
var vals = c.NEW_VALUES && Object.keys(c.NEW_VALUES).length > 0 ? c.NEW_VALUES : c.OLD_VALUES;
|
||||||
|
html += '<tr class="' + cls + '"><td>' + c.ROW_NUM + '</td><td>' + c.CHANGE_TYPE + '</td><td style="max-width:300px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">' + (vals.NAME||'') + '</td><td>' + (vals.PRICE||'') + '</td><td>' + (vals.QTY||'') + '</td><td>' + (vals.SUM||'') + '</td></tr>';
|
||||||
|
}
|
||||||
|
html += '</table>';
|
||||||
|
document.getElementById('diffBody').innerHTML = html;
|
||||||
|
document.getElementById('diffCard').style.display = 'block';
|
||||||
|
} else { log('❌ ' + (data.ERROR||'')); }
|
||||||
|
} catch(e) { log('❌ ' + e.message); }
|
||||||
|
log('✅ Полный цикл завершён');
|
||||||
|
btn.disabled = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// ── Промпт ─────────────────────────────────────────────────
|
||||||
|
var promptEditor = document.getElementById('promptEditor');
|
||||||
|
promptEditor.value = localStorage.getItem('llm_prompt') || '';
|
||||||
|
promptEditor.addEventListener('input', function() {
|
||||||
|
localStorage.setItem('llm_prompt', this.value);
|
||||||
|
});
|
||||||
|
|
||||||
// ── Чат ───────────────────────────────────────────────────
|
// ── Чат ───────────────────────────────────────────────────
|
||||||
document.getElementById('chatSend').addEventListener('click', async function() {
|
document.getElementById('chatSend').addEventListener('click', async function() {
|
||||||
var input = document.getElementById('chatInput');
|
var input = document.getElementById('chatInput');
|
||||||
|
|||||||
Reference in New Issue
Block a user