起步软件技术论坛
搜索
 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 24586|回复: 39

利用BeX5做随机抽取试题的考试系统

  [复制链接]

377

主题

2594

帖子

5117

积分

论坛元老

Rank: 8Rank: 8

积分
5117
QQ
发表于 2014-12-4 19:17:28 | 显示全部楼层 |阅读模式
碰到一个项目,要求用X5做一个能够在题库中随机抽取试题的考试系统
主要要求如下:
1、客户给出题库,题目类型包括公共判断题、公共单选题、公共多选题、区域判断题、区域单选题、区域多选题和区域定向题(每种题型有300道)
2、考生登录系统后,按开始考试按钮,要求从题库中随机抽取不重复的30道公共判断题,10道公共单选题,10道公共多选题;20道区域判断题,10道区域单选题,10道区域多选题和10道区域定向题。
3、考试时间为1个小时,要求在考试过程中不能掉线,页面不能闪烁。
4、要求页面增加计时器,显示剩余时间,剩余5分钟时,给出特殊提示。考试时间到,如果考试没有提交试卷,系统强制提交
5、试卷提交后,立即计算考试成绩病显示出来。同时,锁死各个数据项(不允许考生继续答题)


相关的界面已经做完,并放到了网上:      考试系统地址
用户名:    演示
密码:    123456
进去之后点击:     出租车从业资格证管理/模拟考试/运行


评分

参与人数 3威望 +50 +40 收起 理由
tiger0425 + 10 很给力!
X5联盟帮扶部 + 40 很给力!
make + 40 赞一个!

查看全部评分

长春鱼熊企业管理咨询有限公司



X5开发出入库培训视频
(出处: 起步论坛)

377

主题

2594

帖子

5117

积分

论坛元老

Rank: 8Rank: 8

积分
5117
QQ
 楼主| 发表于 2016-11-14 12:57:01 | 显示全部楼层
