数据库表设计
- 题库Library:用来放置试题
var librarySchema = new Schema({
number: Number,
content: String
});
- 试题库:用来放学生抽到的试题
var testSchema = new Schema({
uid:{
type: Schema.Types.ObjectId,
ref: 'student'//关联student表
},
qId: {
type: Schema.Types.ObjectId,
ref: 'Library'
},
qContent: String,
answer: String,
score: String
});
学生端
- 考生一共有四个状态:"UNLOGIN":表示考生未登录;"LOGIN":表示考生已登录;"TEST":表示考生已开始答卷;"SUBMIT":表示考生已交卷。
- 考试开始之后,考生点击开始考试按钮,改变学生的状态为"TEST",同时通知服务器进行分题,
socket.emit("allocate",usrId);
- 系统从题库中抽题并分配给该考生,同时保证题目没有重复的。因为考生中途掉线之后再登录的话可能会出现重复分题的情况,所以要先判断有没有给改考生分配过题,分配过的话就不重复再分。
//考生题目分配,分配完之后通知学生端显示题目,同时通知教师端
socket.on("allocate",function (usrId) {
dbHelper.allocate(usrId,function(success,doc) {
console.log("allocate success")
});
socket.emit("show question",usrId);
sockets[teacher].emit("check student");
});
exports.allocate = function(data,cb) {
//先判断是不是已经分过题了,如果分过了就不用再分题了。
Test.find({uid: data}).exec(function(err,docs){
if(docs.length==0){
var array=JSON.parse(JSON.stringify(questions));
var num=new Array;
//避免考生抽到重复的题
for (var i=0;i<array.length;i++){
num[i]=i+1;
}
num.sort(function(){ return 0.5 - Math.random();});
for (var i = 0; i < 3; i++) {
Library.findOne({number: num[i]})
.exec(function (err, doc) {
var test = new Test({
uid: data,
qId: doc._id,
qContent: doc.content
});
test.save(function (err, test) {
if (err) {
entries.code = 500;
} else {
entries.code = 0;
}
});
});
}
cb(true,entries);
} else{
cb(false, entries);
}
});
}
- 考生开始答题,考生点击保存按钮,可以保存答案,同时会自动每隔一分钟保存答案。
function doSave() {
var val=$('#v'+testId+' textarea').val();
$.ajax({
type: "POST",
url: "/saveAnswer",
contentType: "application/json",
data: JSON.stringify({
'testId': testId,
'answer': '<pre>'+val+'</pre>'
}),
success: function (data) {
console.log("save success");
setTimeout(doSave,60*1000);
}
});
}
- 考生点击提交按钮,会通知服务器
socket.emit("student submit",usrId);
- 服务器收到信号,先改变学生的状态,然后通知老师。
socket.on('student submit',function (usrId) {
var status="SUBMIT";
var data = {
usrId: usrId,
status: status
}
console.log(teacher);
dbHelper.changeStatus(data,function(success,doc) {
console.log("状态改为提交");
});
sockets[teacher].emit("check student");//通知老师
});
- 考试的时间到了之后,考生停止答题。
教师端
- 教师登录之后,能直接看到考生的状态,灰色代表考生未登录,红色代表考生已登录,蓝色代表考生已经开始答题,绿色代表考生已经提交试卷
socket.on("check student",function () {
initStudentList();
});
function initStudentList(){
$.ajax({
type: "POST",
url: "/getStudentList",
contentType: "application/json",
data: JSON.stringify({
'teaId': teaId
}),
success: function (data) {
$(".tea_wrapper .content").html("");
for(var i=0;i<data.length;i++){
$(".tea_wrapper .content").append(
' <div class="studentStatus" id="student'+data[i]._id+'v">'
* '<span>' + data[i].stuName + '</span>'
* '<span>' + data[i].stuId + '</span>'
* '</div>');
if(data[i].status=="LOGIN"){
$("#student"+data[i]._id+'v').css("background","#FF6766")
} else if(data[i].status=="TEST"){
$("#student"+data[i]._id+'v').css("background","#2376ae")
} else if(data[i].status=="SUBMIT"){
$("#student"+data[i]._id+'v').css("background","#007722")
} else{
$("#student"+data[i]._id+'v').css("background","#dddddd")
}
}
setTimeout(initStudentList,1000);
}
});
}
-
同时老师能够点击已经提交试卷的考生进行批改试卷,会显示该考生的试题以及答案信息。
老师改完题目之后,可以点击保存,保存成绩,然后后台去改学生的成绩
function doSaveScore() {
var sum=0;
for(var i=0;i<grade.length;i++){
var val=$('#g'+grade[i]+'a').val();
console.log(val);
sum=sum+parseInt(val);
socket.emit('change score',sid,grade[i],val);
}
socket.emit('change student grade',sid,sum);
$('.alert').show();
}
//改每一题的成绩
socket.on('change score',function (sid,tid,value) {
var data={
uid: sid,
_id: tid,
score: value
}
dbHelper.setScore(data,function (success,doc) {
console.log("save score success");
})
})
//改学生的总成绩
socket.on('change student grade',function(sid,sum){
var data={
_id: sid,
grade: sum
}
dbHelper.changeStudentGrade(data,function (success,doc) {
console.log("save score success");
})
});
-
同时老师可以添加考生
题库可以以json文件的格式进行导入
var questions = require('../db/json');
exports.allQuestions=function (cb) {
var array=JSON.parse(JSON.stringify(questions));
for(var i=0;i<array.length;i++){
var question=new Library({
number: array[i].num,
content: array[i].content
});
question.save(function (err,doc) {
if(err){
entries.code=500;
cb(false, entries);
} else{
entries.code=0;
cb(true, entries);
}
});
}
}
参考网址: