v96: LTIF, dashboards export, rename to QAZAQtelecom HSE
This commit is contained in:
parent
d3ffd7ea38
commit
9dbd1ece8c
129
index.html
129
index.html
@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>План ПБ 2026 — Казахтелеком</title>
|
||||
<title>QAZAQtelecom HSE — План ПБ 2026</title>
|
||||
<style>
|
||||
|
||||
*{box-sizing:border-box;margin:0;padding:0}
|
||||
@ -70,8 +70,8 @@ tr:hover{background:#FAFBFC}
|
||||
</head>
|
||||
<body onload="init()" style="margin:0">
|
||||
<div id="login"><div>
|
||||
<h1><span>План ПБ</span> 2026</h1>
|
||||
<p>AO «Казахтелеком»</p>
|
||||
<h1><span>QAZAQtelecom</span> HSE</h1>
|
||||
<p>План производственной безопасности 2026</p>
|
||||
<input id="lem" placeholder="curator@telecom.kz">
|
||||
<input id="lpw" type="password" placeholder="Пароль">
|
||||
<p id="lerr" style="color:#EF4444;font-size:12px;display:none">Неверная почта</p>
|
||||
@ -79,7 +79,7 @@ tr:hover{background:#FAFBFC}
|
||||
</div></div>
|
||||
<div id="app">
|
||||
<div id="sidebar">
|
||||
<div class="logo">План <span>ПБ</span> 2026</div>
|
||||
<div class="logo">QAZAQtelecom <span>HSE</span></div>
|
||||
<div class="user" id="su_name"></div>
|
||||
<a class=" active" id="snav_events" onclick="switchTab('events')"><span>Мероприятия</span></a>
|
||||
<a class="" id="snav_analytics" onclick="switchTab('analytics')"><span>Аналитика</span></a>
|
||||
@ -109,6 +109,31 @@ 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 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>
|
||||
<button class="btn btn-sm" onclick="dlAnalyticsWord()">Скачать Word</button>
|
||||
</div>
|
||||
<div class="card" id="ltif_card"><h3>LTIF — Коэффициент частоты травм</h3>
|
||||
<p style="font-size:12px;color:#64748B;margin-bottom:8px">LTIF = (A × 1 000 000) / Человеко-часы, где A — число пострадавших</p>
|
||||
<div style="display:flex;gap:8px;flex-wrap:wrap;align-items:end;margin-bottom:10px">
|
||||
<div><span style="font-size:11px;color:#64748B">Месяц</span>
|
||||
<select id="ltif_month" style="padding:6px 10px;border:1px solid #E2E8F0;border-radius:6px;font-size:12px">
|
||||
<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">Декабрь</option>
|
||||
</select></div>
|
||||
<div><span style="font-size:11px;color:#64748B">Человеко-часы</span>
|
||||
<input id="ltif_hours" type="number" placeholder="0" style="width:130px;padding:6px;border:1px solid #E2E8F0;border-radius:6px;font-size:12px"></div>
|
||||
<div><span style="font-size:11px;color:#64748B">Пострадавших (A)</span>
|
||||
<input id="ltif_inj" type="number" placeholder="0" style="width:80px;padding:6px;border:1px solid #E2E8F0;border-radius:6px;font-size:12px"></div>
|
||||
<button class="btn btn-sm btn-g" onclick="saveLTIF()">Сохранить</button>
|
||||
<button class="btn btn-sm" onclick="loadLTIF()">Загрузить</button>
|
||||
</div>
|
||||
<div id="ltif_result" style="font-size:14px;padding:8px 0"></div>
|
||||
<div id="ltif_table"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="tab_reports" style="display:none">
|
||||
<div class="card"><h3>Выгрузка сводного отчёта</h3>
|
||||
@ -291,6 +316,8 @@ function showApp(){
|
||||
document.getElementById("su_name").textContent=cu?cu.n:"";
|
||||
var unav=document.getElementById("snav_users");
|
||||
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";
|
||||
switchTab("events")
|
||||
}
|
||||
|
||||
@ -672,6 +699,7 @@ function storCheck(){
|
||||
}
|
||||
|
||||
function renderAnalytics(){
|
||||
if(cu&&cu.bg===0)loadLTIF();
|
||||
var total=evs.length;
|
||||
var done=0,late=0,warn=0;
|
||||
for(var i=0;i<evs.length;i++){
|
||||
@ -765,24 +793,29 @@ 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:#00B4D8;display:block}</style></head><body><h2>План производственной безопасности</h2><p>АО Казахтелеком за "+month+"."+year+"</p><br><table><tr><th>N</th><th>Мероприятие</th><th>Срок</th><th>Статус</th><th>Кол-во</th><th>Примечание / Файлы</th></tr>";
|
||||
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>";
|
||||
for(var i=0;i<fl.length;i++){
|
||||
var e=fl[i];
|
||||
var notes=esc(e.n||"");
|
||||
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++){
|
||||
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];
|
||||
var lb=si>=0?e.sub[si].l:"";
|
||||
fhtml+="<a href='"+f.data+"' download='"+esc(f.n)+"'>"+esc((lb?lb+". ":"")+f.n)+" ("+Math.round(f.s/1024)+" KB"+", "+esc(f.u||"")+")</a>"
|
||||
}}catch(ex){}
|
||||
}
|
||||
keysToTry.push("sf_"+e.id+sk+"_b"+bk)
|
||||
}
|
||||
}
|
||||
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>";
|
||||
@ -1048,7 +1081,45 @@ function delUser(k){
|
||||
saveUsers();
|
||||
renderUsers()
|
||||
}
|
||||
function saveUsers(){
|
||||
function saveLTIF(){
|
||||
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}
|
||||
var data=localStorage.getItem("ltif_data");
|
||||
var ltif=[];
|
||||
if(data){try{ltif=JSON.parse(data)}catch(e){}}
|
||||
ltif[m]={h:h,a:a};
|
||||
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 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>";
|
||||
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+="</table>";
|
||||
if(totalH>0){
|
||||
var totalLT=totalA*1000000/totalH;
|
||||
res.innerHTML="<strong>Годовой LTIF: "+totalLT.toFixed(2)+"</strong> (пострадавших: "+totalA+", чел-часов: "+totalH.toLocaleString()+")"
|
||||
}else{res.innerHTML=""}
|
||||
document.getElementById("ltif_table").innerHTML=tbl;
|
||||
document.getElementById("ltif_card").style.display=cu&&cu.bg===0?"":"none"
|
||||
}
|
||||
var ex={};
|
||||
for(var k in USR){
|
||||
if(!USR.hasOwnProperty(k))continue;
|
||||
@ -1056,6 +1127,32 @@ function saveUsers(){
|
||||
}
|
||||
try{localStorage.setItem("ext_users",JSON.stringify(ex))}catch(e){}
|
||||
}
|
||||
function dlAnalyticsPPT(){
|
||||
var total=evs.length;
|
||||
var done=0,late=0,warn=0;
|
||||
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()
|
||||
}
|
||||
function dlAnalyticsPDF(){
|
||||
var h=document.getElementById("tab_analytics").innerHTML;
|
||||
var w=window.open("","_blank","width=900,height=700");
|
||||
w.document.write("<!DOCTYPE html><html><head><meta charset='utf-8'><title>Аналитика</title><style>body{font:14px Arial;padding:20px}@media print{body{padding:10mm}}.card{background:#fff;border:1px solid #E8ECF1;border-radius:12px;padding:16px;margin-bottom:12px}.num{font-size:28px;font-weight:800}</style></head><body><h2>QAZAQtelecom HSE — Аналитика</h2><p>"+new Date().toLocaleDateString("ru-RU")+"</p><br>"+h+"<script>window.onload=function(){window.print()}<\/script></body></html>");
|
||||
w.document.close()
|
||||
}
|
||||
function dlAnalyticsWord(){
|
||||
var total=evs.length;
|
||||
var done=0,late=0,warn=0;
|
||||
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="<html xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:w='urn:schemas-microsoft-com:office:word'><head><meta charset='utf-8'><title>Аналитика HSE</title><style>@page{size:A4;margin:20mm}body{font:14pt 'Times New Roman'}h1{color:#005BAA}table{border-collapse:collapse}td{border:1px solid #000;padding:12px 20px;font-size:20pt;font-weight:700}</style></head><body><h1>QAZAQtelecom HSE — Аналитика</h1><p>Дата: "+new Date().toLocaleDateString("ru-RU")+"</p><br><table><tr><td>Всего<br><span style='font-size:28pt'>"+total+"</span></td><td>Исполнено<br><span style='font-size:28pt'>"+done+" ("+Math.round(done/total*100)+"%)</span></td><td>В процессе<br><span style='font-size:28pt'>"+warn+"</span></td><td>Просрочено<br><span style='font-size:28pt;color:red'>"+late+"</span></td></tr></table></body></html>";
|
||||
var blob=new Blob([h],{type:"application/msword"});
|
||||
var a=document.createElement("a");a.href=URL.createObjectURL(blob);a.download="analytics.doc";a.click()
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user