chore: 后端首次基线提交

运行必须源码:app/(controller/model/service/middleware/lib/utils/validate/router)、config/、database/(migrations/seeders/sql)、启动脚本、app/public/templates 模板。
已忽略运行非必须:node_modules/、logs/、run/、app/public 运行时上传数据、.env*、构建/缓存产物。
This commit is contained in:
WorkBuddy
2026-08-17 12:25:42 +08:00
commit a303cf2d53
109 changed files with 25904 additions and 0 deletions

View File

@@ -0,0 +1,207 @@
-- =====================================================================
-- 种子数据:选择题(50题×1分) + 判断题(20题×1分) + 综合性任务(1题×30分)
-- 总分:100分,符合"卫星通信与导航应用技术创新赛线上选拔赛"题型结构
-- =====================================================================
-- 清空现有数据
DELETE FROM choice_questions;
DELETE FROM judge_questions;
DELETE FROM word_questions;
ALTER TABLE choice_questions AUTO_INCREMENT = 1;
ALTER TABLE judge_questions AUTO_INCREMENT = 1;
ALTER TABLE word_questions AUTO_INCREMENT = 1;
-- =====================================================================
-- 第一篇:卫星通信技术(第1-6章)——选择题 (16题)
-- =====================================================================
INSERT INTO choice_questions (`group`, question, options, answer, score, sort_order, created_at, updated_at) VALUES
('zhongzhi', '卫星通信定义为?', '[{"key":"A","text":"利用卫星在地面站之间进行的通信"},{"key":"B","text":"利用卫星转发无线电信号实现多个地球站之间的通信"},{"key":"C","text":"卫星与飞机之间的通信"},{"key":"D","text":"卫星之间的宇宙通信"}]', 'B', 1, 1, NOW(), NOW()),
('zhongzhi', '卫星通信中,地球站向卫星发射信号的链路称为?', '[{"key":"A","text":"下行链路"},{"key":"B","text":"上行链路"},{"key":"C","text":"前向链路"},{"key":"D","text":"反向链路"}]', 'B', 1, 2, NOW(), NOW()),
('zhongzhi', '卫星通信的主要优点不包括以下哪项?', '[{"key":"A","text":"覆盖范围大"},{"key":"B","text":"通信容量大"},{"key":"C","text":"建站成本低"},{"key":"D","text":"不受地理条件限制"}]', 'C', 1, 3, NOW(), NOW()),
('zhongzhi', '通信系统中,将原始信号转换为适合信道传输的信号的过程称为?', '[{"key":"A","text":"编码"},{"key":"B","text":"调制"},{"key":"C","text":"解码"},{"key":"D","text":"解调"}]', 'B', 1, 4, NOW(), NOW()),
('zhongzhi', 'GEO卫星的轨道高度约为?', '[{"key":"A","text":"500-1500 km"},{"key":"B","text":"5000-12000 km"},{"key":"C","text":"20200 km"},{"key":"D","text":"35786 km"}]', 'D', 1, 5, NOW(), NOW()),
('zhongzhi', 'MEO卫星的轨道高度范围是?', '[{"key":"A","text":"低于500 km"},{"key":"B","text":"500-2000 km"},{"key":"C","text":"5000-20000 km"},{"key":"D","text":"35786 km"}]', 'C', 1, 6, NOW(), NOW()),
('zhongzhi', 'LEO卫星的轨道倾角通常为?', '[{"key":"A","text":"0度"},{"key":"B","text":"近极地轨道"},{"key":"C","text":"赤道轨道"},{"key":"D","text":"地球同步轨道"}]', 'B', 1, 7, NOW(), NOW()),
('zhongzhi', '卫星通信中,频率复用技术的主要作用是?', '[{"key":"A","text":"提高频率利用率"},{"key":"B","text":"降低发射功率"},{"key":"C","text":"减少卫星数量"},{"key":"D","text":"提高信号质量"}]', 'A', 1, 8, NOW(), NOW()),
('zhongzhi', '以下哪种不是卫星通信的多址方式?', '[{"key":"A","text":"FDMA"},{"key":"B","text":"TDMA"},{"key":"C","text":"CDMA"},{"key":"D","text":"ADMA"}]', 'D', 1, 9, NOW(), NOW()),
('zhongzhi', '卫星物联网中,星上处理的主要目的是?', '[{"key":"A","text":"增加卫星重量"},{"key":"B","text":"提高传输效率"},{"key":"C","text":"降低功率"},{"key":"D","text":"增加轨道高度"}]', 'B', 1, 10, NOW(), NOW()),
('zhongzhi', '低轨卫星星座的特点是?', '[{"key":"A","text":"单星覆盖大,但需要星上处理"},{"key":"B","text":"全球覆盖,大容量低时延"},{"key":"C","text":"只有一颗卫星"},{"key":"D","text":"不需要切换"}]', 'B', 1, 11, NOW(), NOW()),
('zhongzhi', '卫星通信系统的转发器作用是?', '[{"key":"A","text":"存储数据"},{"key":"B","text":"放大变频转发信号"},{"key":"C","text":"计算信号"},{"key":"D","text":"控制卫星姿态"}]', 'B', 1, 12, NOW(), NOW()),
('zhongzhi', '卫星天线的指向精度影响?', '[{"key":"A","text":"信号接收功率"},{"key":"B","text":"卫星重量"},{"key":"C","text":"轨道高度"},{"key":"D","text":"卫星寿命"}]', 'A', 1, 13, NOW(), NOW()),
('zhongzhi', '卫星电源系统主要采用?', '[{"key":"A","text":"燃料电池"},{"key":"B","text":"太阳能电池阵+蓄电池组"},{"key":"C","text":"核能发电"},{"key":"D","text":"化学电池"}]', 'B', 1, 14, NOW(), NOW()),
('zhongzhi', '以下哪个频段常用作卫星通信上行?', '[{"key":"A","text":"UHF"},{"key":"B","text":"C-band"},{"key":"C","text":"Ku-band"},{"key":"D","text":"Ka-band"}]', 'D', 1, 15, NOW(), NOW()),
('zhongzhi', '卫星姿态控制的目的是?', '[{"key":"A","text":"改变轨道高度"},{"key":"B","text":"保持天线指向目标区域"},{"key":"C","text":"改变速度"},{"key":"D","text":"减少功耗"}]', 'B', 1, 16, NOW(), NOW());
-- =====================================================================
-- 第二篇:卫星导航技术(第1-8章)——选择题 (34题)
-- =====================================================================
INSERT INTO choice_questions (`group`, question, options, answer, score, sort_order, created_at, updated_at) VALUES
('zhongzhi', 'GNSS的全称是?', '[{"key":"A","text":"Global Navigation Satellite System"},{"key":"B","text":"Global Network Service System"},{"key":"C","text":"General Navigation Support System"},{"key":"D","text":"Geo Navigation Satellite System"}]', 'A', 1, 17, NOW(), NOW()),
('zhongzhi', '以下哪个不属于四大全球导航卫星星座?', '[{"key":"A","text":"GPS"},{"key":"B","text":"北斗"},{"key":"C","text":"GLONASS"},{"key":"D","text":"WAAS"}]', 'D', 1, 18, NOW(), NOW()),
('zhongzhi', '北斗三号全球系统提供多少颗卫星?', '[{"key":"A","text":"24"},{"key":"B","text":"30"},{"key":"C","text":"35"},{"key":"D","text":"40"}]', 'C', 1, 19, NOW(), NOW()),
('zhongzhi', 'GPS卫星导航系统至少需要几颗卫星才能实现三维定位?', '[{"key":"A","text":"2颗"},{"key":"B","text":"3颗"},{"key":"C","text":"4颗"},{"key":"D","text":"5颗"}]', 'C', 1, 20, NOW(), NOW()),
('zhongzhi', '伪距测量测量的是?', '[{"key":"A","text":"卫星到接收机的几何距离"},{"key":"B","text":"卫星信号传播时间乘以光速得到的距离"},{"key":"C","text":"卫星到地心的距离"},{"key":"D","text":"接收机到地面的距离"}]', 'B', 1, 21, NOW(), NOW()),
('zhongzhi', '卫星定位误差中,属于系统误差的是?', '[{"key":"A","text":"电离层延迟误差"},{"key":"B","text":"接收机噪声"},{"key":"C","text":"多径效应随机误差"},{"key":"D","text":"测量噪声"}]', 'A', 1, 22, NOW(), NOW()),
('zhongzhi', '差分定位技术中,RTK的全称是?', '[{"key":"A","text":"Real-Time Kinematic"},{"key":"B","text":"Rapid Tracking Kinematic"},{"key":"C","text":"Real-Time Kalman"},{"key":"D","text":"Radio Transmission Kinematic"}]', 'A', 1, 23, NOW(), NOW()),
('zhongzhi', 'NMEA-0183协议中,GGA语句主要提供什么信息?', '[{"key":"A","text":"卫星星历"},{"key":"B","text":"定位数据"},{"key":"C","text":"卫星状态"},{"key":"D","text":"速度信息"}]', 'B', 1, 24, NOW(), NOW()),
('zhongzhi', '北斗系统独具特色的服务是?', '[{"key":"A","text":"仅定位"},{"key":"B","text":"短报文通信"},{"key":"C","text":"仅授时"},{"key":"D","text":"仅测速"}]', 'B', 1, 25, NOW(), NOW()),
('zhongzhi', '高精度差分定位中,NTRIP协议用于?', '[{"key":"A","text":"卫星轨道计算"},{"key":"B","text":"通过互联网传输差分改正数据"},{"key":"C","text":"信号调制"},{"key":"D","text":"误差计算"}]', 'B', 1, 26, NOW(), NOW()),
('zhongzhi', '卫星导航接收机的灵敏度主要影响?', '[{"key":"A","text":"捕获卫星信号的能力"},{"key":"B","text":"发射功率"},{"key":"C","text":"卫星轨道高度"},{"key":"D","text":"计算速度"}]', 'A', 1, 27, NOW(), NOW()),
('zhongzhi', '组合导航GNSS+IMU中,IMU的作用是?', '[{"key":"A","text":"提供加速度和角速度"},{"key":"B","text":"提供定位结果"},{"key":"C","text":"提供时间信息"},{"key":"D","text":"提供卫星星历"}]', 'A', 1, 28, NOW(), NOW()),
('zhongzhi', '多路径效应产生的原因是?', '[{"key":"A","text":"卫星信号经过反射后与直达信号干涉"},{"key":"B","text":"多颗卫星信号叠加"},{"key":"C","text":"多个接收机同时工作"},{"key":"D","text":"电离层反射信号"}]', 'A', 1, 29, NOW(), NOW()),
('zhongzhi', 'RTCM标准主要用于?', '[{"key":"A","text":"卫星导航电文标准"},{"key":"B","text":"差分改正数据标准"},{"key":"C","text":"NMEA输出标准"},{"key":"D","text":"接口通信标准"}]', 'B', 1, 30, NOW(), NOW()),
('zhongzhi', 'PDOP值越大表示?', '[{"key":"A","text":"定位精度越好"},{"key":"B","text":"定位几何误差越大"},{"key":"C","text":"卫星越多"},{"key":"D","text":"温度越高"}]', 'B', 1, 31, NOW(), NOW()),
('zhongzhi', '北斗卫星导航系统的服务区覆盖?', '[{"key":"A","text":"仅中国"},{"key":"B","text":"亚太地区"},{"key":"C","text":"全球"},{"key":"D","text":"仅北半球"}]', 'C', 1, 32, NOW(), NOW()),
('zhongzhi', 'GPS卫星星历更新周期通常为?', '[{"key":"A","text":"30秒"},{"key":"B","text":"2小时"},{"key":"C","text":"1天"},{"key":"D","text":"1周"}]', 'B', 1, 33, NOW(), NOW()),
('zhongzhi', '静态相对定位主要用于?', '[{"key":"A","text":"需要高精度大地测量"},{"key":"B","text":"车辆导航"},{"key":"C","text":"船舶导航"},{"key":"D","text":"飞机导航"}]', 'A', 1, 34, NOW(), NOW()),
('zhongzhi', '载波相位测量相比伪距测量?', '[{"key":"A","text":"精度更高"},{"key":"B","text":"精度更低"},{"key":"C","text":"精度相同"},{"key":"D","text":"无法比较"}]', 'A', 1, 35, NOW(), NOW()),
('zhongzhi', '电离层延迟对伪距测量的影响?', '[{"key":"A","text":"夜间比白天大"},{"key":"B","text":"白天比夜间大"},{"key":"C","text":"没有影响"},{"key":"D","text":"只在冬季有影响"}]', 'B', 1, 36, NOW(), NOW()),
('zhongzhi', '周跳发生在?', '[{"key":"A","text":"载波相位测量中"},{"key":"B","text":"伪距测量中"},{"key":"C","text":"信号发射时"},{"key":"D","text":"卫星星历计算时"}]', 'A', 1, 37, NOW(), NOW()),
('zhongzhi', 'GPS系统由多少颗卫星组成?', '[{"key":"A","text":"24"},{"key":"B","text":"31"},{"key":"C","text":"35"},{"key":"D","text":"40"}]', 'A', 1, 38, NOW(), NOW()),
('zhongzhi', '以下哪种不属于北斗增强系统?', '[{"key":"A","text":"SBAS"},{"key":"B","text":"GBAS"},{"key":"C","text":"BDS-IS"},{"key":"D","text":"GLONASS"}]', 'D', 1, 39, NOW(), NOW()),
('zhongzhi', '单点定位精度通常为?', '[{"key":"A","text":"厘米级"},{"key":"B","text":"米级"},{"key":"C","text":"分米级"},{"key":"D","text":"毫米级"}]', 'B', 1, 40, NOW(), NOW()),
('zhongzhi', 'RTK定位精度通常达到?', '[{"key":"A","text":"厘米级"},{"key":"B","text":"米级"},{"key":"C","text":"千米级"},{"key":"D","text":"十米级"}]', 'A', 1, 41, NOW(), NOW()),
('zhongzhi', 'NMEA-0183语句的结束标志是?', '[{"key":"A","text":"换行"},{"key":"B","text":"校验和"},{"key":"C","text":"星号"},{"key":"D","text":"回车"}]', 'B', 1, 42, NOW(), NOW()),
('zhongzhi', '以下哪个不是北斗卫星导航系统的特点?', '[{"key":"A","text":"有源定位"},{"key":"B","text":"短报文通信"},{"key":"C","text":"区域服务不能全球覆盖"},{"key":"D","text":"三频信号"}]', 'C', 1, 43, NOW(), NOW()),
('zhongzhi', '卫星导航接收机捕获阶段的主要作用是?', '[{"key":"A","text":"搜索卫星信号并确定频率码相位"},{"key":"B","text":"跟踪信号"},{"key":"C","text":"计算位置"},{"key":"D","text":"输出速度"}]', 'A', 1, 44, NOW(), NOW()),
('zhongzhi', '对流层延迟改正模型中,通常使用?', '[{"key":"A","text":"Hopfield模型"},{"key":"B","text":"Klobuchar模型"},{"key":"C","text":"Black模型"},{"key":"D","text":"高斯模型"}]', 'A', 1, 45, NOW(), NOW()),
('zhongzhi', '全球定位系统中,UTC表示?', '[{"key":"A","text":"世界时"},{"key":"B","text":"协调世界时"},{"key":"C","text":"原子时"},{"key":"D","text":"恒星时"}]', 'B', 1, 46, NOW(), NOW()),
('zhongzhi', '整周模糊度解算属于?', '[{"key":"A","text":"伪距测量问题"},{"key":"B","text":"载波相位测量问题"},{"key":"C","text":"卫星轨道问题"},{"key":"D","text":"电离层问题"}]', 'B', 1, 47, NOW(), NOW()),
('zhongzhi', '以下哪个频率是北斗B1I信号频率?', '[{"key":"A","text":"1561.098 MHz"},{"key":"B","text":"1268.52 MHz"},{"key":"C","text":"1176.45 MHz"},{"key":"D","text":"1575.42 MHz"}]', 'A', 1, 48, NOW(), NOW()),
('zhongzhi', 'GPS选择的PRN码特点是?', '[{"key":"A","text":"自相关特性好,互相关特性弱"},{"key":"B","text":"自相关特性弱,互相关特性强"},{"key":"C","text":"长度固定不变"},{"key":"D","text":"只有一个码"}]', 'A', 1, 49, NOW(), NOW()),
('zhongzhi', '下列哪项不属于卫星导航的应用?', '[{"key":"A","text":"车辆导航"},{"key":"B","text":"工程测量"},{"key":"C","text":"火力发电"},{"key":"D","text":"时间同步"}]', 'C', 1, 50, NOW(), NOW());
-- =====================================================================
-- 高职组补充选择题(同样50题)
-- =====================================================================
INSERT INTO choice_questions (`group`, question, options, answer, score, sort_order, created_at, updated_at) VALUES
('gaozhi', '卫星通信中,FDMA的含义是?', '[{"key":"A","text":"频分多址"},{"key":"B","text":"时分多址"},{"key":"C","text":"码分多址"},{"key":"D","text":"空分多址"}]', 'A', 1, 1, NOW(), NOW()),
('gaozhi', 'GEO卫星的星下点位置相对于地面观察者?', '[{"key":"A","text":"不断高速移动"},{"key":"B","text":"基本静止"},{"key":"C","text":"每天环绕一次"},{"key":"D","text":"每月环绕一次"}]', 'B', 1, 2, NOW(), NOW()),
('gaozhi', 'OFDM技术中,子载波之间保持正交性的目的是?', '[{"key":"A","text":"提高发射功率"},{"key":"B","text":"避免子载波间干扰"},{"key":"C","text":"增加带宽"},{"key":"D","text":"降低频率"}]', 'B', 1, 3, NOW(), NOW()),
('gaozhi', '北斗三号全球卫星导航系统具备以下哪种特色服务?', '[{"key":"A","text":"仅定位服务"},{"key":"B","text":"短报文通信"},{"key":"C","text":"仅授时服务"},{"key":"D","text":"仅测速服务"}]', 'B', 1, 4, NOW(), NOW()),
('gaozhi', '5G网络中,Massive MIMO技术的主要优势是?', '[{"key":"A","text":"降低功耗"},{"key":"B","text":"提升频谱效率和容量"},{"key":"C","text":"减少天线数量"},{"key":"D","text":"简化网络架构"}]', 'B', 1, 5, NOW(), NOW()),
('gaozhi', '网络切片技术属于5G的哪个核心特性?', '[{"key":"A","text":"eMBB"},{"key":"B","text":"URLLC"},{"key":"C","text":"mMTC"},{"key":"D","text":"网络能力开放"}]', 'D', 1, 6, NOW(), NOW()),
('gaozhi', '在通信安全中,以下哪种攻击属于被动攻击?', '[{"key":"A","text":"篡改"},{"key":"B","text":"窃听"},{"key":"C","text":"拒绝服务"},{"key":"D","text":"伪装"}]', 'B', 1, 7, NOW(), NOW()),
('gaozhi', 'NTRIP协议主要用于什么场景?', '[{"key":"A","text":"卫星遥测"},{"key":"B","text":"差分数据网络传输"},{"key":"C","text":"卫星轨道控制"},{"key":"D","text":"信号加密传输"}]', 'B', 1, 8, NOW(), NOW()),
('gaozhi', '组合导航(GNSS+IMU)的核心优势是什么?', '[{"key":"A","text":"降低成本"},{"key":"B","text":"无缝切换与误差互补"},{"key":"C","text":"减少卫星数量"},{"key":"D","text":"提高发射功率"}]', 'B', 1, 9, NOW(), NOW()),
('gaozhi', '5G网络中,URLLC场景的主要特征是?', '[{"key":"A","text":"高速率大带宽"},{"key":"B","text":"低时延高可靠"},{"key":"C","text":"海量连接"},{"key":"D","text":"广域覆盖"}]', 'B', 1, 10, NOW(), NOW()),
('gaozhi', '卫星定位中,伪距测量的误差来源不包括?', '[{"key":"A","text":"电离层延迟"},{"key":"B","text":"对流层延迟"},{"key":"C","text":"卫星轨道误差"},{"key":"D","text":"用户设备重量"}]', 'D', 1, 11, NOW(), NOW()),
('gaozhi', '低轨卫星物联网相比GEO卫星的主要优势是?', '[{"key":"A","text":"覆盖范围更大"},{"key":"B","text":"传输时延更低"},{"key":"C","text":"单星容量更大"},{"key":"D","text":"使用寿命更长"}]', 'B', 1, 12, NOW(), NOW()),
('gaozhi', 'QPSK调制属于?', '[{"key":"A","text":"模拟调制"},{"key":"B","text":"数字相位调制"},{"key":"C","text":"幅度调制"},{"key":"D","text":"频率调制"}]', 'B', 1, 13, NOW(), NOW()),
('gaozhi', '信道编码的主要目的是?', '[{"key":"A","text":"提高传输速率"},{"key":"B","text":"对抗传输错误"},{"key":"C","text":"增加功率"},{"key":"D","text":"压缩数据"}]', 'B', 1, 14, NOW(), NOW()),
('gaozhi', 'CDMA技术的特点是?', '[{"key":"A","text":"所有用户同时占用相同频段"},{"key":"B","text":"每个用户占用不同频率"},{"key":"C","text":"每个用户占用不同时隙"},{"key":"D","text":"用户按空间分隔"}]', 'A', 1, 15, NOW(), NOW()),
('gaozhi', 'M-QAM调制中,M越大?', '[{"key":"A","text":"频谱效率越高,误码性能越好"},{"key":"B","text":"频谱效率越高,误码性能越差"},{"key":"C","text":"频谱效率越低,误码性能越好"},{"key":"D","text":"频谱效率越低,误码性能越差"}]', 'B', 1, 16, NOW(), NOW()),
('gaozhi', '香农公式给出了?', '[{"key":"A","text":"信道容量与带宽信噪比的关系"},{"key":"B","text":"信号功率与频率的关系"},{"key":"C","text":"噪声功率与温度的关系"},{"key":"D","text":"带宽与频率的关系"}]', 'A', 1, 17, NOW(), NOW()),
('gaozhi', '均衡技术主要用于补偿?', '[{"key":"A","text":"信道衰落引起的码间干扰"},{"key":"B","text":"噪声干扰"},{"key":"C","text":"频率偏移"},{"key":"D","text":"相位噪声"}]', 'A', 1, 18, NOW(), NOW()),
('gaozhi', '编码效率等于?', '[{"key":"A","text":"信息位长度/总码长"},{"key":"B","text":"总码长/信息位长度"},{"key":"C","text":"监督位长度/总码长"},{"key":"D","text":"信息位长度/监督位长度"}]', 'A', 1, 19, NOW(), NOW()),
('gaozhi', 'RS编码属于?', '[{"key":"A","text":"分组码"},{"key":"B","text":"卷积码"},{"key":"C","text":"循环码"},{"key":"D","text":"RS不是编码"}]', 'A', 1, 20, NOW(), NOW()),
('gaozhi', 'TCM编码是?', '[{"key":"A","text":"网格编码调制"},{"key":"B","text":" Turbo编码"},{"key":"C","text":"卷积编码"},{"key":"D","text":"里德所罗门编码"}]', 'A', 1, 21, NOW(), NOW()),
('gaozhi', '扩频通信的主要优点不包括?', '[{"key":"A","text":"抗干扰能力强"},{"key":"B","text":"隐蔽性好"},{"key":"C","text":"功率大"},{"key":"D","text":"多址能力强"}]', 'C', 1, 22, NOW(), NOW()),
('gaozhi', 'DSSS表示?', '[{"key":"A","text":"跳频扩频"},{"key":"B","text":"直接序列扩频"},{"key":"C","text":"跳时扩频"},{"key":"D","text":"线性扩频"}]', 'B', 1, 23, NOW(), NOW()),
('gaozhi', 'AOS协议主要用于?', '[{"key":"A","text":"地面互联网传输"},{"key":"B","text":"星地链路 packet 传输"},{"key":"C","text":"卫星轨道测量"},{"key":"D","text":"信号调制"}]', 'B', 1, 24, NOW(), NOW()),
('gaozhi', 'CCSDS标准是?', '[{"key":"A","text":"空间数据系统咨询委员会标准"},{"key":"B","text":"通信系统标准"},{"key":"C","text":"卫星导航标准"},{"key":"D","text":"互联网标准"}]', 'A', 1, 25, NOW(), NOW()),
('gaozhi', 'LDPC编码属于?', '[{"key":"A","text":"低密度奇偶校验码"},{"key":"B","text":"低密度分组码"},{"key":"C","text":"循环码"},{"key":"D","text":"卷积码"}]', 'A', 1, 26, NOW(), NOW()),
('gaozhi', 'MIMO技术可以提高?', '[{"key":"A","text":"信道容量"},{"key":"B","text":"发射功率"},{"key":"C","text":"噪声功率"},{"key":"D","text":"传播距离"}]', 'A', 1, 27, NOW(), NOW()),
('gaozhi', 'OFDM循环前缀的作用是?', '[{"key":"A","text":"增加功率"},{"key":"B","text":"消除符号间干扰"},{"key":"C","text":"提高频率"},{"key":"D","text":"降低速度"}]', 'B', 1, 28, NOW(), NOW()),
('gaozhi', 'Turbo码的主要优点是?', '[{"key":"A","text":"接近香农极限的性能"},{"key":"B","text":"编码简单"},{"key":"C","text":"译码简单"},{"key":"D","text":"速率很高"}]', 'A', 1, 29, NOW(), NOW()),
('gaozhi', 'ARQ协议的作用是?', '[{"key":"A","text":"自动重传请求"},{"key":"B","text":"自动编码"},{"key":"C","text":"自动应答"},{"key":"D","text":"自动加密"}]', 'A', 1, 30, NOW(), NOW()),
('gaozhi', 'TCP/IP协议中,TCP提供?', '[{"key":"A","text":"面向连接可靠服务"},{"key":"B","text":"无连接不可靠服务"},{"key":"C","text":"广播服务"},{"key":"D","text":"组播服务"}]', 'A', 1, 31, NOW(), NOW()),
('gaozhi', 'UDP协议提供?', '[{"key":"A","text":"面向连接可靠服务"},{"key":"B","text":"无连接不可靠服务"},{"key":"C","text":"广播服务"},{"key":"D","text":"组播服务"}]', 'B', 1, 32, NOW(), NOW()),
('gaozhi', 'HTTPS协议使用什么端口?', '[{"key":"A","text":"80"},{"key":"B","text":"443"},{"key":"C","text":"8080"},{"key":"D","text":"22"}]', 'B', 1, 33, NOW(), NOW()),
('gaozhi', 'IPv6地址长度为?', '[{"key":"A","text":"32位"},{"key":"B","text":"64位"},{"key":"C","text":"128位"},{"key":"D","text":"256位"}]', 'C', 1, 34, NOW(), NOW()),
('gaozhi', 'OSI模型有几层?', '[{"key":"A","text":"5"},{"key":"B","text":"6"},{"key":"C","text":"7"},{"key":"D","text":"8"}]', 'C', 1, 35, NOW(), NOW()),
('gaozhi', '调制的主要作用是?', '[{"key":"A","text":"将基带信号搬移到高频载波"},{"key":"B","text":"将高频信号搬移到基带"},{"key":"C","text":"放大信号"},{"key":"D","text":"滤波信号"}]', 'A', 1, 36, NOW(), NOW()),
('gaozhi', '解调的主要作用是?', '[{"key":"A","text":"从高频载波提取基带信号"},{"key":"B","text":"放大信号"},{"key":"C","text":"滤波信号"},{"key":"D","text":"变频信号"}]', 'A', 1, 37, NOW(), NOW()),
('gaozhi', '信源编码的主要目的是?', '[{"key":"A","text":"提高传输可靠性"},{"key":"B","text":"压缩数据率"},{"key":"C","text":"增加冗余"},{"key":"D","text":"提高功率"}]', 'B', 1, 38, NOW(), NOW()),
('gaozhi', '信道编码的主要目的是?', '[{"key":"A","text":"压缩数据"},{"key":"B","text":"差错控制"},{"key":"C","text":"提高速率"},{"key":"D","text":"降低功率"}]', 'B', 1, 39, NOW(), NOW()),
('gaozhi', 'AM调制中,调幅指数m满足?', '[{"key":"A","text":"0 ≤ m ≤ 1"},{"key":"B","text":"m > 1"},{"key":"C","text":"m < 0"},{"key":"D","text":"m = 0"}]', 'A', 1, 40, NOW(), NOW()),
('gaozhi', 'FM调制相比AM调制?', '[{"key":"A","text":"抗噪声性能更好"},{"key":"B","text":"功率更小"},{"key":"C","text":"带宽更小"},{"key":"D","text":"实现更简单"}]', 'A', 1, 41, NOW(), NOW()),
('gaozhi', 'PCM编码三个步骤依次是?', '[{"key":"A","text":"抽样、量化、编码"},{"key":"B","text":"量化、抽样、编码"},{"key":"C","text":"编码、抽样、量化"},{"key":"D","text":"抽样、编码、量化"}]', 'A', 1, 42, NOW(), NOW()),
('gaozhi', '奈奎斯特第一准则解决什么问题?', '[{"key":"A","text":"无码间干扰的传输特性"},{"key":"B","text":"信噪比计算"},{"key":"C","text":"信道容量计算"},{"key":"D","text":"功率分配"}]', 'A', 1, 43, NOW(), NOW()),
('gaozhi', '匹配滤波器输出信噪比在什么时候最大?', '[{"key":"A","text":"抽样时刻"},{"key":"B","text":"发送时刻"},{"key":"C","text":"接收开始"},{"key":"D","text":"接收结束"}]', 'A', 1, 44, NOW(), NOW()),
('gaozhi', '升余弦滚降滤波器的作用是?', '[{"key":"A","text":"降低码间干扰"},{"key":"B","text":"增加码间干扰"},{"key":"C","text":"提高功率"},{"key":"D","text":"改变频率"}]', 'A', 1, 45, NOW(), NOW()),
('gaozhi', '希尔伯特变换主要用于?', '[{"key":"A","text":"产生解析信号"},{"key":"B","text":"滤波信号"},{"key":"C","text":"放大信号"},{"key":"D","text":"变频信号"}]', 'A', 1, 46, NOW(), NOW()),
('gaozhi', '随机过程的均值反映了?', '[{"key":"A","text":"信号的平均强度"},{"key":"B","text":"信号的起伏程度"},{"key":"C","text":"信号的相关性"},{"key":"D","text":"信号的频率"}]', 'A', 1, 47, NOW(), NOW()),
('gaozhi', '傅里叶变换将信号变换到?', '[{"key":"A","text":"时域"},{"key":"B","text":"频域"},{"key":"C","text":"空域"},{"key":"D","text":"码域"}]', 'B', 1, 48, NOW(), NOW()),
('gaozhi', '信噪比等于?', '[{"key":"A","text":"信号功率除以噪声功率"},{"key":"B","text":"噪声功率除以信号功率"},{"key":"C","text":"信号电压除以噪声电压"},{"key":"D","text":"信号电流除以噪声电流"}]', 'A', 1, 49, NOW(), NOW()),
('gaozhi', '纠错编码的主要作用是?', '[{"key":"A","text":"降低误码率"},{"key":"B","text":"提高误码率"},{"key":"C","text":"增加传输速率"},{"key":"D","text":"降低带宽占用"}]', 'A', 1, 50, NOW(), NOW());
-- =====================================================================
-- 判断题 (20题 × 中职组 + 20题 × 高职组 = 40题)
-- =====================================================================
INSERT INTO judge_questions (`group`, question, answer, score, sort_order, created_at, updated_at) VALUES
-- 中职组 第1-20题
('zhongzhi', '调制的目的是将低频信号搬移到高频载波上,以便于天线辐射和信道传输。', 'true', 1, 1, NOW(), NOW()),
('zhongzhi', 'GPS接收机只需要接收到3颗卫星的信号即可实现三维定位。', 'false', 1, 2, NOW(), NOW()),
('zhongzhi', 'AM调制的抗干扰能力优于FM调制。', 'false', 1, 3, NOW(), NOW()),
('zhongzhi', '卫星通信中的上行频率通常高于下行频率。', 'true', 1, 4, NOW(), NOW()),
('zhongzhi', 'NMEA-0183协议中每条语句都以"$"开头,以校验和结尾。', 'true', 1, 5, NOW(), NOW()),
('zhongzhi', '北斗卫星导航系统由空间段、地面段、用户段三部分组成。', 'true', 1, 6, NOW(), NOW()),
('zhongzhi', 'RTK定位可以达到厘米级精度。', 'true', 1, 7, NOW(), NOW()),
('zhongzhi', '电离层延迟误差与太阳活动无关。', 'false', 1, 8, NOW(), NOW()),
('zhongzhi', '差分定位可以提高定位精度。', 'true', 1, 9, NOW(), NOW()),
('zhongzhi', 'GPS卫星本身就是原子钟,提供精确的时间标准。', 'true', 1, 10, NOW(), NOW()),
('zhongzhi', '编码与调制是一回事,都是将信号变换为适合传输的形式。', 'false', 1, 11, NOW(), NOW()),
('zhongzhi', 'GEO卫星的星下点始终在赤道上空一个固定点的正上方。', 'true', 1, 12, NOW(), NOW()),
('zhongzhi', 'FDMA中,每个用户使用相同的频率。', 'false', 1, 13, NOW(), NOW()),
('zhongzhi', '电磁波在自由空间中的传播损耗与距离的平方成正比。', 'true', 1, 14, NOW(), NOW()),
('zhongzhi', 'NTRIP协议用于实时传输差分改正数据。', 'true', 1, 15, NOW(), NOW()),
('zhongzhi', '多路径效应可以通过提高接收机灵敏度来消除。', 'false', 1, 16, NOW(), NOW()),
('zhongzhi', '卫星导航中,PDOP值越小定位精度越好。', 'true', 1, 17, NOW(), NOW()),
('zhongzhi', 'GNSS接收机输出符合NMEA-0183标准的数据。', 'true', 1, 18, NOW(), NOW()),
('zhongzhi', 'GPS卫星信号包含两个频率L1和L2。', 'true', 1, 19, NOW(), NOW()),
('zhongzhi', '卫星通信时延与卫星高度无关。', 'false', 1, 20, NOW(), NOW()),
-- 高职组 第21-40题
('gaozhi', 'OFDM系统中,循环前缀的长度必须大于信道的最大时延扩展。', 'true', 1, 21, NOW(), NOW()),
('gaozhi', '北斗系统只能提供区域导航定位服务,不能提供全球服务。', 'false', 1, 22, NOW(), NOW()),
('gaozhi', '边缘计算可以将计算任务从云端下沉到网络边缘,降低时延。', 'true', 1, 23, NOW(), NOW()),
('gaozhi', '数字签名技术可以防止通信内容被窃听。', 'false', 1, 24, NOW(), NOW()),
('gaozhi', 'Massive MIMO技术通过增加天线数量来提升系统容量。', 'true', 1, 25, NOW(), NOW()),
('gaozhi', '香农公式说明信道容量与带宽和信噪比都正相关。', 'true', 1, 26, NOW(), NOW()),
('gaozhi', 'LDPC码是一种高性能的信道编码。', 'true', 1, 27, NOW(), NOW()),
('gaozhi', 'TCP协议提供面向连接的可靠服务。', 'true', 1, 28, NOW(), NOW()),
('gaozhi', 'UDP协议提供流量控制和拥塞控制。', 'false', 1, 29, NOW(), NOW()),
('gaozhi', '奈奎斯特第一准则告诉我们理想低通信道的最高码元传输速率等于2B。', 'true', 1, 30, NOW(), NOW()),
('gaozhi', 'CRC校验可以检测出所有的传输错误。', 'false', 1, 31, NOW(), NOW()),
('gaozhi', 'BPSK的误码性能优于QPSK。', 'false', 1, 32, NOW(), NOW()),
('gaozhi', '协方差函数反映了两个随机变量之间的相关程度。', 'true', 1, 33, NOW(), NOW()),
('gaozhi', '瑞利分布常用于描述没有直射径的多径衰落信道。', 'true', 1, 34, NOW(), NOW()),
('gaozhi', 'NMEA-0183的GGA语句包含卫星数量和HDOP信息。', 'true', 1, 35, NOW(), NOW()),
('gaozhi', '卡尔曼滤波可以用于组合导航中的状态估计。', 'true', 1, 36, NOW(), NOW()),
('gaozhi', '对流层延迟对L1和L2频段信号的影响相同。', 'false', 1, 37, NOW(), NOW()),
('gaozhi', 'AOS协议是CCSDS标准中用于空间通信的链路层协议。', 'true', 1, 38, NOW(), NOW()),
('gaozhi', '扩频通信中,扩频码速率越高,抗干扰能力越强。', 'true', 1, 39, NOW(), NOW()),
('gaozhi', '卷积码的译码通常使用维特比算法。', 'true', 1, 40, NOW(), NOW());
-- =====================================================================
-- 综合性任务 (1题 × 中职组 + 1题 × 高职组)
-- =====================================================================
INSERT INTO word_questions (`group`, title, description, score, sort_order, created_at, updated_at) VALUES
('zhongzhi', '卫星通信系统基本原理', '请结合第一篇卫星通信技术,简述卫星通信系统的基本组成,包括空间段、地面段、用户段三大部分,并说明各部分的主要功能。分析GEO/MEO/LEO三种轨道的特点及其适用场景,举例说明典型应用。', 30, 1, NOW(), NOW()),
('gaozhi', '卫星导航融合定位方案设计', '请结合第二篇卫星导航技术,设计一个GNSS/INS组合导航定位方案。要求:(1) 分析组合导航的必要性;(2) 说明GNSS和INS各自优缺点;(3) 给出卡尔曼滤波融合框架;(4) 分析预期性能改进。', 30, 1, NOW(), NOW());
-- =====================================================================
-- 统计报告
-- =====================================================================
-- 每组:选择题 50 × 1 = 50, 判断题 20 × 1 = 20, 综合性任务 1 × 30 = 30 → 总分 100
-- =====================================================================
SELECT
(SELECT COUNT(*) FROM choice_questions WHERE `group`='zhongzhi') AS 'zhongzhi_choice',
(SELECT COUNT(*) FROM judge_questions WHERE `group`='zhongzhi') AS 'zhongzhi_judge',
(SELECT COUNT(*) FROM word_questions WHERE `group`='zhongzhi') AS 'zhongzhi_word',
(SELECT SUM(score) FROM choice_questions WHERE `group`='zhongzhi') +
(SELECT SUM(score) FROM judge_questions WHERE `group`='zhongzhi') +
(SELECT SUM(score) FROM word_questions WHERE `group`='zhongzhi') AS 'zhongzhi_total',
(SELECT COUNT(*) FROM choice_questions WHERE `group`='gaozhi') AS 'gaozhi_choice',
(SELECT COUNT(*) FROM judge_questions WHERE `group`='gaozhi') AS 'gaozhi_judge',
(SELECT COUNT(*) FROM word_questions WHERE `group`='gaozhi') AS 'gaozhi_word',
(SELECT SUM(score) FROM choice_questions WHERE `group`='gaozhi') +
(SELECT SUM(score) FROM judge_questions WHERE `group`='gaozhi') +
(SELECT SUM(score) FROM word_questions WHERE `group`='gaozhi') AS 'gaozhi_total';

