- fix per-year computation: termYearOf parses semester terms (2023-2024-1) so year Scots no longer skipped the semester filter (previous bug made yearly score empty) - academic score now uses semester.gpa shown on grades page (single source of truth); fallback recalculates with the same band-linear + category weights formula - gradeLabel infers grade year (freshman/sophomore) from eduStart, falls back to earliest semester year - info grid 3x3 with phone number as the 9th cell (page + word export) - evidence gallery shows every activity/competition record with attachments in scope (no 2-image cap), records marked scored/unscored - scoring rules reference panel: default rules editable and persisted with profile; restore-default button; no college/school names in citations - word export mirrors all of the above, adds rules annex table; removed dead zongceWord.ts with school citation - sync-server/www rebuilt
28 lines
34 KiB
JavaScript
28 lines
34 KiB
JavaScript
import{c as je,d as Ne,f as me,r as S,ai as Ce,aj as ke,j as e,S as Se,B as A,ak as xe,ah as _e,m as pe,H as he,af as Oe,ag as ze,v as Me,M as Ie}from"./index-BhG5FvHJ.js";import{R as fe,P as Ke,C as Fe}from"./rotate-ccw-BDKjoLu6.js";/**
|
||
* @license lucide-react v0.475.0 - ISC
|
||
*
|
||
* This source code is licensed under the ISC license.
|
||
* See the LICENSE file in the root directory of this source tree.
|
||
*/const Le=[["path",{d:"m15 18-6-6 6-6",key:"1wnfg3"}]],Re=je("ChevronLeft",Le);/**
|
||
* @license lucide-react v0.475.0 - ISC
|
||
*
|
||
* This source code is licensed under the ISC license.
|
||
* See the LICENSE file in the root directory of this source tree.
|
||
*/const Ee=[["path",{d:"M18 22H4a2 2 0 0 1-2-2V6",key:"pblm9e"}],["path",{d:"m22 13-1.296-1.296a2.41 2.41 0 0 0-3.408 0L11 18",key:"nf6bnh"}],["circle",{cx:"12",cy:"8",r:"2",key:"1822b1"}],["rect",{width:"16",height:"16",x:"6",y:"2",rx:"2",key:"12espp"}]],Te=je("Images",Ee),be={politics:{中共党员:3,中共预备党员:2.5,入党积极分子:2,共青团员:1.5,群众:1},conductDefault:8,integrityDefault:2,sportsFactor:.025,gpaFactor:10,table2:{国家级:{一等奖:3,二等奖:2,三等奖:1,优秀奖:.5},省市级:{一等奖:2,二等奖:1,三等奖:.5,优秀奖:.2},区县级:{一等奖:1,二等奖:.5,三等奖:.2,优秀奖:.1},校级:{一等奖:.5,二等奖:.2,三等奖:.1,优秀奖:.05},二级学院:{一等奖:.2,二等奖:.1,三等奖:.05,优秀奖:0}},table4:{校级:{干部:4,干事:2,社团干部:1,学工助理:2},院级:{干部:3,干事:1.5,支部委员:1.5,支部组长:1,班长:1,团支书:1,班委:.5,社团干部:1,学工助理:2}},publicGood:{无偿献血:.5,捐献骨髓:3,国家级:1.5,省市级:1,区县级:.5,校级:.2,二级学院:.1},rewards:{荣誉称号:{院级:.3,校级:.5,区级:1,市级:1.5,国家级:2},英语等级:{三级:.5,四级:1,六级:2},计算机等级:{一级:.5,二级:1,三级:2},职业资格:{从业资格:.5,初级:1,中级:2,高级:3}},penalties:{留校察看:5,记过:4,严重警告:3,警告:2,通报批评:1}};function le(c){const l=/^(\d{4})-(\d{4})/.exec(String(c??"").trim());return l?l[1]+"-"+l[2]:null}function ve(c){const l=/^(\d{4})-(\d{4})$/.exec(c);return l?[l[1]+"-09-01",l[2]+"-09-01"]:null}function ue(c,l){const p=le(c)??c,h=/^(\d{4})/.exec(p),g=/^(\d{4})/.exec(l??"");if(!h||!g)return p+" 学年";const i=Number(h[1])-Number(g[1])+1,f=["大一","大二","大三","大四","大五","大六","大七"];return i<1?p+" 学年":(f[i-1]??i+"年级")+"("+p+" 学年)"}function De(c,l){if(!l)return!0;const p=(c??"").slice(0,10);return p>=l[0]&&p<l[1]}function re(c){const l=(c??"").trim();return l?l.includes("国家")?"国家级":l.includes("省")||l.includes("市")?"省市级":l.includes("区")?"区县级":l.includes("院")||l.includes("二级")?"二级学院":l.includes("校")?"校级":null:null}function ge(c){const l=(c??"").trim();return l?/特等|一等|金(色)?奖|冠军|第1名|第一名/.test(l)?"一等奖":/二等|银(色)?奖|亚军|第2名|第3名|第二名|第三名/.test(l)?"二等奖":/三等|铜(色)?奖|第[4-6]名|第四名|第五名|第六名/.test(l)?"三等奖":/优秀|优胜|第[7-9]名|第七名/.test(l)?"优秀奖":null:null}const F=c=>Math.round(c*100)/100;function ye(c,l,p){var g;return!l||!p?null:((g=c.table2[l])==null?void 0:g[p])??null}function We(c){var z,U,X,P;const{year:l,records:p,semesters:h,bands:g,weights:i,profile:f,rules:a,ov:N}=c,_=l==="all"?null:ve(l),u=p.filter(t=>t.status!=="draft"&&De(t.start_date??t.created_at,_)),j=t=>{var n;return(n=N.itemOverrides)==null?void 0:n[t]},k=(t,n,d,m,C,G)=>{const K=j(t),we=(K==null?void 0:K.score)??m??0;return{itemKey:t,title:n,source:d,score:we,overridden:(K==null?void 0:K.score)!=null,note:C,fromRecord:G}},L=(t,n,d,m)=>({key:t,label:n,cap:d,items:m,subtotal:F(m.reduce((C,G)=>C+G.score,0))}),O=[],v=f.political??"",y=Object.keys(a.politics).find(t=>v.includes(t)),B=y?a.politics[y]:1,w=N.conduct??a.conductDefault,se=N.integrity??a.integrityDefault;O.push(L("conduct","品行素质",13,[{itemKey:"politics",title:"思想政治基础分("+(v||"群众")+")",source:"个人信息 · 政治面貌",score:B},{itemKey:"conduct",title:"操行考评成绩",source:"辅导员考评(可修改)",score:w,overridden:N.conduct!=null},{itemKey:"integrity",title:"诚信分",source:"默认满分(可修改)",score:se,overridden:N.integrity!=null}]));const V=t=>{if(t.grade_point!=null)return t.grade_point;if(g&&t.score!=null){const n=g.find(d=>t.score>=d.min&&(t.score<d.max||d.max>=100&&t.score<=d.max));if(n&&n.gp!=null){if(n.gpTop!=null){const d=n.max>=100?n.max:n.max-1,m=(n.gpTop-n.gp)/Math.max(1,d-n.min);return F(n.gp+(t.score-n.min)*m)}return n.gp}}return null},J=t=>i?i[t.category??"其他"]??i.其他??1:1,Q=le(l),ee=h.filter(t=>!Q||le(t.term)===Q),Y=[],R=[];for(const t of ee){if(Y.push(...t.courses??[]),t.gpa!=null){R.push({term:t.term,gpa:t.gpa,fallback:!1});continue}const n=(t.courses??[]).map(m=>({...m,grade_point:V(m)})).filter(m=>m.grade_point!=null&&m.credit>0);if(!n.length)continue;const d=n.reduce((m,C)=>m+C.credit,0);R.push({term:t.term,gpa:F(n.reduce((m,C)=>m+C.grade_point*J(C)*C.credit,0)/d),fallback:!0})}const T=R.length?F(R.reduce((t,n)=>t+n.gpa,0)/R.length):null,ce=T==null?"该学年暂无学期绩点数据(先在「成绩」页录入学期或课程)":R.some(t=>t.fallback)?"部分学期绩点未录入,按课程推算":void 0,q=T!=null?F(T*a.gpaFactor):0;O.push(L("academic","学业成绩",60,[{itemKey:"gpa",title:"学年平均学分绩点 "+(T!=null?T.toFixed(2):"—")+" × "+a.gpaFactor,source:"成绩模块 · "+ee.length+" 学期"+(R.length?"(绩点均值)":""),score:q,note:ce||(T==null?void 0:Y.length+" 门课程")}]));const Z=Y.filter(t=>/体育/.test(t.course_name)),ae=F(Z.reduce((t,n)=>t+(n.score??0),0)*a.sportsFactor),I=[];Z.length&&I.push({itemKey:"sports",title:"体育成绩("+Z.length+" 学期体育课)",source:"体育课成绩之和 × "+a.sportsFactor,score:Math.min(ae,5)});const te=[];for(const t of u.filter(n=>n.type_name==="文体活动")){const n=ye(a,re(t.level),ge(t.award_grade));n==null&&!((z=j("w"+t.id))!=null&&z.score)||te.push(k("w"+t.id,t.title,t.type_name+" · "+(t.level??"")+" "+(t.award_grade??""),n,void 0,t.id))}const de=F(Math.min(te.reduce((t,n)=>t+n.score,0),5));O.push(L("sports","文体素质",10,[...I,{itemKey:"wcap",title:"文体类加分(上限 5 分)",source:te.length+" 条记录",score:de,note:te.map(t=>t.title+" "+t.score+"分").join(";")||"无匹配记录"}]));const D=[];for(const t of u.filter(n=>n.type_name==="竞赛"||n.type_name==="科研")){const n=ye(a,re(t.level),ge(t.award_grade));n==null&&!((U=j("c"+t.id))!=null&&U.score)||D.push(k("c"+t.id,t.title,t.type_name+" · "+(t.level??"")+" "+(t.award_grade??""),n,void 0,t.id))}const oe=F(Math.min(D.reduce((t,n)=>t+n.score,0),10)),W=[];for(const t of u.filter(n=>n.type_name==="学生工作")){const n=re(t.level)??"院级",d=(t.role??"")+" "+t.title,m=a.table4[n==="国家级"||n==="省市级"||n==="区县级"?"校级":n]??a.table4.院级;let C=null;for(const[G,K]of Object.entries(m))if(d.includes(G)){C=K;break}C==null&&!((X=j("k"+t.id))!=null&&X.score)||W.push(k("k"+t.id,t.title,"学生工作 · "+(t.level??"院级")+" "+(t.role??""),C,C==null?"请手动填写分值":void 0,t.id))}const ie=F(Math.min(W.reduce((t,n)=>t+n.score,0),4)),$=[];for(const t of u.filter(n=>n.type_name==="志愿公益")){const n=re(t.level),d=/献血/.test(t.title);let m=d?a.publicGood.无偿献血:n?a.publicGood[n]??null:null;m==null&&!((P=j("g"+t.id))!=null&&P.score)||$.push(k("g"+t.id,t.title,"公益 · "+(d?"无偿献血":t.level??"校级"),m,void 0,t.id))}const s=F(Math.min($.reduce((t,n)=>t+n.score,0),3));O.push(L("expand","拓展性素质",17,[{itemKey:"ccap",title:"竞赛获奖(上限 10 分)",source:D.length+" 条记录",score:oe,note:D.map(t=>t.title+" "+t.score+"分").join(";")||"无匹配记录"},{itemKey:"kcap",title:"担任学生工作(上限 4 分)",source:W.length+" 条记录",score:ie,note:W.map(t=>t.title+" "+t.score+"分").join(";")||"无匹配记录"},{itemKey:"gcap",title:"公益活动(上限 3 分)",source:$.length+" 条记录",score:s,note:$.map(t=>t.title+" "+t.score+"分").join(";")||"无匹配记录"}]));const r=[];for(const t of u.filter(n=>n.type_name==="荣誉惩处"||n.type_name==="证书技能")){const n=j("h"+t.id),d=t.title+" "+(t.award_grade??"");if(/综合测评奖学金/.test(d))continue;let m=null,C=t.type_name;if(/留校察看/.test(d))m=-a.penalties.留校察看;else if(/记过/.test(d))m=-a.penalties.记过;else if(/严重警告/.test(d))m=-a.penalties.严重警告;else if(/警告/.test(d))m=-a.penalties.警告;else if(/通报批评/.test(d))m=-a.penalties.通报批评;else if(/六级|专八/.test(d))m=a.rewards.英语等级.六级;else if(/四级|专四/.test(d))m=a.rewards.英语等级.四级;else if(/三级/.test(d)&&/英语/.test(d))m=a.rewards.英语等级.三级;else if(/计算机/.test(d)&&/三级/.test(d))m=a.rewards.计算机等级.三级;else if(/计算机/.test(d)&&/二级/.test(d))m=a.rewards.计算机等级.二级;else if(/计算机/.test(d)&&/一级/.test(d))m=a.rewards.计算机等级.一级;else if(/高级/.test(d))m=a.rewards.职业资格.高级;else if(/中级/.test(d))m=a.rewards.职业资格.中级;else if(/初级/.test(d))m=a.rewards.职业资格.初级;else if(/从业|资格证|教师资格|普通话|驾驶证|软考/.test(d))m=a.rewards.职业资格.从业资格;else{const G=re(t.level),K=G==="省市级"?"市级":G==="区县级"?"区级":G==="二级学院"?"院级":G;K&&a.rewards.荣誉称号[K]!=null&&(m=a.rewards.荣誉称号[K],C="荣誉 · "+K)}m==null&&!(n!=null&&n.score)||r.push(k("h"+t.id,t.title,C,m,void 0,t.id))}const o=F(Math.max(Math.min(r.reduce((t,n)=>t+n.score,0),5),-5));O.push(L("rewards","奖惩分",5,[{itemKey:"hcap",title:"奖惩合计(±5 分)",source:r.length+" 条记录",score:o,note:r.map(t=>t.title+" "+t.score+"分").join(";")||"无匹配记录"}]));for(const t of N.manual??[]){const n=O.find(d=>d.label===t.section)??O[O.length-1];n.items.push({itemKey:"m"+t.title+t.score,title:t.title,source:"手动添加",score:t.score}),n.subtotal=F(n.items.reduce((d,m)=>d+m.score,0))}const x=F(O.reduce((t,n)=>{const d=n.key==="rewards"?n.subtotal:Math.min(n.subtotal,n.cap);return t+d},0));return{sections:O,total:x,gpa:T}}function M(c){return String(c??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function Ue(c,l){var g;const p="----=_fp_zongce",h=[];h.push(`MIME-Version: 1.0\r
|
||
Content-Type: multipart/related; type="text/html"; boundary="`+p+`"\r
|
||
\r
|
||
--`+p+`\r
|
||
Content-Location: document.html\r
|
||
Content-Type: text/html; charset="utf-8"\r
|
||
Content-Transfer-Encoding: 8bit\r
|
||
\r
|
||
`+c+`\r
|
||
`);for(const i of l){const f=i.dataUri.indexOf(","),a=i.dataUri.slice(0,f),N=i.dataUri.slice(f+1),_=((g=/data:([^;]+)/.exec(a))==null?void 0:g[1])??"image/png";h.push("--"+p+`\r
|
||
Content-Location: `+i.name+`\r
|
||
Content-Type: `+_+`\r
|
||
Content-Transfer-Encoding: base64\r
|
||
\r
|
||
`+N+`\r
|
||
`)}return h.push("--"+p+`--\r
|
||
`),new Blob([h.join("")],{type:'multipart/related; type="text/html"; boundary="'+p+'"'})}const b="border:0.75pt solid #4a4a4a;padding:4pt 7pt;font-size:10.5pt;vertical-align:middle",E=b+";background:#e8eaf0;font-weight:bold;font-family:SimHei;letter-spacing:1pt";function Ge(c){const l='<table style="border-collapse:collapse;width:100%;margin:4pt 0" border="1"><tr><td style="'+E+';width:30%">基础项</td><td style="'+E+'">分值 / 规则</td></tr><tr><td style="'+b+'">政治面貌分</td><td style="'+b+'">'+M(Object.entries(c.politics).map(([u,j])=>u+" "+j+" 分").join(";"))+'</td></tr><tr><td style="'+b+'">操行考评 / 诚信分默认</td><td style="'+b+'">'+M(c.conductDefault)+" 分 / "+M(c.integrityDefault)+' 分</td></tr><tr><td style="'+b+'">学业成绩</td><td style="'+b+'">学年平均学分绩点 × '+M(c.gpaFactor)+'(上限 60 分)</td></tr><tr><td style="'+b+'">体育加分</td><td style="'+b+'">体育课成绩之和 × '+M(c.sportsFactor)+'(上限 5 分)</td></tr><tr><td style="'+b+'">公益服务</td><td style="'+b+'">'+M(Object.entries(c.publicGood).map(([u,j])=>u+" "+j).join(";"))+"</td></tr></table>",p=c.table2,h=c.table4,g=c.rewards,i=Object.keys(p),f=["一等奖","二等奖","三等奖","优秀奖"],a='<table style="border-collapse:collapse;width:100%;margin:4pt 0" border="1"><tr><td style="'+E+';width:20%">获奖级别</td>'+f.map(u=>'<td style="'+E+'">'+u+"</td>").join("")+"</tr>"+i.map(u=>'<tr><td style="'+b+'">'+M(u)+"</td>"+f.map(j=>{var k;return'<td style="'+b+';text-align:right" class="num">'+M(((k=p[u])==null?void 0:k[j])??"—")+"</td>"}).join("")+"</tr>").join("")+"</table>",N='<table style="border-collapse:collapse;width:100%;margin:4pt 0" border="1"><tr><td style="'+E+';width:20%">学生工作级别</td><td style="'+E+'">岗位分值</td></tr>'+Object.keys(h).map(u=>'<tr><td style="'+b+'">'+M(u)+'</td><td style="'+b+'">'+M(Object.entries(h[u]).map(([j,k])=>j+" "+k).join(";"))+"</td></tr>").join("")+"</table>",_='<table style="border-collapse:collapse;width:100%;margin:4pt 0" border="1"><tr><td style="'+E+';width:20%">类别</td><td style="'+E+'">分值</td></tr>'+["荣誉称号","英语等级","计算机等级","职业资格"].map(u=>'<tr><td style="'+b+'">'+M(u)+'</td><td style="'+b+'">'+M(Object.entries(g[u]??{}).map(([j,k])=>j+" "+k).join(";"))+"</td></tr>").join("")+'<tr><td style="'+b+'">违纪扣分</td><td style="'+b+'">'+M(Object.entries(c.penalties).map(([u,j])=>u+" -"+j).join(";"))+"</td></tr></table>";return'<div style="font-family:SimHei;font-size:12pt;margin:14pt 0 4pt">附 2:评分细则参考(默认值,可自行调整)</div>'+l+a+N+_}function He(c,l,p,h,g){const i=v=>M(v),f=p.school?'<div style="text-align:center;font-size:10.5pt;letter-spacing:1pt;color:#333">'+i(p.school)+"</div>":"",a=(v,y)=>'<td style="'+E+';width:14%">'+y+'</td><td style="'+b+'">'+i(v||"")+"</td>",N=l.sections.map(v=>{const y=v.key==="rewards"?v.subtotal:Math.min(v.subtotal,v.cap),B=v.items.map(w=>'<tr><td style="'+b+'">'+i(w.title)+(w.overridden?"(已手动修正)":"")+'</td><td style="'+b+';color:#555;font-size:9.5pt">'+i(w.note||w.source)+'</td><td style="'+b+';text-align:right;width:64pt" class="num">'+i(w.score)+"</td></tr>").join("");return'<table style="border-collapse:collapse;width:100%;margin:6pt 0 0" border="1"><tr><td style="'+E+';width:34%">考评项目</td><td style="'+E+'">评分依据</td><td style="'+E+';width:64pt;text-align:center">分值</td></tr>'+B+'<tr><td colspan="2" style="'+b+';text-align:right;background:#f4f5f7"><b>'+i(v.label)+"小计</b>(板块上限 "+i(v.cap)+' 分)</td><td style="'+b+';text-align:right;background:#f4f5f7"><b class="num">'+i(y)+"</b></td></tr></table>"}).join(""),_=[];let u=0;const j=h.map(v=>{const y=v.images.map(B=>{u++;const w="ev"+v.recordId+"_"+_.length;return _.push({name:w,dataUri:B}),'<div style="text-align:center;margin:2pt 0"><img src="'+w+'" style="width:196pt;border:0.75pt solid #8a8a8a" alt="附图"><br><span style="font-size:9pt;color:#444">图 '+u+" "+i(v.title)+"</span></div>"}).join("");return'<tr><td style="'+b+';width:26%;vertical-align:top;background:#fafafa"><b style="font-size:10pt">'+i(v.title)+'</b><br><span style="font-size:9pt;color:#666">'+i(v.meta)+'</span></td><td style="'+b+'">'+y+"</td></tr>"}).join(""),k=j?'<div style="font-family:SimHei;font-size:12pt;margin:14pt 0 4pt">附 1:加分证明材料 — '+i(h.length)+" 项记录 · "+i(u)+' 张材料图</div><table style="border-collapse:collapse;width:100%" border="1">'+j+"</table>":"",L='<table style="border-collapse:collapse;width:100%;margin-top:10pt" border="1"><tr>'+a(p.studentId,"学 号")+a(p.name,"姓 名")+a(p.gender,"性 别")+"</tr><tr>"+a(p.college,"学 院")+a(p.major,"专 业")+a(p.className,"班 级")+"</tr><tr>"+a(p.political,"政治面貌")+a(c,"统计周期")+a(p.phone,"电话号码")+"</tr></table>",O='<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word"><head><meta charset="utf-8"><title>学生综合素质测评表</title><style>@page WordSection1 { size:595.3pt 841.9pt; margin:56.7pt 62pt 62pt; mso-footer: f1; }div.WordSection1 { page:WordSection1; }body { font-family:SimSun,serif; font-size:10.5pt; color:#1a1a1a; }h1.title { font-family:SimHei; font-size:16pt; text-align:center; letter-spacing:2pt; margin:0 0 4pt; }p.sub { text-align:center; font-size:10pt; color:#333; margin:0; }table { border-collapse:collapse; }.total td { background:#eef1f6; font-family:SimHei; font-size:12pt; }.num { font-family:Calibri,SimSun; }</style></head><body><div class="WordSection1">'+f+'<h1 class="title">学生综合素质测评表</h1><p class="sub">测评学年:'+i(c)+"</p>"+L+N+'<table style="border-collapse:collapse;width:100%;margin-top:8pt" border="1"><tr class="total"><td style="'+b+';text-align:left;font-family:SimHei">综合素质测评总分</td><td style="'+b+';text-align:right;width:64pt" class="num">'+i(l.total)+"</td></tr></table>"+k+Ge(g)+'<table style="width:100%;border-collapse:collapse;margin-top:22pt;font-size:10.5pt"><tr><td style="width:25%">学生签名:_____</td><td style="width:25%">班长签名:_____</td><td style="width:25%">辅导员签名:_____</td><td>日期:______</td></tr></table><p style="font-size:9pt;color:#555;margin-top:10pt">说明:本表依据《学生综合素质测评评分细则》自动生成(细则参考默认值见附 2,可在综合测评页自行调整);带「已手动修正」标记的分值为手动核定结果。导出前请核对加分记录与证明材料一致。</p></div></body></html>';return Ue(O,_)}const H=({value:c,onChange:l,wide:p})=>e.jsx("input",{type:"number",step:"0.05",className:"num rounded-md border border-neutral-200 bg-white px-1 py-0.5 text-right text-[11.5px] focus:border-brand focus:outline-none "+(p?"w-[76px]":"w-[58px]"),value:c,onChange:h=>l(h.target.value===""?0:Number(h.target.value))}),ne=({head:c,children:l})=>e.jsxs("table",{className:"w-full border border-neutral-200 text-[11.5px]",children:[e.jsx("thead",{children:e.jsx("tr",{children:c.map((p,h)=>e.jsx("th",{className:"border-b border-neutral-200 bg-neutral-50 px-2 py-1 text-left font-medium text-neutral-500",children:p},h))})}),e.jsx("tbody",{children:l})]});function Ae(){var ie,$;const c=Ne(),l=me({queryKey:["profile"],queryFn:ze}),p=me({queryKey:["zc-records"],queryFn:()=>Me({page:1,page_size:500})}),h=me({queryKey:["grades"],queryFn:Ie}),g=(ie=l.data)==null?void 0:ie.content,i={...(g==null?void 0:g.info)??{}},[f,a]=S.useState(""),[N,_]=S.useState({}),[u,j]=S.useState([]),[k,L]=S.useState(!1),[O,v]=S.useState(!1),[y,B]=S.useState(be),[w,se]=S.useState(null);S.useEffect(()=>{var s,r;g&&(_(((s=g.zongce)==null?void 0:s.overrides)??{}),(r=g.zongce)!=null&&r.rules&&B(g.zongce.rules))},[g]),S.useEffect(()=>{var r,o;if(!g)return;_(((r=g.zongce)==null?void 0:r.overrides)??{});const s=Array.from(new Set((((o=h.data)==null?void 0:o.semesters)??[]).map(x=>le(x.term)).filter(Boolean)));!f&&s.length&&a(s[0])},[g,h.data]);const V=(($=p.data)==null?void 0:$.items)??[],J=N[f]??{},Q=S.useMemo(()=>{var s,r,o;return We({year:f||"all",records:V,semesters:((s=h.data)==null?void 0:s.semesters)??[],bands:(r=h.data)==null?void 0:r.bands,weights:(o=h.data)==null?void 0:o.weights,profile:i,rules:y,ov:J})},[V,h.data,i,y,J,f]),ee=S.useMemo(()=>{var s;return Array.from(new Set((((s=h.data)==null?void 0:s.semesters)??[]).map(r=>le(r.term)).filter(Boolean))).sort()},[h.data]),Y=i.eduStart||(ee.length?ee[0]+"-09":""),R=f==="all"||!f?"全部学年":ue(f,Y),T=S.useMemo(()=>{const s=f&&f!=="all"?ve(f):null;return V.filter(r=>{if(r.status==="draft")return!1;if(!s)return!0;const o=(r.start_date??r.created_at??"").slice(0,10);return o>=s[0]&&o<s[1]}).map(r=>r.id)},[V,f]),ce=S.useMemo(()=>{const s=new Set;return Q.sections.forEach(r=>r.items.forEach(o=>{o.fromRecord&&s.add(o.fromRecord)})),s},[Q]);S.useEffect(()=>{let s=!0;return(async()=>{const r=[];for(const o of T){const x=V.find(z=>z.id===o);try{const z=await Ce(o),U=[];for(const X of z.items.filter(P=>P.id&&(P.mime??"").startsWith("image/"))){const P=await ke(X.id);P.data_b64&&U.push("data:"+(X.mime==="image/jpeg"?"image/jpeg":"image/webp")+";base64,"+P.data_b64)}if(U.length){const X=[x==null?void 0:x.type_name,x==null?void 0:x.level,x==null?void 0:x.award_grade].filter(Boolean).join(" · ");r.push({recordId:o,title:(x==null?void 0:x.title)??"记录 "+o,meta:X,images:U})}}catch{}}s&&j(r)})(),()=>{s=!1}},[T.join(",")]);const q=S.useMemo(()=>{const s=[];for(const r of u)for(const o of r.images)s.push({src:o,title:r.title});return s},[u]),Z=s=>void Oe({info:i,zongce:{rules:s.rules??y,overrides:s.overrides??N}}).catch(r=>c("error",r.message)),ae=s=>{_(r=>({...r,[f]:s})),Z({overrides:{...N,[f]:s}})},I=s=>{const r=JSON.parse(JSON.stringify(y));s(r),B(r),Z({rules:r})},te=()=>{const s=JSON.parse(JSON.stringify(be));B(s),Z({rules:s}),c("success","评分细则已恢复默认")},de=()=>{const s=He(R,Q,i,u,y),r=URL.createObjectURL(s),o=document.createElement("a");o.href=r,o.download="综合素质测评_"+R+".doc",o.click(),setTimeout(()=>URL.revokeObjectURL(r),6e4),c("success","综测表已导出(.doc,附证明材料图 "+q.length+" 张 + 细则参考)")},D=w?q.findIndex(s=>s.src===w.src):-1,oe=s=>{const r=D+s;r>=0&&r<q.length&&se({src:q[r].src,title:q[r].title,index:r})},W=q.length;return e.jsxs("div",{className:"mx-auto max-w-[1080px] px-3 py-4 sm:px-6 sm:py-5",children:[e.jsxs("div",{className:"no-print mb-4 flex flex-wrap items-center justify-between gap-2",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-[15px] font-semibold text-ink-1",children:"综合测评"}),e.jsx("p",{className:"mt-0.5 text-[11.5px] text-ink-3",children:"按学年依据评分细则自动计算,可手动修正分值,支持导出 Word 测评表"})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(Se,{className:"w-[190px]",value:f,onChange:s=>a(s.target.value),options:[...ee.map(s=>({value:s,label:ue(s,Y)})),{value:"all",label:"全部学年"}]}),e.jsxs(A,{variant:"secondary",onClick:()=>v(s=>!s),children:[e.jsx(xe,{size:13})," 评分细则参考"]}),e.jsxs(A,{variant:"secondary",onClick:de,children:[e.jsx(_e,{size:13})," 导出 Word"]}),e.jsxs(A,{variant:"secondary",onClick:()=>L(!0),children:[e.jsx(fe,{size:13})," 初始化"]}),e.jsxs(A,{variant:"primary",onClick:()=>window.print(),children:[e.jsx(Ke,{size:13})," 打印"]})]})]}),e.jsxs("div",{className:"print-sheet mx-auto w-full max-w-[820px] rounded-xl border border-line bg-white shadow-card sm:p-8",children:[i.school&&e.jsx("div",{className:"text-center text-[11px] tracking-widest text-neutral-500",children:i.school}),e.jsx("h1",{className:"mt-0.5 text-center text-[19px] font-bold tracking-wide text-neutral-900",children:"学生综合素质测评表"}),e.jsxs("div",{className:"mt-1 text-center text-[12px] text-neutral-500",children:["测评学年:",R]}),e.jsx("div",{className:"mt-4 grid grid-cols-2 gap-px overflow-hidden rounded-lg border border-neutral-300 bg-neutral-300 text-[12.5px] sm:grid-cols-3",children:[["学 号",i.studentId],["姓 名",i.name],["性 别",i.gender],["学 院",i.college],["专 业",i.major],["班 级",i.className],["政治面貌",i.political],["统计周期",R],["电话号码",i.phone]].map(([s,r])=>e.jsxs("div",{className:"flex bg-white",children:[e.jsx("span",{className:"w-[62px] shrink-0 bg-neutral-50 px-2 py-1.5 font-medium text-neutral-500",children:s}),e.jsx("span",{className:"min-w-0 flex-1 truncate px-2 py-1.5 text-neutral-900",children:r||"—"})]},s))}),e.jsxs("div",{className:"mt-4 flex items-center justify-center rounded-lg bg-gradient-to-r from-neutral-900 to-neutral-700 px-4 py-2.5 text-white",children:[e.jsx("span",{className:"text-[12px] opacity-80",children:"综合素质测评总分"}),e.jsx("span",{className:"num ml-3 text-[26px] font-bold leading-none",children:Q.total}),e.jsx("span",{className:"ml-1.5 text-[12px] opacity-80",children:"/ 100 分"})]}),Q.sections.map(s=>e.jsxs("div",{className:"mt-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"h-4 w-1 rounded-full bg-brand"}),e.jsx("span",{className:"text-[13.5px] font-bold text-neutral-900",children:s.label}),e.jsxs(pe,{className:"no-print",color:"var(--text-3)",children:["上限 ",s.cap," 分"]})]}),e.jsxs("span",{className:"num rounded-md bg-neutral-100 px-2 py-0.5 text-[12px] font-semibold text-neutral-700",children:["小计 ",s.key==="rewards"?s.subtotal:Math.min(s.subtotal,s.cap)]})]}),e.jsxs("div",{className:"mt-2 flex flex-col gap-1.5 rounded-lg border border-neutral-200 bg-neutral-50/60 p-3",children:[s.items.map(r=>e.jsxs("div",{className:"flex items-center gap-2 text-[12.5px]",children:[e.jsxs("span",{className:"min-w-0 flex-1",children:[e.jsx("span",{className:"text-neutral-900",children:r.title}),e.jsx("span",{className:"ml-2 text-[11px] text-neutral-400",children:r.source}),r.note&&e.jsx("div",{className:"text-[11px] leading-relaxed text-neutral-400",children:r.note})]}),e.jsx("input",{type:"number",step:"0.1",className:"num w-[72px] rounded-md border border-neutral-200 bg-white px-1.5 py-0.5 text-right text-[12px] focus:border-brand focus:outline-none",value:r.score,onChange:o=>{var x;if(r.itemKey==="conduct"||r.itemKey==="integrity")ae({...J,[r.itemKey]:Number(o.target.value)});else{const z={...J.itemOverrides??{},[r.itemKey]:{...((x=J.itemOverrides)==null?void 0:x[r.itemKey])??{},score:Number(o.target.value)}};ae({...J,itemOverrides:z})}}})]},r.itemKey)),!s.items.length&&e.jsx("div",{className:"text-[12px] text-neutral-400",children:"暂无数据"})]})]},s.key)),(u.length>0||W>0)&&e.jsxs("div",{className:"mt-7",children:[e.jsx("div",{className:"flex items-center justify-between border-t border-neutral-200 pt-4",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Te,{size:15,className:"text-neutral-500"}),e.jsx("span",{className:"text-[13.5px] font-bold text-neutral-900",children:"附:加分证明材料"}),e.jsxs("span",{className:"text-[11.5px] text-neutral-400",children:["共 ",u.length," 项记录 · ",W," 张图片(点击可放大)"]})]})}),e.jsx("div",{className:"mt-3 grid grid-cols-1 gap-3 sm:grid-cols-2",children:u.map(s=>e.jsxs("div",{className:"rounded-lg border border-neutral-200 bg-white p-2.5 transition-shadow hover:shadow-md",children:[e.jsxs("div",{className:"flex items-baseline justify-between gap-2",children:[e.jsxs("div",{className:"flex min-w-0 items-center gap-1.5",children:[ce.has(s.recordId)?e.jsx(pe,{color:"var(--brand-text)",children:"计分"}):e.jsx(pe,{className:"no-print",color:"var(--text-3)",children:"未计分"}),e.jsx("div",{className:"min-w-0 truncate text-[12.5px] font-semibold text-neutral-800",children:s.title})]}),e.jsx("div",{className:"shrink-0 text-[10.5px] text-neutral-400",children:s.meta})]}),e.jsx("div",{className:"mt-2 gap-2 "+(s.images.length>1?"grid grid-cols-2":"flex"),children:s.images.map((r,o)=>e.jsx("button",{onClick:()=>se({src:r,title:s.title,index:q.findIndex(x=>x.src===r)}),className:"group overflow-hidden rounded-md border border-neutral-200 bg-neutral-50",children:e.jsx("img",{src:r,alt:"证明 "+(o+1),className:"aspect-[4/3] w-full object-cover transition-transform group-hover:scale-[1.03]"})},o))})]},s.recordId))})]}),O&&e.jsxs("div",{className:"no-print mt-7 rounded-xl border border-line bg-white p-4 shadow-card",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(xe,{size:15,className:"text-neutral-500"}),e.jsx("span",{className:"text-[13.5px] font-bold text-neutral-900",children:"评分细则参考"}),e.jsx("span",{className:"text-[11.5px] text-neutral-400",children:"默认值可自行调整,调整后即时生效并随档案保存"})]}),e.jsxs(A,{variant:"ghost",onClick:te,children:[e.jsx(fe,{size:13})," 恢复默认"]})]}),e.jsxs("div",{className:"mt-3 grid gap-4 md:grid-cols-2",children:[e.jsxs("div",{children:[e.jsx("div",{className:"mb-1.5 text-[12px] font-semibold text-neutral-600",children:"基础分值"}),e.jsxs(ne,{head:["项目","分值"],children:[Object.entries(y.politics).map(([s,r])=>e.jsxs("tr",{children:[e.jsx("td",{className:"border-b border-neutral-100 px-2 py-1",children:s}),e.jsx("td",{className:"border-b border-neutral-100 px-2 py-1",children:e.jsx(H,{value:r,onChange:o=>I(x=>{x.politics[s]=o})})})]},s)),e.jsxs("tr",{children:[e.jsx("td",{className:"border-b border-neutral-100 px-2 py-1",children:"操行考评默认分"}),e.jsx("td",{className:"border-b border-neutral-100 px-2 py-1",children:e.jsx(H,{value:y.conductDefault,onChange:s=>I(r=>{r.conductDefault=s})})})]}),e.jsxs("tr",{children:[e.jsx("td",{className:"border-b border-neutral-100 px-2 py-1",children:"诚信分默认"}),e.jsx("td",{className:"border-b border-neutral-100 px-2 py-1",children:e.jsx(H,{value:y.integrityDefault,onChange:s=>I(r=>{r.integrityDefault=s})})})]}),e.jsxs("tr",{children:[e.jsx("td",{className:"border-b border-neutral-100 px-2 py-1",children:"学业成绩(绩点 ×)"}),e.jsx("td",{className:"border-b border-neutral-100 px-2 py-1",children:e.jsx(H,{value:y.gpaFactor,onChange:s=>I(r=>{r.gpaFactor=s})})})]}),e.jsxs("tr",{children:[e.jsx("td",{className:"border-b border-neutral-100 px-2 py-1",children:"体育加分(成绩 ×)"}),e.jsx("td",{className:"border-b border-neutral-100 px-2 py-1",children:e.jsx(H,{value:y.sportsFactor,onChange:s=>I(r=>{r.sportsFactor=s})})})]})]}),e.jsx("div",{className:"mb-1.5 mt-3 text-[12px] font-semibold text-neutral-600",children:"公益服务"}),e.jsx(ne,{head:["项目","分值"],children:Object.entries(y.publicGood).map(([s,r])=>e.jsxs("tr",{children:[e.jsx("td",{className:"border-b border-neutral-100 px-2 py-1",children:s}),e.jsx("td",{className:"border-b border-neutral-100 px-2 py-1",children:e.jsx(H,{value:r,onChange:o=>I(x=>{x.publicGood[s]=o})})})]},s))}),e.jsx("div",{className:"mb-1.5 mt-3 text-[12px] font-semibold text-neutral-600",children:"违纪扣分"}),e.jsx(ne,{head:["项目","扣分"],children:Object.entries(y.penalties).map(([s,r])=>e.jsxs("tr",{children:[e.jsx("td",{className:"border-b border-neutral-100 px-2 py-1",children:s}),e.jsx("td",{className:"border-b border-neutral-100 px-2 py-1",children:e.jsx(H,{value:r,onChange:o=>I(x=>{x.penalties[s]=o})})})]},s))})]}),e.jsxs("div",{children:[e.jsx("div",{className:"mb-1.5 text-[12px] font-semibold text-neutral-600",children:"竞赛 / 文体奖项加分(级别 × 奖项)"}),e.jsxs("table",{className:"w-full border border-neutral-200 text-[11.5px]",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{className:"border-b border-neutral-200 bg-neutral-50 px-2 py-1 text-left font-medium text-neutral-500",children:"级别"}),["一等奖","二等奖","三等奖","优秀奖"].map(s=>e.jsx("th",{className:"border-b border-neutral-200 bg-neutral-50 px-2 py-1 text-left font-medium text-neutral-500",children:s},s))]})}),e.jsx("tbody",{children:Object.entries(y.table2).map(([s,r])=>e.jsxs("tr",{children:[e.jsx("td",{className:"border-b border-neutral-100 px-2 py-1 font-medium text-neutral-700",children:s}),["一等奖","二等奖","三等奖","优秀奖"].map(o=>e.jsx("td",{className:"border-b border-neutral-100 px-1 py-1",children:e.jsx(H,{value:r[o]??0,onChange:x=>I(z=>{z.table2[s][o]=x})})},o))]},s))})]}),e.jsx("div",{className:"mb-1.5 mt-3 text-[12px] font-semibold text-neutral-600",children:"学生工作"}),e.jsx(ne,{head:["级别 / 岗位","分值"],children:Object.entries(y.table4).flatMap(([s,r])=>Object.entries(r).map(([o,x])=>e.jsxs("tr",{children:[e.jsxs("td",{className:"border-b border-neutral-100 px-2 py-1",children:[s," · ",o]}),e.jsx("td",{className:"border-b border-neutral-100 px-2 py-1",children:e.jsx(H,{value:x,onChange:z=>I(U=>{U.table4[s][o]=z})})})]},s+o)))}),e.jsx("div",{className:"mb-1.5 mt-3 text-[12px] font-semibold text-neutral-600",children:"荣誉与证照加分"}),e.jsx(ne,{head:["类别 / 等级","分值"],children:Object.entries(y.rewards).flatMap(([s,r])=>Object.entries(r).map(([o,x])=>e.jsxs("tr",{children:[e.jsxs("td",{className:"border-b border-neutral-100 px-2 py-1",children:[s," · ",o]}),e.jsx("td",{className:"border-b border-neutral-100 px-2 py-1",children:e.jsx(H,{value:x,onChange:z=>I(U=>{U.rewards[s][o]=z})})})]},s+o)))})]})]})]}),e.jsx("div",{className:"mt-6 border-t border-neutral-200 pt-3 text-[11px] leading-relaxed text-neutral-400",children:"计分依据:《学生综合素质测评评分细则》(默认值可在上方「评分细则参考」查看与修改)。 自动匹配条目均可手动修正分值;「初始化」清除本学年全部手动修正。导出 Word / 打印前请核对加分记录与证明材料一致。"})]}),e.jsx(he,{open:!!w,onClose:()=>se(null),width:920,title:w?w.title+"("+(D+1)+"/"+W+")":"",footer:e.jsxs("div",{className:"flex w-full items-center justify-between",children:[e.jsxs(A,{variant:"secondary",disabled:D<=0,onClick:()=>oe(-1),children:[e.jsx(Re,{size:13})," 上一张"]}),e.jsx("span",{className:"num text-[12px] text-ink-3",children:w?D+1+" / "+W:""}),e.jsxs(A,{variant:"primary",disabled:D>=W-1,onClick:()=>oe(1),children:["下一张 ",e.jsx(Fe,{size:13})]})]}),children:w&&e.jsx("img",{src:w.src,alt:w.title,className:"mx-auto max-h-[74vh] rounded-md"})}),e.jsx(he,{open:k,onClose:()=>L(!1),width:440,title:"初始化综测",footer:e.jsxs(e.Fragment,{children:[e.jsx(A,{variant:"ghost",onClick:()=>L(!1),children:"取消"}),e.jsx(A,{variant:"primary",onClick:()=>{const s={...N};delete s[f],_(s),Z({overrides:s}),L(!1),c("success","已恢复自动计算")},children:"恢复自动计算"})]}),children:e.jsxs("div",{className:"text-[12.5px] leading-relaxed text-ink-2",children:["将清除 ",e.jsx("b",{children:f==="all"||!f?"全部学年":ue(f,Y)})," 的全部手动修正 (分值覆盖、操行/诚信分修改),恢复为按细则规则的自动计算结果。",e.jsx("div",{className:"mt-2 text-ink-3",children:"记录数据、个人信息与评分细则不受影响。"})]})})]})}export{Ae as AssessmentPage};
|