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:
207
database/006-seed-50-20-30.sql
Normal file
207
database/006-seed-50-20-30.sql
Normal 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
71
database/config.json
Normal 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"
|
||||
}
|
||||
}
|
||||
125
database/migrations/001-create-accounts.js
Normal file
125
database/migrations/001-create-accounts.js
Normal 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');
|
||||
},
|
||||
};
|
||||
105
database/migrations/001-create-contestants.js
Normal file
105
database/migrations/001-create-contestants.js
Normal 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');
|
||||
},
|
||||
};
|
||||
61
database/migrations/002-create-admins.js
Normal file
61
database/migrations/002-create-admins.js
Normal 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');
|
||||
},
|
||||
};
|
||||
56
database/migrations/002-create-teams.js
Normal file
56
database/migrations/002-create-teams.js
Normal 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');
|
||||
},
|
||||
};
|
||||
42
database/migrations/003-create-competition-info.js
Normal file
42
database/migrations/003-create-competition-info.js
Normal 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');
|
||||
},
|
||||
};
|
||||
94
database/migrations/004-create-aggregation.js
Normal file
94
database/migrations/004-create-aggregation.js
Normal 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');
|
||||
},
|
||||
};
|
||||
69
database/migrations/004-create-exam-questions.js
Normal file
69
database/migrations/004-create-exam-questions.js
Normal 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');
|
||||
},
|
||||
};
|
||||
67
database/migrations/005-create-exam-submissions.js
Normal file
67
database/migrations/005-create-exam-submissions.js
Normal 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');
|
||||
},
|
||||
};
|
||||
68
database/migrations/005-create-news.js
Normal file
68
database/migrations/005-create-news.js
Normal 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');
|
||||
},
|
||||
};
|
||||
58
database/migrations/006-create-carousel.js
Normal file
58
database/migrations/006-create-carousel.js
Normal 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');
|
||||
},
|
||||
};
|
||||
85
database/migrations/006-create-work-submissions.js
Normal file
85
database/migrations/006-create-work-submissions.js
Normal 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');
|
||||
},
|
||||
};
|
||||
69
database/migrations/007-create-zhongzhi-questions.js
Normal file
69
database/migrations/007-create-zhongzhi-questions.js
Normal 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');
|
||||
},
|
||||
};
|
||||
69
database/migrations/008-create-gaozhi-questions.js
Normal file
69
database/migrations/008-create-gaozhi-questions.js
Normal 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');
|
||||
},
|
||||
};
|
||||
82
database/migrations/009-create-zhongzhi-submissions.js
Normal file
82
database/migrations/009-create-zhongzhi-submissions.js
Normal 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');
|
||||
},
|
||||
};
|
||||
82
database/migrations/010-create-gaozhi-submissions.js
Normal file
82
database/migrations/010-create-gaozhi-submissions.js
Normal 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');
|
||||
},
|
||||
};
|
||||
77
database/migrations/011-create-benke-submissions.js
Normal file
77
database/migrations/011-create-benke-submissions.js
Normal 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');
|
||||
},
|
||||
};
|
||||
77
database/migrations/012-create-jiaoshi-submissions.js
Normal file
77
database/migrations/012-create-jiaoshi-submissions.js
Normal 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');
|
||||
},
|
||||
};
|
||||
57
database/migrations/013-create-competition-times.js
Normal file
57
database/migrations/013-create-competition-times.js
Normal 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');
|
||||
},
|
||||
};
|
||||
42
database/migrations/014-create-system-configs.js
Normal file
42
database/migrations/014-create-system-configs.js
Normal 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');
|
||||
},
|
||||
};
|
||||
68
database/migrations/015-create-choice-questions.js
Normal file
68
database/migrations/015-create-choice-questions.js
Normal 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');
|
||||
},
|
||||
};
|
||||
63
database/migrations/016-create-judge-questions.js
Normal file
63
database/migrations/016-create-judge-questions.js
Normal 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');
|
||||
},
|
||||
};
|
||||
68
database/migrations/017-create-word-questions.js
Normal file
68
database/migrations/017-create-word-questions.js
Normal 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');
|
||||
},
|
||||
};
|
||||
23
database/migrations/018-add-test-flag-to-contestants.js
Normal file
23
database/migrations/018-add-test-flag-to-contestants.js
Normal 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');
|
||||
},
|
||||
};
|
||||
17
database/migrations/019-add-title-to-carousel.js
Normal file
17
database/migrations/019-add-title-to-carousel.js
Normal 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');
|
||||
},
|
||||
};
|
||||
40
database/migrations/020-add-question-type-to-submissions.js
Normal file
40
database/migrations/020-add-question-type-to-submissions.js
Normal 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');
|
||||
},
|
||||
};
|
||||
99
database/migrations/021-unique-submission-indexes.js
Normal file
99
database/migrations/021-unique-submission-indexes.js
Normal 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'],
|
||||
});
|
||||
},
|
||||
};
|
||||
56
database/migrations/022-add-content-button-to-carousel.js
Normal file
56
database/migrations/022-add-content-button-to-carousel.js
Normal 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 地址',
|
||||
});
|
||||
},
|
||||
};
|
||||
21
database/seeders/001-seed-competition-info.js
Normal file
21
database/seeders/001-seed-competition-info.js
Normal 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',
|
||||
}, {});
|
||||
},
|
||||
};
|
||||
50
database/seeders/001-seed-contestants.js
Normal file
50
database/seeders/001-seed-contestants.js
Normal 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, {});
|
||||
},
|
||||
};
|
||||
36
database/seeders/002-seed-admin.js
Normal file
36
database/seeders/002-seed-admin.js
Normal 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',
|
||||
}, {});
|
||||
},
|
||||
};
|
||||
36
database/seeders/003-seed-carousel.js
Normal file
36
database/seeders/003-seed-carousel.js
Normal 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, {});
|
||||
},
|
||||
};
|
||||
85
database/seeders/003-seed-news.js
Normal file
85
database/seeders/003-seed-news.js
Normal 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, {});
|
||||
},
|
||||
};
|
||||
23
database/seeders/004-seed-exam-questions.js
Normal file
23
database/seeders/004-seed-exam-questions.js
Normal 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, {});
|
||||
},
|
||||
};
|
||||
61
database/seeders/005-seed-competition-times.js
Normal file
61
database/seeders/005-seed-competition-times.js
Normal 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, {});
|
||||
},
|
||||
};
|
||||
176
database/seeders/006-seed-choice-judge-word-questions.js
Normal file
176
database/seeders/006-seed-choice-judge-word-questions.js
Normal 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, {});
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user