71
database/config.json Normal file
View File

@@ -0,0 +1,71 @@
{
"development": {
"username": "root",
"password": "74191221",
"database": "competition_db",
"host": "localhost",
"port": 3306,
"dialect": "mysql",
"dialectOptions": {
"charset": "utf8mb4",
"collate": "utf8mb4_unicode_ci"
},
"define": {
"underscored": true,
"freezeTableName": true,
"timestamps": true,
"createdAt": "created_at",
"updatedAt": "updated_at",
"charset": "utf8mb4",
"collate": "utf8mb4_unicode_ci"
},
"timezone": "+08:00",
"seederStorage": "sequelize"
},
"test": {
"username": "root",
"password": "74191221",
"database": "competition_db_test",
"host": "localhost",
"port": 3306,
"dialect": "mysql",
"dialectOptions": {
"charset": "utf8mb4",
"collate": "utf8mb4_unicode_ci"
},
"define": {
"underscored": true,
"freezeTableName": true,
"timestamps": true,
"createdAt": "created_at",
"updatedAt": "updated_at",
"charset": "utf8mb4",
"collate": "utf8mb4_unicode_ci"
},
"timezone": "+08:00",
"seederStorage": "sequelize"
},
"production": {
"username": "root",
"password": null,
"database": "competition_db",
"host": "localhost",
"port": 3306,
"dialect": "mysql",
"dialectOptions": {
"charset": "utf8mb4",
"collate": "utf8mb4_unicode_ci"
},
"define": {
"underscored": true,
"freezeTableName": true,
"timestamps": true,
"createdAt": "created_at",
"updatedAt": "updated_at",
"charset": "utf8mb4",
"collate": "utf8mb4_unicode_ci"
},
"timezone": "+08:00",
"seederStorage": "sequelize"
}
}

