feat(demo): 25 footprints w/ 10 competition awards + real drawn certificate attachments, grade data aligned to gpa formula, seed.mjs reuses demo_seed command layer

This commit is contained in:
root
2026-10-17 17:04:37 +08:00
parent 48aa5dc07f
commit b7ad7ef5dc
17 changed files with 90 additions and 70 deletions
+47 -20
View File
@@ -5,6 +5,7 @@ import fs from 'node:fs';
import path from 'node:path';
import crypto from 'node:crypto';
import { fileURLToPath } from 'node:url';
import { loadCert, CERT_BY_TITLE } from './demo-certs.mjs';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
export const DATA_DIR = process.env.DATA_DIR || path.join(__dirname, '..', '.data');
@@ -412,6 +413,27 @@ export const DEMO_ROWS = [
['证书技能', '计算机技术与软件专业技术资格(软件设计师)', '参加', '国家级', null, '工业和信息化部', '2025-11-08', null, 'ongoing',
'备考软件设计师(中级)', '', ['软考'], ['职业发展'],
{}, {}],
['竞赛', 'ACM-ICPC 国际大学生程序设计竞赛', '核心', '国家级', '银奖', '中国大学生程序设计竞赛组委会', '2025-10-18', '2025-10-19', 'finished',
'赛区内团队排名前 5%,与队友分工负责图论与动态规划、数据结构与搜索方向', '亚洲区域赛银奖', ['算法', '团队协作'], ['学业深造'],
{ my_work: '图论建模与状态转移设计', team_members: '王五、赵六' }, {}],
['竞赛', '中国大学生计算机设计大赛', '主导', '国家级', '二等奖', '中国大学生计算机设计大赛组织委员会', '2025-05-10', '2025-07-30', 'finished',
'作品《基于流量特征的入侵检测系统》,负责整体方案设计与检测算法实现', '全国总决赛二等奖', ['计算机', '安全'], ['学业深造'],
{ my_work: '方案设计、检测算法实现', team_members: '张三、李四' }, {}],
['竞赛', '第三届"强网杯"全国大学生网络安全挑战赛', '核心', '国家级', '二等奖', '战略支援部队信息工程大学', '2024-11-09', '2024-11-11', 'finished',
'CTF 攻防模式,负责 Web 渗透与 RSA 共模攻击类密码题', '半决赛二等奖', ['CTF', '密码', '安全'], ['职业发展'],
{ my_work: 'Web 渗透与密码工具编写', team_members: '张三、王五' }, {}],
['竞赛', '"挑战杯"全国大学生课外学术科技作品竞赛(省赛)', '核心', '省市级', '三等奖', '共青团重庆市委员会', '2025-03-15', '2025-06-20', 'finished',
'作品「基于流量特征的入侵检测研究」,负责研究报告撰写与答辩', '省赛三等奖', ['科研', '学术'], ['学业深造'],
{ my_work: '研究报告撰写' }, {}],
['竞赛', '全国大学生英语竞赛', '参加', '省市级', '三等奖', '高等学校大学外语教学研究会', '2024-04-14', '2024-04-14', 'finished',
'C 类笔试,词汇与阅读优势明显', 'C类省级三等奖', ['英语'], ['学业深造'],
{ score: '88' }, {}],
['竞赛', '院"新生杯"程序设计竞赛', '参加', '二级学院', '一等奖', '计算机网络学院', '2023-11-18', '2023-11-18', 'finished',
'大一入门竞赛,C 语言实现图书管理系统', '院级一等奖', ['编程'], ['学业深造'],
{}, {}],
['竞赛', '全国大学生密码技术竞赛', '参加', '国家级', null, '中国密码学会', '2025-11-20', null, 'ongoing',
'组队备战国赛(SM9 聚群签名方向)', '', ['密码', '学术'], ['学业深造'],
{}, {}],
['实习实践', '某安全公司渗透测试实习生', '参加', null, null, '某网络安全科技有限公司', '2025-07-01', '2025-08-25', 'finished',
'参与企业授权渗透测试项目 3 个,编写测试报告', '获实习优秀评价', ['实习', '安全'], ['职业发展'],
{ position: '渗透测试实习生', mentor: '陈工' }, {}]
@@ -446,27 +468,27 @@ export const DEMO_PROFILE = {
resume: DEMO_RESUME
};
// 演示附件用真实 PNG(1x1,可在预览查看并进入综测证明材料)
const DEMO_PNG = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==';
// 学期: { term, gpa, rank, total, courses: [课程名, 学分, 分数, 绩点, 类别][] }
// 学期: { term, gpa, rank, total, courses: [课程名, 学分, 分数, 绩点, 类别][] }
// 演示成绩与成绩梯度公式一致:分段线性 gp(90→4.0 至 100→5.0,80→3.0 至 89→3.9 …),
// 学期 GPA 为分类加权(必修 1.2 / 专业选修 1.1),与 grades_overview 的综合算法结果吻合。
export const DEMO_SEMESTERS = [
{ term: '2023-2024-1', gpa: 3.42, rank: 38, total: 156, courses: [
['高等数学(上)', 5, 78, 3.0, '必修课'], ['大学英语(一)', 3, 85, 3.7, '必修课'], ['程序设计基础', 4, 91, 4.0, '必修课'],
['思想道德与法治', 2, 88, 3.9, '必修课'], ['体育(一)', 1, 82, 3.5, '必修课']
{ term: '2023-2024-1', gpa: 4.13, rank: 48, total: 156, courses: [
['高等数学(上)', 5, 78, 2.8, '必修课'], ['大学英语(一)', 3, 85, 3.5, '必修课'], ['程序设计基础', 4, 91, 4.1, '必修课'],
['思想道德与法治', 2, 88, 3.8, '必修课'], ['体育(一)', 1, 82, 3.2, '必修课']
]},
{ term: '2023-2024-2', gpa: 3.61, rank: 29, total: 156, courses: [
['高等数学(下)', 5, 84, 3.7, '必修课'], ['线性代数', 3, 76, 2.9, '必修课'], ['数据结构', 4, 90, 4.0, '必修课'],
['大学英语(二)', 3, 87, 3.8, '必修课'], ['中国近现代史纲要', 2, 84, 3.5, '必修课'], ['体育(二)', 1, 86, 3.8, '必修课']
{ term: '2023-2024-2', gpa: 4.15, rank: 36, total: 156, courses: [
['高等数学(下)', 5, 84, 3.4, '必修课'], ['线性代数', 3, 76, 2.6, '必修课'], ['数据结构', 4, 90, 4.0, '必修课'],
['大学英语(二)', 3, 87, 3.7, '必修课'], ['中国近现代史纲要', 2, 84, 3.4, '必修课'], ['体育(二)', 1, 86, 3.6, '必修课']
]},
{ term: '2024-2025-1', gpa: 3.78, rank: 18, total: 156, courses: [
['概率论与数理统计', 3, 88, 3.9, '必修课'], ['操作系统', 4, 92, 4.0, '必修课'], ['计算机网络', 4, 86, 3.8, '必修课'],
['数据库原理', 3, 94, 4.0, '必修课'], ['马克思主义基本原理', 2, 81, 3.3, '必修课'], ['体育(三)', 1, 88, 3.9, '必修课']
{ term: '2024-2025-1', gpa: 4.63, rank: 11, total: 156, courses: [
['概率论与数理统计', 3, 88, 3.8, '必修课'], ['操作系统', 4, 92, 4.18, '必修课'], ['计算机网络', 4, 86, 3.6, '必修课'],
['数据库原理', 3, 94, 4.36, '必修课'], ['马克思主义基本原理', 2, 81, 3.1, '必修课'], ['体育(三)', 1, 88, 3.8, '必修课']
]},
{ term: '2024-2025-2', gpa: 3.85, rank: 12, total: 156, courses: [
['软件工程', 3, 90, 4.0, '必修课'], ['信息安全导论', 3, 95, 4.0, '必修课'], ['密码学基础', 3, 89, 3.9, '必修课'],
['Web 应用开发', 2, 96, 4.0, '专业选修课'], ['数字逻辑', 3, 79, 3.1, '必修课'], ['体育(四)', 1, 90, 4.0, '必修课']
{ term: '2024-2025-2', gpa: 4.65, rank: 7, total: 156, courses: [
['软件工程', 3, 90, 4.0, '必修课'], ['信息安全导论', 3, 95, 4.45, '必修课'], ['密码学基础', 3, 89, 3.9, '必修课'],
['Web 应用开发', 2, 96, 4.55, '专业选修课'], ['数字逻辑', 3, 79, 2.9, '必修课'], ['体育(四)', 1, 90, 4.0, '必修课']
]}
];
@@ -1261,11 +1283,16 @@ function listFootprints(d, query) {
dimension_ids: (dimNames || []).map((nm) => dimIds[nm]).filter(Boolean),
}});
n++;
// 演示附件:竞赛/荣誉记录附带证书图片(可预览、可进综测证明材料)
if (/竞赛|优秀共青团员/.test(String(title)) && status === 'finished') {
try {
handleCommand('attachment_add', { owner_id: fr.item.id, file_name: '获奖证书.png', mime: 'image/png', size: DEMO_PNG.length, data_b64: DEMO_PNG, thumb_b64: DEMO_PNG });
} catch {}
// 演示附件:按标题匹配对应证书图片(可预览、可进综测证明材料)
const certKey = CERT_BY_TITLE.find((p2) => p2[0].test(String(title)))?.[1];
if (certKey && status === 'finished') {
const cert = loadCert(certKey);
if (cert) {
try {
const att = handleCommand('attachment_add', { owner_id: fr.id, ...cert });
console.log('[demo-seed] 证书附件已挂到「' + title + '」:', att.item?.id || att.item?.uuid || '?');
} catch (e) { console.log('[demo-seed] 证书附件失败 ' + title + ':', e.message); }
}
}
}
let sems = 0;