v84: add period selector to reports, quantity+notes to events modal

This commit is contained in:
Dauren777 2026-06-10 04:15:46 +00:00
parent 24fd146b10
commit c43e733419

View File

@ -109,11 +109,26 @@ tr:hover{background:#FAFBFC}
<div class="card"><h3>TOP-10 проблемных мероприятий</h3><div id="an_top"></div></div>
</div>
<div id="tab_reports" style="display:none">
<div class="fr"><span style="font-size:13px;color:#64748B">Сформировать отчёт:</span>
<div class="fr">
<span style="font-size:13px;color:#64748B">Период:</span>
<select id="rp_month" style="padding:6px 10px;border:1px solid #E2E8F0;border-radius:6px">
<option value="0">Январь</option><option value="1">Февраль</option><option value="2">Март</option>
<option value="3">Апрель</option><option value="4">Май</option><option value="5">Июнь</option>
<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" 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()">
<option value="">Все статусы</option>
<option value="wait">Не начато</option><option value="warn">В процессе</option>
<option value="done">Исполнено</option><option value="late">Просрочено</option>
</select>
<button class="btn btn-sm btn-g" onclick="dlCSV()">CSV</button>
<button class="btn btn-sm" onclick="dlHTML()">HTML</button>
</div>
<div class="card" id="rp_preview"><p style="color:#64748B;font-size:13px">Нажми кнопку для скачивания</p></div>
<div class="card" id="rp_preview"></div>
</div>
<div id="tab_ai" style="display:none">
<div class="card">
@ -210,7 +225,9 @@ function loadEv(){
e.s=smap[e.id].s||e.s;
if(smap[e.id].p!==undefined)e.p=smap[e.id].p;
if(smap[e.id].done)e.done=smap[e.id].done;
if(smap[e.id].h)e.h=smap[e.id].h
if(smap[e.id].h)e.h=smap[e.id].h;
if(smap[e.id].q!==undefined)e.q=smap[e.id].q;
if(smap[e.id].n!==undefined)e.n=smap[e.id].n
}
evs.push(e)
}
@ -220,7 +237,7 @@ function loadEv(){
function saveEv(){
var out=[];
for(var i=0;i<evs.length;i++){
out.push({id:evs[i].id,s:evs[i].s,p:evs[i].p,done:evs[i].done,h:evs[i].h})
out.push({id:evs[i].id,s:evs[i].s,p:evs[i].p,done:evs[i].done,h:evs[i].h,q:evs[i].q,n:evs[i].n})
}
try{localStorage.setItem("se5",JSON.stringify(out))}catch(e){}
storCheck()
@ -357,6 +374,20 @@ function openEv(id){
h+="</ul></div>"
}
h+="<div style='margin-bottom:12px;padding:10px;background:#F0F9FF;border-radius:8px'><strong>AI-анализ:</strong> <span style='font-size:13px;color:#64748B'>"+esc(e.ai||"\u2014")+"</span></div>";
h+="<div style='margin-bottom:12px'><strong>Отчётность:</strong></div>";
h+="<div style='margin-bottom:8px;display:flex;gap:8px;flex-wrap:wrap;align-items:center'>";
h+="<span style='font-size:12px'>Количество:</span> <input type='number' id='evq_"+e.id+"' value='"+(e.q||"")+"' min='0' style='width:80px;padding:4px;border:1px solid #E2E8F0;border-radius:4px;font-size:12px'>";
var now=new Date();
var curMonth=now.getMonth();
h+="<span style='font-size:12px;margin-left:8px'>Месяц:</span> <select id='evm_"+e.id+"' style='padding:4px;border:1px solid #E2E8F0;border-radius:4px;font-size:12px'>";
var mnames=["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"];
for(var mi=0;mi<12;mi++){
h+="<option value='"+mi+"'";
if(mi===curMonth)h+=" selected";
h+=">"+mnames[mi]+"</option>"
}
h+="</select></div>";
h+="<div style='margin-bottom:12px'><textarea id='evn_"+e.id+"' placeholder='Примечание / описание выполнения...' style='width:100%;padding:8px;border:1px solid #E2E8F0;border-radius:6px;font-size:12px;resize:vertical;min-height:50px'>"+esc(e.n||"")+"</textarea></div>";
h+="<div style='margin-bottom:12px'><strong>Файлы:</strong>";
var fk="sf_"+e.id;
var fd=localStorage.getItem(fk);
@ -398,10 +429,14 @@ function closeModal(){
function saveEvModal(id){
var sel=document.getElementById("evs_"+id);
var inp=document.getElementById("evp_"+id);
var inq=document.getElementById("evq_"+id);
var inn=document.getElementById("evn_"+id);
for(var i=0;i<evs.length;i++){
if(evs[i].id===id){
if(sel)evs[i].s=sel.value;
if(inp)evs[i].p=parseInt(inp.value,10)||0;
if(inq)evs[i].q=parseInt(inq.value,10)||0;
if(inn)evs[i].n=inn.value.trim();
if(sel&&sel.value==="done"&&(evs[i].done==="\u2014"||!evs[i].done)){
var d=new Date();
evs[i].done=d.getDate()+"."+String(d.getMonth()+1).padStart(2,"0")+"."+d.getFullYear()
@ -573,35 +608,70 @@ function renderAnalytics(){
}
}
function renderReports(){}
function dlCSV(){
var csv="\uFEFFN;\u041C\u0435\u0440\u043E\u043F\u0440\u0438\u044F\u0442\u0438\u0435;\u0420\u0430\u0437\u0434\u0435\u043B;\u0424\u0438\u043B\u0438\u0430\u043B;\u0421\u0440\u043E\u043A;\u0421\u0442\u0430\u0442\u0443\u0441;\u041F\u0440\u043E\u0433\u0440\u0435\u0441\u0441;\u041E\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043D\u043D\u044B\u0439\n";
function getFilteredEvs(){
var month=parseInt(document.getElementById("rp_month").value,10)||0;
var year=parseInt(document.getElementById("rp_year").value,10)||2026;
var statusF=document.getElementById("rp_status").value;
var r=[];
for(var i=0;i<evs.length;i++){
var e=evs[i];
csv+=e.id+";\""+esc(e.t)+"\";\""+secs[e.sec]+"\";\""+brs[e.b]+"\";"+e.due+";"+stn[e.s]+";"+(e.p||0)+"%;\""+esc(nl2c(e.r))+"\"\n"
if(statusF&&e.s!==statusF)continue;
var dp=e.due.split(".");
if(dp.length===3){
var em=parseInt(dp[1],10)-1;
var ey=parseInt(dp[2],10);
if(em===month&&ey===year)r.push(e)
}
}
return r
}
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
}
function dlCSV(){
var fl=getFilteredEvs();
var csv="\uFEFFN;\u041C\u0435\u0440\u043E\u043F\u0440\u0438\u044F\u0442\u0438\u0435;\u0424\u0438\u043B\u0438\u0430\u043B;\u0421\u0440\u043E\u043A;\u0421\u0442\u0430\u0442\u0443\u0441;\u041F\u0440\u043E\u0433\u0440\u0435\u0441\u0441;\u041A\u043E\u043B-\u0432\u043E;\u041F\u0440\u0438\u043C\u0435\u0447\u0430\u043D\u0438\u0435;\u041E\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043D\u043D\u044B\u0439\n";
for(var i=0;i<fl.length;i++){
var e=fl[i];
csv+=e.id+";\""+esc(e.t)+"\";\""+brs[e.b]+"\";"+e.due+";"+stn[e.s]+";"+(e.p||0)+"%;"+(e.q||"")+";\""+esc(e.n||"")+"\";\""+esc(nl2c(e.r))+"\"\n"
}
var blob=new Blob([csv],{type:"text/csv;charset=utf-8"});
var a=document.createElement("a");
a.href=URL.createObjectURL(blob);
a.download="plan_pb_2026.csv";
a.download="report_"+document.getElementById("rp_year").value+"_"+(parseInt(document.getElementById("rp_month").value,10)+1)+".csv";
a.click()
}
function dlHTML(){
var hh="<!DOCTYPE html><html><head><meta charset='utf-8'><title>\u041E\u0442\u0447\u0451\u0442 \u041F\u043B\u0430\u043D \u041F\u0411 2026</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 \u043C\u0435\u0440\u043E\u043F\u0440\u0438\u044F\u0442\u0438\u0439 \u043F\u043E \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 2026</h2><p>AO \u00AB\u041A\u0430\u0437\u0430\u0445\u0442\u0435\u043B\u0435\u043A\u043E\u043C\u00BB</p><br><table><tr><th>N</th><th>\u041C\u0435\u0440\u043E\u043F\u0440\u0438\u044F\u0442\u0438\u0435</th><th>\u0420\u0430\u0437\u0434\u0435\u043B</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></tr>";
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;
for(var i=0;i<evs.length;i++){
var e=evs[i];
if(e.sec!==lastSec){
hh+="<tr class='s'><td colspan='7'>"+esc(secs[e.sec])+"</td></tr>";
lastSec=e.sec
}
hh+="<tr><td>"+e.id+"</td><td>"+esc(e.t)+"</td><td>"+esc(e.dname)+"</td><td>"+brs[e.b]+"</td><td>"+e.due+"</td><td>"+stn[e.s]+"</td><td>"+(e.p||0)+"%</td></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+="</table></body></html>";
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>";
var blob=new Blob([hh],{type:"text/html"});
var a=document.createElement("a");
a.href=URL.createObjectURL(blob);
a.download="report_pb_2026.html";
a.download="report_pb_"+year+"_"+month+".html";
a.click()
}