View File

@@ -0,0 +1,125 @@
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable('accounts', {
uid: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
comment: '用户唯一标识',
},
role: {
type: Sequelize.STRING(32),
allowNull: false,
defaultValue: 'student',
comment: '角色:student/teacher/judge/admin',
},
name_cn: {
type: Sequelize.STRING(64),
allowNull: false,
comment: '中文姓名',
},
name_en: {
type: Sequelize.STRING(128),
allowNull: true,
comment: '英文姓名/拼音',
},
gender: {
type: Sequelize.STRING(8),
allowNull: true,
comment: '性别:男/女',
},
phone: {
type: Sequelize.STRING(32),
allowNull: true,
comment: '手机号码',
},
email: {
type: Sequelize.STRING(128),
allowNull: true,
comment: '电子邮箱',
},
id_number: {
type: Sequelize.STRING(32),
allowNull: false,
unique: true,
comment: '身份证号(唯一)',
},
password: {
type: Sequelize.STRING(128),
allowNull: false,
comment: '密码(加密存储)',
},
salt: {
type: Sequelize.STRING(64),
allowNull: false,
comment: '密码盐值',
},
position: {
type: Sequelize.STRING(64),
allowNull: true,
comment: '职务/职称',
},
major: {
type: Sequelize.STRING(128),
allowNull: true,
comment: '专业',
},
country: {
type: Sequelize.STRING(64),
allowNull: true,
comment: '国家',
},
region: {
type: Sequelize.STRING(64),
allowNull: true,
comment: '地区/省份',
},
organization_cn: {
type: Sequelize.STRING(255),
allowNull: true,
comment: '所属单位(中文)',
},
organization_en: {
type: Sequelize.STRING(255),
allowNull: true,
comment: '所属单位(英文)',
},
activated: {
type: Sequelize.TINYINT,
allowNull: false,
defaultValue: 0,
comment: '激活状态:0未激活 1已激活',
},
score: {
type: Sequelize.INTEGER,
allowNull: true,
comment: '总分/积分',
},
created_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
comment: '创建时间',
},
updated_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'),
comment: '更新时间',
},
}).then(() => {
return Promise.all([
queryInterface.addIndex('accounts', ['role'], { name: 'idx_role' }),
queryInterface.addIndex('accounts', ['phone'], { name: 'idx_phone' }),
queryInterface.addIndex('accounts', ['name_cn'], { name: 'idx_name_cn' }),
]);
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable('accounts');
},
};

View File

@@ -0,0 +1,105 @@
'use strict';
/**
* 迁移文件:创建选手表(contestants)
* 包含选手基本信息、身份认证、组别和成绩字段
*/
module.exports = {
/**
* 执行迁移:创建 contestants 表
* @param {import('sequelize').QueryInterface} queryInterface
* @param {import('sequelize').Sequelize} Sequelize
*/
up: async (queryInterface, Sequelize) => {
const { INTEGER, STRING, BOOLEAN, DATE } = Sequelize;
await queryInterface.createTable('contestants', {
// 主键 ID,自增
id: {
type: INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
comment: '选手唯一标识',
},
// 身份证号,唯一,18位
id_number: {
type: STRING(18),
allowNull: false,
unique: true,
comment: '身份证号',
},
// 选手姓名
name: {
type: STRING(50),
allowNull: false,
comment: '选手姓名',
},
// 手机号码
phone: {
type: STRING(20),
allowNull: false,
comment: '手机号码',
},
// 参赛组别
group: {
type: STRING(20),
allowNull: false,
comment: '参赛组别(zhongzhi/gaozhi/benke/jiaoshi)',
},
// 登录密码
password: {
type: STRING(100),
allowNull: false,
defaultValue: '',
comment: '登录密码',
},
// 账号激活状态
activated: {
type: BOOLEAN,
allowNull: false,
defaultValue: false,
comment: '账号激活状态',
},
// 总分
score: {
type: INTEGER,
allowNull: true,
defaultValue: null,
comment: '选手总分',
},
// 创建时间
created_at: {
type: DATE,
allowNull: false,
comment: '创建时间',
},
// 更新时间
updated_at: {
type: DATE,
allowNull: false,
comment: '更新时间',
},
});
// 为 id_number 创建唯一索引
await queryInterface.addIndex('contestants', ['id_number'], {
unique: true,
name: 'idx_contestants_id_number',
});
// 为 group 创建索引
await queryInterface.addIndex('contestants', ['group'], {
name: 'idx_contestants_group',
});
},
/**
* 回滚迁移:删除 contestants 表
* @param {import('sequelize').QueryInterface} queryInterface
*/
down: async (queryInterface) => {
await queryInterface.dropTable('contestants');
},
};

View File

@@ -0,0 +1,61 @@
'use strict';
/**
* 迁移文件:创建管理员表(admins)
* 存储后台管理员账号信息
*/
module.exports = {
/**
* 执行迁移:创建 admins 表
* @param {import('sequelize').QueryInterface} queryInterface
* @param {import('sequelize').Sequelize} Sequelize
*/
up: async (queryInterface, Sequelize) => {
const { INTEGER, STRING, DATE } = Sequelize;
await queryInterface.createTable('admins', {
id: {
type: INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
comment: '管理员唯一标识',
},
username: {
type: STRING(50),
allowNull: false,
unique: true,
comment: '管理员用户名',
},
password: {
type: STRING(100),
allowNull: false,
comment: '管理员密码',
},
created_at: {
type: DATE,
allowNull: false,
comment: '创建时间',
},
updated_at: {
type: DATE,
allowNull: false,
comment: '更新时间',
},
});
await queryInterface.addIndex('admins', ['username'], {
unique: true,
name: 'idx_admins_username',
});
},
/**
* 回滚迁移:删除 admins 表
* @param {import('sequelize').QueryInterface} queryInterface
*/
down: async (queryInterface) => {
await queryInterface.dropTable('admins');
},
};

View File

@@ -0,0 +1,56 @@
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable('teams', {
team_uid: {
type: Sequelize.INTEGER,
primaryKey: true,
// 注意:运行库中 teams 表真实自增主键为 id,team_uid 为非自增普通列,
// 由应用层(importFromExcel 显式 MAX+1)赋值。故此处不声明 autoIncrement,
// 使迁移与运行库一致,避免新建库时 team_uid 被设为自增而与运行库行为背离。
allowNull: false,
comment: '团队唯一标识(由应用层显式生成,非 DB 自增)',
},
group_name: {
type: Sequelize.STRING(64),
allowNull: false,
comment: '组别名称',
},
team_id: {
type: Sequelize.STRING(64),
allowNull: false,
unique: true,
comment: '团队编号(唯一)',
},
team_number: {
type: Sequelize.STRING(32),
allowNull: true,
comment: '团队序号',
},
address: {
type: Sequelize.STRING(255),
allowNull: true,
comment: '地址',
},
created_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
comment: '创建时间',
},
updated_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'),
comment: '更新时间',
},
}).then(() => {
return queryInterface.addIndex('teams', ['group_name'], { name: 'idx_group_name' });
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable('teams');
},
};

View File

@@ -0,0 +1,42 @@
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable('competition_info', {
competition_uid: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
comment: '赛事唯一标识',
},
competition_name: {
type: Sequelize.STRING(128),
allowNull: false,
comment: '赛事名称',
},
competition_code: {
type: Sequelize.STRING(64),
allowNull: false,
unique: true,
comment: '赛事编码(唯一)',
},
created_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
comment: '创建时间',
},
updated_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'),
comment: '更新时间',
},
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable('competition_info');
},
};

View File

