fix: DEMO_RESUME declared before use
This commit is contained in:
@@ -23,15 +23,6 @@ export const RESUME_SECTION_DEFS: ResumeSectionDef[] = [
|
||||
{ key: 'self', defaultTitle: '自我评价', kind: 'text', fixed: true },
|
||||
];
|
||||
|
||||
// 首次使用种子内容(虚构示例,可自由修改)
|
||||
const SEED: Record<string, { text?: string; items?: { title: string; subtitle?: string; date?: string; desc?: string }[] }> = {
|
||||
skills: { text: '程序设计:熟悉 Python 与 C/C++,掌握常用数据结构与算法,能独立完成中小型工具与脚本开发。\n网络安全:熟悉常见 Web 漏洞原理(SQL 注入、XSS、CSRF 等)与防护方案,掌握 Burp Suite、Nmap、Wireshark 等常用工具。\n网络基础:熟悉 TCP/IP 协议栈与交换路由基础配置,理解 VLAN、NAT、ACL 等核心技术。\n运维基础:熟悉 Linux 常用操作与 Shell 脚本,了解 Docker 容器化部署与 Nginx 服务配置。' },
|
||||
campus: { items: [
|
||||
{ title: '校图书馆学生助理', subtitle: '读者服务岗', date: '2024.9 - 2025.6', desc: '负责书库整理与借阅服务,协助开展入馆培训与阅读推广活动,累计服务读者千余人次。培养了责任意识与服务意识,锻炼了多任务时间管理能力。' },
|
||||
{ title: '院学生会宣传部干事', subtitle: '平面设计与文案', date: '2023.9 - 2024.6', desc: '参与学院活动的海报设计与推文撰写,负责活动现场的后勤与设备保障。锻炼了审美表达、协作沟通与临场应变能力。' },
|
||||
]},
|
||||
self: { text: '性格沉稳踏实,做事有计划性,习惯提前预判风险并准备预案;学习能力强,能快速上手新技术与工具;责任心强,注重细节与条理,凡事有始有终,能独立推进任务并在压力下保持稳定输出。' },
|
||||
};
|
||||
|
||||
|
||||
export type ResumeTemplate = 'classic' | 'tech' | 'minimal';
|
||||
@@ -43,9 +34,6 @@ export function defaultResumeConfig(): ResumeConfig {
|
||||
fontScale: 1, density: 'normal', onePage: false,
|
||||
sections: RESUME_SECTION_DEFS.map(d => ({
|
||||
key: d.key, title: d.defaultTitle, enabled: true, kind: d.kind, types: d.types,
|
||||
...(d.key === 'skills' ? { text: SEED.skills.text } : {}),
|
||||
...(d.key === 'campus' ? { items: SEED.campus.items } : {}),
|
||||
...(d.key === 'self' ? { text: SEED.self.text } : {}),
|
||||
})),
|
||||
};
|
||||
}
|
||||
@@ -68,9 +56,6 @@ export function migrateResumeConfig(raw: unknown): ResumeConfig {
|
||||
kind: dd ? d.kind : (old?.kind ?? d.kind),
|
||||
types: dd?.types ?? old?.types,
|
||||
};
|
||||
if (d.key === 'skills' && base.text == null) base.text = SEED.skills.text;
|
||||
if (d.key === 'campus' && !(base.items?.length)) base.items = SEED.campus.items;
|
||||
if (d.key === 'self' && base.text == null) base.text = SEED.self.text;
|
||||
return base;
|
||||
});
|
||||
// 旧版本已被取代的板块 key:直接丢弃,避免残留造成内容重复
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Download, Printer, RotateCcw } from 'lucide-react';
|
||||
import { attachmentList, attachmentThumb, footprintList, gradesOverview, profileGet, profileUpsert } from '@/lib/api';
|
||||
import type { FootprintRow, ProfileInfo, ZcOverrides } from '@/lib/types';
|
||||
import { computeZongce, gradeLabel, ZC_DEFAULT_RULES, type ZcRules, type ZcResult } from '@/lib/zongce';
|
||||
import { Button, Select, useToast } from '@/components/ui';
|
||||
import { Button, Dialog, Select, useToast } from '@/components/ui';
|
||||
|
||||
interface Evidence { recordId: number; title: string; images: string[] }
|
||||
|
||||
@@ -72,6 +72,7 @@ export function AssessmentPage() {
|
||||
const [year, setYear] = useState('');
|
||||
const [ovMap, setOvMap] = useState<Record<string, ZcOverrides>>({});
|
||||
const [evidence, setEvidence] = useState<Evidence[]>([]);
|
||||
const [initOpen, setInitOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!stored) return;
|
||||
@@ -124,13 +125,6 @@ export function AssessmentPage() {
|
||||
setOvMap(m => ({ ...m, [year]: next }));
|
||||
void profileUpsert({ info: profile, zongce: { rules, overrides: { ...ovMap, [year]: next } } }).catch(e => toast('error', e.message));
|
||||
};
|
||||
const resetOverrides = () => {
|
||||
const next = { ...ovMap };
|
||||
delete next[year];
|
||||
setOvMap(next);
|
||||
void profileUpsert({ info: profile, zongce: { rules, overrides: next } }).then(() => toast('success', '已恢复自动计算')).catch(e => toast('error', e.message));
|
||||
};
|
||||
|
||||
const termLabel = year === 'all' ? '全部学年' : gradeLabel(year, profile.eduStart);
|
||||
|
||||
const exportWord = () => {
|
||||
@@ -149,8 +143,8 @@ export function AssessmentPage() {
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<Select className="w-[190px]" value={year} onChange={e => setYear(e.target.value)}
|
||||
options={[...Array.from(new Set((gradesQ.data?.semesters ?? []).map(x => x.term.slice(0, 7)))).map(y => ({ value: y, label: gradeLabel(y, profile.eduStart) })), { value: 'all', label: '全部学年' }]} />
|
||||
<Button variant="secondary" onClick={resetOverrides}><RotateCcw size={13} /> 恢复自动</Button>
|
||||
<Button variant="secondary" onClick={exportWord}><Download size={13} /> 导出材料</Button>
|
||||
<Button variant="secondary" onClick={() => setInitOpen(true)}><RotateCcw size={13} /> 初始化</Button>
|
||||
<Button variant="primary" onClick={() => window.print()}><Printer size={13} /> 打印</Button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -216,6 +210,26 @@ export function AssessmentPage() {
|
||||
「恢复自动」清除本学年全部手动修正。导出材料前请核对每条加分记录与证明材料一致。
|
||||
</div>
|
||||
</div>
|
||||
<Dialog
|
||||
open={initOpen}
|
||||
onClose={() => setInitOpen(false)}
|
||||
width={440}
|
||||
title="初始化综测"
|
||||
footer={<>
|
||||
<Button variant="ghost" onClick={() => setInitOpen(false)}>取消</Button>
|
||||
<Button variant="primary" onClick={() => {
|
||||
const next = { ...ovMap };
|
||||
delete next[year];
|
||||
setOvMap(next);
|
||||
void profileUpsert({ info: profile, zongce: { rules, overrides: next } }).then(() => { setInitOpen(false); toast('success', '已恢复自动计算'); }).catch(e => toast('error', e.message));
|
||||
}}>恢复自动计算</Button>
|
||||
</>}>
|
||||
<div className="text-[12.5px] leading-relaxed text-ink-2">
|
||||
将清除 <b>{year === 'all' ? '全部学年' : gradeLabel(year, profile.eduStart)}</b> 的全部手动修正
|
||||
(分值覆盖、操行/诚信分修改),恢复为按细则规则的自动计算结果。
|
||||
<div className="mt-2 text-ink-3">记录数据与个人信息不受影响。</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { ArrowDown, ArrowUp, ChevronRight, Download, GripVertical, PanelRightClose, PanelRightOpen, Plus, Printer, RefreshCw, RotateCcw, Trash2 } from 'lucide-react';
|
||||
import { ArrowDown, ArrowUp, ChevronRight, Download, GripVertical, PanelRightClose, PanelRightOpen, Plus, Printer, RotateCcw, Trash2 } from 'lucide-react';
|
||||
import { footprintList, profileGet, profileUpsert } from '@/lib/api';
|
||||
import type { FootprintRow, ProfileInfo, ResumeConfig, ResumeItemCfg, ResumeSectionCfg } from '@/lib/types';
|
||||
import {
|
||||
@@ -182,19 +182,6 @@ export function ResumePage() {
|
||||
.catch(e => toast('error', e.message));
|
||||
};
|
||||
|
||||
// 重新载入:从服务器拉最新记录与配置,丢弃本地未保存状态
|
||||
const reloadAll = async () => {
|
||||
try {
|
||||
const [p] = await Promise.all([profileQ.refetch(), listQ.refetch()]);
|
||||
const stored = p.data?.content;
|
||||
if (stored) {
|
||||
setConfig(migrateResumeConfig(stored.resume));
|
||||
setSelfIntro((stored.info as ProfileInfo | undefined)?.selfIntro ?? '');
|
||||
}
|
||||
toast('success', '已重新载入最新数据');
|
||||
} catch (e) { toast('error', (e as Error).message); }
|
||||
};
|
||||
|
||||
const exportConfig = () => {
|
||||
const blob = new Blob([JSON.stringify(cfg, null, 2)], { type: 'application/json' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
@@ -223,9 +210,6 @@ export function ResumePage() {
|
||||
{panelOpen ? <PanelRightClose size={13} /> : <PanelRightOpen size={13} />}
|
||||
{panelOpen ? '收起设置' : '展开设置'}
|
||||
</Button>
|
||||
<Button variant="secondary" onClick={() => void reloadAll()}>
|
||||
<RefreshCw size={13} /> 重新载入
|
||||
</Button>
|
||||
<Button variant="ghost" className="text-danger hover:bg-danger-subtle" onClick={() => setInitOpen(true)}>
|
||||
<RotateCcw size={13} /> 初始化简历
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user