Files
2026-10-28 09:36:55 +08:00

10 lines
3.0 KiB
JavaScript

const PAGE_DEFS=[{page:1,key:'P',title:'红色火星站',color:'linear-gradient(145deg,#ff8a9b,#ff3b52 42%,#c40f31 74%,#4a0416)',desc:'按钮:火箭准备 / 燃料检查 / 通讯开启'},{page:2,key:'Q',title:'蓝色深海舱',color:'linear-gradient(145deg,#8ab4ff,#357bff 42%,#1146d6 74%,#041348)',desc:'按钮:声呐 / 压载舱 / 探照灯'},{page:3,key:'R',title:'绿色能量站',color:'linear-gradient(145deg,#7dffb4,#00d164 42%,#009e49 74%,#02321a)',desc:'按钮:风机 / 储能 / 调度'},{page:4,key:'T',title:'黄色指挥所',color:'linear-gradient(145deg,#fff176,#ffdb00 42%,#ff9800 74%,#4a2c00)',desc:'按钮:地图 / 队伍 / 命令'},{page:5,key:'Y',title:'紫色观测台',color:'linear-gradient(145deg,#e4a6ff,#c159ff 42%,#7c3aed 74%,#22065a)',desc:'按钮:星图 / 光谱 / 记录'},{page:6,key:'U',title:'橙色发射场',color:'linear-gradient(145deg,#ffb377,#ff7a18 42%,#e03a00 74%,#451000)',desc:'按钮:倒计时 / 气象 / 外部链接'}];
let logged=false;
async function init(){const s=await API.get('/api/student/state');logged=!!s.authenticated;render();if(logged){await applyStudentState(s);setInterval(refreshStudent,1000)}}
function render(){document.getElementById('loginArea').classList.toggle('hidden',logged);document.getElementById('mainArea').classList.toggle('hidden',!logged);document.getElementById('toolbar').classList.toggle('hidden',!logged);if(!logged)return;const wrap=document.getElementById('pages');wrap.innerHTML='';PAGE_DEFS.forEach(p=>{const el=document.createElement('article');el.className='page-card';el.style.background=p.color;el.dataset.page=p.page;el.innerHTML=`<span class="kb">Alt + ${p.key}</span><h3>${p.page}. ${p.title}</h3><p>${p.desc}</p>`;const b=document.createElement('button');b.textContent='在新标签页打开';b.onclick=()=>openPage(p.page);el.appendChild(b);wrap.appendChild(el)})}
function openPage(n){window.open(`/page/${n}`,'_blank')}
document.getElementById('loginForm').onsubmit=async e=>{e.preventDefault();const r=await API.post('/api/login',{username:username.value,password:password.value});if(!r.ok){API.notify(notice,r.message);return}const s=await API.get('/api/student/state');if(studentMustChange(s.student)){document.getElementById('passwordChange').classList.remove('hidden');API.notify(notice,'首次使用,请先修改密码');return}logged=true;notice.textContent='';render();await applyStudentState(s);setInterval(refreshStudent,1000)};
document.getElementById('passwordChange').onsubmit=async e=>{e.preventDefault();const r=await API.post('/api/password',{oldPassword:oldPassword.value,newPassword:newPassword.value});API.notify(notice,r.message);if(r.ok){logged=true;document.getElementById('passwordChange').classList.add('hidden');render()}};
document.getElementById('logout').onclick=async()=>{await API.post('/api/logout');location.reload()};
document.addEventListener('keydown',e=>{if(!logged||e.ctrlKey||e.metaKey)return;const k=keyName(e);if(e.altKey&&'PQRTYU'.includes(k)){consumeKey(e);openPage('PQRTYU'.indexOf(k)+1);reportEvent({type:'page',page:'PQRTYU'.indexOf(k)+1})}},true);