v92: reports cleanup, no ranking, HTML export with files

This commit is contained in:
Dauren777 2026-06-10 06:48:10 +00:00
parent d15064d624
commit d807e15dc1

View File

@ -106,10 +106,11 @@ tr:hover{background:#FAFBFC}
</div>
<div id="tab_analytics" style="display:none">
<div class="stat-grid" id="an_stats"></div>
<div class="card"><h3>Рейтинг филиалов</h3><div id="an_ranking"></div></div>
<div class="card"><h3>TOP-10 проблемных мероприятий</h3><div id="an_top"></div></div>
</div>
<div id="tab_reports" style="display:none">
<div class="card"><h3>Выгрузка сводного отчёта</h3>
<p style="font-size:13px;color:#64748B;margin-bottom:12px">Выберите период и формат для скачивания отчёта.</p>
<div class="fr">
<span style="font-size:13px;color:#64748B">Период:</span>
<select id="rp_period" style="padding:6px 10px;border:1px solid #E2E8F0;border-radius:6px" onchange="rpPeriodChange()">
@ -121,7 +122,6 @@ tr:hover{background:#FAFBFC}
<option value="q4">Октябрь-Декабрь (Q4)</option>
<option value="h1">1-е полугодие</option>
<option value="h2">2-е полугодие</option>
<option value="year">Год</option>
</select>
<select id="rp_month" onchange="renderReports()" style="padding:6px 10px;border:1px solid #E2E8F0;border-radius:6px;display:none">
<option value="0">Январь</option><option value="1">Февраль</option><option value="2">Март</option>
@ -129,20 +129,26 @@ tr:hover{background:#FAFBFC}
<option value="6">Июль</option><option value="7">Август</option><option value="8">Сентябрь</option>
<option value="9">Октябрь</option><option value="10">Ноябрь</option><option value="11" selected>Декабрь</option>
</select>
<select id="rp_year" onchange="renderReports()" style="padding:6px 10px;border:1px solid #E2E8F0;border-radius:6px">
<select id="rp_year" style="padding:6px 10px;border:1px solid #E2E8F0;border-radius:6px">
<option>2026</option><option>2027</option>
</select>
<select id="rp_status" style="padding:6px 10px;border:1px solid #E2E8F0;border-radius:6px" onchange="renderReports()">
<select id="rp_status" style="padding:6px 10px;border:1px solid #E2E8F0;border-radius:6px">
<option value="">Все статусы</option>
<option value="warn">В процессе</option>
<option value="done">Исполнено</option>
<option value="late">Просрочено</option>
</select>
</div>
<div style="display:flex;gap:8px;flex-wrap:wrap">
<button class="btn btn-sm btn-g" onclick="dlCSV()">CSV</button>
<button class="btn btn-sm" onclick="dlHTML()">HTML</button>
<button class="btn btn-sm btn-o" onclick="dlWord()">Word</button>
<button class="btn btn-sm btn-r" onclick="dlPdf()">PDF</button>
</div>
<p id="rp_count" style="font-size:12px;color:#64748B;margin-top:8px"></p>
</div>
<div class="card" id="rp_preview"></div>
</div>
<div class="card" id="rp_preview"></div>
</div>
<div id="tab_hse" style="display:none">
@ -632,19 +638,6 @@ function renderAnalytics(){
html+="<div class='stat-card'><div class='lb'>В процессе</div><div class='num'>"+warn+"</div></div>";
document.getElementById("an_stats").innerHTML=html;
var brd=[];
for(var i=0;i<brs.length;i++){brd.push({n:brs[i],t:0,d:0})}
for(var i=0;i<evs.length;i++){var e=evs[i];brd[e.b].t++;if(e.s==="done")brd[e.b].d++}
brd.sort(function(a,b){return(b.d/b.t||0)-(a.d/a.t||0)});
var rh="<table><tr><th>\u0424\u0438\u043B\u0438\u0430\u043B</th><th>\u0418\u0441\u043F\u043E\u043B\u043D\u0435\u043D\u043E</th><th>\u0412\u0441\u0435\u0433\u043E</th><th>%</th></tr>";
for(var i=0;i<brd.length;i++){
var pct=brd[i].t?Math.round(brd[i].d/brd[i].t*100):0;
var barCl=pct>50?"#10B981":pct>25?"#F59E0B":"#EF4444";
rh+="<tr><td>"+esc(brd[i].n)+"</td><td>"+brd[i].d+"</td><td>"+brd[i].t+"</td><td>"+pct+"%<div class='rank-bar'><div style='width:"+pct+"%;background:"+barCl+"'></div></div></td></tr>"
}
rh+="</table>";
document.getElementById("an_ranking").innerHTML=rh;
var problem=[];
for(var i=0;i<evs.length;i++){
if(evs[i].s==="late"||evs[i].s==="warn"){
@ -702,22 +695,9 @@ function rpPeriodChange(){
}
function renderReports(){
var fl=getFilteredEvs();
var h="<table><tr><th>N</th><th>\u041C\u0435\u0440\u043E\u043F\u0440\u0438\u044F\u0442\u0438\u0435</th><th>\u0424\u0438\u043B\u0438\u0430\u043B</th><th>\u0421\u0440\u043E\u043A</th><th>\u0421\u0442\u0430\u0442\u0443\u0441</th><th>\u041A\u043E\u043B-\u0432\u043E</th></tr>";
for(var i=0;i<fl.length;i++){
var e=fl[i];
var cl=stc[e.s]||"w";
h+="<tr>";
h+="<td>"+e.id+"</td>";
h+="<td style='font-size:12px'>"+esc(e.t)+"</td>";
h+="<td>"+brs[e.b]+"</td>";
h+="<td>"+e.due+"</td>";
h+="<td><span class='badge "+cl+"'>"+stn[e.s]+"</span></td>";
h+="<td>"+(e.q||"")+"</td>";
h+="</tr>"
}
if(!fl.length)h="<p style='color:#64748B;font-size:13px;text-align:center;padding:20px'>\u041D\u0435\u0442 \u043C\u0435\u0440\u043E\u043F\u0440\u0438\u044F\u0442\u0438\u0439 \u0437\u0430 \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u044B\u0439 \u043F\u0435\u0440\u0438\u043E\u0434</p>";
h+="<p style='margin-top:8px;font-size:12px;color:#64748B'>\u0412\u0441\u0435\u0433\u043E: "+fl.length+" \u043C\u0435\u0440\u043E\u043F\u0440\u0438\u044F\u0442\u0438\u0439</p>";
document.getElementById("rp_preview").innerHTML=h
var cnt=document.getElementById("rp_count");
if(cnt)cnt.textContent="Выбрано мероприятий: "+fl.length;
document.getElementById("rp_preview").innerHTML=""
}
function dlCSV(){
var fl=getFilteredEvs();
@ -736,13 +716,35 @@ function dlHTML(){
var fl=getFilteredEvs();
var month=parseInt(document.getElementById("rp_month").value,10)+1;
var year=document.getElementById("rp_year").value;
var hh="<!DOCTYPE html><html><head><meta charset='utf-8'><title>\u041E\u0442\u0447\u0451\u0442 \u041F\u043B\u0430\u043D \u041F\u0411 "+month+"."+year+"</title><style>body{font:14px Arial;padding:20px}table{border-collapse:collapse;width:100%}th,td{border:1px solid #ccc;padding:6px 10px;font-size:12px;text-align:left}th{background:#0B1A2E;color:#fff}.s{background:#F1F5F9;font-weight:700}</style></head><body><h2>\u041F\u043B\u0430\u043D \u043F\u0440\u043E\u0438\u0437\u0432\u043E\u0434\u0441\u0442\u0432\u0435\u043D\u043D\u043E\u0439 \u0431\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u043E\u0441\u0442\u0438</h2><p>AO \u00AB\u041A\u0430\u0437\u0430\u0445\u0442\u0435\u043B\u0435\u043A\u043E\u043C\u00BB \u0437\u0430 "+month+"."+year+"</p><br><table><tr><th>N</th><th>\u041C\u0435\u0440\u043E\u043F\u0440\u0438\u044F\u0442\u0438\u0435</th><th>\u0424\u0438\u043B\u0438\u0430\u043B</th><th>\u0421\u0440\u043E\u043A</th><th>\u0421\u0442\u0430\u0442\u0443\u0441</th><th>\u041F\u0440\u043E\u0433\u0440\u0435\u0441\u0441</th><th>\u041A\u043E\u043B-\u0432\u043E</th><th>\u041F\u0440\u0438\u043C\u0435\u0447\u0430\u043D\u0438\u0435</th></tr>";
var lastSec=-1;
var hh="<!DOCTYPE html><html><head><meta charset='utf-8'><title>Отчёт План ПБ "+month+"."+year+"</title><style>body{font:14px Arial;padding:20px}table{border-collapse:collapse;width:100%}th,td{border:1px solid #ccc;padding:6px 10px;font-size:12px;text-align:left}th{background:#0B1A2E;color:#fff}.s{background:#F1F5F9;font-weight:700}</style></head><body><h2>План производственной безопасности</h2><p>AO Казахтелеком за "+month+"."+year+"</p><br><table><tr><th>N</th><th>Мероприятие</th><th>Срок</th><th>Статус</th><th>Кол-во</th><th>Примечание</th></tr>";
for(var i=0;i<fl.length;i++){
var e=fl[i];
hh+="<tr><td>"+e.id+"</td><td>"+esc(e.t)+"</td><td>"+brs[e.b]+"</td><td>"+e.due+"</td><td>"+stn[e.s]+"</td><td>"+(e.p||0)+"%</td><td>"+(e.q||"")+"</td><td>"+esc(e.n||"")+"</td></tr>"
hh+="<tr><td>"+e.id+"</td><td>"+esc(e.t)+"</td><td>"+e.due+"</td><td>"+stn[e.s]+"</td><td>"+(e.q||"")+"</td><td>"+esc(e.n||"")+"</td></tr>"
}
hh+="</table><p><br><em>\u041E\u0442\u0447\u0451\u0442 \u0441\u0444\u043E\u0440\u043C\u0438\u0440\u043E\u0432\u0430\u043D: "+new Date().toLocaleDateString("ru-RU")+"</em></p></body></html>";
hh+="</table>";
hh+="<br><h3>Приложенные файлы</h3>";
var hasFiles=false;
for(var i=0;i<fl.length;i++){
var e=fl[i];
var k="sf_"+e.id;
var fd=localStorage.getItem(k);
if(fd){
try{
var arr=JSON.parse(fd);
if(arr.length){
hasFiles=true;
hh+="<p><strong>N"+e.id+":</strong>";
for(var fi=0;fi<arr.length;fi++){
var f=arr[fi];
if(f.s&&f.n)hh+="<br><a href='"+f.data+"' download='"+esc(f.n)+"'>"+esc(f.n)+" ("+Math.round(f.s/1024)+" KB)</a>"
}
hh+="</p>"
}
}catch(ex){}
}
}
if(!hasFiles)hh+="<p>Нет приложенных файлов</p>";
hh+="<p><br><em>Отчёт сформирован: "+new Date().toLocaleDateString("ru-RU")+"</em></p></body></html>";
var blob=new Blob([hh],{type:"text/html"});
var a=document.createElement("a");
a.href=URL.createObjectURL(blob);