@@ -0,0 +1,94 @@
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable('aggregation', {
aggregation_uid: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
comment: '报名记录唯一标识',
},
competition_uid: {
type: Sequelize.INTEGER,
allowNull: false,
comment: '赛事ID(关联competition_info)',
references: { model: 'competition_info', key: 'competition_uid' },
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
team_uid: {
type: Sequelize.INTEGER,
allowNull: false,
comment: '团队ID(关联teams)',
references: { model: 'teams', key: 'team_uid' },
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
account_uid: {
type: Sequelize.INTEGER,
allowNull: false,
comment: '用户ID(关联accounts)',
references: { model: 'accounts', key: 'uid' },
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
identity: {
type: Sequelize.STRING(32),
allowNull: true,
comment: '身份标识',
},
is_registrant: {
type: Sequelize.TINYINT,
allowNull: false,
defaultValue: 0,
comment: '是否为主要报名人:0否 1是',
},
registration_form: {
type: Sequelize.STRING(512),
allowNull: true,
comment: '报名表文件路径',
},
stamped_form: {
type: Sequelize.STRING(512),
allowNull: true,
comment: '盖章报名表文件路径',
},
audit_status: {
type: Sequelize.STRING(32),
allowNull: false,
defaultValue: 'pending',
comment: '审核状态:pending/approved/rejected',
},
reject_reason: {
type: Sequelize.STRING(512),
allowNull: true,
comment: '驳回原因',
},
created_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
comment: '创建时间',
},
updated_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'),
comment: '更新时间',
},
}).then(() => {
return Promise.all([
queryInterface.addIndex('aggregation', ['competition_uid'], { name: 'idx_competition_uid' }),
queryInterface.addIndex('aggregation', ['team_uid'], { name: 'idx_team_uid' }),
queryInterface.addIndex('aggregation', ['account_uid'], { name: 'idx_account_uid' }),
queryInterface.addIndex('aggregation', ['audit_status'], { name: 'idx_audit_status' }),
]);
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable('aggregation');
},
};

View File

@@ -0,0 +1,69 @@
'use strict';
/**
* 迁移文件:创建试卷题目表(exam_questions)
* 存储各组别的试卷题目
*/
module.exports = {
up: async (queryInterface, Sequelize) => {
const { INTEGER, STRING, TEXT, DATE } = Sequelize;
await queryInterface.createTable('exam_questions', {
id: {
type: INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
comment: '题目唯一标识',
},
group: {
type: STRING(20),
allowNull: false,
comment: '题目所属组别',
},
title: {
type: STRING(200),
allowNull: false,
comment: '题目标题',
},
content: {
type: TEXT,
allowNull: false,
comment: '题目内容描述',
},
score: {
type: INTEGER,
allowNull: false,
comment: '题目分值',
},
sort_order: {
type: INTEGER,
allowNull: false,
defaultValue: 0,
comment: '排序序号',
},
created_at: {
type: DATE,
allowNull: false,
comment: '创建时间',
},
updated_at: {
type: DATE,
allowNull: false,
comment: '更新时间',
},
});
await queryInterface.addIndex('exam_questions', ['group'], {
name: 'idx_exam_questions_group',
});
await queryInterface.addIndex('exam_questions', ['group', 'sort_order'], {
name: 'idx_exam_questions_group_sort',
});
},
down: async (queryInterface) => {
await queryInterface.dropTable('exam_questions');
},
};

View File

@@ -0,0 +1,67 @@
'use strict';
/**
* 迁移文件:创建答题记录表(exam_submissions)
* 存储选手的试卷答题记录
*/
module.exports = {
up: async (queryInterface, Sequelize) => {
const { INTEGER, TEXT, DATE } = Sequelize;
await queryInterface.createTable('exam_submissions', {
id: {
type: INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
comment: '答题记录唯一标识',
},
contestant_id: {
type: INTEGER,
allowNull: false,
comment: '选手 ID',
references: {
model: 'contestants',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
answers: {
type: TEXT,
allowNull: false,
comment: '答题内容(JSON)',
},
submit_time: {
type: DATE,
allowNull: false,
comment: '提交时间',
},
score: {
type: INTEGER,
allowNull: true,
defaultValue: null,
comment: '试卷得分',
},
created_at: {
type: DATE,
allowNull: false,
comment: '创建时间',
},
updated_at: {
type: DATE,
allowNull: false,
comment: '更新时间',
},
});
await queryInterface.addIndex('exam_submissions', ['contestant_id'], {
name: 'idx_exam_submissions_contestant_id',
});
},
down: async (queryInterface) => {
await queryInterface.dropTable('exam_submissions');
},
};

View File

@@ -0,0 +1,68 @@
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable('news', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
comment: '新闻ID',
},
title: {
type: Sequelize.STRING(255),
allowNull: false,
comment: '新闻标题',
},
content: {
type: Sequelize.TEXT('long'),
allowNull: true,
comment: '新闻内容(富文本)',
},
wx_link: {
type: Sequelize.STRING(512),
allowNull: true,
comment: '微信链接',
},
publish_time: {
type: Sequelize.DATE,
allowNull: true,
comment: '发布时间',
},
pinned: {
type: Sequelize.TINYINT,
allowNull: false,
defaultValue: 0,
comment: '是否置顶:0否 1是',
},
group_name: {
type: Sequelize.STRING(64),
allowNull: true,
comment: '目标组别',
},
created_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
comment: '创建时间',
},
updated_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'),
comment: '更新时间',
},
}).then(() => {
return Promise.all([
queryInterface.addIndex('news', ['publish_time'], { name: 'idx_publish_time' }),
queryInterface.addIndex('news', ['pinned', 'publish_time'], { name: 'idx_pinned_publish_time' }),
queryInterface.addIndex('news', ['group_name'], { name: 'idx_group_name' }),
]);
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable('news');
},
};

View File

@@ -0,0 +1,58 @@
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable('carousel', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
comment: '轮播图ID',
},
image_url: {
type: Sequelize.STRING(512),
allowNull: false,
comment: '图片URL',
},
sort_order: {
type: Sequelize.INTEGER,
allowNull: false,
defaultValue: 0,
comment: '排序序号',
},
link_url: {
type: Sequelize.STRING(512),
allowNull: true,
comment: '点击跳转链接',
},
enabled: {
type: Sequelize.TINYINT,
allowNull: false,
defaultValue: 1,
comment: '是否启用:0禁用 1启用',
},
created_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
comment: '创建时间',
},
updated_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'),
comment: '更新时间',
},
}).then(() => {
return Promise.all([
queryInterface.addIndex('carousel', ['sort_order'], { name: 'idx_sort_order' }),
queryInterface.addIndex('carousel', ['enabled'], { name: 'idx_enabled' }),
]);
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable('carousel');
},
};

View File

@@ -0,0 +1,85 @@
'use strict';
/**
* 迁移文件:创建作品提交表(work_submissions)
* 存储选手上传的作品文件信息
*/
module.exports = {
up: async (queryInterface, Sequelize) => {
const { INTEGER, STRING, DATE } = Sequelize;
await queryInterface.createTable('work_submissions', {
id: {
type: INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
comment: '作品提交唯一标识',
},
contestant_id: {
type: INTEGER,
allowNull: false,
comment: '选手 ID',
references: {
model: 'contestants',
key: 'id',
},
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
file_type: {
type: STRING(20),
allowNull: false,
comment: '文件类型(plan/ppt)',
},
file_name: {
type: STRING(200),
allowNull: false,
comment: '原始文件名',
},
file_path: {
type: STRING(500),
allowNull: false,
comment: '文件存储路径',
},
file_size: {
type: INTEGER,
allowNull: false,
comment: '文件大小(字节)',
},
submit_time: {
type: DATE,
allowNull: false,
comment: '提交时间',
},
score: {
type: INTEGER,
allowNull: true,
defaultValue: null,
comment: '作品得分',
},
created_at: {
type: DATE,
allowNull: false,
comment: '创建时间',
},
updated_at: {
type: DATE,
allowNull: false,
comment: '更新时间',
},
});
await queryInterface.addIndex('work_submissions', ['contestant_id'], {
name: 'idx_work_submissions_contestant_id',
});
await queryInterface.addIndex('work_submissions', ['file_type'], {
name: 'idx_work_submissions_file_type',
});
},
down: async (queryInterface) => {
await queryInterface.dropTable('work_submissions');
},
};

View File

@@ -0,0 +1,69 @@
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable('zhongzhi_questions', {
question_uid: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
comment: '题目唯一标识',
},
question: {
type: Sequelize.TEXT,
allowNull: false,
comment: '题目内容',
},
answer: {
type: Sequelize.STRING(32),
allowNull: false,
comment: '正确答案',
},
question_type: {
type: Sequelize.STRING(16),
allowNull: false,
defaultValue: 'choice',
comment: '题目类型:choice选择题 judge判断题',
},
options: {
type: Sequelize.JSON,
allowNull: true,
comment: '选项(JSON格式)',
},
score: {
type: Sequelize.INTEGER,
allowNull: false,
defaultValue: 0,
comment: '题目分值',
},
sort_order: {
type: Sequelize.INTEGER,
allowNull: false,
defaultValue: 0,
comment: '排序序号',
},
created_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
comment: '创建时间',
},
updated_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'),
comment: '更新时间',
},
}).then(() => {
return Promise.all([
queryInterface.addIndex('zhongzhi_questions', ['question_type'], { name: 'idx_question_type' }),
queryInterface.addIndex('zhongzhi_questions', ['sort_order'], { name: 'idx_sort_order' }),
]);
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable('zhongzhi_questions');
},
};

View File

@@ -0,0 +1,69 @@
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable('gaozhi_questions', {
question_uid: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
comment: '题目唯一标识',
},
question: {
type: Sequelize.TEXT,
allowNull: false,
comment: '题目内容',
},
answer: {
type: Sequelize.STRING(32),
allowNull: false,
comment: '正确答案',
},
question_type: {
type: Sequelize.STRING(16),
allowNull: false,
defaultValue: 'choice',
comment: '题目类型:choice选择题 judge判断题',
},
options: {
type: Sequelize.JSON,
allowNull: true,
comment: '选项(JSON格式)',
},
score: {
type: Sequelize.INTEGER,
allowNull: false,
defaultValue: 0,
comment: '题目分值',
},
sort_order: {
type: Sequelize.INTEGER,
allowNull: false,
defaultValue: 0,
comment: '排序序号',
},
created_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
comment: '创建时间',
},
updated_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'),
comment: '更新时间',
},
}).then(() => {
return Promise.all([
queryInterface.addIndex('gaozhi_questions', ['question_type'], { name: 'idx_question_type' }),
queryInterface.addIndex('gaozhi_questions', ['sort_order'], { name: 'idx_sort_order' }),
]);
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable('gaozhi_questions');
},
};

View File

@@ -0,0 +1,82 @@
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable('zhongzhi_submissions', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
comment: '提交记录ID',
},
aggregation_uid: {
type: Sequelize.INTEGER,
allowNull: false,
comment: '报名记录ID(关联aggregation)',
references: { model: 'aggregation', key: 'aggregation_uid' },
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
question_uid: {
type: Sequelize.INTEGER,
allowNull: false,
comment: '题目ID(关联zhongzhi_questions)',
references: { model: 'zhongzhi_questions', key: 'question_uid' },
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
answer_data: {
type: Sequelize.STRING(255),
allowNull: true,
comment: '提交的答案',
},
is_correct: {
type: Sequelize.TINYINT,
allowNull: true,
comment: '是否正确:0错误 1正确',
},
score: {
type: Sequelize.INTEGER,
allowNull: true,
comment: '得分',
},
word_file_path: {
type: Sequelize.STRING(512),
allowNull: true,
comment: 'Word文件路径',
},
word_file_name: {
type: Sequelize.STRING(255),
allowNull: true,
comment: 'Word文件原始名称',
},
word_file_md5: {
type: Sequelize.STRING(64),
allowNull: true,
comment: 'Word文件MD5哈希值',
},
created_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
comment: '创建时间',
},
updated_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'),
comment: '更新时间',
},
}).then(() => {
return Promise.all([
queryInterface.addIndex('zhongzhi_submissions', ['aggregation_uid'], { name: 'idx_aggregation_uid' }),
queryInterface.addIndex('zhongzhi_submissions', ['question_uid'], { name: 'idx_question_uid' }),
]);
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable('zhongzhi_submissions');
},
};

View File

@@ -0,0 +1,82 @@
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable('gaozhi_submissions', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
comment: '提交记录ID',
},
aggregation_uid: {
type: Sequelize.INTEGER,
allowNull: false,
comment: '报名记录ID(关联aggregation)',
references: { model: 'aggregation', key: 'aggregation_uid' },
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
question_uid: {
type: Sequelize.INTEGER,
allowNull: false,
comment: '题目ID(关联gaozhi_questions)',
references: { model: 'gaozhi_questions', key: 'question_uid' },
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
answer_data: {
type: Sequelize.STRING(255),
allowNull: true,
comment: '提交的答案',
},
is_correct: {
type: Sequelize.TINYINT,
allowNull: true,
comment: '是否正确:0错误 1正确',
},
score: {
type: Sequelize.INTEGER,
allowNull: true,
comment: '得分',
},
word_file_path: {
type: Sequelize.STRING(512),
allowNull: true,
comment: 'Word文件路径',
},
word_file_name: {
type: Sequelize.STRING(255),
allowNull: true,
comment: 'Word文件原始名称',
},
word_file_md5: {
type: Sequelize.STRING(64),
allowNull: true,
comment: 'Word文件MD5哈希值',
},
created_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
comment: '创建时间',
},
updated_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'),
comment: '更新时间',
},
}).then(() => {
return Promise.all([
queryInterface.addIndex('gaozhi_submissions', ['aggregation_uid'], { name: 'idx_aggregation_uid' }),
queryInterface.addIndex('gaozhi_submissions', ['question_uid'], { name: 'idx_question_uid' }),
]);
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable('gaozhi_submissions');
},
};

View File

@@ -0,0 +1,77 @@
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable('benke_submissions', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
comment: '提交记录ID',
},
aggregation_uid: {
type: Sequelize.INTEGER,
allowNull: false,
comment: '报名记录ID(关联aggregation)',
references: { model: 'aggregation', key: 'aggregation_uid' },
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
work_name: {
type: Sequelize.STRING(255),
allowNull: false,
comment: '作品名称',
},
file_path: {
type: Sequelize.STRING(512),
allowNull: false,
comment: '文件存储路径',
},
file_name: {
type: Sequelize.STRING(255),
allowNull: false,
comment: '文件原始名称',
},
file_size: {
type: Sequelize.INTEGER.UNSIGNED,
allowNull: false,
defaultValue: 0,
comment: '文件大小(字节)',
},
file_md5: {
type: Sequelize.STRING(64),
allowNull: true,
comment: '文件MD5哈希值',
},
upload_time: {
type: Sequelize.DATE,
allowNull: true,
comment: '上传时间',
},
score: {
type: Sequelize.INTEGER,
allowNull: true,
comment: '评分',
},
created_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
comment: '创建时间',
},
updated_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'),
comment: '更新时间',
},
}).then(() => {
return queryInterface.addIndex('benke_submissions', ['aggregation_uid'], { name: 'idx_aggregation_uid' });
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable('benke_submissions');
},
};

View File

@@ -0,0 +1,77 @@
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable('jiaoshi_submissions', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
comment: '提交记录ID',
},
aggregation_uid: {
type: Sequelize.INTEGER,
allowNull: false,
comment: '报名记录ID(关联aggregation)',
references: { model: 'aggregation', key: 'aggregation_uid' },
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
},
work_name: {
type: Sequelize.STRING(255),
allowNull: false,
comment: '作品名称',
},
file_path: {
type: Sequelize.STRING(512),
allowNull: false,
comment: '文件存储路径',
},
file_name: {
type: Sequelize.STRING(255),
allowNull: false,
comment: '文件原始名称',
},
file_size: {
type: Sequelize.INTEGER.UNSIGNED,
allowNull: false,
defaultValue: 0,
comment: '文件大小(字节)',
},
file_md5: {
type: Sequelize.STRING(64),
allowNull: true,
comment: '文件MD5哈希值',
},
upload_time: {
type: Sequelize.DATE,
allowNull: true,
comment: '上传时间',
},
score: {
type: Sequelize.INTEGER,
allowNull: true,
comment: '评分',
},
created_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
comment: '创建时间',
},
updated_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'),
comment: '更新时间',
},
}).then(() => {
return queryInterface.addIndex('jiaoshi_submissions', ['aggregation_uid'], { name: 'idx_aggregation_uid' });
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable('jiaoshi_submissions');
},
};

View File

