feat: document upload — real files (PDF/Word/Excel) extracted and fed into analysis

This commit is contained in:
wasrusgen 2026-05-30 13:18:13 +03:00
parent ade80274ff
commit deba1b0852

View File

@ -207,7 +207,15 @@ body{font-family:'Inter',sans-serif;background:var(--bg);color:var(--text);displ
<!-- Этап 3 — Документы --> <!-- Этап 3 — Документы -->
<div class="sv" id="sv3"> <div class="sv" id="sv3">
<div class="hero"><div class="hero-ic">📁</div><div><div class="hero-tag">Этап 3 из 5</div><div class="hero-h">Документы</div><div class="hero-d">Загрузите материалы — Елена учтёт их в анализе</div></div></div> <div class="hero"><div class="hero-ic">📁</div><div><div class="hero-tag">Этап 3 из 5</div><div class="hero-h">Документы</div><div class="hero-d">Загрузите материалы — Елена учтёт их в анализе</div></div></div>
<div class="scroll"><div class="pad"><div class="drop"><div class="drop-ic">📎</div><div style="font-size:14px;font-weight:600;margin-bottom:4px">Перетащите документы сюда</div><div style="font-size:12px;color:#9ca3af">Прайс, оргструктура, отчёты — что есть</div><button class="btn btn-p" style="margin-top:14px">Выбрать файлы</button></div></div></div> <div class="scroll"><div class="pad">
<div class="drop" id="dropZone" onclick="document.getElementById('fileInp').click()">
<div class="drop-ic">📎</div>
<div style="font-size:14px;font-weight:600;margin-bottom:4px">Нажмите или перетащите документы</div>
<div style="font-size:12px;color:#9ca3af">PDF, Word, Excel, txt · прайс, оргструктура, отчёты</div>
<input type="file" id="fileInp" multiple style="display:none" onchange="handleFiles(this.files)">
</div>
<div id="docList" style="max-width:520px;margin:16px auto 0"></div>
</div></div>
</div> </div>
<!-- Этап 4 — Анализ --> <!-- Этап 4 — Анализ -->
@ -244,6 +252,7 @@ function go(n){
document.querySelectorAll('.si').forEach(s=>s.classList.remove('active')); document.querySelectorAll('.si').forEach(s=>s.classList.remove('active'));
document.getElementById('si'+n).classList.add('active'); document.getElementById('si'+n).classList.add('active');
if(PCTS[n]!=null){document.getElementById('pbPct').textContent=PCTS[n]+'%';document.getElementById('pbFill').style.width=PCTS[n]+'%';} if(PCTS[n]!=null){document.getElementById('pbPct').textContent=PCTS[n]+'%';document.getElementById('pbFill').style.width=PCTS[n]+'%';}
if(n===3)renderDocs();
if(n===4)renderAnalysis(); if(n===4)renderAnalysis();
if(n===5)renderSpecPane(); if(n===5)renderSpecPane();
} }
@ -298,6 +307,27 @@ function fillProfile(){
if(state.niche)document.getElementById("pfNiche").value=state.niche; if(state.niche)document.getElementById("pfNiche").value=state.niche;
if(state.description)document.getElementById("pfDesc").value=state.description; if(state.description)document.getElementById("pfDesc").value=state.description;
} }
/* ── Документы (Этап 3) ── */
function renderDocs(){
const dl=document.getElementById("docList");if(!dl)return;
const docs=state.documents||[];
dl.innerHTML=docs.length?docs.map(d=>`<div style="display:flex;align-items:center;gap:10px;background:var(--white);border:1px solid var(--border);border-radius:10px;padding:11px 14px;margin-bottom:8px"><span style="font-size:18px">📄</span><div style="flex:1"><div style="font-size:13px;font-weight:600">${esc(d.filename)}</div><div style="font-size:11px;color:#9ca3af">${(d.size/1024).toFixed(0)} КБ · учтён в анализе</div></div><span style="color:var(--primary);font-weight:700;font-size:13px"></span></div>`).join(""):'<div style="text-align:center;color:#cbd5e1;font-size:13px;padding:10px">Документов пока нет</div>';
}
async function handleFiles(files){
const dl=document.getElementById("docList");
for(const f of files){
const tmp=document.createElement("div");tmp.style.cssText="background:var(--white);border:1px solid var(--border);border-radius:10px;padding:11px 14px;margin-bottom:8px;font-size:13px";tmp.innerHTML=`<span class="spin"></span> ${esc(f.name)} — загрузка...`;dl.prepend(tmp);
try{
const b64=await new Promise((res,rej)=>{const r=new FileReader();r.onload=()=>res(r.result);r.onerror=rej;r.readAsDataURL(f)});
const r=await fetch(`${API}/api/upload`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({token,filename:f.name,content:b64})});
const d=await r.json();
if(d.error){tmp.innerHTML=`❌ ${esc(f.name)}: ${d.error}`;continue}
state.documents=state.documents||[];state.documents.push({filename:d.filename,size:d.size});
}catch(e){tmp.innerHTML=`❌ ${esc(f.name)}: ${e.message}`;continue}
}
renderDocs();
}
function renderAll(){ function renderAll(){
if(state.client_name)document.getElementById("hdrClient").textContent="· "+state.client_name; if(state.client_name)document.getElementById("hdrClient").textContent="· "+state.client_name;
chat.innerHTML=""; chat.innerHTML="";