js/main.js · 约 11775 字符
1\
2(function(){
3 var page=(location.pathname.split('/').pop()||'index.html').replace('.html','');
4 document.querySelectorAll('.tabbar a').forEach(function(a){if(a.getAttribute('href')===page+'.html')a.classList.add('on');});
5 function toast(m){var t=document.createElement('div');t.className='toast';t.textContent=m;document.body.appendChild(t);requestAnimationFrame(function(){t.classList.add('show');});setTimeout(function(){t.classList.remove('show');setTimeout(function(){t.remove();},300);},1700);}
6 function esc(s){return String(s==null?'':s).replace(/[&<>"']/g,function(c){return {'&':'&','<':'<','>':'>','"':'"',"'":'''}[c];});}
7 function getParam(n){var m=location.search.match(new RegExp('[?&]'+n+'=([^&]*)'));return m?decodeURIComponent(m[1]):null;}
8 function gid(){return Date.now().toString(36)+Math.random().toString(36).slice(2,6);}
9 function todayStr(){var d=new Date();return d.getFullYear()+'-'+('0'+(d.getMonth()+1)).slice(-2)+'-'+('0'+d.getDate()).slice(-2);}
10 var KEY='enroll_apps';
11 var SEED=[{"id": "a1", "name": "陈晓萱", "gender": "女", "birth": "2008-05-12", "phone": "13900139001", "major": "计算机科学与技术", "level": "本科", "source": "官网", "status": "已通过", "note": "中考成绩优异,获信息学竞赛奖。", "created": "2026-07-03", "review": "材料齐全,优先录取。"}, {"id": "a2", "name": "刘子轩", "gender": "男", "birth": "2007-11-02", "phone": "13900139002", "major": "软件工程", "level": "本科", "source": "招生宣讲", "status": "待审核", "note": "", "created": "2026-07-09", "review": ""}, {"id": "a3", "name": "王梓涵", "gender": "女", "birth": "2009-02-20", "phone": "13900139003", "major": "数字媒体艺术", "level": "专科", "source": "抖音", "status": "待审核", "note": "有美术特长,作品集已提交。", "created": "2026-07-11", "review": ""}, {"id": "a4", "name": "赵明远", "gender": "男", "birth": "2008-08-15", "phone": "13900139004", "major": "人工智能", "level": "本科", "source": "老师推荐", "status": "已通过", "note": "竞赛保送候选。", "created": "2026-07-05", "review": "复试通过,拟录取。"}, {"id": "a5", "name": "孙雨桐", "gender": "女", "birth": "2009-01-08", "phone": "13900139005", "major": "护理学", "level": "专科", "source": "官网", "status": "已拒绝", "note": "相关专业名额已满。", "created": "2026-06-28", "review": "专业已满,建议转报其他方向。"}, {"id": "a6", "name": "周浩然", "gender": "男", "birth": "2008-03-30", "phone": "13900139006", "major": "电子信息工程", "level": "本科", "source": "招生宣讲", "status": "待审核", "note": "", "created": "2026-07-12", "review": ""}];
12 function la(){try{return JSON.parse(localStorage.getItem(KEY))||null}catch(e){return null}}
13 function sa(a){localStorage.setItem(KEY,JSON.stringify(a));}
14 function ensureSeed(){if(la()===null)sa(SEED);}
15 function statusCls(s){return s==='已通过'?'st-ok':(s==='已拒绝'?'st-lost':'st-ing');}
16 ensureSeed();
17
18 if(page==='index'){
19 var apps=la();
20 function stat(n,l,c){return '<div class="stat"><div class="n '+(c||'')+'">'+n+'</div><div class="l">'+l+'</div></div>';}
21 var total=apps.length;
22 var pending=apps.filter(function(a){return a.status==='待审核';}).length;
23 var passed=apps.filter(function(a){return a.status==='已通过';}).length;
24 var today=apps.filter(function(a){return a.created===todayStr();}).length;
25 document.getElementById('stats4').innerHTML=stat(total,'总报名')+stat(pending,'待审核','w')+stat(passed,'已录取','g')+stat(today,'今日新增');
26 var recent=apps.slice().sort(function(a,b){return a.created<b.created?1:-1;}).slice(0,3);
27 document.getElementById('recent').innerHTML=recent.map(function(a){
28 return '<a class="app" href="detail.html?id='+a.id+'">'
29 +'<div class="av">'+esc((a.name||'?')[0])+'</div>'
30 +'<div class="ci"><div class="cn">'+esc(a.name)+' <span class="tag '+statusCls(a.status)+'">'+a.status+'</span></div>'
31 +'<div class="cm">'+esc(a.major)+' · '+esc(a.phone)+'</div></div>'
32 +'<div class="ca">›</div></a>';
33 }).join('')||'<div class="empty">暂无报名</div>';
34 }
35
36 if(page==='apply'){
37 document.getElementById('f').addEventListener('submit',function(e){
38 e.preventDefault();
39 var name=document.getElementById('name').value.trim();
40 var phone=document.getElementById('phone').value.trim();
41 if(!name||!phone){toast('请填写姓名和手机号');return;}
42 var apps=la();
43 apps.push({id:gid(),name:name,gender:document.getElementById('gender').value,
44 birth:document.getElementById('birth').value,phone:phone,
45 major:document.getElementById('major').value,level:document.getElementById('level').value,
46 source:document.getElementById('source').value,status:'待审核',
47 note:document.getElementById('note').value.trim(),created:todayStr(),review:''});
48 sa(apps);toast('报名提交成功 ✅');setTimeout(function(){location='list.html';},900);
49 });
50 }
51
52 if(page==='list'){
53 var apps=la();
54 function render(){
55 var kw=(document.getElementById('kw').value||'').trim().toLowerCase();
56 var f=document.querySelector('#seg .on').getAttribute('data-f');
57 var list=apps.filter(function(a){
58 if(f!=='all'&&a.status!==f)return false;
59 if(kw){var hay=(a.name+' '+(a.major||'')+' '+(a.phone||'')+' '+(a.source||'')).toLowerCase();if(hay.indexOf(kw)<0)return false;}
60 return true;
61 });
62 var el=document.getElementById('appList');
63 if(!list.length){el.innerHTML='<div class="empty">没有匹配的报名</div>';return;}
64 el.innerHTML=list.map(function(a){
65 return '<a class="app" href="detail.html?id='+a.id+'">'
66 +'<div class="av">'+esc((a.name||'?')[0])+'</div>'
67 +'<div class="ci"><div class="cn">'+esc(a.name)+' <span class="tag '+statusCls(a.status)+'">'+a.status+'</span></div>'
68 +'<div class="cm">'+esc(a.major)+' · '+esc(a.level)+' · '+esc(a.phone)+'</div></div>'
69 +'<div class="ca">›</div></a>';
70 }).join('');
71 }
72 document.getElementById('kw').addEventListener('input',render);
73 document.getElementById('seg').addEventListener('click',function(e){var s=e.target.closest('span');if(!s)return;document.querySelectorAll('#seg span').forEach(function(x){x.classList.remove('on');});s.classList.add('on');render();});
74 render();
75 }
76
77 if(page==='detail'){
78 var apps=la();
79 var id=getParam('id');
80 var a=apps.filter(function(x){return x.id===id;})[0]||apps[0];
81 if(!a){location='list.html';return;}
82 document.getElementById('dHead').innerHTML='<div class="d-head"><div class="av">'+esc((a.name||'?')[0])+'</div><div><div class="nm">'+esc(a.name)+' <span class="tag '+statusCls(a.status)+'">'+a.status+'</span></div><div class="cp">'+esc(a.major)+' · '+esc(a.level)+'</div></div></div>';
83 document.getElementById('dInfo').innerHTML=
84 '<div class="kv"><span class="k">手机号</span><span class="v"><a href="tel:'+esc(a.phone)+'" style="color:var(--pri)">'+esc(a.phone)+'</a></span></div>'
85 +'<div class="kv"><span class="k">性别</span><span class="v">'+esc(a.gender||'—')+'</span></div>'
86 +'<div class="kv"><span class="k">出生日期</span><span class="v">'+esc(a.birth||'—')+'</span></div>'
87 +'<div class="kv"><span class="k">报读专业</span><span class="v">'+esc(a.major)+'</span></div>'
88 +'<div class="kv"><span class="k">学历层次</span><span class="v">'+esc(a.level)+'</span></div>'
89 +'<div class="kv"><span class="k">来源渠道</span><span class="v">'+esc(a.source)+'</span></div>'
90 +'<div class="kv"><span class="k">报名时间</span><span class="v">'+esc(a.created||'—')+'</span></div>'
91 +'<div class="kv"><span class="k">备注</span><span class="v">'+esc(a.note||'—')+'</span></div>';
92 var rvBox=document.getElementById('rvBox');
93 rvBox.value=a.review||'';
94 function setStatus(st){
95 a.status=st;sa(apps);toast(st==='已通过'?'已通过录取 ✅':'已标记为拒绝');
96 setTimeout(function(){location='detail.html?id='+a.id;},800);
97 }
98 document.getElementById('passBtn').addEventListener('click',function(){
99 a.review=rvBox.value.trim();sa(apps);setStatus('已通过');
100 });
101 document.getElementById('rejBtn').addEventListener('click',function(){
102 a.review=rvBox.value.trim();sa(apps);setStatus('已拒绝');
103 });
104 }
105
106 if(page==='review'){
107 var apps=la();
108 function render(){
109 var list=apps.filter(function(a){return a.status==='待审核';});
110 document.getElementById('rc').textContent='共 '+list.length+' 条待审核';
111 var el=document.getElementById('rvList');
112 if(!list.length){el.innerHTML='<div class="empty">🎉 全部审核完毕</div>';return;}
113 el.innerHTML=list.map(function(a){
114 return '<div class="rv" data-id="'+a.id+'"><div class="fh"><span class="nm">'+esc(a.name)+'</span><span class="dt">'+esc(a.created)+'</span></div>'
115 +'<div class="fb">'+esc(a.major)+' · '+esc(a.level)+' · '+esc(a.phone)+'</div>'
116 +'<div class="btns"><button class="btn-ok" data-act="pass" data-id="'+a.id+'">✅ 通过</button>'
117 +'<button class="btn-danger" data-act="rej" data-id="'+a.id+'">❌ 拒绝</button></div></div>';
118 }).join('');
119 }
120 document.getElementById('rvList').addEventListener('click',function(e){
121 var b=e.target.closest('button');if(!b)return;
122 var id=b.getAttribute('data-id');
123 var apps2=la();
124 var a=apps2.filter(function(x){return x.id===id;})[0];if(!a)return;
125 a.status=b.getAttribute('data-act')==='pass'?'已通过':'已拒绝';
126 a.review=a.review||(a.status==='已通过'?'材料审核通过。':'不符合本次招生要求。');
127 sa(apps2);toast(a.status==='已通过'?'已通过录取 ✅':'已拒绝');render();
128 });
129 render();
130 }
131
132 if(page==='stats'){
133 var apps=la();
134 var tot=apps.length||1;
135 function group(field){var m={};apps.forEach(function(a){var k=a[field]||'未填';m[k]=(m[k]||0)+1;});return m;}
136 function bars(obj,max,order){var ks=order||Object.keys(obj);return ks.map(function(k){var v=obj[k]||0;return '<div class="bar"><div class="bl"><span>'+esc(k)+'</span><b>'+v+' 人</b></div><div class="track"><div class="fill" style="width:'+(max?(v/max*100):0)+'%"></div></div></div>';}).join('');}
137 var major=group('major');var majorMax=Math.max(1,Math.max.apply(null,Object.values(major)));
138 document.getElementById('byMajor').innerHTML=bars(major,majorMax);
139 var src=group('source');var srcMax=Math.max(1,Math.max.apply(null,Object.values(src)));
140 document.getElementById('bySource').innerHTML=bars(src,srcMax);
141 var lvl=group('level');var lvlMax=Math.max(1,Math.max.apply(null,Object.values(lvl)));
142 document.getElementById('byLevel').innerHTML=bars(lvl,lvlMax);
143 var st={};apps.forEach(function(a){st[a.status]=(st[a.status]||0)+1;});
144 var okD=(st['已通过']||0)/tot*360,ingD=(st['待审核']||0)/tot*360,lostD=360-okD-ingD;
145 document.getElementById('ring').style.background='conic-gradient(var(--ok) 0 '+okD+'deg, var(--warn) '+okD+'deg '+(okD+ingD)+'deg, var(--danger) '+(okD+ingD)+'deg 360deg)';
146 document.getElementById('donutLg').innerHTML='<div><i style="background:var(--ok)"></i>已通过 '+(st['已通过']||0)+' 人</div><div><i style="background:var(--warn)"></i>待审核 '+(st['待审核']||0)+' 人</div><div><i style="background:var(--danger)"></i>已拒绝 '+(st['已拒绝']||0)+' 人</div>';
147 }
148})();
149