@@ -0,0 +1,57 @@
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable('competition_times', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
comment: '配置ID',
},
group_name: {
type: Sequelize.STRING(64),
allowNull: false,
unique: true,
comment: '组别名称(唯一)',
},
start_time: {
type: Sequelize.DATE,
allowNull: true,
comment: '比赛开始时间',
},
end_time: {
type: Sequelize.DATE,
allowNull: true,
comment: '比赛结束时间',
},
deadline: {
type: Sequelize.DATE,
allowNull: true,
comment: '报名/提交截止时间',
},
word_template: {
type: Sequelize.STRING(512),
allowNull: true,
comment: 'Word模板文件路径',
},
created_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
comment: '创建时间',
},
updated_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'),
comment: '更新时间',
},
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable('competition_times');
},
};

View File

@@ -0,0 +1,42 @@
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable('system_configs', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
comment: '配置ID',
},
config_key: {
type: Sequelize.STRING(128),
allowNull: false,
unique: true,
comment: '配置键名(唯一)',
},
config_value: {
type: Sequelize.TEXT,
allowNull: true,
comment: '配置值',
},
created_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
comment: '创建时间',
},
updated_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'),
comment: '更新时间',
},
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable('system_configs');
},
};

View File

@@ -0,0 +1,68 @@
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable('choice_questions', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
comment: '题目ID',
},
group: {
type: Sequelize.STRING(20),
allowNull: false,
comment: '组别:zhongzhi/gaozhi',
},
question: {
type: Sequelize.TEXT,
allowNull: false,
comment: '题目内容',
},
options: {
type: Sequelize.JSON,
allowNull: false,
comment: '选项列表 [{ key: "A", text: "..." }, ...]',
},
answer: {
type: Sequelize.STRING(10),
allowNull: false,
comment: '正确答案(如 A / AB / ABCD)',
},
score: {
type: Sequelize.INTEGER,
allowNull: false,
defaultValue: 5,
comment: '分值',
},
sort_order: {
type: Sequelize.INTEGER,
allowNull: false,
defaultValue: 0,
comment: '排序',
},
created_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
comment: '创建时间',
},
updated_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'),
comment: '更新时间',
},
}).then(() => {
return Promise.all([
queryInterface.addIndex('choice_questions', ['group'], { name: 'idx_choice_group' }),
queryInterface.addIndex('choice_questions', ['sort_order'], { name: 'idx_choice_sort' }),
]);
});
},
down: async (queryInterface) => {
await queryInterface.dropTable('choice_questions');
},
};

View File

@@ -0,0 +1,63 @@
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable('judge_questions', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
comment: '题目ID',
},
group: {
type: Sequelize.STRING(20),
allowNull: false,
comment: '组别:zhongzhi/gaozhi',
},
question: {
type: Sequelize.TEXT,
allowNull: false,
comment: '题目内容',
},
answer: {
type: Sequelize.STRING(10),
allowNull: false,
comment: '正确答案:true 或 false',
},
score: {
type: Sequelize.INTEGER,
allowNull: false,
defaultValue: 5,
comment: '分值',
},
sort_order: {
type: Sequelize.INTEGER,
allowNull: false,
defaultValue: 0,
comment: '排序',
},
created_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
comment: '创建时间',
},
updated_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'),
comment: '更新时间',
},
}).then(() => {
return Promise.all([
queryInterface.addIndex('judge_questions', ['group'], { name: 'idx_judge_group' }),
queryInterface.addIndex('judge_questions', ['sort_order'], { name: 'idx_judge_sort' }),
]);
});
},
down: async (queryInterface) => {
await queryInterface.dropTable('judge_questions');
},
};

View File

@@ -0,0 +1,68 @@
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable('word_questions', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
comment: '题目ID',
},
group: {
type: Sequelize.STRING(20),
allowNull: false,
comment: '组别:zhongzhi/gaozhi',
},
title: {
type: Sequelize.STRING(200),
allowNull: false,
comment: '题目标题',
},
description: {
type: Sequelize.TEXT,
allowNull: true,
comment: '题目描述/操作要求',
},
score: {
type: Sequelize.INTEGER,
allowNull: false,
defaultValue: 30,
comment: '分值',
},
sort_order: {
type: Sequelize.INTEGER,
allowNull: false,
defaultValue: 0,
comment: '排序',
},
template_path: {
type: Sequelize.STRING(500),
allowNull: true,
comment: 'Word 模板文件路径',
},
created_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
comment: '创建时间',
},
updated_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'),
comment: '更新时间',
},
}).then(() => {
return Promise.all([
queryInterface.addIndex('word_questions', ['group'], { name: 'idx_word_group' }),
queryInterface.addIndex('word_questions', ['sort_order'], { name: 'idx_word_sort' }),
]);
});
},
down: async (queryInterface) => {
await queryInterface.dropTable('word_questions');
},
};

View File

@@ -0,0 +1,23 @@
'use strict';
/**
* 迁移文件:为 contestants 表添加 test_flag 字段
* 用于区分测试数据和生产数据,防止重置操作误删生产数据
*/
module.exports = {
up: async (queryInterface, Sequelize) => {
const { INTEGER } = Sequelize;
await queryInterface.addColumn('contestants', 'test_flag', {
type: INTEGER,
allowNull: false,
defaultValue: 0,
comment: '测试数据标记:0=生产数据,1=测试数据',
});
},
down: async (queryInterface) => {
await queryInterface.removeColumn('contestants', 'test_flag');
},
};

View File

@@ -0,0 +1,17 @@
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.addColumn('carousel', 'title', {
type: Sequelize.STRING(200),
allowNull: true,
defaultValue: null,
comment: '轮播图标题',
after: 'image_url',
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.removeColumn('carousel', 'title');
},
};

View File

@@ -0,0 +1,40 @@
'use strict';
/**
* 迁移 020:为 zhongzhi_submissions / gaozhi_submissions 增加 question_type 列
*
* 背景(Bug #11 / B11):选择题(choice_questions)与判断题(judge_questions)的 id
* 在不同表中数值重叠(如 choice#5 与 judge#5 均为 5),原 saveAnswers 仅按
* (aggregation_uid, question_uid) 查找并 upsert,导致同 id 的选择题与判断题被
* 折叠成一条记录,考生作答数少于抽题数、部分答案静默丢失。
*
* 修复:新增 question_type 列(choice/judge),与 question_uid 联合唯一标识一道题;
* service.saveAnswers 的查找/写入键改为 (aggregation_uid, question_uid, question_type);
* autoScore 判分不受影响(其本就按 question_type 选模型 + 用原始 id 作主键)。
*/
module.exports = {
up: async (queryInterface, Sequelize) => {
const addCol = async (table) => {
await queryInterface.addColumn(table, 'question_type', {
type: Sequelize.STRING(16),
allowNull: false,
defaultValue: '',
comment: '题型:choice/judge,与 question_uid 联合区分题目',
});
await queryInterface.addIndex(
table,
['aggregation_uid', 'question_uid', 'question_type'],
{ name: `idx_${table}_agg_qtype` }
);
};
await addCol('zhongzhi_submissions');
await addCol('gaozhi_submissions');
},
down: async (queryInterface, Sequelize) => {
await queryInterface.removeIndex('zhongzhi_submissions', 'idx_zhongzhi_submissions_agg_qtype');
await queryInterface.removeColumn('zhongzhi_submissions', 'question_type');
await queryInterface.removeIndex('gaozhi_submissions', 'idx_gaozhi_submissions_agg_qtype');
await queryInterface.removeColumn('gaozhi_submissions', 'question_type');
},
};

View File

@@ -0,0 +1,99 @@
'use strict';
/**
* 迁移 021:为答题提交表增加唯一约束,杜绝并发作答重复落库(Bug #12 / B12)
*
* 背景(B12):原 saveAnswers 使用「先 findOne 再 create」的非原子写法,且
* (aggregation_uid, question_uid, question_type) 仅为普通索引。同一用户并发提交
* 时,多个请求都 find 不到记录,于是各自 create,导致同一题被插入多行
* (实测:3 路并发产生 57 行 / 20 题,exam_submissions 出现 3 条同选手记录)。
* 重复行会污染 answeredCount、判分明细与成绩恢复,属数据一致性缺陷。
*
* 修复:
* 1) zhongzhi_submissions / gaozhi_submissions 的复合索引升级为唯一索引
* uk_{table}_submission (aggregation_uid, question_uid, question_type);
* service.saveAnswers 改用 upsert(conflictFields=[...]),由 MySQL 的
* INSERT ... ON DUPLICATE KEY UPDATE 在并发下原子折叠为单行更新。
* 2) exam_submissions 的 contestant_id 索引升级为唯一索引
* uk_exam_submission_contestant,配合 service 中并发安全的
* _ensureExamSubmissionSafe,保证每选手仅一条提交记录。
*
* 注意:up/down 均先去重(保留最小 id)再加减索引,确保幂等且不会因历史脏数据失败。
*/
module.exports = {
up: async (queryInterface) => {
// ---- 去重:同 (aggregation_uid, question_uid, question_type) 仅留最小 id ----
await queryInterface.sequelize.query(`
DELETE t FROM zhongzhi_submissions t
WHERE t.id NOT IN (
SELECT min_id FROM (
SELECT MIN(id) AS min_id FROM zhongzhi_submissions
GROUP BY aggregation_uid, question_uid, question_type
) AS keep
)
`);
await queryInterface.sequelize.query(`
DELETE t FROM gaozhi_submissions t
WHERE t.id NOT IN (
SELECT min_id FROM (
SELECT MIN(id) AS min_id FROM gaozhi_submissions
GROUP BY aggregation_uid, question_uid, question_type
) AS keep
)
`);
// exam_submissions:每 contestant_id 仅留最小 id
await queryInterface.sequelize.query(`
DELETE t FROM exam_submissions t
WHERE t.id NOT IN (
SELECT min_id FROM (
SELECT MIN(id) AS min_id FROM exam_submissions
GROUP BY contestant_id
) AS keep
)
`);
// ---- zhongzhi ----
await queryInterface.removeIndex('zhongzhi_submissions', 'idx_zhongzhi_submissions_agg_qtype').catch(() => {});
await queryInterface.addIndex('zhongzhi_submissions', {
name: 'uk_zhongzhi_submission',
unique: true,
fields: ['aggregation_uid', 'question_uid', 'question_type'],
}).catch(() => {});
// ---- gaozhi ----
await queryInterface.removeIndex('gaozhi_submissions', 'idx_gaozhi_submissions_agg_qtype').catch(() => {});
await queryInterface.addIndex('gaozhi_submissions', {
name: 'uk_gaozhi_submission',
unique: true,
fields: ['aggregation_uid', 'question_uid', 'question_type'],
}).catch(() => {});
// ---- exam_submissions ----
await queryInterface.removeIndex('exam_submissions', 'idx_exam_submissions_contestant_id').catch(() => {});
await queryInterface.addIndex('exam_submissions', {
name: 'uk_exam_submission_contestant',
unique: true,
fields: ['contestant_id'],
}).catch(() => {});
},
down: async (queryInterface) => {
await queryInterface.removeIndex('zhongzhi_submissions', 'uk_zhongzhi_submission').catch(() => {});
await queryInterface.addIndex('zhongzhi_submissions', {
name: 'idx_zhongzhi_submissions_agg_qtype',
fields: ['aggregation_uid', 'question_uid', 'question_type'],
});
await queryInterface.removeIndex('gaozhi_submissions', 'uk_gaozhi_submission').catch(() => {});
await queryInterface.addIndex('gaozhi_submissions', {
name: 'idx_gaozhi_submissions_agg_qtype',
fields: ['aggregation_uid', 'question_uid', 'question_type'],
});
await queryInterface.removeIndex('exam_submissions', 'uk_exam_submission_contestant').catch(() => {});
await queryInterface.addIndex('exam_submissions', {
name: 'idx_exam_submissions_contestant_id',
fields: ['contestant_id'],
});
},
};

View File

@@ -0,0 +1,56 @@
'use strict';
/**
* 为 carousel 表新增富文本正文与可配置按钮字段,并放宽 image_url 允许为空
* (支持"渐变底图回退"的固定页迁移)。
*
* 新增:
* - content TEXT 富文本正文(HTML,由 wangEditor 生成,前端 v-html 渲染)
* - button_text VARCHAR(100) 按钮文字(为空则不显示按钮)
* - button_link VARCHAR(500) 按钮链接(内部路由如 /activate,或外部 http(s):// 链接)
* 变更:
* - image_url 由 NOT NULL 放宽为 允许 NULL(无底图时前端回退 CSS 渐变)
*/
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.addColumn('carousel', 'content', {
type: Sequelize.TEXT,
allowNull: true,
defaultValue: null,
comment: '富文本正文(HTML)',
after: 'title',
});
await queryInterface.addColumn('carousel', 'button_text', {
type: Sequelize.STRING(100),
allowNull: true,
defaultValue: null,
comment: '按钮文字(为空则不显示按钮)',
after: 'content',
});
await queryInterface.addColumn('carousel', 'button_link', {
type: Sequelize.STRING(500),
allowNull: true,
defaultValue: null,
comment: '按钮链接(内部路由/外部URL)',
after: 'button_text',
});
// 放宽 image_url 允许为空,支持渐变底图回退
await queryInterface.changeColumn('carousel', 'image_url', {
type: Sequelize.STRING(500),
allowNull: true,
defaultValue: null,
comment: '图片 URL 地址(可为空时前端回退渐变)',
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.removeColumn('carousel', 'content');
await queryInterface.removeColumn('carousel', 'button_text');
await queryInterface.removeColumn('carousel', 'button_link');
await queryInterface.changeColumn('carousel', 'image_url', {
type: Sequelize.STRING(500),
allowNull: false,
comment: '图片 URL 地址',
});
},
};

View File

@@ -0,0 +1,21 @@
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
const now = new Date();
await queryInterface.bulkInsert('competition_info', [
{
competition_name: '金砖国家职业技能大赛-卫星导航技术应用赛项',
competition_code: 'BRICS2026-ST-027',
created_at: now,
updated_at: now,
},
], {});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.bulkDelete('competition_info', {
competition_code: 'BRICS2026-ST-027',
}, {});
},
};

View File

@@ -0,0 +1,50 @@
'use strict';
/**
* 种子数据:初始化选手数据
* 包含 20 名选手,中职/高职/本科/教师各 5 名
* 账号未激活,密码为空
*/
module.exports = {
up: async (queryInterface) => {
const contestants = [
// ==================== 中职组(5名) ====================
{ id_number: '110101200501010101', name: '张明远', phone: '13800010001', group: 'zhongzhi', password: '', activated: false, created_at: new Date(), updated_at: new Date() },
{ id_number: '110101200502020102', name: '李雨桐', phone: '13800010002', group: 'zhongzhi', password: '', activated: false, created_at: new Date(), updated_at: new Date() },
{ id_number: '110101200503030103', name: '王浩然', phone: '13800010003', group: 'zhongzhi', password: '', activated: false, created_at: new Date(), updated_at: new Date() },
{ id_number: '110101200504040104', name: '赵思琪', phone: '13800010004', group: 'zhongzhi', password: '', activated: false, created_at: new Date(), updated_at: new Date() },
{ id_number: '110101200505050105', name: '陈子涵', phone: '13800010005', group: 'zhongzhi', password: '', activated: false, created_at: new Date(), updated_at: new Date() },
// ==================== 高职组(5名) ====================
{ id_number: '110101200301010201', name: '刘博文', phone: '13800020001', group: 'gaozhi', password: '', activated: false, created_at: new Date(), updated_at: new Date() },
{ id_number: '110101200302020202', name: '杨紫萱', phone: '13800020002', group: 'gaozhi', password: '', activated: false, created_at: new Date(), updated_at: new Date() },
{ id_number: '110101200303030203', name: '黄俊杰', phone: '13800020003', group: 'gaozhi', password: '', activated: false, created_at: new Date(), updated_at: new Date() },
{ id_number: '110101200304040204', name: '周雅琪', phone: '13800020004', group: 'gaozhi', password: '', activated: false, created_at: new Date(), updated_at: new Date() },
{ id_number: '110101200305050205', name: '吴天宇', phone: '13800020005', group: 'gaozhi', password: '', activated: false, created_at: new Date(), updated_at: new Date() },
// ==================== 本科组(5名) ====================
{ id_number: '110101200101010301', name: '郑佳怡', phone: '13800030001', group: 'benke', password: '', activated: false, created_at: new Date(), updated_at: new Date() },
{ id_number: '110101200102020302', name: '冯子辰', phone: '13800030002', group: 'benke', password: '', activated: false, created_at: new Date(), updated_at: new Date() },
{ id_number: '110101200103030303', name: '褚文博', phone: '13800030003', group: 'benke', password: '', activated: false, created_at: new Date(), updated_at: new Date() },
{ id_number: '110101200104040304', name: '林晓萱', phone: '13800030004', group: 'benke', password: '', activated: false, created_at: new Date(), updated_at: new Date() },
{ id_number: '110101200105050305', name: '何志远', phone: '13800030005', group: 'benke', password: '', activated: false, created_at: new Date(), updated_at: new Date() },
// ==================== 教师组(5名) ====================
{ id_number: '110101198501010401', name: '韩建国', phone: '13800040001', group: 'jiaoshi', password: '', activated: false, created_at: new Date(), updated_at: new Date() },
{ id_number: '110101198602020402', name: '唐慧芳', phone: '13800040002', group: 'jiaoshi', password: '', activated: false, created_at: new Date(), updated_at: new Date() },
{ id_number: '110101198703030403', name: '沈志强', phone: '13800040003', group: 'jiaoshi', password: '', activated: false, created_at: new Date(), updated_at: new Date() },
{ id_number: '110101198804040404', name: '许美玲', phone: '13800040004', group: 'jiaoshi', password: '', activated: false, created_at: new Date(), updated_at: new Date() },
{ id_number: '110101198905050405', name: '曹永康', phone: '13800040005', group: 'jiaoshi', password: '', activated: false, created_at: new Date(), updated_at: new Date() },
];
await queryInterface.bulkInsert('contestants', contestants, {});
},
/**
* 回滚种子数据:删除所有选手
*/
down: async (queryInterface) => {
await queryInterface.bulkDelete('contestants', null, {});
},
};