470772345 发表于 2016-11-14 10:13
顶一两个`~~~

这你都发现了?
长春鱼熊企业管理咨询有限公司



X5开发出入库培训视频
(出处: 起步论坛)
回复 支持 1 反对 0

使用道具 举报

377

主题

2594

帖子

5117

积分

论坛元老

Rank: 8Rank: 8

积分
5117
QQ
 楼主| 发表于 2014-12-4 19:24:30 | 显示全部楼层
本帖最后由 Masion 于 2014-12-4 20:24 编辑

题库的ontology设置如下:
题库.PNG
长春鱼熊企业管理咨询有限公司



X5开发出入库培训视频
(出处: 起步论坛)
回复 支持 反对

使用道具 举报

377

主题

2594

帖子

5117

积分

论坛元老

Rank: 8Rank: 8

积分
5117
QQ
 楼主| 发表于 2014-12-4 19:29:10 | 显示全部楼层
本帖最后由 Masion 于 2014-12-4 20:33 编辑

考试系统的界面如下:
考试界面.PNG

界面上放了两个普通data组件,一个用于存储 考生姓名,公共科目成绩,区域科目成绩,相当于主表
另一个存放100道试题,相当于从表
长春鱼熊企业管理咨询有限公司



X5开发出入库培训视频
(出处: 起步论坛)
回复 支持 反对

使用道具 举报

377

主题

2594

帖子

5117

积分

论坛元老

Rank: 8Rank: 8

积分
5117
QQ
 楼主| 发表于 2014-12-4 19:32:03 | 显示全部楼层
本帖最后由 Masion 于 2014-12-4 20:34 编辑

考试结束后,提交后的界面如图所示
提交后的考试界面.PNG

提交后,界面显示考生的考试成绩,考试结果
长春鱼熊企业管理咨询有限公司



X5开发出入库培训视频
(出处: 起步论坛)
回复 支持 反对

使用道具 举报

377

主题

2594

帖子

5117

积分

论坛元老

Rank: 8Rank: 8

积分
5117
QQ
 楼主| 发表于 2014-12-4 19:46:50 | 显示全部楼层
本帖最后由 Masion 于 2014-12-4 20:03 编辑

考生按“开始考试”按钮后的js代码如下:
mainActivity.TriggerStartClick = function(event){
   //清空examData里的数据
   var d = justep.xbl("examData");
   var rowIDs = "";
   for ( var i = 0; i < d.getCount(); i++) {
       rowIDs += d.getID(i)+",";        //将所有rowID并到一个字符串中
   }        
   justep.xbl('examData').deleteConfirm = false;    //设置删除数据时不提示
   justep.xbl("examData").deleteData(rowIDs);     //清空上次模拟考试留下来的数据(本界面以模拟考试界面为例,允许考试提交试卷后再次按开始考试按钮反复练习)
   justep.xbl("MainExamData").setValue("fPublicScore", ""); //清空上次考试公共科目成绩
   justep.xbl("MainExamData").setValue("fRegionScore", ""); //清空上次考试区域科目成绩
    //从题库中随机提取试题
   justep.xbl("examData").setReadonly(false);     //打开examdata组件,允许考生答题
   
   justep.Request.sendBizRequest2({
   dataType : "json",
   action : "queryExamList",
   callback: function(result) {
    if(result.state){
  
     justep.xbl("examData").loadJson(result.response); //将查询来的随机试题加载到examData中
     justep.xbl("TriggerStart").setDisabled(true);  //锁死“开始考试”按钮
     justep.xbl("triggerCommit").setDisabled(false);  //打开“提交试卷”按钮
    } else{
    throw new Error ("调用失败|"+result.response.message);
    }
   }
   });
timer = setInterval("CountDown()",1000);        //(在界面中添加一个div组件,id为time),设置每秒钟刷新一次
//为了适应不同题型,做了2个view,其中viewJudge放的是判断题的2个单选按钮,view放的单选题的4个单选按钮,背景上放的是多选题的4个复选框。
$("#viewCheck").hide();            //(现在刚刚点击开始答题,需要显示viewJudge。)隐藏viewCheck
$("#viewJudge").show();            //显示viewJudge,同时挡住了背景上的4个复选框
};




//计时器代码
var maxtime = 60*60 //一个小时,按秒计算,自己调整!  
function CountDown(){  
if(maxtime>=0){  
minutes = Math.floor(maxtime/60);  
seconds = Math.floor(maxtime%60);  
msg = "距离结束还有"+minutes+"分"+seconds+"秒";  
document.all["timer"].innerHTML=msg;

//为了保证在考试过程中不掉线,每隔20分钟,向服务器发一个空的action
  if(maxtime==20*60||maxtime==40*60){
     justep.Request.sendBizRequest2({
      dataType: "json",
      action: "keepOnlineQuery",
      callback: function(result) {
       if (result.state) {
        //alert("保持在线调用成功!");
       } else {
        throw new Error("调用失败!|" + result.response.message);
       }
      }

});
  }
  
  //5分钟又一次对话框提示
if(maxtime == 5*60) alert('注意,还有5分钟!');  
--maxtime;  
}  
else{  
   alert("时间到,结束!");                                      //时间到,强制提交
examFinish();

//清空计时器
document.all["timer"].innerHTML="";                  
clearInterval(timer);   

}  
}  

长春鱼熊企业管理咨询有限公司



X5开发出入库培训视频
(出处: 起步论坛)
回复 支持 反对

使用道具 举报

377

主题

2594

帖子

5117

积分

论坛元老

Rank: 8Rank: 8

积分
5117
QQ
 楼主| 发表于 2014-12-4 19:53:28 | 显示全部楼层
本帖最后由 Masion 于 2014-12-4 20:26 编辑

模型加载事件中需要加载如下代码,做一些初始化
mainActivity.model1Load = function(event){
load_part("viewCheck");                                                 //加载viewCheck视图
load_part("viewJudge");                                                 //加载viewJudge视图
$("#viewCheck").hide();                                                //隐藏viewCheck
$("#viewJudge").show();                                              //显示viewJudge挡住背景图上的4个多选复选框
//隐藏"公共科目成绩",“区域科目考试成绩"和”考试结果“等几个html标签
$("#label3").hide();                                                     
$("#label4").hide();
$("#label2").hide();
$("#label5").hide();
$("#label6").hide();
  $('body').focus();
//在考试过程中,如果考生按enter,则examData移到下一个试题上
          $('body').bind('keydown',function(event){
                  if(event.keyCode==13||event.keyCode==32){
                      justep.xbl("examData").next();
              }
         });
  
};

长春鱼熊企业管理咨询有限公司



X5开发出入库培训视频
(出处: 起步论坛)
回复 支持 反对

使用道具 举报

377

主题

2594

帖子

5117

积分

论坛元老

Rank: 8Rank: 8

积分
5117
QQ
 楼主| 发表于 2014-12-4 19:54:38 | 显示全部楼层
mainActivity.examDataIndexChanging = function(event){
//当学员变更试题时,根据试题的题目显示选择框

if(justep.xbl("examData").getValue("fExamType")=="公共科目多选题"||justep.xbl("examData").getValue("fExamType")=="区域科目多选题"){
        $("#viewCheck").show();
        $("#viewJudge").hide();

}else if(justep.xbl("examData").getValue("fExamType")=="公共科目判断题"||justep.xbl("examData").getValue("fExamType")=="区域科目判断题"){
        $("#viewCheck").hide();
        $("#viewJudge").show();
} else{
        $("#viewCheck").hide();
        $("#viewJudge").hide();
}

};
长春鱼熊企业管理咨询有限公司



X5开发出入库培训视频
(出处: 起步论坛)
回复 支持 反对

使用道具 举报

377

主题

2594

帖子

5117

积分

论坛元老

Rank: 8Rank: 8

积分
5117
QQ
 楼主| 发表于 2014-12-4 19:58:11 | 显示全部楼层
在后台使用java写随机生成考试题的action
public static Table queryExamList(){
  //在题库中随机抽取30道公共判断题,10道公共单选题,10到公共多选题,20道区域判断题,10道区域单选题,10道区域单选题,10道定向题组成试卷(带题目序号)
  //这条语句用于MYSQL
  StringBuffer sbSql = new StringBuffer();
  sbSql.append("SELECT @rownum:=@rownum+1 AS fRowNo, a.* from (");
        sbSql.append("(SELECT * FROM MY_ExamBasic where fExamType='公共科目判断题' ORDER BY RAND() LIMIT 30) ");
        sbSql.append("union (SELECT * FROM MY_ExamBasic where fExamType='公共科目单选题' ORDER BY RAND() LIMIT 10)");
        sbSql.append("union (SELECT * FROM MY_ExamBasic where fExamType='公共科目多选题' ORDER BY RAND() LIMIT 10) ");
   
        sbSql.append("union (SELECT * FROM MY_ExamBasic where fExamType='区域科目判断题' ORDER BY RAND() LIMIT 20) ");
        sbSql.append("union (SELECT * FROM MY_ExamBasic where fExamType='区域科目单选题' ORDER BY RAND() LIMIT 10)");
        sbSql.append("union (SELECT * FROM MY_ExamBasic where fExamType='区域科目多选题' ORDER BY RAND() LIMIT 10) ");
        sbSql.append("union (SELECT * FROM MY_ExamBasic where fExamType='区域科目定向题' ORDER BY RAND() LIMIT 10) ");
        sbSql.append(") a,(select @rownum :=0) b ");
        //这条语句用于SQLSERVER
        StringBuffer sbSql1 = new StringBuffer();
  //sbSql1.append("SELECT fRowNo=row_number(), a.* from (");
        sbSql1.append("select row_number() over (order by fExamType) as fRowNo ,* from (select top 30 * from MY_ExamBasic  where fExamType='公共科目判断题' order by NewID()) a ");
        sbSql1.append(" union all select row_number() over (order by fExamType) as fRowNo ,* from (select top 10 * from MY_ExamBasic  where fExamType='公共科目单选题' order by NewID()) b ");
        sbSql1.append("union all select row_number() over (order by fExamType) as fRowNo ,* from (select top 10 * from MY_ExamBasic  where fExamType='公共科目多选题' order by NewID()) c ");
        sbSql1.append("union all select row_number() over (order by fExamType) as fRowNo ,* from (select top 20 * from MY_ExamBasic  where fExamType='区域科目判断题' order by NewID()) c ");
        sbSql1.append("union all select row_number() over (order by fExamType) as fRowNo ,* from (select top 10 * from MY_ExamBasic  where fExamType='区域科目单选题' order by NewID()) c ");
        sbSql1.append("union all select row_number() over (order by fExamType) as fRowNo ,* from (select top 10 * from MY_ExamBasic  where fExamType='区域科目多选题' order by NewID()) c ");
        sbSql1.append("union all select row_number() over (order by fExamType) as fRowNo ,* from (select top 10 * from MY_ExamBasic  where fExamType='区域科目定向题' order by NewID()) d ");
      

        HashMap<String, String> sqlMap = new HashMap<String, String>();
  
  sqlMap.put(SQL.DEFAULT_DB_NAME, sbSql1.toString());
  sqlMap.put(DatabaseProduct.MSSQL.name(), sbSql1.toString());
  sqlMap.put(DatabaseProduct.SYBASE.name(), sbSql1.toString());
  Table table = SQL.select(sqlMap, null, "/MyProject/TaxiManage/data");
  table.getProperties().put(Table.PROP_NAME_ROWID, "fID");
  return table;
}

长春鱼熊企业管理咨询有限公司



X5开发出入库培训视频
(出处: 起步论坛)
回复 支持 反对

使用道具 举报

377

主题

2594

帖子

5117

积分

论坛元老

Rank: 8Rank: 8

积分
5117
QQ
 楼主| 发表于 2014-12-4 20:22:36 | 显示全部楼层
考生按”提交“按钮后的js代码:
mainActivity.triggerCommitClick = function(event){
//学员提交试卷后系统进行的操作。

//检查是否答题完毕
var examData=justep.xbl("examData");
var strFinish="填写完毕";
for(var i=0; i<examData.getCount();i++){
var id=examData.getID(i);
if (examData.getValue("fChecked",id)==""){
  strFinish="未结束";
  
}
};
if (strFinish!=="填写完毕"){                                 //如果检查到有试题没有完成,给出对话框提示
  justep.xbl("messageDialog1").open({
  callback: function(e){
   if (e.status!=="yes"){
    return;                                                            //如果考生选择继续答题,则返回考试界面
   }else{
    examFinish();                                                    //如果考生选择继续提交,则执行提交过程
   };
   }
  });
  
}else{                                                                //如果所有试题都完成了
document.all["timer"].innerHTML="";                    //清空计时器
clearInterval(timer);
examFinish();                                                        //提交试卷
}
};

//提交考试
var examFinish=function(){                             

var tempPublic=0;                                                           //公共科目成绩
var tempRegion=0;                                                          //区域科目成绩
var examData=justep.xbl("examData");
justep.xbl("TriggerStart").setDisabled(false);                     //打开“开始考试”按钮(因为是模拟考试界面,允许考生反复练习)
justep.xbl("triggerCommit").setDisabled(true);                     //锁死提交按钮,不允许反复提交
examData.setReadonly(true);                                                //锁死数据组件,不允许考生继续答题

//显示“公共科目成绩”、“区域科目成绩”和“考试结果”等html标签
$('#label3').css('display','block');
$('#label4').css('display','block');
$('#label2').css('display','block');
$('#label5').css('display','block');
$('#label6').css('display','block');

//统计成绩
for(var i=0;i<examData.getCount();i++){
  var id=examData.getID(i);
  if (examData.getValue("fChecked",id)==examData.getValue("fCorrectAnswer",id)){        //判断考生的选择是否与标准答案一致
   examData.setValue("fResult","正确",id);                                                                     //如果答对了,在考试结果中填写"正确"
   if(examData.getValue("fExamType",id).indexOf("公共科目")>=0){                     //根据考题类型,分别给公共科目成绩和区域科目成绩计分
    tempPublic=tempPublic+2;                                                                                     //每题2分
   }else{
    tempRegion=tempRegion+2;
  }
   
  }else{
   examData.setValue("fResult","错误",id);                                               //如果答错了,在考试结果中填写"错误"
  };
}
justep.xbl("MainExamData").setValue("fPublicScore", tempPublic);                                //显示公共科目成绩
justep.xbl("MainExamData").setValue("fRegionScore", tempRegion);                             //显示区域科目成绩
};
长春鱼熊企业管理咨询有限公司



X5开发出入库培训视频
(出处: 起步论坛)
回复 支持 反对

使用道具 举报

377

主题

2594

帖子

5117

积分

论坛元老

Rank: 8Rank: 8

积分
5117
QQ
 楼主| 发表于 2015-1-6 11:51:14 | 显示全部楼层
当然,这个考试系统只是初级阶段,能够实现考试功能
再严格一点的算法应该是考试提交后,将考生的回答传回后台去,在后台判卷,将考试成绩传回来(不让正确答案到前台来)
长春鱼熊企业管理咨询有限公司



X5开发出入库培训视频
(出处: 起步论坛)
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|X3技术论坛|Justep Inc.    

GMT+8, 2024-11-22 03:27 , Processed in 0.166780 second(s), 28 queries .

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表