40 lines
32 KiB
JavaScript
40 lines
32 KiB
JavaScript
import{c as I,d as ye,f as te,r as E,j as e,B as L,ag as be,ae as B,H as U,S as se,ac as oe,P as W,a8 as ke,T as ne,I as H,af as je,v as ve}from"./index-j5Xhw0AZ.js";import{C as ie,a as ae,b as le}from"./card-G_DTWQFR.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 Ne=[["path",{d:"M12 5v14",key:"s699le"}],["path",{d:"m19 12-7 7-7-7",key:"1idqje"}]],ce=I("ArrowDown",Ne);/**
|
||
* @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 we=[["path",{d:"m5 12 7-7 7 7",key:"hav0vg"}],["path",{d:"M12 19V5",key:"x0mq9r"}]],de=I("ArrowUp",we);/**
|
||
* @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 Ce=[["path",{d:"m9 18 6-6-6-6",key:"mthhwq"}]],Se=I("ChevronRight",Ce);/**
|
||
* @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 _e=[["circle",{cx:"9",cy:"12",r:"1",key:"1vctgf"}],["circle",{cx:"9",cy:"5",r:"1",key:"hp0tcf"}],["circle",{cx:"9",cy:"19",r:"1",key:"fkjjf6"}],["circle",{cx:"15",cy:"12",r:"1",key:"1tmaij"}],["circle",{cx:"15",cy:"5",r:"1",key:"19l28e"}],["circle",{cx:"15",cy:"19",r:"1",key:"f4zoj3"}]],ze=I("GripVertical",_e);/**
|
||
* @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 Pe=[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}],["path",{d:"M15 3v18",key:"14nvp0"}],["path",{d:"m8 9 3 3-3 3",key:"12hl5m"}]],Re=I("PanelRightClose",Pe);/**
|
||
* @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=[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}],["path",{d:"M15 3v18",key:"14nvp0"}],["path",{d:"m10 15-3-3 3-3",key:"1pgupc"}]],Te=I("PanelRightOpen",Ee);/**
|
||
* @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 Oe=[["path",{d:"M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2",key:"143wyd"}],["path",{d:"M6 9V3a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v6",key:"1itne7"}],["rect",{x:"6",y:"14",width:"12",height:"8",rx:"1",key:"1ue0tg"}]],Le=I("Printer",Oe),K=[{key:"info",defaultTitle:"基本信息",kind:"info",fixed:!0},{key:"education",defaultTitle:"教育经历",kind:"edu",fixed:!0},{key:"skills",defaultTitle:"核心技能",kind:"text"},{key:"projects",defaultTitle:"项目经历",kind:"list",types:["竞赛","科研","实习实践"]},{key:"certs",defaultTitle:"证书与荣誉",kind:"list",types:["荣誉惩处","证书技能"]},{key:"campus",defaultTitle:"在校经历",kind:"list",types:["学生工作","志愿公益"]},{key:"activity",defaultTitle:"文体活动",kind:"list",types:["文体活动"]},{key:"other",defaultTitle:"其他经历",kind:"list"},{key:"self",defaultTitle:"自我评价",kind:"text",fixed:!0}],D={skills:{text:`程序设计:熟悉 Python 与 C/C++,掌握常用数据结构与算法,能独立完成中小型工具与脚本开发。
|
||
网络安全:熟悉常见 Web 漏洞原理(SQL 注入、XSS、CSRF 等)与防护方案,掌握 Burp Suite、Nmap、Wireshark 等常用工具。
|
||
网络基础:熟悉 TCP/IP 协议栈与交换路由基础配置,理解 VLAN、NAT、ACL 等核心技术。
|
||
运维基础:熟悉 Linux 常用操作与 Shell 脚本,了解 Docker 容器化部署与 Nginx 服务配置。`},campus:{items:[{title:"校图书馆学生助理",subtitle:"读者服务岗",date:"2024.9 - 2025.6",desc:"负责书库整理与借阅服务,协助开展入馆培训与阅读推广活动,累计服务读者千余人次。培养了责任意识与服务意识,锻炼了多任务时间管理能力。"},{title:"院学生会宣传部干事",subtitle:"平面设计与文案",date:"2023.9 - 2024.6",desc:"参与学院活动的海报设计与推文撰写,负责活动现场的后勤与设备保障。锻炼了审美表达、协作沟通与临场应变能力。"}]},self:{text:"性格沉稳踏实,做事有计划性,习惯提前预判风险并准备预案;学习能力强,能快速上手新技术与工具;责任心强,注重细节与条理,凡事有始有终,能独立推进任务并在压力下保持稳定输出。"}};function q(){return{version:2,template:"tech",accent:"#3056d3",fontScale:1,density:"normal",onePage:!1,sections:K.map(a=>({key:a.key,title:a.defaultTitle,enabled:!0,kind:a.kind,types:a.types,...a.key==="skills"?{text:D.skills.text}:{},...a.key==="campus"?{items:D.campus.items}:{},...a.key==="self"?{text:D.self.text}:{}}))}}function V(a){const h=q();if(!a||typeof a!="object")return h;const u=a,w=Array.isArray(u.sections)?u.sections:[],b=h.sections.map(l=>{var S;const i=w.find(P=>P.key===l.key),_=K.find(P=>P.key===l.key),k={...l,...i??{},enabled:(i==null?void 0:i.enabled)??!0,title:(i==null?void 0:i.title)??(_==null?void 0:_.defaultTitle)??l.title,kind:_?l.kind:(i==null?void 0:i.kind)??l.kind,types:(_==null?void 0:_.types)??(i==null?void 0:i.types)};return l.key==="skills"&&k.text==null&&(k.text=D.skills.text),l.key==="campus"&&!((S=k.items)!=null&&S.length)&&(k.items=D.campus.items),l.key==="self"&&k.text==null&&(k.text=D.self.text),k}),c=new Set(["awards","competition","practice","research"]);for(const l of w)c.has(l.key)||b.some(i=>i.key===l.key)||b.push({key:l.key,title:l.title||l.key,enabled:l.enabled??!0,kind:"text",text:""});return{version:2,template:u.template??"tech",accent:u.accent??"#3056d3",fontScale:Math.min(1.2,Math.max(.8,u.fontScale??1)),density:u.density??"normal",onePage:u.onePage??!1,sections:b}}function Fe(){return K.filter(a=>a.types).flatMap(a=>a.types)}function Ie(a){const h=[a.organizer,a.level,a.award_grade].filter(w=>w!=null&&w!=="").map(String).join(" · "),u=[a.result,a.description].filter(w=>w!=null&&w!=="").map(String).join(" — ");return{title:a.title,subtitle:h||void 0,date:a.start_date??a.created_at.slice(0,10),desc:u||void 0,fromRecord:a.id}}function me(a,h){var c;const u=[],w=Fe(),b=new Set;for(const l of h.sections){if(!l.enabled)continue;const i=K.find(d=>d.key===l.key);if(l.key==="info"){u.push({key:l.key,title:l.title,kind:"info",hiddenFields:l.hiddenFields??[]});continue}if(l.key==="self"||l.kind==="text"){const d=l.text??"";if(!d.trim())continue;u.push({key:l.key,title:l.title,kind:"text",text:d});continue}const _=new Set(l.excluded??[]);let k=[];const S=i==null?void 0:i.types;S?k=a.filter(d=>S.includes(d.type_name)&&d.status!=="draft"&&!_.has(d.id)&&!b.has(d.id)):k=a.filter(d=>d.status!=="draft"&&!_.has(d.id)&&!b.has(d.id)&&!w.includes(d.type_name));const P=new Map((l.itemOrder??[]).map((d,v)=>[d,v])),j=[];for(const d of k){const v={itemKey:"r"+d.id,...Ie(d),...((c=l.overrides)==null?void 0:c[String(d.id)])??{}};j.push({...v,_ord:P.get(v.itemKey)??9999}),b.add(d.id)}for(const d of l.items??[]){const v=d.id??"c"+(l.items??[]).indexOf(d);j.push({itemKey:v,...d,_ord:P.get(v)??9999})}j.sort((d,v)=>d._ord-v._ord||(v.date??"").localeCompare(d.date??"")),j.length&&u.push({key:l.key,title:l.title,kind:"list",items:j.map(d=>{const{_ord:v,...m}=d;return m})})}return u}const xe=[{key:"tech",name:"互联网技术风",desc:"品牌色标题 + 左侧色条,紧凑现代"},{key:"minimal",name:"极简风",desc:"灰色大写字距标题,大量留白"},{key:"classic",name:"经典风",desc:"黑色衬线标题 + 通栏分隔线,正式通用"}],pe=["#3056d3","#0f766e","#7c3aed","#c2410c","#0e7490","#1f2937"],z=a=>String(a??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">");function Me(a,h,u,w){var O,s,x;const b=u.fontScale,c=r=>(r*b).toFixed(1)+"pt",l=u.accent,i=h,_={classic:"font-size:"+c(14)+";color:#111;border-bottom:1.5pt solid #333;padding-bottom:3pt;margin:14pt 0 7pt",tech:"font-size:"+c(14)+";color:"+l+";border-bottom:1pt solid "+l+";padding-bottom:3pt;margin:14pt 0 7pt",minimal:"font-size:"+c(11.5)+";color:#555;letter-spacing:1.5pt;text-transform:uppercase;border-bottom:0.75pt solid #e0e0e0;padding-bottom:3pt;margin:14pt 0 7pt"},k=u.template==="tech"?l:"#111",S=[i.school,i.college,i.major,i.degree].filter(r=>r!=="").map(r=>z(r)).join(" · "),P=[i.phone,i.email,i.homepage].filter(r=>r!=="").map(r=>z(r)).join(" · "),j=(((O=u.header)==null?void 0:O.showPhoto)??!0)&&w&&i.photoUrl?'<td style="width:'+(120*b).toFixed(0)+'px;text-align:right;vertical-align:top"><img src="'+z(i.photoUrl)+'" alt="证件照" width="'+Math.round(120*b)+'" height="'+Math.round(160*b)+'" style="width:'+Math.round(120*b)+"px;height:"+Math.round(160*b)+'px" /></td>':"",d='<table style="width:100%;border-collapse:collapse"><tr><td style="vertical-align:top"><div style="font-size:'+c(20)+";font-weight:bold;color:"+k+'">'+z(i.name||"个人简历")+"</div>"+((((s=u.header)==null?void 0:s.showSchool)??!0)&&S?'<div style="color:#555;font-size:'+c(11)+';margin-top:3pt">'+S+"</div>":"")+((((x=u.header)==null?void 0:x.showContact)??!0)&&P?'<div style="color:#555;font-size:'+c(11)+';margin-top:2pt">'+P+"</div>":"")+"</td>"+j+"</tr></table>",v=r=>'<table style="width:100%;border-collapse:collapse;margin-top:'+(u.density==="compact"?4:7)+'pt"><tr><td style="font-weight:bold;font-size:'+c(12)+'">'+z(r.title)+'</td><td style="text-align:right;color:#666;font-size:'+c(10.5)+';white-space:nowrap">'+z(r.date??"")+"</td></tr></table>"+(r.subtitle?'<div style="color:#666;font-size:'+c(10.5)+'">'+z(r.subtitle)+"</div>":"")+(r.desc?'<div style="color:#444;font-size:'+c(11)+';line-height:1.55;margin-top:2pt">'+z(r.desc)+"</div>":""),m=a.map(r=>{let C="";if(r.kind==="edu"){const M=[["学校",i.school??""],["专业",i.major??""],["学制",i.eduLength??""],["学历",i.degree??""],["入学",i.eduStart??""],["毕业",i.eduEnd??""]].filter(y=>y[1]!=="");C='<table style="width:100%;border-collapse:collapse;font-size:'+c(12)+'">'+M.map(y=>'<tr><td style="width:80px;padding:3px 6px;color:#555">'+z(y[0])+'</td><td style="padding:3px 6px">'+z(y[1])+"</td></tr>").join("")+"</table>"+(i.majorCourses?'<div style="margin-top:6pt;font-size:'+c(11.5)+';line-height:1.6"><b>主修课程:</b>'+z(i.majorCourses)+"</div>":"")}else if(r.kind==="info"){const M=[["name","姓名",i.name??""],["gender","性别",i.gender??""],["birth","出生年月",i.birth??""],["nation","民族",i.nation??""],["native","籍贯",i.native??""],["political","政治面貌",i.political??""],["className","班级",i.className??""],["studentId","学号",i.studentId??""],["degree","学历",i.degree??""],["phone","手机",i.phone??""],["email","邮箱",i.email??""]].filter(y=>y[2]!==""&&!(r.hiddenFields??[]).includes(y[0]));C='<table style="width:100%;border-collapse:collapse;font-size:'+c(12)+'">'+M.map((y,F)=>(F%2===0?"<tr>":"")+'<td style="width:80px;padding:3px 6px;color:#555">'+z(y[1])+'</td><td style="padding:3px 6px">'+z(y[2])+"</td>"+(F%2===1?"</tr>":"")).join("")+"</table>"}else r.kind==="list"?C="<div>"+(r.items??[]).map(v).join("")+"</div>":C='<p style="font-size:'+c(12)+';line-height:1.7;margin:0;text-align:justify">'+z(r.text??"").replace(/\n/g,"<br/>")+"</p>";return'<div style="'+_[u.template]+'">'+z(r.title)+"</div>"+C}).join("");return'<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word"><head><meta charset="utf-8"><title>'+z(i.name||"个人简历")+'</title><!--[if gte mso 9]><xml><w:WordDocument><w:View>Print</w:View></w:WordDocument></xml><![endif]--></head><body style="font-family:Calibri,SimSun,sans-serif;margin:36pt;color:#222">'+d+m+"</body></html>"}const De=Object.freeze(Object.defineProperty({__proto__:null,ACCENT_CHOICES:pe,RESUME_SECTION_DEFS:K,TEMPLATES:xe,assembleSections:me,defaultResumeConfig:q,migrateResumeConfig:V,resumeToWordHtml:Me},Symbol.toStringTag,{value:"Module"})),Ke={姓名:"name",性别:"gender",���生年月:"birth",民族:"nation",籍贯:"native",政治面貌:"political",班级:"className",学号:"studentId",手机:"phone",邮箱:"email"},Ue=[["name","姓名"],["gender","性别"],["birth","出生年月"],["nation","民族"],["native","籍贯"],["political","政治面貌"],["className","班级"],["studentId","学号"],["phone","手机"],["email","邮箱"]];function re(a){const h=/^(\d{4})-(\d{1,2})/.exec(a??"");return h?h[1]+"."+Number(h[2]):a??""}function T({html:a,onCommit:h,className:u}){const w=a.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">");return e.jsx("span",{contentEditable:!0,suppressContentEditableWarning:!0,spellCheck:!1,className:"outline-none break-words rounded-sm transition-shadow focus:shadow-[0_0_0_1.5px_rgba(48,86,211,0.5)] cursor-text "+(u??""),dangerouslySetInnerHTML:{__html:w},onBlur:b=>{const c=(b.currentTarget.textContent??"").trim();c!==a&&h(c)}})}function We(){var Q,J,Y,Z,X,ee;const a=ye(),h=te({queryKey:["profile"],queryFn:je}),u=te({queryKey:["resume-records"],queryFn:()=>ve({page:1,page_size:500})}),[w,b]=E.useState(null),[c,l]=E.useState(""),[i,_]=E.useState(!0),[k,S]=E.useState(new Set),[P,j]=E.useState(1),d=E.useRef(null),v=E.useRef(null);E.useEffect(()=>{var o,n;const t=(o=h.data)==null?void 0:o.content;t&&(b(V(t.resume)),l(((n=t.info)==null?void 0:n.selfIntro)??""))},[h.data]);const m={...((J=(Q=h.data)==null?void 0:Q.content)==null?void 0:J.info)??{}},O=((Y=u.data)==null?void 0:Y.items)??[],s=w??q(),x={...m,selfIntro:c},r=[re(m.eduStart),re(m.eduEnd)].filter(Boolean).join("-"),C=E.useMemo(()=>me(O,s),[O,s]),M=(t,o)=>b(n=>{if(!n)return n;const f=[...n.sections],N=t+o;return N<0||N>=f.length?n:([f[t],f[N]]=[f[N],f[t]],{...n,sections:f})}),y=t=>{b(t),B({info:{...m,selfIntro:c},resume:t}).catch(o=>a("error",o.message))},F=t=>{b(o=>{const n=o??s,f=n.sections.map(p=>{var g;if(p.key!==t.secKey)return p;if(t.field==="text")return{...p,text:t.value};if(t.fromRecord!=null){const R={...((g=p.overrides)==null?void 0:g[t.fromRecord])??{},[t.field]:t.value};return{...p,overrides:{...p.overrides??{},[t.fromRecord]:R}}}if(t.itemIdx!=null&&p.items){const R=[...p.items];return R[t.itemIdx]={...R[t.itemIdx],[t.field]:t.value},{...p,items:R}}return p}),N={...n,sections:f};return B({info:{...m,selfIntro:c},resume:N}).catch(p=>a("error",p.message)),N})},A=(t,o)=>{B({info:{...x,[t]:o}}).then(()=>h.refetch()).catch(n=>a("error",n.message))};E.useEffect(()=>{if(!s.onePage){j(1);return}const t=d.current;if(!t)return;const o=1043,n=t.scrollHeight;j(n>o?Math.max(.7,o/n):1)},[s.onePage,s.fontScale,s.density,C]);const $=s.fontScale*(s.onePage?P:1),ue=()=>{ke(()=>Promise.resolve().then(()=>De),void 0).then(function(t){const o=t.resumeToWordHtml(C,x,s,m.photoUrl),n=new Blob(["\uFEFF"+o],{type:"application/msword"}),f=URL.createObjectURL(n),N=document.createElement("a");N.href=f,N.download=(m.name||"个人简历")+".doc",N.click(),setTimeout(()=>URL.revokeObjectURL(f),6e4),a("success","Word 文档已导出")})},G=t=>{const o="custom_"+Date.now();y({...s,sections:[...s.sections,t==="text"?{key:o,title:"自定义板块",enabled:!0,kind:"text",text:""}:{key:o,title:"自定义经历",enabled:!0,kind:"list",items:[]}]}),S(n=>new Set(n).add(o))},he=t=>{var o,n;return((n=(o=K.find(f=>f.key===t))==null?void 0:o.types)==null?void 0:n.join(" / "))??"固定板块"},fe=()=>{const t=new Blob([JSON.stringify(s,null,2)],{type:"application/json"}),o=URL.createObjectURL(t),n=document.createElement("a");n.href=o,n.download="简历配置.json",n.click(),setTimeout(()=>URL.revokeObjectURL(o),6e4),a("success","简历配置已导出")},ge=t=>{t&&t.text().then(o=>{try{const n=V(JSON.parse(o));y(n),a("success","配置已导入")}catch{a("error","配置文件格式不正确")}})};return e.jsxs("div",{className:"mx-auto max-w-[1280px] 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.jsx("h2",{className:"text-[15px] font-semibold text-ink-1",children:"我的简历"}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsxs(L,{variant:"secondary",onClick:()=>_(t=>!t),children:[i?e.jsx(Re,{size:13}):e.jsx(Te,{size:13}),i?"收起设置":"展开设置"]}),e.jsxs(L,{variant:"secondary",onClick:ue,children:[e.jsx(be,{size:13})," 导出 Word"]}),e.jsxs(L,{variant:"primary",onClick:()=>window.print(),children:[e.jsx(Le,{size:13})," 打印 / PDF"]})]})]}),e.jsxs("div",{className:"grid gap-4 "+(i?"lg:grid-cols-[1fr_340px]":"grid-cols-1"),children:[e.jsxs("div",{children:[e.jsx("div",{className:"print-sheet mx-auto w-full max-w-[794px] rounded-lg border border-line bg-white shadow-card",style:{minHeight:s.onePage?1123:void 0},children:e.jsxs("div",{ref:d,className:"min-w-0 overflow-x-hidden p-5 sm:p-10 resume-tpl-"+s.template,style:{zoom:$,"--accent":s.accent},children:[e.jsxs("div",{className:"mb-6 flex items-start justify-between gap-4 sm:gap-6",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("h1",{className:"text-[26px] font-bold leading-tight "+(s.template==="tech"?"text-[var(--accent)]":"text-neutral-900"),children:m.name||"姓名"}),(((Z=s.header)==null?void 0:Z.showSchool)??!0)&&e.jsx("div",{className:"mt-1.5 text-[12.5px] text-neutral-500",children:[m.school,m.college,m.major,m.degree].filter(Boolean).join(" · ")||"完善个人信息后自动展示"}),(((X=s.header)==null?void 0:X.showContact)??!0)&&e.jsx("div",{className:"mt-1 text-[12px] text-neutral-500",children:[m.phone,m.email,m.homepage].filter(Boolean).join(" · ")})]}),(((ee=s.header)==null?void 0:ee.showPhoto)??!0)&&m.photoUrl&&e.jsx("img",{src:m.photoUrl,alt:"证件照",className:"h-[110px] w-[82px] rounded border border-neutral-200 object-cover"})]}),C.map(t=>{var o;return e.jsxs("div",{className:"mb-5 r-sec",children:[e.jsx("div",{className:"r-sec-title mb-2.5 text-[14px] font-bold text-neutral-900",children:e.jsx(T,{html:t.title,onCommit:n=>F({secKey:t.key,field:"title",value:n})})}),t.kind==="edu"?e.jsxs("div",{children:[e.jsxs("div",{className:"flex flex-wrap items-baseline justify-between gap-x-4 gap-y-0.5 text-[13px]",children:[e.jsx("span",{className:"num shrink-0 text-neutral-500",children:e.jsx(T,{html:r,onCommit:n=>{const f=/(\d{4})\.(\d{1,2})\s*[-—~至]\s*(\d{4})\.(\d{1,2})/.exec(n);if(!f){a("error","时间格式:2023.9-2027.6");return}B({info:{...x,eduStart:f[1]+"-"+f[2].padStart(2,"0"),eduEnd:f[3]+"-"+f[4].padStart(2,"0")}}).then(()=>h.refetch()).catch(N=>a("error",N.message))}})}),e.jsx("span",{className:"min-w-0 font-semibold text-neutral-900",children:e.jsx(T,{html:m.school??"",onCommit:n=>A("school",n)})}),e.jsxs("span",{className:"shrink-0 text-neutral-600",children:[e.jsx(T,{html:m.major??"",onCommit:n=>A("major",n)}),m.degree?e.jsxs("span",{children:[" | ",e.jsx(T,{html:m.degree,onCommit:n=>A("degree",n)})]}):null]})]}),m.majorCourses&&e.jsxs("p",{className:"mt-1.5 text-[12px] leading-relaxed text-justify text-neutral-700",children:[e.jsx("b",{children:"主修课程:"}),e.jsx(T,{html:m.majorCourses,onCommit:n=>A("majorCourses",n)})]})]}):t.kind==="info"?e.jsx("div",{className:"grid grid-cols-1 gap-x-8 gap-y-1 text-[12.5px] sm:grid-cols-2",children:[["姓名",m.name],["性别",m.gender],["出生年月",m.birth],["民族",m.nation],["籍贯",m.native],["政治面貌",m.political],["班级",m.className],["学号",m.studentId],["手机",m.phone],["邮箱",m.email]].filter(n=>n[1]&&!(t.hiddenFields??[]).includes(Ke[n[0]])).map(n=>e.jsxs("div",{className:"flex gap-2",children:[e.jsx("span",{className:"w-16 shrink-0 text-neutral-500",children:n[0]}),e.jsx("span",{children:n[1]})]},n[0]))}):t.kind==="text"?e.jsx("p",{className:"whitespace-pre-wrap text-justify text-neutral-700 "+(s.density==="compact"?"":"leading-relaxed"),children:e.jsx(T,{html:t.text??"",onCommit:n=>F({secKey:t.key,field:"text",value:n})})}):e.jsx("div",{className:s.density==="compact"?"flex flex-col gap-1.5":"flex flex-col gap-3",children:(o=t.items)==null?void 0:o.map((n,f)=>e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-baseline justify-between gap-3",children:[e.jsx("span",{className:"text-[13px] font-semibold text-neutral-900 r-item-title",children:e.jsx(T,{html:n.title,onCommit:N=>F({secKey:t.key,field:"title",value:N,itemIdx:f,fromRecord:n.fromRecord})})}),e.jsx("span",{className:"num shrink-0 text-[11.5px] text-neutral-500",children:e.jsx(T,{html:n.date??"",onCommit:N=>F({secKey:t.key,field:"date",value:N,itemIdx:f,fromRecord:n.fromRecord})})})]}),n.subtitle&&e.jsx("div",{className:"text-[12px] text-neutral-600",children:n.subtitle}),n.desc&&e.jsx("p",{className:"text-justify text-[12px] text-neutral-500 "+(s.density==="compact"?"":"mt-0.5"),children:e.jsx(T,{html:n.desc,onCommit:N=>F({secKey:t.key,field:"desc",value:N,itemIdx:f,fromRecord:n.fromRecord})})})]},n.itemKey??(n.title??"")+f))})]},t.key)})]})}),s.onePage&&e.jsxs("div",{className:"no-print mt-2 text-center text-[11.5px] text-ink-3",children:["一页限定已启用:内容自动缩放 ",Math.round($*100),"% 以适配单页 A4"]})]}),i&&e.jsxs("div",{className:"no-print flex flex-col gap-4 lg:sticky lg:top-4 lg:max-h-[calc(100vh-2rem)] lg:self-start lg:overflow-y-auto lg:pr-1",children:[e.jsxs(ie,{children:[e.jsx(ae,{title:"模板与风格"}),e.jsxs(le,{className:"flex flex-col gap-3",children:[e.jsx("div",{className:"grid grid-cols-1 gap-2",children:xe.map(t=>e.jsxs("button",{className:"rounded-md border px-3 py-2 text-left transition-all "+(s.template===t.key?"border-brand bg-brand-subtle":"border-line bg-surface hover:border-line-strong"),onClick:()=>y({...s,template:t.key}),children:[e.jsx("div",{className:"text-[12.5px] font-semibold "+(s.template===t.key?"text-brand-text":"text-ink-1"),children:t.name}),e.jsx("div",{className:"text-[11px] text-ink-3",children:t.desc})]},t.key))}),e.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[e.jsx(U,{label:"主题色",children:e.jsx("div",{className:"flex flex-wrap gap-1.5 pt-1",children:pe.map(t=>e.jsx("button",{"aria-label":"主题色 "+t,className:"size-5 rounded-full border-2 transition-transform "+(s.accent===t?"scale-110 border-ink-1":"border-transparent"),style:{backgroundColor:t},onClick:()=>y({...s,accent:t})},t))})}),e.jsx(U,{label:"字号",children:e.jsx(se,{value:String(s.fontScale),onChange:t=>y({...s,fontScale:Number(t.target.value)}),options:[{value:"0.9",label:"小"},{value:"1",label:"标准"},{value:"1.1",label:"大"}]})})]}),e.jsx(U,{label:"头部布局",children:e.jsx("div",{className:"flex flex-wrap gap-1.5 pt-1",children:[["showPhoto","证件照"],["showContact","联系行"],["showSchool","学校行"]].map(t=>{var n;const o=((n=s.header)==null?void 0:n[t[0]])??!0;return e.jsx("button",{className:"rounded-md border px-2.5 py-1 text-[11.5px] transition-colors "+(o?"border-brand bg-brand-subtle text-brand-text":"border-line bg-surface text-ink-3"),onClick:()=>y({...s,header:{...s.header,[t[0]]:!o}}),children:t[1]},t[0])})})}),e.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[e.jsx(U,{label:"间距",children:e.jsx(se,{value:s.density,onChange:t=>y({...s,density:t.target.value}),options:[{value:"compact",label:"紧凑"},{value:"normal",label:"标准"},{value:"relaxed",label:"宽松"}]})}),e.jsx(U,{label:"单页限定",children:e.jsx("button",{className:"flex h-9 w-full items-center justify-center gap-1.5 rounded-md border text-[12px] transition-colors "+(s.onePage?"border-brand bg-brand-subtle text-brand-text":"border-line bg-surface text-ink-2"),onClick:()=>y({...s,onePage:!s.onePage}),children:s.onePage?"已开启":"已关闭"})})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-2 border-t border-line pt-3",children:[e.jsx(L,{size:"sm",variant:"secondary",onClick:fe,children:"导出配置"}),e.jsxs("label",{className:"flex h-8 cursor-pointer items-center justify-center rounded-md border border-line bg-surface text-[12px] text-ink-2 transition-colors hover:border-line-strong",children:["导入配置",e.jsx("input",{type:"file",accept:"application/json",className:"hidden",onChange:t=>{var o;ge((o=t.target.files)==null?void 0:o[0]),t.target.value=""}})]})]})]})]}),e.jsxs(ie,{children:[e.jsx(ae,{title:"板块布局",extra:e.jsx("span",{className:"text-[11px] text-ink-3",children:"拖动排序 · 点击预览可改内容"})}),e.jsx(le,{className:"p-0",children:e.jsxs("div",{className:"flex flex-col divide-y divide-line",children:[s.sections.map((t,o)=>{var N;const n=k.has(t.key),f=t.kind==="info"?"固定":t.kind==="text"?"文本":t.kind==="edu"?"教育":"记录";return e.jsxs("div",{draggable:!0,onDragStart:()=>{v.current=t.key},onDragOver:p=>p.preventDefault(),onDrop:()=>{const p=s.sections.findIndex(g=>g.key===v.current);if(p>=0&&p!==o){const g=[...s.sections],R=g.splice(p,1)[0];g.splice(o,0,R),y({...s,sections:g})}v.current=null},className:"bg-surface "+(v.current===t.key?"opacity-40":""),children:[e.jsxs("div",{className:"flex items-center gap-1 px-3 py-2",children:[e.jsx(ze,{size:13,className:"shrink-0 cursor-grab text-ink-3"}),e.jsx("input",{className:"min-w-0 flex-1 rounded-sm border border-transparent bg-transparent px-1 py-0.5 text-[12.5px] font-medium text-ink-1 hover:border-line focus:border-brand focus:outline-none",value:t.title,onChange:p=>y({...s,sections:s.sections.map(g=>g.key===t.key?{...g,title:p.target.value}:g)})}),e.jsx("button",{className:"rounded p-1 text-ink-3 hover:text-ink-1 disabled:opacity-30","aria-label":"上移",disabled:o===0,onClick:()=>M(o,-1),children:e.jsx(de,{size:12})}),e.jsx("button",{className:"rounded p-1 text-ink-3 hover:text-ink-1 disabled:opacity-30","aria-label":"下移",disabled:o===s.sections.length-1,onClick:()=>M(o,1),children:e.jsx(ce,{size:12})}),e.jsx("button",{className:"ml-0.5 rounded-sm border px-1.5 py-0.5 text-[11px] transition-colors "+(t.enabled?"border-brand/40 bg-brand-subtle text-brand-text":"border-line bg-surface-2 text-ink-3"),onClick:()=>y({...s,sections:s.sections.map(p=>p.key===t.key?{...p,enabled:!p.enabled}:p)}),children:t.enabled?"显示":"隐藏"}),e.jsx("button",{className:"rounded p-1 text-ink-3 hover:text-ink-1","aria-label":"展开编辑",onClick:()=>S(p=>{const g=new Set(p);return g.has(t.key)?g.delete(t.key):g.add(t.key),g}),children:e.jsx(Se,{size:13,className:"transition-transform "+(n?"rotate-90":"")})})]}),n&&e.jsx("div",{className:"border-t border-line bg-surface-2 px-3 py-2.5",children:t.kind==="text"?e.jsx(oe,{rows:4,value:t.text??"",placeholder:"输入该板块内容…",onChange:p=>y({...s,sections:s.sections.map(g=>g.key===t.key?{...g,text:p.target.value}:g)})}):t.kind==="info"?e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("div",{className:"mb-0.5 text-[11px] text-ink-3",children:"勾选 = 在基本信息中显示"}),Ue.map(p=>e.jsxs("label",{className:"flex cursor-pointer items-center gap-2 text-[12px]",children:[e.jsx("input",{type:"checkbox",className:"size-3.5",checked:!(t.hiddenFields??[]).includes(p[0]),onChange:()=>y({...s,sections:s.sections.map(g=>{if(g.key!==t.key)return g;const R=new Set(g.hiddenFields??[]);return R.has(p[0])?R.delete(p[0]):R.add(p[0]),{...g,hiddenFields:[...R]}})})}),p[1]]},p[0]))]}):t.kind==="list"?e.jsx(Ae,{cfg:s,section:t,records:O,persist:y,sectionTypes:he(t.key)}):e.jsx("p",{className:"text-[11.5px] text-ink-3",children:"该板块内容来自「个人信息」页与记录数据。"})}),e.jsxs("div",{className:"px-3 pb-1.5 text-[10.5px] text-ink-3",children:[f,(N=t.types)!=null&&N.length?" · "+t.types.join("/"):""]})]},t.key)}),e.jsxs("div",{className:"grid grid-cols-2 gap-2 p-3",children:[e.jsxs(L,{size:"sm",variant:"secondary",onClick:()=>G("text"),children:[e.jsx(W,{size:13})," 文本板块"]}),e.jsxs(L,{size:"sm",variant:"secondary",onClick:()=>G("list"),children:[e.jsx(W,{size:13})," 列表板块"]})]})]})})]})]})]})]})}function Ae({cfg:a,section:h,records:u,persist:w,sectionTypes:b}){const[c,l]=E.useState(null),i=new Set(h.excluded??[]),_=u.filter(s=>(h.types??[]).includes(s.type_name)&&s.status!=="draft").sort((s,x)=>(x.start_date??x.created_at).localeCompare(s.start_date??s.created_at)),k=h.items??[],S=s=>w({...a,sections:a.sections.map(x=>x.key===h.key?{...x,...s}:x)}),P=s=>{const x=new Set(h.excluded??[]);x.has(s)?x.delete(s):x.add(s),S({excluded:[...x]})},j=[...h.itemOrder??[]],d=new Set(j),v=new Map;_.forEach(s=>{const x="r"+s.id;v.set(x,{type:"record",r:s}),d.has(x)||(j.push(x),d.add(x))}),k.forEach((s,x)=>{const r=s.id??"c"+x;v.set(r,{type:"custom",c:s,idx:x}),d.has(r)||(j.push(r),d.add(r))});const m=(s,x)=>{const r=j.indexOf(s),C=r+x;r<0||C<0||C>=j.length||([j[r],j[C]]=[j[C],j[r]],S({itemOrder:j}))},O=({k:s})=>e.jsxs("span",{className:"flex shrink-0 flex-col",children:[e.jsx("button",{className:"text-ink-3 hover:text-ink-1","aria-label":"上移",onClick:()=>m(s,-1),children:e.jsx(de,{size:11})}),e.jsx("button",{className:"text-ink-3 hover:text-ink-1","aria-label":"下移",onClick:()=>m(s,1),children:e.jsx(ce,{size:11})})]});return e.jsxs("div",{className:"flex flex-col gap-2.5",children:[e.jsx("div",{className:"text-[11px] text-ink-3",children:"条目排序(↑↓)· 记录勾选显隐 · 自定义条目可增删"}),j.map(s=>{const x=v.get(s);if(!x)return null;if(x.type==="record"){const r=x.r;return e.jsxs("div",{className:"flex items-center gap-2 text-[12px]",children:[e.jsx(O,{k:s}),e.jsxs("label",{className:"flex min-w-0 flex-1 cursor-pointer items-center gap-2",children:[e.jsx("input",{type:"checkbox",className:"size-3.5",checked:!i.has(r.id),onChange:()=>P(r.id)}),e.jsx("span",{className:"min-w-0 flex-1 truncate text-ink-1",children:r.title})]}),e.jsx("span",{className:"num shrink-0 text-[11px] text-ink-3",children:(r.start_date??"").slice(0,7)})]},s)}return e.jsxs("div",{className:"flex items-center gap-2 rounded-md border border-line bg-surface p-1.5 text-[12px]",children:[e.jsx(O,{k:s}),e.jsxs("span",{className:"min-w-0 flex-1 truncate text-ink-1",children:[x.c.title,e.jsxs("span",{className:"text-ink-3",children:[" · ",x.c.date??""]})]}),e.jsx("button",{className:"text-ink-3 hover:text-danger","aria-label":"删除条目",onClick:()=>S({items:k.filter((r,C)=>C!==x.idx)}),children:e.jsx(ne,{size:12})})]},s)}),e.jsxs("div",{className:"mt-1 border-t border-line pt-2",children:[e.jsxs("div",{className:"mb-1.5 flex items-center justify-between",children:[e.jsxs("span",{className:"text-[11.5px] font-medium text-ink-2",children:["自定义条目(",k.length,")"]}),e.jsxs(L,{size:"sm",variant:"ghost",onClick:()=>l({title:""}),children:[e.jsx(W,{size:12})," 添加"]})]}),c&&e.jsxs("div",{className:"mb-2 rounded-md border border-line bg-surface p-2",children:[e.jsx(H,{className:"mb-1.5",placeholder:"标题",value:c.title,onChange:s=>l({...c,title:s.target.value})}),e.jsxs("div",{className:"mb-1.5 grid grid-cols-2 gap-1.5",children:[e.jsx(H,{placeholder:"副标题(单位/角色)",value:c.subtitle??"",onChange:s=>l({...c,subtitle:s.target.value})}),e.jsx(H,{placeholder:"日期(2025.9)",value:c.date??"",onChange:s=>l({...c,date:s.target.value})})]}),e.jsx(oe,{rows:2,placeholder:"描述:做了什么、负责什么、学会什么",value:c.desc??"",onChange:s=>l({...c,desc:s.target.value})}),e.jsxs("div",{className:"mt-1.5 flex gap-1.5",children:[e.jsx(L,{size:"sm",variant:"primary",disabled:!c.title.trim(),onClick:()=>{c.title.trim()&&(S({items:[...k,{...c,id:"c"+Date.now()}]}),l(null))},children:"添加"}),e.jsx(L,{size:"sm",variant:"ghost",onClick:()=>l(null),children:"取消"})]})]}),k.map((s,x)=>e.jsxs("div",{className:"flex items-center gap-2 rounded-md border border-line bg-surface p-1.5 text-[12px]",children:[e.jsxs("span",{className:"min-w-0 flex-1 truncate text-ink-1",children:[s.title,e.jsxs("span",{className:"text-ink-3",children:[" · ",s.date??""]})]}),e.jsx("button",{className:"text-ink-3 hover:text-danger","aria-label":"删除条目",onClick:()=>S({items:k.filter((r,C)=>C!==x)}),children:e.jsx(ne,{size:12})})]},x)),!k.length&&!c&&e.jsx("p",{className:"text-[11.5px] text-ink-3",children:"暂无自定义条目"})]}),e.jsxs("p",{className:"text-[11px] text-ink-3",children:["「",b,"」相关条目来自你的记录数据,此处可隐藏不需要展示的条目;描述可在预览中点击直接修改。"]})]})}export{We as ResumePage};
|