View File

@@ -0,0 +1,36 @@
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
const now = new Date();
await queryInterface.bulkInsert('accounts', [
{
role: 'admin',
name_cn: '系统管理员',
name_en: 'Administrator',
gender: null,
phone: null,
email: 'admin@competition.com',
id_number: '000000000000000000',
password: '$2b$10$Nc6PCJItIwuOzpM22dTiAezB.jZMI8mzkCbg3oRZkAWx.QaI4co9.',
salt: '$2b$10$Nc6PCJItIwuOzpM22dTiAe',
position: '系统管理员',
major: null,
country: '中国',
region: null,
organization_cn: '赛事组委会',
organization_en: 'Competition Committee',
activated: 1,
score: null,
created_at: now,
updated_at: now,
},
], {});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.bulkDelete('accounts', {
id_number: '000000000000000000',
}, {});
},
};

View File

@@ -0,0 +1,36 @@
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.bulkInsert('carousel', [
{
image_url: 'https://images.unsplash.com/photo-1446776811953-b23d57bd21aa?w=1200&h=480&fit=crop',
sort_order: 1,
link_url: '',
enabled: 1,
created_at: new Date(),
updated_at: new Date(),
},
{
image_url: 'https://images.unsplash.com/photo-1451187580459-43490279c0fa?w=1200&h=480&fit=crop',
sort_order: 2,
link_url: '',
enabled: 1,
created_at: new Date(),
updated_at: new Date(),
},
{
image_url: 'https://images.unsplash.com/photo-1614728263952-84ea256f9679?w=1200&h=480&fit=crop',
sort_order: 3,
link_url: '',
enabled: 1,
created_at: new Date(),
updated_at: new Date(),
},
]);
},
down: async (queryInterface, Sequelize) => {
await queryInterface.bulkDelete('carousel', null, {});
},
};

View File

@@ -0,0 +1,85 @@
'use strict';
module.exports = {
up: async (queryInterface) => {
const now = new Date();
const newsItems = [
{
title: '2026年通信与导航应用技术创新赛线上选拔赛通知',
content: '<p>为深入贯彻落实国家创新驱动发展战略,推动通信与导航技术领域的创新应用,现举办2026年通信与导航应用技术创新赛线上选拔赛。本次比赛面向全国职业院校和高等院校师生,欢迎广大师生踊跃报名参赛。</p>',
publish_time: new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000),
pinned: true,
group: 'all',
created_at: now,
updated_at: now,
},
{
title: '中职组比赛时间安排通知',
content: '<p>中职组线上选拔赛将于2026年7月15日上午9:00准时开始,请各位参赛选手提前做好准备。</p>',
publish_time: new Date(now.getTime() - 25 * 24 * 60 * 60 * 1000),
pinned: false,
group: 'zhongzhi',
created_at: now,
updated_at: now,
},
{
title: '高职组比赛时间安排通知',
content: '<p>高职组线上选拔赛将于2026年7月16日上午9:00准时开始,比赛时长3小时。</p>',
publish_time: new Date(now.getTime() - 25 * 24 * 60 * 60 * 1000),
pinned: false,
group: 'gaozhi',
created_at: now,
updated_at: now,
},
{
title: '本科组作品提交截止日期提醒',
content: '<p>本科组线上选拔赛作品提交截止日期为2026年7月20日23:59。</p>',
publish_time: new Date(now.getTime() - 20 * 24 * 60 * 60 * 1000),
pinned: false,
group: 'benke',
created_at: now,
updated_at: now,
},
{
title: '教师组作品提交截止日期提醒',
content: '<p>教师组线上选拔赛作品提交截止日期为2026年7月20日23:59。</p>',
publish_time: new Date(now.getTime() - 20 * 24 * 60 * 60 * 1000),
pinned: false,
group: 'jiaoshi',
created_at: now,
updated_at: now,
},
{
title: '关于账号激活说明',
content: '<p>各位参赛选手请使用身份证号进行账号激活。激活流程:输入身份证号验证,获取验证码,设置密码。</p>',
publish_time: new Date(now.getTime() - 15 * 24 * 60 * 60 * 1000),
pinned: true,
group: 'all',
created_at: now,
updated_at: now,
},
{
title: '比赛系统操作指南',
content: '<p>为帮助各位选手熟悉比赛系统,请仔细阅读操作指南。中职/高职组在线答题,本科/教师组上传作品。</p>',
publish_time: new Date(now.getTime() - 10 * 24 * 60 * 60 * 1000),
pinned: false,
group: 'all',
created_at: now,
updated_at: now,
},
{
title: '温馨提示:比赛期间注意事项',
content: '<p>为确保比赛顺利进行,请使用Chrome或Edge浏览器最新版本,保持网络稳定,比赛过程中请勿刷新页面。</p>',
publish_time: new Date(now.getTime() - 5 * 24 * 60 * 60 * 1000),
pinned: false,
group: 'all',
created_at: now,
updated_at: now,
},
];
await queryInterface.bulkInsert('news', newsItems, {});
},
down: async (queryInterface) => {
await queryInterface.bulkDelete('news', null, {});
},
};

View File

@@ -0,0 +1,23 @@
'use strict';
module.exports = {
up: async (queryInterface) => {
const now = new Date();
const questions = [
{ group: 'zhongzhi', title: '通信系统的基本组成', content: '请简述通信系统的基本组成,包括信源、发送设备、信道、接收设备和信宿五大组成部分,并简要说明各部分的功能。', score: 20, sort_order: 1, created_at: now, updated_at: now },
{ group: 'zhongzhi', title: 'GPS导航原理', content: '请阐述GPS全球定位系统的基本工作原理,包括卫星星座、信号结构、伪距测量和定位解算等关键技术。', score: 20, sort_order: 2, created_at: now, updated_at: now },
{ group: 'zhongzhi', title: '信号调制与解调', content: '请比较分析AM调制、FM调制和数字调制(如QPSK)的基本原理、优缺点及适用场景。', score: 20, sort_order: 3, created_at: now, updated_at: now },
{ group: 'zhongzhi', title: '移动通信发展历程', content: '请简述移动通信从1G到5G的发展历程,重点说明各代通信技术的主要特点和技术突破。', score: 20, sort_order: 4, created_at: now, updated_at: now },
{ group: 'zhongzhi', title: '创新应用方案设计', content: '请结合通信与导航技术,设计一个创新应用方案,需包含应用场景描述、技术方案选型、预期效果分析等。', score: 20, sort_order: 5, created_at: now, updated_at: now },
{ group: 'gaozhi', title: 'OFDM技术原理与应用', content: '请详细阐述OFDM(正交频分复用)技术的基本原理,包括子载波正交性、循环前缀的作用以及在4G/5G中的应用。', score: 20, sort_order: 1, created_at: now, updated_at: now },
{ group: 'gaozhi', title: '北斗卫星导航系统', content: '请分析北斗卫星导航系统的发展历程、系统组成、服务类型,并与GPS系统进行对比分析。', score: 20, sort_order: 2, created_at: now, updated_at: now },
{ group: 'gaozhi', title: '5G网络架构与关键技术', content: '请描述5G网络的核心架构(包括核心网和接入网),并分析Massive MIMO、网络切片、边缘计算等关键技术。', score: 20, sort_order: 3, created_at: now, updated_at: now },
{ group: 'gaozhi', title: '通信网络安全', content: '请分析通信网络中常见的安全威胁(如窃听、篡改、拒绝服务攻击等),并提出相应的防护措施。', score: 20, sort_order: 4, created_at: now, updated_at: now },
{ group: 'gaozhi', title: '综合创新项目设计', content: '请设计一个通信与导航融合的创新应用项目,需包含项目背景、技术路线、实施方案、预期成果和可行性分析。', score: 20, sort_order: 5, created_at: now, updated_at: now },
];
await queryInterface.bulkInsert('exam_questions', questions, {});
},
down: async (queryInterface) => {
await queryInterface.bulkDelete('exam_questions', null, {});
},
};

View File

@@ -0,0 +1,61 @@
'use strict';
/**
* 种子数据:初始化比赛时间配置
* 中职组和高职组设置起止时间(在线答题模式)
* 本科组和教师组设置截止时间(作品提交模式)
*/
module.exports = {
up: async (queryInterface) => {
const now = new Date();
const times = [
// 中职组:在线答题,有起止时间
{
group: 'zhongzhi',
start_time: new Date(now.getTime() + 1 * 24 * 60 * 60 * 1000), // 1天后开始
end_time: new Date(now.getTime() + 1 * 24 * 60 * 60 * 1000 + 3 * 60 * 60 * 1000), // 持续3小时
deadline: null,
created_at: now,
updated_at: now,
},
// 高职组:在线答题,有起止时间
{
group: 'gaozhi',
start_time: new Date(now.getTime() + 2 * 24 * 60 * 60 * 1000), // 2天后开始
end_time: new Date(now.getTime() + 2 * 24 * 60 * 60 * 1000 + 3 * 60 * 60 * 1000), // 持续3小时
deadline: null,
created_at: now,
updated_at: now,
},
// 本科组:作品提交,只有截止时间
{
group: 'benke',
start_time: null,
end_time: null,
deadline: new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000), // 7天后截止
created_at: now,
updated_at: now,
},
// 教师组:作品提交,只有截止时间
{
group: 'jiaoshi',
start_time: null,
end_time: null,
deadline: new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000), // 7天后截止
created_at: now,
updated_at: now,
},
];
await queryInterface.bulkInsert('competition_times', times, {});
},
/**
* 回滚种子数据:删除所有时间配置
*/
down: async (queryInterface) => {
await queryInterface.bulkDelete('competition_times', null, {});
},
};

View File

