app.js · 约 7792 字符
1
2$(function(){
3 function load(){ return JSON.parse(localStorage.getItem('homework_list')||'[]'); }
4 function save(list){ localStorage.setItem('homework_list', JSON.stringify(list)); }
5
6 // 预置演示数据
7 if(!localStorage.getItem('homework_list')){ save(SEED.slice()); }
8
9 function subjColor(s){
10 var map={'语文':'#ef4444','数学':'#2563eb','英语':'#f59e0b','科学':'#10b981','美术':'#ec4899','其他':'#64748b'};
11 return map[s]||'#64748b';
12 }
13
14 function renderToday(){
15 var list=load();
16 if(list.length===0){ $('#today-list').html('<div class="empty">今天还没有作业<br>点「登记」添加一条吧~</div>'); return; }
17 $('#today-list').html(list.map(function(h){
18 var st = h.done ? '<span class="tag tag-green">已完成</span>' : '<span class="tag tag-amber">进行中</span>';
19 return '<div class="hw" data-id="'+h.id+'">'
20 +'<div class="head"><div class="sub" style="background:'+subjColor(h.subject)+'">'+h.subject.slice(0,1)+'</div>'
21 +'<div class="name">'+h.subject+'</div><div class="time">'+h.deadline+'</div></div>'
22 +'<div class="body"><div class="content">'+h.content+'</div>'
23 +'<div class="foot">'+st+'<span class="tag tag-gray">约 '+h.duration+' 分钟</span>'
24 +'<button class="btn btn-ghost btn-sm" style="margin-left:auto" onclick="goDetail(\''+h.id+'\')">详情</button></div></div></div>';
25 }).join(''));
26 }
27
28 function renderProgress(){
29 var list=load();
30 var total=list.length, done=list.filter(function(h){return h.done;}).length;
31 var pct = total? Math.round(done/total*100):0;
32 var off = 251.2*(1-pct/100);
33 $('#pg-num').text(pct+'%');
34 $('#pg-fill').attr('stroke-dashoffset', off);
35 $('#pg-text').text(done+'/'+total+' 项完成');
36 $('#progress-list').html(list.map(function(h){
37 var st = h.done ? '<span class="tag tag-green">✓ 已完成</span>' : '<span class="tag tag-amber">未完成</span>';
38 return '<div style="display:flex;align-items:center;gap:10px;padding:11px 0;border-bottom:1px dashed #e2e8f0">'
39 +'<div class="sub" style="width:30px;height:30px;border-radius:9px;background:'+subjColor(h.subject)+';color:#fff;display:grid;place-items:center;font-weight:800">'+h.subject.slice(0,1)+'</div>'
40 +'<div style="flex:1"><div style="font-weight:700;font-size:14px">'+h.subject+'</div><div style="font-size:12px;color:#94a3b8">'+h.deadline+'</div></div>'
41 +st
42 +'<button class="btn btn-primary btn-sm" style="margin-left:8px" onclick="toggleDone(\''+h.id+'\')">'+(h.done?'撤销':'完成')+'</button></div>';
43 }).join(''));
44 }
45
46 function renderParent(){
47 var list=load();
48 if(list.length===0){ $('#parent-list').html('<div class="empty">暂无作业可点评</div>'); return; }
49 $('#parent-list').html(list.map(function(h){
50 var stars='';
51 for(var i=1;i<=5;i++){ stars+='<span data-id="'+h.id+'" data-n="'+i+'" class="'+(i<=h.parentStar?'on':'')+'">★</span>'; }
52 return '<div class="card" id="pc-'+h.id+'">'
53 +'<div class="hd"><strong>'+h.subject+'</strong>'+(h.done?'<span class="tag tag-green">已完成</span>':'<span class="tag tag-amber">未完成</span>')+'</div>'
54 +'<div style="font-size:13px;color:#475569;margin-bottom:10px">'+h.content+'</div>'
55 +'<div class="stars" data-id="'+h.id+'">'+stars+'</div>'
56 +'<textarea class="pc-text" data-id="'+h.id+'" placeholder="写下家长点评…" style="margin-top:10px;width:100%;min-height:70px;border:1px solid #bfdbfe;border-radius:10px;padding:10px;font-family:inherit;font-size:13px">'+h.parentComment+'</textarea>'
57 +'<button class="btn btn-primary btn-sm" style="margin-top:8px" onclick="saveParent(\''+h.id+'\')">保存家长点评</button></div>';
58 }).join(''));
59 }
60
61 function renderTeacher(){
62 var list=load();
63 var has=list.filter(function(h){return h.teacherComment;}).length;
64 if(has===0){ $('#teacher-list').html('<div class="empty">老师还没有点评哦</div>'); return; }
65 $('#teacher-list').html(list.filter(function(h){return h.teacherComment;}).map(function(h){
66 return '<div class="card"><div class="hd"><strong>'+h.subject+'</strong>'+(h.done?'<span class="tag tag-green">已完成</span>':'<span class="tag tag-amber">未完成</span>')+'</div>'
67 +'<div class="comment"><div class="who">👩🏫 老师点评</div>'+h.teacherComment+'</div></div>';
68 }).join(''));
69 }
70
71 function renderSummary(){
72 var list=load();
73 var total=list.length, done=list.filter(function(h){return h.done;}).length;
74 var commented=list.filter(function(h){return h.parentComment;}).length;
75 var rated=list.filter(function(h){return h.parentStar>0;}).length;
76 $('#sm-total').text(total);
77 $('#sm-done').text(done);
78 $('#sm-comment').text(commented);
79 $('#sm-rate').text(rated);
80 var rows='';
81 var bySub={};
82 list.forEach(function(h){ if(!bySub[h.subject]) bySub[h.subject]={t:0,d:0}; bySub[h.subject].t++; if(h.done)bySub[h.subject].d++; });
83 Object.keys(bySub).forEach(function(k){
84 var p=bySub[k].t?Math.round(bySub[k].d/bySub[k].t*100):0;
85 rows+='<div class="bar-row"><div class="lab">'+k+'</div><div class="track"><div class="fill" style="width:'+p+'%"></div></div><div class="num">'+p+'%</div></div>';
86 });
87 $('#sm-bars').html(rows||'<div class="empty">暂无数据</div>');
88 }
89
90 function go(hash){ location.hash=hash; }
91 window.goDetail=function(id){ var h=load().find(function(x){return x.id===id;}); if(!h)return; $('#d-subject').text(h.subject); $('#d-content').text(h.content); $('#d-meta').text('预计 '+h.duration+' 分钟 · 截止 '+h.deadline); go('detail'); };
92 window.toggleDone=function(id){ var l=load(); var h=l.find(function(x){return x.id===id;}); if(h){h.done=!h.done; save(l); renderProgress(); renderToday(); toast(h.done?'已标记为完成':'已撤销');} };
93 window.saveParent=function(id){ var l=load(); var h=l.find(function(x){return x.id===id;}); if(!h)return; var box=$('#pc-'+id); h.parentStar=box.find('.stars span.on').length; h.parentComment=box.find('.pc-text').val(); save(l); toast('家长点评已保存'); };
94
95 function route(){
96 var h=location.hash.replace('#','')||'today';
97 $('.view').removeClass('active'); $('#v-'+h).addClass('active');
98 $('.tabbar a').removeClass('on'); $('.tabbar a[data-tab="'+h+'"]').addClass('on');
99 if(h==='today') renderToday();
100 else if(h==='progress') renderProgress();
101 else if(h==='parent') renderParent();
102 else if(h==='teacher') renderTeacher();
103 else if(h==='summary') renderSummary();
104 window.scrollTo(0,0);
105 }
106 $(window).on('hashchange', route);
107
108 // 登记作业提交
109 $('#add-submit').on('click', function(){
110 var subject=$('#a-subject').val();
111 var content=$('#a-content').val().trim();
112 var duration=$('#a-duration').val();
113 var deadline=$('#a-deadline').val();
114 if(!content){ toast('请填写作业内容'); return; }
115 var list=load();
116 list.unshift({id:'h'+Date.now(), subject:subject, content:content, duration:parseInt(duration)||30, deadline:deadline||'今天 20:00', done:false, parentStar:0, parentComment:'', teacherComment:''});
117 save(list); toast('作业已登记'); go('today');
118 });
119 $('#a-subject').on('change', function(){ /* select */ });
120
121 // 家长星级点击
122 $(document).on('click','.stars span', function(){
123 var id=$(this).data('id'), n=$(this).data('n');
124 $(this).parent().find('span').each(function(i){
125 $(this).toggleClass('on', (i+1)<=n);
126 });
127 });
128
129 function toast(msg){ var t=$('#toast'); t.text(msg).show(); setTimeout(function(){t.hide();},1600); }
130
131 route();
132});
133