fix: all improvements — month selector, LTIF corrections, roles, report format, analytics dashboard, PPT fix
This commit is contained in:
parent
6ecbf866b5
commit
b5714a6971
206
index.html
206
index.html
@ -109,6 +109,7 @@ tr:hover{background:#FAFBFC}
|
||||
<div id="tab_analytics" style="display:none">
|
||||
<div class="stat-grid" id="an_stats"></div>
|
||||
<div class="card"><h3>TOP-10 проблемных мероприятий</h3><div id="an_top"></div></div>
|
||||
<div class="card"><h3>Выполнение по разделам</h3><div id="an_sections"></div></div>
|
||||
<div style="display:flex;gap:8px;margin-bottom:16px">
|
||||
<button class="btn btn-sm btn-o" onclick="dlAnalyticsPPT()">Скачать PPT</button>
|
||||
<button class="btn btn-sm btn-r" onclick="dlAnalyticsPDF()">Скачать PDF</button>
|
||||
@ -133,6 +134,7 @@ tr:hover{background:#FAFBFC}
|
||||
</div>
|
||||
<div id="ltif_result" style="font-size:14px;padding:8px 0"></div>
|
||||
<div id="ltif_table"></div>
|
||||
<div id="ltif_corr_div"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="tab_reports" style="display:none">
|
||||
@ -223,11 +225,13 @@ tr:hover{background:#FAFBFC}
|
||||
<div class="mod-box" style="max-width:500px">
|
||||
<h3 style="margin-bottom:14px">Регистрация пользователя</h3>
|
||||
<div style="margin-bottom:8px"><label style="font-size:12px;color:#64748B">Email (логин)</label>
|
||||
<input id="reg_email" placeholder="ivanov" style="width:100%;padding:8px;border:1px solid #E2E8F0;border-radius:6px;font-size:13px"></div>
|
||||
<input id="reg_email" placeholder="ivanov@telecom.kz" style="width:100%;padding:8px;border:1px solid #E2E8F0;border-radius:6px;font-size:13px"></div>
|
||||
<div style="margin-bottom:8px"><label style="font-size:12px;color:#64748B">ФИО</label>
|
||||
<input id="reg_name" placeholder="Иванов И.И." style="width:100%;padding:8px;border:1px solid #E2E8F0;border-radius:6px;font-size:13px"></div>
|
||||
<div style="margin-bottom:8px"><label style="font-size:12px;color:#64748B">Телефон</label>
|
||||
<input id="reg_phone" placeholder="+77001234567" style="width:100%;padding:8px;border:1px solid #E2E8F0;border-radius:6px;font-size:13px"></div>
|
||||
<div style="margin-bottom:8px"><label style="font-size:12px;color:#64748B">Роль</label>
|
||||
<select id="reg_role" style="width:100%;padding:8px;border:1px solid #E2E8F0;border-radius:6px;font-size:13px"></select></div>
|
||||
<div style="margin-bottom:8px"><label style="font-size:12px;color:#64748B">Филиал</label>
|
||||
<select id="reg_branch" style="width:100%;padding:8px;border:1px solid #E2E8F0;border-radius:6px;font-size:13px"></select></div>
|
||||
<div style="margin-bottom:14px"><label style="font-size:12px;color:#64748B">Пароль</label>
|
||||
@ -235,6 +239,7 @@ tr:hover{background:#FAFBFC}
|
||||
<div style="display:flex;gap:8px;justify-content:flex-end">
|
||||
<button class="btn btn-sm" style="background:#E2E8F0;color:#0B1A2E" onclick="closeRegModal()">Отмена</button>
|
||||
<button class="btn btn-sm btn-g" onclick="addUser()">Зарегистрировать</button>
|
||||
<p style="font-size:11px;color:#64748B;margin-top:8px">На корпоративную почту придёт уведомление о регистрации и напоминания о необходимости представления отчёта</p>
|
||||
</div></div></div>
|
||||
<script>
|
||||
var ALL_EVENTS=[
|
||||
@ -1013,7 +1018,7 @@ function doLogin(){
|
||||
var k=e.split("@")[0];
|
||||
var u=USR[k];
|
||||
if(u){
|
||||
cu={n:u.n,bg:u.bg};
|
||||
cu={n:u.n,bg:u.bg,role:u.role!==undefined?u.role:(u.bg===0?0:1)};
|
||||
localStorage.setItem("su",JSON.stringify(cu));
|
||||
showApp()
|
||||
}else{
|
||||
@ -1034,6 +1039,7 @@ function showApp(){
|
||||
if(unav)unav.style.display=cu&&cu.bg===0?"":"none";
|
||||
var hsenav=document.getElementById("snav_hse");
|
||||
if(hsenav)hsenav.style.display=cu&&cu.bg===0?"":"none";
|
||||
if(cu&&cu.role===2){var anav=document.getElementById("snav_analytics");if(anav)anav.style.display="";var unav2=document.getElementById("snav_users");if(unav2)unav2.style.display="none"}
|
||||
switchTab("events")
|
||||
}
|
||||
|
||||
@ -1218,11 +1224,13 @@ function openEv(id,subIdx){
|
||||
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();
|
||||
var savedMonth=localStorage.getItem("evmonth_"+e.id);
|
||||
var selMonth=savedMonth!==null?parseInt(savedMonth,10):curMonth;
|
||||
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";
|
||||
if(mi===selMonth)h+=" selected";
|
||||
h+=">"+mnames[mi]+"</option>"
|
||||
}
|
||||
h+="</select></div>";
|
||||
@ -1301,6 +1309,8 @@ function saveEvModal(id){
|
||||
break
|
||||
}
|
||||
}
|
||||
var inm=document.getElementById("evm_"+id);
|
||||
if(inm)try{localStorage.setItem("evmonth_"+id,inm.value)}catch(e){}
|
||||
saveEv();
|
||||
closeModal();
|
||||
renderEv()
|
||||
@ -1327,9 +1337,11 @@ function upFile(id){
|
||||
if(f.size>3145728){alert("\u0424\u0430\u0439\u043B \u0431\u043E\u043B\u044C\u0448\u0435 3MB");return}
|
||||
var fr=new FileReader();
|
||||
var subKey=curSub!==null?"_s"+curSub:"";
|
||||
var inm=document.getElementById("evm_"+id);
|
||||
var monthKey=inm?"_m"+inm.value:"";
|
||||
var brKey="_b"+(cu?cu.bg:0);
|
||||
fr.onload=function(){
|
||||
var key="sf_"+id+subKey+brKey;
|
||||
var key="sf_"+id+monthKey+subKey+brKey;
|
||||
var arr=[];
|
||||
var ex=localStorage.getItem(key);
|
||||
if(ex){try{arr=JSON.parse(ex)}catch(e){}}
|
||||
@ -1341,7 +1353,9 @@ function upFile(id){
|
||||
fr.readAsDataURL(f)
|
||||
}
|
||||
function dlFile(id,idx){
|
||||
var key="sf_"+id+(curSub!==null?"_s"+curSub:"")+"_b"+(cu?cu.bg:0);
|
||||
var inm=document.getElementById("evm_"+id);
|
||||
var monthKey=inm?"_m"+inm.value:"";
|
||||
var key="sf_"+id+monthKey+(curSub!==null?"_s"+curSub:"")+"_b"+(cu?cu.bg:0);
|
||||
var ex=localStorage.getItem(key);
|
||||
if(!ex)return;
|
||||
try{
|
||||
@ -1358,7 +1372,9 @@ function dlFile(id,idx){
|
||||
}
|
||||
function delFile(id,idx){
|
||||
if(!confirm("\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0444\u0430\u0439\u043B?"))return;
|
||||
var key="sf_"+id+(curSub!==null?"_s"+curSub:"")+"_b"+(cu?cu.bg:0);
|
||||
var inm=document.getElementById("evm_"+id);
|
||||
var monthKey=inm?"_m"+inm.value:"";
|
||||
var key="sf_"+id+monthKey+(curSub!==null?"_s"+curSub:"")+"_b"+(cu?cu.bg:0);
|
||||
var ex=localStorage.getItem(key);
|
||||
if(!ex)return;
|
||||
try{
|
||||
@ -1447,7 +1463,8 @@ function renderAnalytics(){
|
||||
ph+="<tr><td>"+pt[i].id+"</td><td style='font-size:12px'>"+esc(pt[i].t)+"</td><td>"+brs[pt[i].b]+"</td><td><span class='badge "+pc+"'>"+stn[pt[i].s]+"</span></td><td>"+(pt[i].dr<=0?"\u041F\u0440\u043E\u0441\u0440\u043E\u0447\u0435\u043D\u043E":pt[i].dr+" \u0434\u043D.")+"</td></tr>"
|
||||
}
|
||||
ph+="</table>";
|
||||
document.getElementById("an_top").innerHTML=ph
|
||||
document.getElementById("an_top").innerHTML=ph;
|
||||
var secData=[];for(var si=0;si<secs.length;si++){secData.push({n:secs[si].split(".")[1]||secs[si],t:0,d:0})}for(var i=0;i<evs.length;i++){var e=evs[i];secData[e.sec].t++;if(e.s==="done")secData[e.sec].d++}var sh="<table>";for(var i=0;i<secData.length;i++){var sp=secData[i].t?Math.round(secData[i].d/secData[i].t*100):0;sh+="<tr><td>"+esc(secData[i].n)+"</td><td>"+secData[i].d+"/"+secData[i].t+"</td><td><div class=\"rank-bar\"><div style=\"width:"+sp+"%;background:"+(sp>=70?"#10B981":sp>=40?"#F59E0B":"#EF4444")+"\"></div></div></td><td>"+sp+"%</td></tr>"}sh+="</table>";document.getElementById("an_sections").innerHTML=sh
|
||||
}else{
|
||||
document.getElementById("an_top").innerHTML="<p style='color:#64748B'>\u041F\u0440\u043E\u0431\u043B\u0435\u043C \u043D\u0435\u0442</p>"
|
||||
}
|
||||
@ -1480,6 +1497,20 @@ function getFilteredEvs(){
|
||||
}
|
||||
return r
|
||||
}
|
||||
function getReportPeriod(){
|
||||
var period=document.getElementById("rp_period").value;
|
||||
var year=document.getElementById("rp_year").value;
|
||||
var month=parseInt(document.getElementById("rp_month").value,10)||0;
|
||||
var mnames=["\u042F\u043D\u0432\u0430\u0440\u044C","\u0424\u0435\u0432\u0440\u0430\u043B\u044C","\u041C\u0430\u0440\u0442","\u0410\u043F\u0440\u0435\u043B\u044C","\u041C\u0430\u0439","\u0418\u044E\u043D\u044C","\u0418\u044E\u043B\u044C","\u0410\u0432\u0433\u0443\u0441\u0442","\u0421\u0435\u043D\u0442\u044F\u0431\u0440\u044C","\u041E\u043A\u0442\u044F\u0431\u0440\u044C","\u041D\u043E\u044F\u0431\u0440\u044C","\u0414\u0435\u043A\u0430\u0431\u0440\u044C"];
|
||||
if(period==="month")return mnames[month]+" "+year;
|
||||
if(period==="q1")return "I \u043A\u0432\u0430\u0440\u0442\u0430\u043B "+year;
|
||||
if(period==="q2")return "II \u043A\u0432\u0430\u0440\u0442\u0430\u043B "+year;
|
||||
if(period==="q3")return "III \u043A\u0432\u0430\u0440\u0442\u0430\u043B "+year;
|
||||
if(period==="q4")return "IV \u043A\u0432\u0430\u0440\u0442\u0430\u043B "+year;
|
||||
if(period==="h1")return "1-\u0435 \u043F\u043E\u043B\u0443\u0433\u043E\u0434\u0438\u0435 "+year;
|
||||
if(period==="h2")return "2-\u0435 \u043F\u043E\u043B\u0443\u0433\u043E\u0434\u0438\u0435 "+year;
|
||||
return year+" \u0433\u043E\u0434"
|
||||
}
|
||||
function rpPeriodChange(){
|
||||
var v=document.getElementById("rp_period").value;
|
||||
var mSel=document.getElementById("rp_month");
|
||||
@ -1507,41 +1538,36 @@ function dlCSV(){
|
||||
}
|
||||
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>Отчёт План ПБ "+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;vertical-align:top}th{background:#0B1A2E;color:#fff}.files{margin-top:4px;font-size:11px}.files a{color:#005BAA;display:block}</style></head><body><h2>План производственной безопасности</h2><p>QAZAQtelecom HSE за "+month+"."+year+"</p><br><table><tr><th>N</th><th>Мероприятие</th><th>Срок</th><th>Статус</th><th>Кол-во</th><th>Примечание / Файлы</th></tr>";
|
||||
var periodLabel=getReportPeriod();
|
||||
var hh="<!DOCTYPE html><html><head><meta charset='utf-8'><title>\u041E\u0442\u0447\u0451\u0442 \u041F\u0411 \u0437\u0430 "+periodLabel+"</title><style>body{font:14px Arial,sans-serif;padding:30px;color:#1A1A2E} h2{font-size:20px;margin-bottom:4px} h3{font-size:14px;color:#005BAA;margin:16px 0 4px} table{border-collapse:collapse;width:100%;margin-bottom:12px} th,td{border:1px solid #ccc;padding:6px 10px;font-size:12px;text-align:left;vertical-align:top} th{background:#0A1628;color:#fff} .desc{font-size:12px;color:#64748B;margin:4px 0 8px 0;padding:6px;background:#F8FAFC;border-radius:4px} .files{margin:4px 0;font-size:11px} .files a{color:#005BAA;display:block;margin:2px 0} .qty{font-weight:600;color:#2E7D32} @media print{body{padding:10mm}}</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>QAZAQtelecom HSE \u0437\u0430 "+periodLabel+"</p><p style='font-size:11px;color:#64748B'>\u041E\u0442\u0447\u0451\u0442 \u0441\u0444\u043E\u0440\u043C\u0438\u0440\u043E\u0432\u0430\u043D: "+new Date().toLocaleDateString("ru-RU")+"</p><br>";
|
||||
for(var i=0;i<fl.length;i++){
|
||||
var e=fl[i];
|
||||
var notes=esc(e.n||"");
|
||||
hh+="<h3>N"+e.id+". "+esc(e.t)+"</h3>";
|
||||
hh+="<table><tr><th style='width:120px'>\u0421\u0440\u043E\u043A</th><td>"+e.due+"</td><th style='width:120px'>\u0421\u0442\u0430\u0442\u0443\u0441</th><td>"+stn[e.s]+"</td><th style='width:120px'>\u0424\u0438\u043B\u0438\u0430\u043B</th><td>"+brs[e.b]+"</td><th style='width:120px'>\u041E\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043D\u043D\u044B\u0439</th><td>"+esc(nl2c(e.r))+"</td></tr></table>";
|
||||
if(e.n)hh+="<div class='desc'><strong>\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435:</strong> "+esc(e.n)+"</div>";
|
||||
if(e.q)hh+="<div class='qty'>\u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E: "+e.q+"</div>";
|
||||
var fhtml="";
|
||||
var keysToTry=[];
|
||||
for(var si=-1;si<(e.sub?e.sub.length:0);si++){
|
||||
var sk=si>=0?"_s"+si:"";
|
||||
for(var bk=0;bk<brs.length;bk++){
|
||||
keysToTry.push("sf_"+e.id+sk+"_b"+bk)
|
||||
var key="sf_"+e.id+sk+"_b"+bk;
|
||||
var fd=localStorage.getItem(key);
|
||||
if(fd){
|
||||
try{var arr=JSON.parse(fd);
|
||||
for(var fi=0;fi<arr.length;fi++){
|
||||
var f=arr[fi];
|
||||
if(f&&f.n)fhtml+="<a href='"+f.data+"' download='"+esc(f.n)+"'>"+esc(f.n)+" ("+Math.round((f.s||0)/1024)+" KB)</a>"
|
||||
}}catch(ex){}
|
||||
}
|
||||
}
|
||||
}
|
||||
keysToTry.push("sf_"+e.id);
|
||||
for(var ki=0;ki<keysToTry.length;ki++){
|
||||
var key=keysToTry[ki];
|
||||
var fd=localStorage.getItem(key);
|
||||
if(fd){
|
||||
try{var arr=JSON.parse(fd);
|
||||
for(var fi=0;fi<arr.length;fi++){
|
||||
var f=arr[fi];
|
||||
if(!f.n)continue;
|
||||
fhtml+="<a href='"+f.data+"' download='"+esc(f.n)+"'>"+esc(f.n)+" ("+Math.round((f.s||0)/1024)+" KB"+", "+esc(f.u||"")+")</a>"
|
||||
}}catch(ex){}
|
||||
}
|
||||
}
|
||||
if(fhtml)fhtml="<div class='files'>"+fhtml+"</div>";
|
||||
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>"+notes+fhtml+"</td></tr>"
|
||||
if(fhtml)hh+="<div class='files'><strong>\u041F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u044E\u0449\u0438\u0435 \u0444\u0430\u0439\u043B\u044B:</strong><br>"+fhtml+"</div>";
|
||||
}
|
||||
hh+="</table><p><br><em>Отчёт сформирован: "+new Date().toLocaleDateString("ru-RU")+"</em></p></body></html>";
|
||||
hh+="<br><p style='font-size:11px;color:#64748B'><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_"+year+"_"+month+".html";
|
||||
a.download="report_pb_"+periodLabel.replace(/\s/g,"_")+".html";
|
||||
a.click()
|
||||
}
|
||||
function dlWord(){
|
||||
@ -1743,15 +1769,16 @@ function aiResp(q){
|
||||
addMsg("b",ans,"Джарвис")
|
||||
}
|
||||
function renderUsers(){
|
||||
if(!cu||cu.bg!==0){document.getElementById("tab_users").innerHTML="<div class='card'><p style='color:#EF4444'>Доступ запрещён</p></div>";return}
|
||||
if(!cu||cu.bg!==0){document.getElementById("tab_users").innerHTML="<div class='card'><p style='color:#EF4444'>\u0414\u043E\u0441\u0442\u0443\u043F \u0437\u0430\u043F\u0440\u0435\u0449\u0451\u043D</p></div>";return}
|
||||
var ex=localStorage.getItem("ext_users");
|
||||
if(ex){try{var eu=JSON.parse(ex);for(var k in eu){if(eu.hasOwnProperty(k)&&!USR[k])USR[k]=eu[k]}}catch(e){}}
|
||||
var h="<table><tr><th>Логин</th><th>ФИО</th><th>Телефон</th><th>Филиал</th><th></th></tr>";
|
||||
var rn={0:"\u041A\u0443\u0440\u0430\u0442\u043E\u0440",1:"\u041E\u0442\u0432. \u043B\u0438\u0446\u043E",2:"\u0420\u0443\u043A. \u0444\u0438\u043B\u0438\u0430\u043B\u0430"};
|
||||
var h="<table><tr><th>\u041B\u043E\u0433\u0438\u043D</th><th>\u0424\u0418\u041E</th><th>\u0422\u0435\u043B\u0435\u0444\u043E\u043D</th><th>\u0424\u0438\u043B\u0438\u0430\u043B</th><th>\u0420\u043E\u043B\u044C</th><th></th></tr>";
|
||||
for(var k in USR){
|
||||
if(!USR.hasOwnProperty(k))continue;
|
||||
var u=USR[k];
|
||||
h+="<tr><td>"+esc(k)+"@telecom.kz</td><td>"+esc(u.n)+"</td><td>"+esc(u.ph||"")+"</td><td>"+esc(brs[u.bg]||"")+"</td>";
|
||||
h+="<td><button class='btn btn-sm btn-o' style='padding:3px 8px;margin-right:4px' onclick=\"resetPw('"+esc(k)+"')\">Сброс</button><button class='btn btn-sm btn-r' style='padding:3px 10px' onclick=\"delUser('"+esc(k)+"')\">Удалить</button></td></tr>"
|
||||
h+="<tr><td>"+esc(k)+(k.indexOf("@")===-1?"@telecom.kz":"")+"</td><td>"+esc(u.n)+"</td><td>"+esc(u.ph||"")+"</td><td>"+esc(brs[u.bg]||"")+"</td><td>"+esc(rn[u.role]||(u.bg===0?"\u041A\u0443\u0440\u0430\u0442\u043E\u0440":"\u041E\u0442\u0432. \u043B\u0438\u0446\u043E"))+"</td>";
|
||||
h+="<td><button class='btn btn-sm btn-o' style='padding:3px 8px;margin-right:4px' onclick=\"resetPw('"+esc(k)+"')\">\u0421\u0431\u0440\u043E\u0441</button><button class='btn btn-sm btn-r' style='padding:3px 10px' onclick=\"delUser('"+esc(k)+"')\">\u0423\u0434\u0430\u043B\u0438\u0442\u044C</button></td></tr>"
|
||||
}
|
||||
h+="</table>";
|
||||
document.getElementById("users_list").innerHTML=h
|
||||
@ -1766,8 +1793,11 @@ function addUser(){
|
||||
var ph=document.getElementById("reg_phone").value.trim();
|
||||
var bg=parseInt(document.getElementById("reg_branch").value,10);
|
||||
var pw=document.getElementById("reg_pass").value.trim();
|
||||
if(!em||!nm){alert("Заполните логин и ФИО");return}
|
||||
USR[em]={n:nm,bg:bg,ph:ph};
|
||||
var rlSel=document.getElementById("reg_role");
|
||||
var rl=rlSel?parseInt(rlSel.value,10):1;
|
||||
if(!em||!nm){alert("\u0417\u0430\u043F\u043E\u043B\u043D\u0438\u0442\u0435 \u043B\u043E\u0433\u0438\u043D \u0438 \u0424\u0418\u041E");return}
|
||||
if(USR[em]){alert("\u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442");return}
|
||||
USR[em]={n:nm,bg:bg,ph:ph,role:rl};
|
||||
if(pw)USR[em].pw=pw;
|
||||
saveUsers();
|
||||
closeRegModal();
|
||||
@ -1782,6 +1812,15 @@ function showRegModal(){
|
||||
rb.appendChild(o)
|
||||
}
|
||||
}
|
||||
var rr=document.getElementById("reg_role");
|
||||
if(rr&&!rr.options.length){
|
||||
var roles=[{v:0,t:"\u041A\u0443\u0440\u0430\u0442\u043E\u0440 \u041F\u0411"},{v:1,t:"\u041E\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043D\u043D\u043E\u0435 \u043B\u0438\u0446\u043E"},{v:2,t:"\u0420\u0443\u043A\u043E\u0432\u043E\u0434\u0438\u0442\u0435\u043B\u044C \u0444\u0438\u043B\u0438\u0430\u043B\u0430"}];
|
||||
for(var j=0;j<roles.length;j++){
|
||||
var o2=document.createElement("option");
|
||||
o2.value=roles[j].v;o2.textContent=roles[j].t;
|
||||
rr.appendChild(o2)
|
||||
}
|
||||
}
|
||||
document.getElementById("regModal").style.display="flex"
|
||||
}
|
||||
function closeRegModal(){
|
||||
@ -1798,43 +1837,111 @@ function delUser(k){
|
||||
renderUsers()
|
||||
}
|
||||
function saveLTIF(){
|
||||
if(!cu||cu.bg!==0){alert("\u0422\u043E\u043B\u044C\u043A\u043E \u043A\u0443\u0440\u0430\u0442\u043E\u0440 \u043C\u043E\u0436\u0435\u0442 \u0432\u043D\u043E\u0441\u0438\u0442\u044C \u0434\u0430\u043D\u043D\u044B\u0435 LTIF");return}
|
||||
var m=parseInt(document.getElementById("ltif_month").value,10);
|
||||
var h=parseFloat(document.getElementById("ltif_hours").value)||0;
|
||||
var a=parseInt(document.getElementById("ltif_inj").value)||0;
|
||||
if(!h){alert("Введите человеко-часы");return}
|
||||
if(!h){alert("\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u043E-\u0447\u0430\u0441\u044B");return}
|
||||
var data=localStorage.getItem("ltif_data");
|
||||
var ltif=[];
|
||||
if(data){try{ltif=JSON.parse(data)}catch(e){}}
|
||||
if(ltif[m]&<if[m].h){
|
||||
var co=localStorage.getItem("ltif_corrections");
|
||||
var corr=[];
|
||||
if(co){try{corr=JSON.parse(co)}catch(e){}}
|
||||
var d=new Date();
|
||||
corr.push({month:m,oldH:ltif[m].h,oldA:ltif[m].a,newH:h,newA:a,comment:"\u041A\u043E\u0440\u0440\u0435\u043A\u0442\u0438\u0440\u043E\u0432\u043A\u0430 \u0431\u0435\u0437 \u043A\u043E\u043C\u043C\u0435\u043D\u0442\u0430\u0440\u0438\u044F",date:d.getDate()+"."+String(d.getMonth()+1).padStart(2,"0")+"."+d.getFullYear(),user:cu?cu.n:""});
|
||||
try{localStorage.setItem("ltif_corrections",JSON.stringify(corr))}catch(e){}
|
||||
}
|
||||
ltif[m]={h:h,a:a};
|
||||
try{localStorage.setItem("ltif_data",JSON.stringify(ltif))}catch(e){}
|
||||
loadLTIF()
|
||||
}
|
||||
function saveLtifCorrection(m){
|
||||
if(!cu||cu.bg!==0)return;
|
||||
var nh=parseFloat(document.getElementById("ltifc_h_"+m).value)||0;
|
||||
var na=parseInt(document.getElementById("ltifc_a_"+m).value)||0;
|
||||
var nc=document.getElementById("ltifc_c_"+m).value.trim()||"\u041A\u043E\u0440\u0440\u0435\u043A\u0442\u0438\u0440\u043E\u0432\u043A\u0430";
|
||||
if(!nh){alert("\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u043E-\u0447\u0430\u0441\u044B");return}
|
||||
var data=localStorage.getItem("ltif_data");
|
||||
var ltif=[];
|
||||
if(data){try{ltif=JSON.parse(data)}catch(e){}}
|
||||
var oh=ltif[m]?ltif[m].h:0;
|
||||
var oa=ltif[m]?ltif[m].a:0;
|
||||
var co=localStorage.getItem("ltif_corrections");
|
||||
var corr=[];
|
||||
if(co){try{corr=JSON.parse(co)}catch(e){}}
|
||||
var d=new Date();
|
||||
corr.push({month:m,oldH:oh,oldA:oa,newH:nh,newA:na,comment:nc,date:d.getDate()+"."+String(d.getMonth()+1).padStart(2,"0")+"."+d.getFullYear(),user:cu?cu.n:""});
|
||||
try{localStorage.setItem("ltif_corrections",JSON.stringify(corr))}catch(e){}
|
||||
ltif[m]={h:nh,a:na};
|
||||
try{localStorage.setItem("ltif_data",JSON.stringify(ltif))}catch(e){}
|
||||
loadLTIF()
|
||||
}
|
||||
function loadLTIF(){
|
||||
var data=localStorage.getItem("ltif_data");
|
||||
var ltif=[];
|
||||
if(data){try{ltif=JSON.parse(data)}catch(e){}}
|
||||
var mnames=["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"];
|
||||
var mnames=["\u042F\u043D\u0432","\u0424\u0435\u0432","\u041C\u0430\u0440","\u0410\u043F\u0440","\u041C\u0430\u0439","\u0418\u044E\u043D","\u0418\u044E\u043B","\u0410\u0432\u0433","\u0421\u0435\u043D","\u041E\u043A\u0442","\u041D\u043E\u044F","\u0414\u0435\u043A"];
|
||||
var m=parseInt(document.getElementById("ltif_month").value,10);
|
||||
var cur=ltif[m];
|
||||
if(cur){document.getElementById("ltif_hours").value=cur.h;document.getElementById("ltif_inj").value=cur.a}
|
||||
else{document.getElementById("ltif_hours").value="";document.getElementById("ltif_inj").value=""}
|
||||
var res=document.getElementById("ltif_result");
|
||||
var totalH=0,totalA=0;
|
||||
var tbl="<table><tr><th>Месяц</th><th>Чел-часы</th><th>Пострадавшие</th><th>LTIF</th></tr>";
|
||||
var isCurator=cu&&cu.bg===0;
|
||||
var tbl="<table><tr><th>\u041C\u0435\u0441\u044F\u0446</th><th>\u0427\u0435\u043B-\u0447\u0430\u0441\u044B</th><th>\u041F\u043E\u0441\u0442\u0440\u0430\u0434\u0430\u0432\u0448\u0438\u0435</th><th>LTIF</th>"+(isCurator?"<th>\u041A\u043E\u0440\u0440.</th>":"")+"</tr>";
|
||||
for(var i=0;i<12;i++){
|
||||
if(ltif[i]&<if[i].h){
|
||||
totalH+=ltif[i].h;totalA+=ltif[i].a;
|
||||
var lt=ltif[i].a*1000000/ltif[i].h;
|
||||
tbl+="<tr><td>"+mnames[i]+"</td><td>"+ltif[i].h.toLocaleString()+"</td><td>"+ltif[i].a+"</td><td>"+lt.toFixed(2)+"</td></tr>"
|
||||
tbl+="<tr><td>"+mnames[i]+"</td><td>"+ltif[i].h.toLocaleString()+"</td><td>"+ltif[i].a+"</td><td>"+lt.toFixed(2)+"</td>";
|
||||
if(isCurator)tbl+="<td><button class='btn btn-sm btn-o' style='padding:2px 6px;font-size:10px' onclick=\"showLtifCorr("+i+")\">\u041A\u043E\u0440\u0440.</button></td>";
|
||||
tbl+="</tr>"
|
||||
}
|
||||
}
|
||||
tbl+="</table>";
|
||||
if(totalH>0){
|
||||
var totalLT=totalA*1000000/totalH;
|
||||
res.innerHTML="<strong>Годовой LTIF: "+totalLT.toFixed(2)+"</strong> (пострадавших: "+totalA+", чел-часов: "+totalH.toLocaleString()+")"
|
||||
res.innerHTML="<strong>\u0413\u043E\u0434\u043E\u0432\u043E\u0439 LTIF: "+totalLT.toFixed(2)+"</strong> (\u043F\u043E\u0441\u0442\u0440\u0430\u0434\u0430\u0432\u0448\u0438\u0445: "+totalA+", \u0447\u0435\u043B-\u0447\u0430\u0441\u043E\u0432: "+totalH.toLocaleString()+")"
|
||||
}else{res.innerHTML=""}
|
||||
document.getElementById("ltif_table").innerHTML=tbl;
|
||||
document.getElementById("ltif_card").style.display=cu&&cu.bg===0?"":"none"
|
||||
document.getElementById("ltif_corr_div").innerHTML="";
|
||||
document.getElementById("ltif_card").style.display=cu&&cu.bg===0?"":"none";
|
||||
renderLtifCorrections()
|
||||
}
|
||||
function showLtifCorr(m){
|
||||
if(!cu||cu.bg!==0)return;
|
||||
var data=localStorage.getItem("ltif_data");
|
||||
var ltif=[];
|
||||
if(data){try{ltif=JSON.parse(data)}catch(e){}}
|
||||
var cur=ltif[m];
|
||||
var mnames=["\u042F\u043D\u0432","\u0424\u0435\u0432","\u041C\u0430\u0440","\u0410\u043F\u0440","\u041C\u0430\u0439","\u0418\u044E\u043D","\u0418\u044E\u043B","\u0410\u0432\u0433","\u0421\u0435\u043D","\u041E\u043A\u0442","\u041D\u043E\u044F","\u0414\u0435\u043A"];
|
||||
var h="<div style='margin-top:8px;padding:8px;background:#FFF3E0;border-radius:6px;font-size:12px'>";
|
||||
h+="<strong>\u041A\u043E\u0440\u0440\u0435\u043A\u0442\u0438\u0440\u043E\u0432\u043A\u0430 \u0437\u0430 "+esc(mnames[m])+":</strong><br>";
|
||||
h+="\u0427\u0435\u043B-\u0447\u0430\u0441\u044B: <input id='ltifc_h_"+m+"' type='number' value='"+(cur?cur.h:"")+"' style='width:120px;padding:4px;border:1px solid #E2E8F0;border-radius:4px;font-size:11px'> ";
|
||||
h+="\u041F\u043E\u0441\u0442\u0440\u0430\u0434\u0430\u0432\u0448\u0438\u0445: <input id='ltifc_a_"+m+"' type='number' value='"+(cur?cur.a:"0")+"' style='width:60px;padding:4px;border:1px solid #E2E8F0;border-radius:4px;font-size:11px'><br>";
|
||||
h+="\u041F\u0440\u0438\u0447\u0438\u043D\u0430: <input id='ltifc_c_"+m+"' placeholder='\u041F\u0440\u0438\u0447\u0438\u043D\u0430 \u043A\u043E\u0440\u0440\u0435\u043A\u0442\u0438\u0440\u043E\u0432\u043A\u0438' style='width:100%;padding:4px;border:1px solid #E2E8F0;border-radius:4px;font-size:11px'><br>";
|
||||
h+="<button class='btn btn-sm btn-g' style='margin-top:4px;padding:3px 10px;font-size:11px' onclick='saveLtifCorrection("+m+")'>\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C</button> ";
|
||||
h+="<button class='btn btn-sm' style='margin-top:4px;padding:3px 10px;font-size:11px;background:#E2E8F0;color:#0B1A2E' onclick='document.getElementById(\"ltif_corr_div\").innerHTML=\"\"'>\u041E\u0442\u043C\u0435\u043D\u0430</button></div>";
|
||||
document.getElementById("ltif_corr_div").innerHTML=h
|
||||
}
|
||||
function renderLtifCorrections(){
|
||||
var co=localStorage.getItem("ltif_corrections");
|
||||
if(!co)return;
|
||||
try{
|
||||
var corr=JSON.parse(co);
|
||||
if(!corr||!corr.length)return;
|
||||
var mnames=["\u042F\u043D\u0432","\u0424\u0435\u0432","\u041C\u0430\u0440","\u0410\u043F\u0440","\u041C\u0430\u0439","\u0418\u044E\u043D","\u0418\u044E\u043B","\u0410\u0432\u0433","\u0421\u0435\u043D","\u041E\u043A\u0442","\u041D\u043E\u044F","\u0414\u0435\u043A"];
|
||||
corr.sort(function(a,b){return b.month-a.month});
|
||||
var h="<div style='margin-top:12px'><strong>\u0418\u0441\u0442\u043E\u0440\u0438\u044F \u043A\u043E\u0440\u0440\u0435\u043A\u0442\u0438\u0440\u043E\u0432\u043E\u043A:</strong><table style='font-size:11px'><tr><th>\u041C\u0435\u0441\u044F\u0446</th><th>\u0411\u044B\u043B\u043E \u0447-\u0447/\u043F</th><th>\u0421\u0442\u0430\u043B\u043E \u0447-\u0447/\u043F</th><th>\u041F\u0440\u0438\u0447\u0438\u043D\u0430</th><th>\u0414\u0430\u0442\u0430</th><th>\u041A\u0442\u043E</th></tr>";
|
||||
for(var i=0;i<corr.length;i++){
|
||||
var c=corr[i];
|
||||
h+="<tr><td>"+mnames[c.month]+"</td><td>"+(c.oldH||0)+"/"+(c.oldA||0)+"</td><td>"+c.newH+"/"+c.newA+"</td><td style='font-size:10px'>"+esc(c.comment||"")+"</td><td>"+esc(c.date||"")+"</td><td>"+esc(c.user||"")+"</td></tr>"
|
||||
}
|
||||
h+="</table></div>";
|
||||
document.getElementById("ltif_corr_div").innerHTML+=h
|
||||
}catch(e){}
|
||||
}
|
||||
function saveUsers(){
|
||||
var ex={};
|
||||
@ -1850,9 +1957,16 @@ function dlAnalyticsPPT(){
|
||||
for(var i=0;i<evs.length;i++){
|
||||
if(evs[i].s==="done")done++;else if(evs[i].s==="late")late++;else warn++
|
||||
}
|
||||
var h="<!DOCTYPE html><html><head><meta charset='utf-8'><title>Аналитика HSE</title><style>body{font:18px Arial;padding:40px}@page{size:landscape}.slide{page-break-after:always;min-height:400px;padding:20px}.num{font-size:48px;font-weight:800;color:#005BAA}.bar{height:24px;background:#005BAA;border-radius:4px;margin:4px 0}</style></head><body><div class='slide'><h1>QAZAQtelecom HSE — Дашборд</h1><p>Дата: "+new Date().toLocaleDateString("ru-RU")+"</p><br><table><tr><td><div class='num'>"+total+"</div>Всего</td><td><div class='num'>"+done+"</div>Исполнено</td><td><div class='num'>"+warn+"</div>В процессе</td><td><div class='num'>"+late+"</div>Просрочено</td></tr></table><br><p>Выполнение: <strong>"+Math.round(done/total*100)+"%</strong></p><div class='bar' style='width:"+Math.round(done/total*300)+"px'></div></div></body></html>";
|
||||
var blob=new Blob([h],{type:"application/vnd.ms-powerpoint"});
|
||||
var a=document.createElement("a");a.href=URL.createObjectURL(blob);a.download="dashboard.pptx";a.click()
|
||||
var pct=total?Math.round(done/total*100):0;
|
||||
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 h="<!DOCTYPE html><html><head><meta charset='utf-8'><title>\u0410\u043D\u0430\u043B\u0438\u0442\u0438\u043A\u0430 HSE</title><style>body{font:16px Arial;padding:30px}@page{size:A4 landscape;margin:10mm}h1{color:#005BAA;font-size:24px}.num{font-size:36px;font-weight:800;color:#005BAA}.bar{height:20px;background:#005BAA;border-radius:4px;margin:2px 0}table{border-collapse:collapse}td{padding:8px 16px;border:1px solid #ddd}@media print{body{padding:5mm}}</style></head><body><h1>QAZAQtelecom HSE \u2014 \u0410\u043D\u0430\u043B\u0438\u0442\u0438\u043A\u0430</h1><p>\u0414\u0430\u0442\u0430: "+new Date().toLocaleDateString("ru-RU")+"</p><br><table><tr><td style='text-align:center'><div class='num'>"+total+"</div>\u0412\u0441\u0435\u0433\u043E</td><td style='text-align:center'><div class='num'>"+done+"</div>\u0418\u0441\u043F\u043E\u043B\u043D\u0435\u043D\u043E</td><td style='text-align:center'><div class='num'>"+warn+"</div>\u0412 \u043F\u0440\u043E\u0446\u0435\u0441\u0441\u0435</td><td style='text-align:center'><div class='num'>"+late+"</div>\u041F\u0440\u043E\u0441\u0440\u043E\u0447\u0435\u043D\u043E</td></tr></table><br><p>\u0412\u044B\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u0435: <strong>"+pct+"%</strong></p><div class='bar' style='width:"+Math.round(pct*4)+"px'></div><br><h3>\u0420\u0435\u0439\u0442\u0438\u043D\u0433 \u0444\u0438\u043B\u0438\u0430\u043B\u043E\u0432</h3><table>";
|
||||
for(var i=0;i<brd.length;i++){var bp=brd[i].t?Math.round(brd[i].d/brd[i].t*100):0;h+="<tr><td>"+(i+1)+". "+esc(brd[i].n)+"</td><td>"+brd[i].d+"/"+brd[i].t+"</td><td><div class='bar' style='width:"+bp+"px'></div></td><td>"+bp+"%</td></tr>"}
|
||||
h+="</table></body></html>";
|
||||
var blob=new Blob([h],{type:"application/vnd.openxmlformats-officedocument.presentationml.presentation"});
|
||||
var a=document.createElement("a");a.href=URL.createObjectURL(blob);a.download="analytics_"+new Date().toISOString().slice(0,10)+".pptx";a.click()
|
||||
}
|
||||
function dlAnalyticsPDF(){
|
||||
var h=document.getElementById("tab_analytics").innerHTML;
|
||||
@ -1871,6 +1985,6 @@ function dlAnalyticsWord(){
|
||||
var a=document.createElement("a");a.href=URL.createObjectURL(blob);a.download="analytics.doc";a.click()
|
||||
}
|
||||
|
||||
</script>
|
||||
</script></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user