diff --git a/public/index.html b/public/index.html index c9df7ef..4547315 100644 --- a/public/index.html +++ b/public/index.html @@ -56,7 +56,7 @@ button.refresh{background:#20a53a;color:#fff;border:none;border-radius:3px;paddi
磁盘
网络
-v1.3.7 +v1.3.8 资享导航站 @@ -89,8 +89,8 @@ let optPoll=null; let optState={running:false,text:''}; function restoreOptUI(){const b=document.getElementById('optBtn');const st=document.getElementById('optStopBtn');const s=document.getElementById('optStatus');if(!b||!st||!s)return;if(optState.running){b.disabled=true;b.style.cssText='background:#ccc;color:#fff;border:none;border-radius:3px;padding:6px 14px;cursor:not-allowed';st.style.display='';}else{st.style.display='none';}if(optState.text)s.textContent=optState.text;} async function optimizeSys(){const b=document.getElementById('optBtn');const st=document.getElementById('optStopBtn');if(!b||b.disabled)return;try{const r=await fetch('/api/sys/optimize',{method:'POST'});const j=await r.json();if(r.status===409&&j.running){return}if(!j.started&&!j.ok){const s=document.getElementById('optStatus');if(s)s.textContent='启动失败,请稍后重试';return}b.disabled=true;b.style.cssText='background:#ccc;color:#fff;border:none;border-radius:3px;padding:6px 14px;cursor:not-allowed';const s=document.getElementById('optStatus');optState={running:true,text:'⏳ 正在优化系统,预计约20秒,页面数据照常刷新…'};if(s)s.textContent=optState.text;if(st)st.style.display='';if(optPoll)clearInterval(optPoll);optPoll=setInterval(pollOptStatus,2000)}catch(e){const s=document.getElementById('optStatus');if(s)s.textContent='启动失败:网络异常'}} -async function stopOpt(){const st=document.getElementById('optStopBtn');if(st)st.disabled=true;try{await fetch('/api/sys/optimize/cancel',{method:'POST'})}catch(e){}const s=document.getElementById('optStatus');if(s)s.textContent='⏳ 正在停止优化…'} -async function pollOptStatus(){try{const r=await fetch('/api/sys/optimize/status');const j=await r.json();const s=document.getElementById('optStatus');if(j.running){optState={running:true,text:'⏳ 正在优化系统,已用时 '+j.elapsed+' 秒,预计约20秒,页面数据照常刷新…'};if(s)s.textContent=optState.text;return}if(optPoll){clearInterval(optPoll);optPoll=null}const b=document.getElementById('optBtn');const st=document.getElementById('optStopBtn');if(b){b.disabled=false;b.style.cssText='';b.className='bigbtn'}if(st){st.style.display='none';st.disabled=false}if(j.cancelled){optState={running:false,text:'⏹ 已停止优化:'+j.steps.join(';')}}else if(j.done){optState={running:false,text:'✅ 优化完成:'+j.steps.join(';')+',释放 '+fmtB(j.freed)+',当前可用 '+fmtB(j.available)}}if(s&&optState.text)s.textContent=optState.text;load(true);setTimeout(restoreOptUI,500)}catch(e){}} +async function stopOpt(){let j=null;try{const r=await fetch('/api/sys/optimize/cancel',{method:'POST'});j=await r.json()}catch(e){}if(!j||!j.ok)return;const st=document.getElementById('optStopBtn');if(st)st.disabled=true;optState={running:true,stopping:true,text:'⏳ 正在停止优化…'};const s=document.getElementById('optStatus');if(s)s.textContent=optState.text} +async function pollOptStatus(){try{const r=await fetch('/api/sys/optimize/status');const j=await r.json();const s=document.getElementById('optStatus');if(j.running){optState={running:true,stopping:!!optState.stopping,text:optState.stopping?'⏳ 正在停止优化…(已用时 '+j.elapsed+' 秒)':'⏳ 正在优化系统,已用时 '+j.elapsed+' 秒,预计约20秒,页面数据照常刷新…'};if(s)s.textContent=optState.text;return}if(optPoll){clearInterval(optPoll);optPoll=null}const b=document.getElementById('optBtn');const st=document.getElementById('optStopBtn');if(b){b.disabled=false;b.style.cssText='';b.className='bigbtn'}if(st){st.style.display='none';st.disabled=false}if(j.cancelled){optState={running:false,text:'⏹ 已停止优化:'+j.steps.join(';')}}else if(j.done){optState={running:false,text:'✅ 优化完成:'+j.steps.join(';')+',释放 '+fmtB(j.freed)+',当前可用 '+fmtB(j.available)}}if(s&&optState.text)s.textContent=optState.text;load(true);setTimeout(restoreOptUI,500)}catch(e){}} let lastAdvise=0; async function cpuSensor(){const el=document.getElementById('cpusensor');try{const r=await fetch('/api/sensors');const j=await r.json();el.style.display='';let h='
🌡️ 温度 / 🌀 风扇
';if(j.temps&&j.temps.length){const cpu=j.temps.filter(t=>t.name.indexOf('CPU')===0);const oth=j.temps.filter(t=>t.name.indexOf('CPU')!==0);const chip=t=>{const c=t.value>=85?'#f00':(t.value>=70?'#ff9900':'#20a53a');return `${esc(t.name)} ${t.value}°C`};if(cpu.length)h+='
'+cpu.map(chip).join('')+'
';if(oth.length)h+='
'+oth.map(chip).join('')+'
'}if(j.fans&&j.fans.length){h+='
'+j.fans.map(f=>`🌀 ${esc(f.name)} ${f.value} RPM`).join('')+'
'}else{h+='
🌀 风扇转速:宿主未暴露(家用 NAS/主板多无此传感器,属正常)
'}if(j.note&&!j.temps.length)h+=`
${esc(j.note)}
`;el.innerHTML=h}catch(e){el.style.display='';el.innerHTML='
🌡️ 温度读取失败
'}} async function cpuAdvise(){const el=document.getElementById('cpuadvise');const now=Date.now();if(now-lastAdvise<15000){if(el.innerHTML)el.style.display='';return;}lastAdvise=now;try{const r=await fetch('/api/cpu/advise');const j=await r.json();const col=j.level==='轻松'||j.level==='正常'?'#20a53a':(j.level==='偏高'?'#ff9900':'#f00');document.getElementById('cpuadvise').style.display='';document.getElementById('cpuadvise').innerHTML=`
📊 负载诊断:${j.level} (1分钟负载 ${j.load[0]} ÷ ${j.logical}核 = 单核 ${j.per_core})
${esc(j.verdict)}
如何更流畅:
${j.tips.map(t=>`
· ${esc(t)}
`).join('')}
会做两件事:① 把内存里暂存的数据写回硬盘(sync,防断电丢数据);② 回收系统缓存占用的内存(drop caches,只清缓存、不动正在运行的程序)。全程不重启、不杀进程,页面照常刷新。
`;restoreOptUI()}catch(e){}}