@@ -0,0 +1,176 @@
'use strict';
/**
* 种子文件:写入选择题、判断题、综合性任务模拟数据
*
* 参考考试大纲"题型结构":
* - 专业基础任务:选择题 50题 × 1分 = 50分,判断题 20题 × 1分 = 20分
* - 综合性任务:1题 × 30分 = 30分
* - 总分:100分
*
* 考试内容覆盖:
* - 第一篇 卫星通信技术(第1-6章)→ 16题
* - 第二篇 卫星导航技术(第1-8章)→ 25题
* - 第三篇 设备实操命令 → 29题(选择+判断总计)
*/
module.exports = {
up: async (queryInterface) => {
const now = new Date();
// ==================== 选择题 ====================
// 总分:50题 × 1分 = 50分
// 覆盖:第1篇(16题)+ 第2篇(25题)+ 第3篇(9题)= 50题
const choiceQuestions = [
// ==================== 第一篇:卫星通信技术(第1-6章)====================
// 第1章:卫星通信基础概论
{ group: 'zhongzhi', question: '卫星通信定义为?', options: '[{"key":"A","text":"利用卫星在地面站之间进行的通信"},{"key":"B","text":"利用卫星转发无线电信号实现多个地球站之间的通信"},{"key":"C","text":"卫星与飞机之间的通信"},{"key":"D","text":"卫星之间的宇宙通信"}]', answer: 'B', score: 1, sort_order: 1, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '卫星通信中,地球站向卫星发射信号的链路称为?', options: '[{"key":"A","text":"下行链路"},{"key":"B","text":"上行链路"},{"key":"C","text":"前向链路"},{"key":"D","text":"反向链路"}]', answer: 'B', score: 1, sort_order: 2, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '卫星通信的主要优点不包括以下哪项?', options: '[{"key":"A","text":"覆盖范围大"},{"key":"B","text":"通信容量大"},{"key":"C","text":"建站成本低"},{"key":"D","text":"不受地理条件限制"}]', answer: 'C', score: 1, sort_order: 3, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '通信系统中,将原始信号转换为适合信道传输的信号的过程称为?', options: '[{"key":"A","text":"编码"},{"key":"B","text":"调制"},{"key":"C","text":"解码"},{"key":"D","text":"解调"}]', answer: 'B', score: 1, sort_order: 4, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: 'GEO卫星的轨道高度约为?', options: '[{"key":"A","text":"500-1500 km"},{"key":"B","text":"5000-12000 km"},{"key":"C","text":"20200 km"},{"key":"D","text":"35786 km"}]', answer: 'D', score: 1, sort_order: 5, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: 'MEO卫星的轨道高度范围是?', options: '[{"key":"A","text":"低于500 km"},{"key":"B","text":"500-2000 km"},{"key":"C","text":"5000-20000 km"},{"key":"D","text":"35786 km"}]', answer: 'C', score: 1, sort_order: 6, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: 'LEO卫星的轨道倾角通常为?', options: '[{"key":"A","text":"0度"},{"key":"B","text":"近极地轨道"},{"key":"C","text":"赤道轨道"},{"key":"D","text":"地球同步轨道"}]', answer: 'B', score: 1, sort_order: 7, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '卫星通信中,频率复用技术的主要作用是?', options: '[{"key":"A","text":"提高频率利用率"},{"key":"B","text":"降低发射功率"},{"key":"C","text":"减少卫星数量"},{"key":"D","text":"提高信号质量"}]', answer: 'A', score: 1, sort_order: 8, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '以下哪种不是卫星通信的多址方式?', options: '[{"key":"A","text":"FDMA"},{"key":"B","text":"TDMA"},{"key":"C","text":"CDMA"},{"key":"D","text":"ADMA"}]', answer: 'D', score: 1, sort_order: 9, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '卫星物联网中,星上处理的主要目的是?', options: '[{"key":"A","text":"增加卫星重量"},{"key":"B","text":"提高传输效率"},{"key":"C","text":"降低功率"},{"key":"D","text":"增加轨道高度"}]', answer: 'B', score: 1, sort_order: 10, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '低轨卫星星座的特点是?', options: '[{"key":"A","text":"单星覆盖大,但需要星上处理"},{"key":"B","text":"全球覆盖,大容量低时延"},{"key":"C","text":"只有一颗卫星"},{"key":"D","text":"不需要切换"}]', answer: 'B', score: 1, sort_order: 11, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '卫星通信系统的转发器作用是?', options: '[{"key":"A","text":"存储数据"},{"key":"B","text":"放大变频转发信号"},{"key":"C","text":"计算信号"},{"key":"D","text":"控制卫星姿态"}]', answer: 'B', score: 1, sort_order: 12, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '卫星天线的指向精度影响?', options: '[{"key":"A","text":"信号接收功率"},{"key":"B","text":"卫星重量"},{"key":"C","text":"轨道高度"},{"key":"D","text":"卫星寿命"}]', answer: 'A', score: 1, sort_order: 13, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '卫星电源系统主要采用?', options: '[{"key":"A","text":"燃料电池"},{"key":"B","text":"太阳能电池阵+蓄电池组"},{"key":"C","text":"核能发电"},{"key":"D","text":"化学电池"}]', answer: 'B', score: 1, sort_order: 14, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '以下哪个频段常用作卫星通信上行?', options: '[{"key":"A","text":"UHF"},{"key":"B","text":"C-band"},{"key":"C","text":"Ku-band"},{"key":"D","text":"Ka-band"}]', answer: 'D', score: 1, sort_order: 15, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '卫星姿态控制的目的是?', options: '[{"key":"A","text":"改变轨道高度"},{"key":"B","text":"保持天线指向目标区域"},{"key":"C","text":"改变速度"},{"key":"D","text":"减少功耗"}]', answer: 'B', score: 1, sort_order: 16, created_at: now, updated_at: now },
// ==================== 第二篇:卫星导航技术(第1-8章)====================
// 第1章:GNSS概述
{ group: 'zhongzhi', question: 'GNSS的全称是?', options: '[{"key":"A","text":"Global Navigation Satellite System"},{"key":"B","text":"Global Network Service System"},{"key":"C","text":"General Navigation Support System"},{"key":"D","text":"Geo Navigation Satellite System"}]', answer: 'A', score: 1, sort_order: 17, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '以下哪个不属于四大全球导航卫星星座?', options: '[{"key":"A","text":"GPS"},{"key":"B","text":"北斗"},{"key":"C","text":"GLONASS"},{"key":"D","text":"WAAS"}]', answer: 'D', score: 1, sort_order: 18, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '北斗三号全球系统提供多少颗卫星?', options: '[{"key":"A","text":"24"},{"key":"B","text":"30"},{"key":"C","text":"35"},{"key":"D","text":"40"}]', answer: 'C', score: 1, sort_order: 19, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: 'GPS卫星导航系统至少需要几颗卫星才能实现三维定位?', options: '[{"key":"A","text":"2颗"},{"key":"B","text":"3颗"},{"key":"C","text":"4颗"},{"key":"D","text":"5颗"}]', answer: 'C', score: 1, sort_order: 20, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '伪距测量测量的是?', options: '[{"key":"A","text":"卫星到接收机的几何距离"},{"key":"B","text":"卫星信号传播时间乘以光速得到的距离"},{"key":"C","text":"卫星到地心的距离"},{"key":"D","text":"接收机到地面的距离"}]', answer: 'B', score: 1, sort_order: 21, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '卫星定位误差中,属于系统误差的是?', options: '[{"key":"A","text":"电离层延迟误差"},{"key":"B","text":"接收机噪声"},{"key":"C","text":"多径效应随机误差"},{"key":"D","text":"测量噪声"}]', answer: 'A', score: 1, sort_order: 22, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '差分定位技术中,RTK的全称是?', options: '[{"key":"A","text":"Real-Time Kinematic"},{"key":"B","text":"Rapid Tracking Kinematic"},{"key":"C","text":"Real-Time Kalman"},{"key":"D","text":"Radio Transmission Kinematic"}]', answer: 'A', score: 1, sort_order: 23, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: 'NMEA-0183协议中,GGA语句主要提供什么信息?', options: '[{"key":"A","text":"卫星星历"},{"key":"B","text":"定位数据"},{"key":"C","text":"卫星状态"},{"key":"D","text":"速度信息"}]', answer: 'B', score: 1, sort_order: 24, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '北斗系统独具特色的服务是?', options: '[{"key":"A","text":"仅定位"},{"key":"B","text":"短报文通信"},{"key":"C","text":"仅授时"},{"key":"D","text":"仅测速"}]', answer: 'B', score: 1, sort_order: 25, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '高精度差分定位中,NTRIP协议用于?', options: '[{"key":"A","text":"卫星轨道计算"},{"key":"B","text":"通过互联网传输差分改正数据"},{"key":"C","text":"信号调制"},{"key":"D","text":"误差计算"}]', answer: 'B', score: 1, sort_order: 26, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '卫星导航接收机的灵敏度主要影响?', options: '[{"key":"A","text":"捕获卫星信号的能力"},{"key":"B","text":"发射功率"},{"key":"C","text":"卫星轨道高度"},{"key":"D","text":"计算速度"}]', answer: 'A', score: 1, sort_order: 27, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '组合导航GNSS+IMU中,IMU的作用是?', options: '[{"key":"A","text":"提供加速度和角速度"},{"key":"B","text":"提供定位结果"},{"key":"C","text":"提供时间信息"},{"key":"D","text":"提供卫星星历"}]', answer: 'A', score: 1, sort_order: 28, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '多路径效应产生的原因是?', options: '[{"key":"A","text":"卫星信号经过反射后与直达信号干涉"},{"key":"B","text":"多颗卫星信号叠加"},{"key":"C","text":"多个接收机同时工作"},{"key":"D","text":"电离层反射信号"}]', answer: 'A', score: 1, sort_order: 29, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: 'RTCM标准主要用于?', options: '[{"key":"A","text":"卫星导航电文标准"},{"key":"B","text":"差分改正数据标准"},{"key":"C","text":"NMEA输出标准"},{"key":"D","text":"接口通信标准"}]', answer: 'B', score: 1, sort_order: 30, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: 'PDOP值越大表示?', options: '[{"key":"A","text":"定位精度越好"},{"key":"B","text":"定位几何误差越大"},{"key":"C","text":"卫星越多"},{"key":"D","text":"温度越高"}]', answer: 'B', score: 1, sort_order: 31, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '北斗卫星导航系统的服务区覆盖?', options: '[{"key":"A","text":"仅中国"},{"key":"B","text":"亚太地区"},{"key":"C","text":"全球"},{"key":"D","text":"仅北半球"}]', answer: 'C', score: 1, sort_order: 32, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: 'GPS卫星星历更新周期通常为?', options: '[{"key":"A","text":"30秒"},{"key":"B","text":"2小时"},{"key":"C","text":"1天"},{"key":"D","text":"1周"}]', answer: 'B', score: 1, sort_order: 33, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '静态相对定位主要用于?', options: '[{"key":"A","text":"需要高精度大地测量"},{"key":"B","text":"车辆导航"},{"key":"C","text":"船舶导航"},{"key":"D","text":"飞机导航"}]', answer: 'A', score: 1, sort_order: 34, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '载波相位测量相比伪距测量?', options: '[{"key":"A","text":"精度更高"},{"key":"B","text":"精度更低"},{"key":"C","text":"精度相同"},{"key":"D","text":"无法比较"}]', answer: 'A', score: 1, sort_order: 35, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '电离层延迟对伪距测量的影响?', options: '[{"key":"A","text":"夜间比白天大"},{"key":"B","text":"白天比夜间大"},{"key":"C","text":"没有影响"},{"key":"D","text":"只在冬季有影响"}]', answer: 'B', score: 1, sort_order: 36, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '周跳发生在?', options: '[{"key":"A","text":"载波相位测量中"},{"key":"B","text":"伪距测量中"},{"key":"C","text":"信号发射时"},{"key":"D","text":"卫星星历计算时"}]', answer: 'A', score: 1, sort_order: 37, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: 'GPS系统由多少颗卫星组成?', options: '[{"key":"A","text":"24"},{"key":"B","text":"31"},{"key":"C","text":"35"},{"key":"D","text":"40"}]', answer: 'A', score: 1, sort_order: 38, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '以下哪种不属于北斗增强系统?', options: '[{"key":"A","text":"SBAS"},{"key":"B","text":"GBAS"},{"key":"C","text":"BDS-IS"},{"key":"D","text":"GLONASS"}]', answer: 'D', score: 1, sort_order: 39, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '单点定位精度通常为?', options: '[{"key":"A","text":"厘米级"},{"key":"B","text":"米级"},{"key":"C","text":"分米级"},{"key":"D","text":"毫米级"}]', answer: 'B', score: 1, sort_order: 40, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: 'RTK定位精度通常达到?', options: '[{"key":"A","text":"厘米级"},{"key":"B","text":"米级"},{"key":"C","text":"千米级"},{"key":"D","text":"十米级"}]', answer: 'A', score: 1, sort_order: 41, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: 'NMEA-0183语句的结束标志是?', options: '[{"key":"A","text":"换行"},{"key":"B","text":"校验和"},{"key":"C","text":"星号"},{"key":"D","text":"回车"}]', answer: 'B', score: 1, sort_order: 42, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '以下哪个不是北斗卫星导航系统的特点?', options: '[{"key":"A","text":"有源定位"},{"key":"B","text":"短报文通信"},{"key":"C","text":"区域服务不能全球覆盖"},{"key":"D","text":"三频信号"}]', answer: 'C', score: 1, sort_order: 43, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '卫星导航接收机捕获阶段的主要作用是?', options: '[{"key":"A","text":"搜索卫星信号并确定频率码相位"},{"key":"B","text":"跟踪信号"},{"key":"C","text":"计算位置"},{"key":"D","text":"输出速度"}]', answer: 'A', score: 1, sort_order: 44, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '对流层延迟改正模型中,通常使用?', options: '[{"key":"A","text":"Hopfield模型"},{"key":"B","text":"Klobuchar模型"},{"key":"C","text":"Black模型"},{"key":"D","text":"高斯模型"}]', answer: 'A', score: 1, sort_order: 45, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '全球定位系统中,UTC表示?', options: '[{"key":"A","text":"世界时"},{"key":"B","text":"协调世界时"},{"key":"C","text":"原子时"},{"key":"D","text":"恒星时"}]', answer: 'B', score: 1, sort_order: 46, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '整周模糊度解算属于?', options: '[{"key":"A","text":"伪距测量问题"},{"key":"B","text":"载波相位测量问题"},{"key":"C","text":"卫星轨道问题"},{"key":"D","text":"电离层问题"}]', answer: 'B', score: 1, sort_order: 47, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '以下哪个频率是北斗B1I信号频率?', options: '[{"key":"A","text":"1561.098 MHz"},{"key":"B","text":"1268.52 MHz"},{"key":"C","text":"1176.45 MHz"},{"key":"D","text":"1575.42 MHz"}]', answer: 'A', score: 1, sort_order: 48, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: 'GPS选择的PRN码特点是?', options: '[{"key":"A","text":"自相关特性好,互相关特性弱"},{"key":"B","text":"自相关特性弱,互相关特性强"},{"key":"C","text":"长度固定不变"},{"key":"D","text":"只有一个码"}]', answer: 'A', score: 1, sort_order: 49, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '下列哪项不属于卫星导航的应用?', options: '[{"key":"A","text":"车辆导航"},{"key":"B","text":"工程测量"},{"key":"C","text":"火力发电"},{"key":"D","text":"时间同步"}]', answer: 'C', score: 1, sort_order: 50, created_at: now, updated_at: now },
// 高职组继续补充题目(总计50题,上述中职组已有50题,高职组继续扩展)
{ group: 'gaozhi', question: '卫星通信中,FDMA的含义是?', options: '[{"key":"A","text":"频分多址"},{"key":"B","text":"时分多址"},{"key":"C","text":"码分多址"},{"key":"D","text":"空分多址"}]', answer: 'A', score: 1, sort_order: 1, created_at: now, updated_at: now },
{ group: 'gaozhi', question: 'GEO卫星的星下点位置相对于地面观察者?', options: '[{"key":"A","text":"不断高速移动"},{"key":"B","text":"基本静止"},{"key":"C","text":"每天环绕一次"},{"key":"D","text":"每月环绕一次"}]', answer: 'B', score: 1, sort_order: 2, created_at: now, updated_at: now },
{ group: 'gaozhi', question: 'OFDM技术中,子载波之间保持正交性的目的是?', options: '[{"key":"A","text":"提高发射功率"},{"key":"B","text":"避免子载波间干扰"},{"key":"C","text":"增加带宽"},{"key":"D","text":"降低频率"}]', answer: 'B', score: 1, sort_order: 3, created_at: now, updated_at: now },
{ group: 'gaozhi', question: '北斗三号全球卫星导航系统具备以下哪种特色服务?', options: '[{"key":"A","text":"仅定位服务"},{"key":"B","text":"短报文通信"},{"key":"C","text":"仅授时服务"},{"key":"D","text":"仅测速服务"}]', answer: 'B', score: 1, sort_order: 4, created_at: now, updated_at: now },
{ group: 'gaozhi', question: '5G网络中,Massive MIMO技术的主要优势是?', options: '[{"key":"A","text":"降低功耗"},{"key":"B","text":"提升频谱效率和容量"},{"key":"C","text":"减少天线数量"},{"key":"D","text":"简化网络架构"}]', answer: 'B', score: 1, sort_order: 5, created_at: now, updated_at: now },
{ group: 'gaozhi', question: '网络切片技术属于5G的哪个核心特性?', options: '[{"key":"A","text":"eMBB"},{"key":"B","text":"URLLC"},{"key":"C","text":"mMTC"},{"key":"D","text":"网络能力开放"}]', answer: 'D', score: 1, sort_order: 6, created_at: now, updated_at: now },
{ group: 'gaozhi', question: '在通信安全中,以下哪种攻击属于被动攻击?', options: '[{"key":"A","text":"篡改"},{"key":"B","text":"窃听"},{"key":"C","text":"拒绝服务"},{"key":"D","text":"伪装"}]', answer: 'B', score: 1, sort_order: 7, created_at: now, updated_at: now },
{ group: 'gaozhi', question: 'NTRIP协议主要用于什么场景?', options: '[{"key":"A","text":"卫星遥测"},{"key":"B","text":"差分数据网络传输"},{"key":"C","text":"卫星轨道控制"},{"key":"D","text":"信号加密传输"}]', answer: 'B', score: 1, sort_order: 8, created_at: now, updated_at: now },
{ group: 'gaozhi', question: '组合导航(GNSS+IMU)的核心优势是什么?', options: '[{"key":"A","text":"降低成本"},{"key":"B","text":"无缝切换与误差互补"},{"key":"C","text":"减少卫星数量"},{"key":"D","text":"提高发射功率"}]', answer: 'B', score: 1, sort_order: 9, created_at: now, updated_at: now },
{ group: 'gaozhi', question: '5G网络中,URLLC场景的主要特征是?', options: '[{"key":"A","text":"高速率大带宽"},{"key":"B","text":"低时延高可靠"},{"key":"C","text":"海量连接"},{"key":"D","text":"广域覆盖"}]', answer: 'B', score: 1, sort_order: 10, created_at: now, updated_at: now },
{ group: 'gaozhi', question: '卫星定位中,伪距测量的误差来源不包括?', options: '[{"key":"A","text":"电离层延迟"},{"key":"B","text":"对流层延迟"},{"key":"C","text":"卫星轨道误差"},{"key":"D","text":"用户设备重量"}]', answer: 'D', score: 1, sort_order: 11, created_at: now, updated_at: now },
{ group: 'gaozhi', question: '低轨卫星物联网相比GEO卫星的主要优势是?', options: '[{"key":"A","text":"覆盖范围更大"},{"key":"B","text":"传输时延更低"},{"key":"C","text":"单星容量更大"},{"key":"D","text":"使用寿命更长"}]', answer: 'B', score: 1, sort_order: 12, created_at: now, updated_at: now },
{ group: 'gaozhi', question: 'QPSK调制属于?', options: '[{"key":"A","text":"模拟调制"},{"key":"B","text":"数字相位调制"},{"key":"C","text":"幅度调制"},{"key":"D","text":"频率调制"}]', answer: 'B', score: 1, sort_order: 13, created_at: now, updated_at: now },
{ group: 'gaozhi', question: '信道编码的主要目的是?', options: '[{"key":"A","text":"提高传输速率"},{"key":"B","text":"对抗传输错误"},{"key":"C","text":"增加功率"},{"key":"D","text":"压缩数据"}]', answer: 'B', score: 1, sort_order: 14, created_at: now, updated_at: now },
{ group: 'gaozhi', question: 'CDMA技术的特点是?', options: '[{"key":"A","text":"所有用户同时占用相同频段"},{"key":"B","text":"每个用户占用不同频率"},{"key":"C","text":"每个用户占用不同时隙"},{"key":"D","text":"用户按空间分隔"}]', answer: 'A', score: 1, sort_order: 15, created_at: now, updated_at: now },
{ group: 'gaozhi', question: 'M-QAM调制中,M越大?', options: '[{"key":"A","text":"频谱效率越高,误码性能越好"},{"key":"B","text":"频谱效率越高,误码性能越差"},{"key":"C","text":"频谱效率越低,误码性能越好"},{"key":"D","text":"频谱效率越低,误码性能越差"}]', answer: 'B', score: 1, sort_order: 16, created_at: now, updated_at: now },
{ group: 'gaozhi', question: '香农公式给出了?', options: '[{"key":"A","text":"信道容量与带宽信噪比的关系"},{"key":"B","text":"信号功率与频率的关系"},{"key":"C","text":"噪声功率与温度的关系"},{"key":"D","text":"带宽与频率的关系"}]', answer: 'A', score: 1, sort_order: 17, created_at: now, updated_at: now },
{ group: 'gaozhi', question: '均衡技术主要用于补偿?', options: '[{"key":"A","text":"信道衰落引起的码间干扰"},{"key":"B","text":"噪声干扰"},{"key":"C","text":"频率偏移"},{"key":"D","text":"相位噪声"}]', answer: 'A', score: 1, sort_order: 18, created_at: now, updated_at: now },
{ group: 'gaozhi', question: '编码效率等于?', options: '[{"key":"A","text":"信息位长度/总码长"},{"key":"B","text":"总码长/信息位长度"},{"key":"C","text":"监督位长度/总码长"},{"key":"D","text":"信息位长度/监督位长度"}]', answer: 'A', score: 1, sort_order: 19, created_at: now, updated_at: now },
{ group: 'gaozhi', question: 'RS编码属于?', options: '[{"key":"A","text":"分组码"},{"key":"B","text":"卷积码"},{"key":"C","text":"循环码"},{"key":"D","text":"RS不是编码"}]', answer: 'A', score: 1, sort_order: 20, created_at: now, updated_at: now },
{ group: 'gaozhi', question: 'TCM编码是?', options: '[{"key":"A","text":"网格编码调制"},{"key":"B","text":" Turbo编码"},{"key":"C","text":"卷积编码"},{"key":"D","text":"里德所罗门编码"}]', answer: 'A', score: 1, sort_order: 21, created_at: now, updated_at: now },
{ group: 'gaozhi', question: '扩频通信的主要优点不包括?', options: '[{"key":"A","text":"抗干扰能力强"},{"key":"B","text":"隐蔽性好"},{"key":"C","text":"功率大"},{"key":"D","text":"多址能力强"}]', answer: 'C', score: 1, sort_order: 22, created_at: now, updated_at: now },
{ group: 'gaozhi', question: 'DSSS表示?', options: '[{"key":"A","text":"跳频扩频"},{"key":"B","text":"直接序列扩频"},{"key":"C","text":"跳时扩频"},{"key":"D","text":"线性扩频"}]', answer: 'B', score: 1, sort_order: 23, created_at: now, updated_at: now },
{ group: 'gaozhi', question: 'AOS协议主要用于?', options: '[{"key":"A","text":"地面互联网传输"},{"key":"B","text":"星地链路 packet 传输"},{"key":"C","text":"卫星轨道测量"},{"key":"D","text":"信号调制"}]', answer: 'B', score: 1, sort_order: 24, created_at: now, updated_at: now },
{ group: 'gaozhi', question: 'CCSDS标准是?', options: '[{"key":"A","text":"空间数据系统咨询委员会标准"},{"key":"B","text":"通信系统标准"},{"key":"C","text":"卫星导航标准"},{"key":"D","text":"互联网标准"}]', answer: 'A', score: 1, sort_order: 25, created_at: now, updated_at: now },
{ group: 'gaozhi', question: 'LDPC编码属于?', options: '[{"key":"A","text":"低密度奇偶校验码"},{"key":"B","text":"低密度分组码"},{"key":"C","text":"循环码"},{"key":"D","text":"卷积码"}]', answer: 'A', score: 1, sort_order: 26, created_at: now, updated_at: now },
{ group: 'gaozhi', question: 'MIMO技术可以提高?', options: '[{"key":"A","text":"信道容量"},{"key":"B","text":"发射功率"},{"key":"C","text":"噪声功率"},{"key":"D","text":"传播距离"}]', answer: 'A', score: 1, sort_order: 27, created_at: now, updated_at: now },
{ group: 'gaozhi', question: 'OFDM循环前缀的作用是?', options: '[{"key":"A","text":"增加功率"},{"key":"B","text":"消除符号间干扰"},{"key":"C","text":"提高频率"},{"key":"D","text":"降低速度"}]', answer: 'B', score: 1, sort_order: 28, created_at: now, updated_at: now },
{ group: 'gaozhi', question: 'Turbo码的主要优点是?', options: '[{"key":"A","text":"接近香农极限的性能"},{"key":"B","text":"编码简单"},{"key":"C","text":"译码简单"},{"key":"D","text":"速率很高"}]', answer: 'A', score: 1, sort_order: 29, created_at: now, updated_at: now },
{ group: 'gaozhi', question: 'ARQ协议的作用是?', options: '[{"key":"A","text":"自动重传请求"},{"key":"B","text":"自动编码"},{"key":"C","text":"自动应答"},{"key":"D","text":"自动加密"}]', answer: 'A', score: 1, sort_order: 30, created_at: now, updated_at: now },
{ group: 'gaozhi', question: 'TCP/IP协议中,TCP提供?', options: '[{"key":"A","text":"面向连接可靠服务"},{"key":"B","text":"无连接不可靠服务"},{"key":"C","text":"广播服务"},{"key":"D","text":"组播服务"}]', answer: 'A', score: 1, sort_order: 31, created_at: now, updated_at: now },
{ group: 'gaozhi', question: 'UDP协议提供?', options: '[{"key":"A","text":"面向连接可靠服务"},{"key":"B","text":"无连接不可靠服务"},{"key":"C","text":"广播服务"},{"key":"D","text":"组播服务"}]', answer: 'B', score: 1, sort_order: 32, created_at: now, updated_at: now },
{ group: 'gaozhi', question: 'HTTPS协议使用什么端口?', options: '[{"key":"A","text":"80"},{"key":"B","text":"443"},{"key":"C","text":"8080"},{"key":"D","text":"22"}]', answer: 'B', score: 1, sort_order: 33, created_at: now, updated_at: now },
{ group: 'gaozhi', question: 'IPv6地址长度为?', options: '[{"key":"A","text":"32位"},{"key":"B","text":"64位"},{"key":"C","text":"128位"},{"key":"D","text":"256位"}]', answer: 'C', score: 1, sort_order: 34, created_at: now, updated_at: now },
{ group: 'gaozhi', question: 'OSI模型有几层?', options: '[{"key":"A","text":"5"},{"key":"B","text":"6"},{"key":"C","text":"7"},{"key":"D","text":"8"}]', answer: 'C', score: 1, sort_order: 35, created_at: now, updated_at: now },
{ group: 'gaozhi', question: '调制的主要作用是?', options: '[{"key":"A","text":"将基带信号搬移到高频载波"},{"key":"B","text":"将高频信号搬移到基带"},{"key":"C","text":"放大信号"},{"key":"D","text":"滤波信号"}]', answer: 'A', score: 1, sort_order: 36, created_at: now, updated_at: now },
{ group: 'gaozhi', question: '解调的主要作用是?', options: '[{"key":"A","text":"从高频载波提取基带信号"},{"key":"B","text":"放大信号"},{"key":"C","text":"滤波信号"},{"key":"D","text":"变频信号"}]', answer: 'A', score: 1, sort_order: 37, created_at: now, updated_at: now },
{ group: 'gaozhi', question: '信源编码的主要目的是?', options: '[{"key":"A","text":"提高传输可靠性"},{"key":"B","text":"压缩数据率"},{"key":"C","text":"增加冗余"},{"key":"D","text":"提高功率"}]', answer: 'B', score: 1, sort_order: 38, created_at: now, updated_at: now },
{ group: 'gaozhi', question: '信道编码的主要目的是?', options: '[{"key":"A","text":"压缩数据"},{"key":"B","text":"差错控制"},{"key":"C","text":"提高速率"},{"key":"D","text":"降低功率"}]', answer: 'B', score: 1, sort_order: 39, created_at: now, updated_at: now },
{ group: 'gaozhi', question: 'AM调制中,调幅指数m满足?', options: '[{"key":"A","text":"0 ≤ m ≤ 1"},{"key":"B","text":"m > 1"},{"key":"C","text":"m < 0"},{"key":"D","text":"m = 0"}]', answer: 'A', score: 1, sort_order: 40, created_at: now, updated_at: now },
{ group: 'gaozhi', question: 'FM调制相比AM调制?', options: '[{"key":"A","text":"抗噪声性能更好"},{"key":"B","text":"功率更小"},{"key":"C","text":"带宽更小"},{"key":"D","text":"实现更简单"}]', answer: 'A', score: 1, sort_order: 41, created_at: now, updated_at: now },
{ group: 'gaozhi', question: 'PCM编码三个步骤依次是?', options: '[{"key":"A","text":"抽样、量化、编码"},{"key":"B","text":"量化、抽样、编码"},{"key":"C","text":"编码、抽样、量化"},{"key":"D","text":"抽样、编码、量化"}]', answer: 'A', score: 1, sort_order: 42, created_at: now, updated_at: now },
{ group: 'gaozhi', question: '奈奎斯特第一准则解决什么问题?', options: '[{"key":"A","text":"无码间干扰的传输特性"},{"key":"B","text":"信噪比计算"},{"key":"C","text":"信道容量计算"},{"key":"D","text":"功率分配"}]', answer: 'A', score: 1, sort_order: 43, created_at: now, updated_at: now },
{ group: 'gaozhi', question: '匹配滤波器输出信噪比在什么时候最大?', options: '[{"key":"A","text":"抽样时刻"},{"key":"B","text":"发送时刻"},{"key":"C","text":"接收开始"},{"key":"D","text":"接收结束"}]', answer: 'A', score: 1, sort_order: 44, created_at: now, updated_at: now },
{ group: 'gaozhi', question: '升余弦滚降滤波器的作用是?', options: '[{"key":"A","text":"降低码间干扰"},{"key":"B","text":"增加码间干扰"},{"key":"C","text":"提高功率"},{"key":"D","text":"改变频率"}]', answer: 'A', score: 1, sort_order: 45, created_at: now, updated_at: now },
{ group: 'gaozhi', question: '希尔伯特变换主要用于?', options: '[{"key":"A","text":"产生解析信号"},{"key":"B","text":"滤波信号"},{"key":"C","text":"放大信号"},{"key":"D","text":"变频信号"}]', answer: 'A', score: 1, sort_order: 46, created_at: now, updated_at: now },
{ group: 'gaozhi', question: '随机过程的均值反映了?', options: '[{"key":"A","text":"信号的平均强度"},{"key":"B","text":"信号的起伏程度"},{"key":"C","text":"信号的相关性"},{"key":"D","text":"信号的频率"}]', answer: 'A', score: 1, sort_order: 47, created_at: now, updated_at: now },
{ group: 'gaozhi', question: '傅里叶变换将信号变换到?', options: '[{"key":"A","text":"时域"},{"key":"B","text":"频域"},{"key":"C","text":"空域"},{"key":"D","text":"码域"}]', answer: 'B', score: 1, sort_order: 48, created_at: now, updated_at: now },
{ group: 'gaozhi', question: '信噪比等于?', options: '[{"key":"A","text":"信号功率除以噪声功率"},{"key":"B","text":"噪声功率除以信号功率"},{"key":"C","text":"信号电压除以噪声电压"},{"key":"D","text":"信号电流除以噪声电流"}]', answer: 'A', score: 1, sort_order: 49, created_at: now, updated_at: now },
{ group: 'gaozhi', question: '纠错编码的主要作用是?', options: '[{"key":"A","text":"降低误码率"},{"key":"B","text":"提高误码率"},{"key":"C","text":"增加传输速率"},{"key":"D","text":"降低带宽占用"}]', answer: 'A', score: 1, sort_order: 50, created_at: now, updated_at: now },
];
await queryInterface.bulkInsert('choice_questions', choiceQuestions, {});
// ==================== 判断题 ====================
// 总分:20题 × 1分 = 20分
const judgeQuestions = [
{ group: 'zhongzhi', question: '调制的目的是将低频信号搬移到高频载波上,以便于天线辐射和信道传输。', answer: 'true', score: 1, sort_order: 1, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: 'GPS接收机只需要接收到3颗卫星的信号即可实现三维定位。', answer: 'false', score: 1, sort_order: 2, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: 'AM调制的抗干扰能力优于FM调制。', answer: 'false', score: 1, sort_order: 3, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '卫星通信中的上行频率通常高于下行频率。', answer: 'true', score: 1, sort_order: 4, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: 'NMEA-0183协议中每条语句都以"$"开头,以校验和结尾。', answer: 'true', score: 1, sort_order: 5, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '北斗卫星导航系统由空间段、地面段、用户段三部分组成。', answer: 'true', score: 1, sort_order: 6, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: 'RTK定位可以达到厘米级精度。', answer: 'true', score: 1, sort_order: 7, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '电离层延迟误差与太阳活动无关。', answer: 'false', score: 1, sort_order: 8, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: '差分定位可以提高定位精度。', answer: 'true', score: 1, sort_order: 9, created_at: now, updated_at: now },
{ group: 'zhongzhi', question: 'GPS卫星本身就是原子钟,提供精确的时间标准。', answer: 'true', score: 1, sort_order: 10, created_at: now, updated_at: now },
{ group: 'gaozhi', question: 'OFDM系统中,循环前缀的长度必须大于信道的最大时延扩展。', answer: 'true', score: 1, sort_order: 11, created_at: now, updated_at: now },
{ group: 'gaozhi', question: '北斗系统只能提供区域导航定位服务,不能提供全球服务。', answer: 'false', score: 1, sort_order: 12, created_at: now, updated_at: now },
{ group: 'gaozhi', question: '边缘计算可以将计算任务从云端下沉到网络边缘,降低时延。', answer: 'true', score: 1, sort_order: 13, created_at: now, updated_at: now },
{ group: 'gaozhi', question: '数字签名技术可以防止通信内容被窃听。', answer: 'false', score: 1, sort_order: 14, created_at: now, updated_at: now },
{ group: 'gaozhi', question: 'Massive MIMO技术通过增加天线数量来提升系统容量。', answer: 'true', score: 1, sort_order: 15, created_at: now, updated_at: now },
{ group: 'gaozhi', question: '香农公式说明信道容量与带宽和信噪比都正相关。', answer: 'true', score: 1, sort_order: 16, created_at: now, updated_at: now },
{ group: 'gaozhi', question: 'LDPC码是一种高性能的信道编码。', answer: 'true', score: 1, sort_order: 17, created_at: now, updated_at: now },
{ group: 'gaozhi', question: 'TCP协议提供面向连接的可靠服务。', answer: 'true', score: 1, sort_order: 18, created_at: now, updated_at: now },
{ group: 'gaozhi', question: 'UDP协议提供流量控制和拥塞控制。', answer: 'false', score: 1, sort_order: 19, created_at: now, updated_at: now },
{ group: 'gaozhi', question: '奈奎斯特第一准则告诉我们理想低通信道的最高码元传输速率等于2B。', answer: 'true', score: 1, sort_order: 20, created_at: now, updated_at: now },
];
await queryInterface.bulkInsert('judge_questions', judgeQuestions, {});
// ==================== 综合性任务 ====================
// 总分:1题 × 30分 = 30分
const wordQuestions = [
{ group: 'zhongzhi', title: '卫星通信系统基本原理', description: '请结合第一篇卫星通信技术,简述卫星通信系统的基本组成,包括空间段、地面段、用户段三大部分,并说明各部分的主要功能。分析GEO/MEO/LEO三种轨道的特点及其适用场景,举例说明典型应用。', score: 30, sort_order: 1, template_path: null, created_at: now, updated_at: now },
{ group: 'gaozhi', title: '卫星导航融合定位方案设计', description: '请结合第二篇卫星导航技术,设计一个GNSS/INS组合导航定位方案。要求:(1) 分析组合导航的必要性;(2) 说明GNSS和INS各自优缺点;(3) 给出卡尔曼滤波融合框架;(4) 分析预期性能改进。', score: 30, sort_order: 1, template_path: null, created_at: now, updated_at: now },
];
await queryInterface.bulkInsert('word_questions', wordQuestions, {});
},
down: async (queryInterface) => {
await queryInterface.bulkDelete('choice_questions', null, {});
await queryInterface.bulkDelete('judge_questions', null, {});
await queryInterface.bulkDelete('word_questions', null, {});
},
};