Это третий день моего участия в Gengwen Challenge.Подробности о мероприятии, пожалуйста, проверьте:Обновить вызов
1. Фон дизайна
В последнее время некоторые пользователи выдвинули требование реализовать набор модулей видеообучения и модулей онлайн-экзаменов на исходном веб-сайте.Здесь я сначала представлю идеи дизайна следующих модулей онлайн-экзаменов.
Для реализации системы онлайн-экзаменов с базовыми функциями необходимы следующие элементы:
1. Управление банком вопросов [Возможно, потребуется разработать разные банки вопросов для разных экзаменов, таких как первый экзамен по вождению, квалификационный аттестат по дорожному транспорту]
2. Управление главами [соответствует главам учебных материалов по экзамену]
3. Управление экзаменационными вопросами [все экзаменационные вопросы включены в банк вопросов]
4. Варианты вопросов экзамена [варианты для каждого вопроса]
5. Точный ответ [точный ответ на каждый вопрос]
6. Управление экзаменами [опубликуйте последнюю ссылку на экзамен на веб-сайте, пользователи могут пройти экзамен по ссылке]
7. Проверьте результаты экзамена [После завершения экзамена проверьте результаты экзамена и неправильные вопросы в режиме реального времени] После того, как вышеперечисленные функции реализованы, это в основном относительно полная система обследования.Затем мы разрабатываем структуру таблицы для этих функциональных точек.
2. Дизайн структуры таблицы
В соответствии с содержанием вышеуказанного уточнения мы сначала проектируем следующую базу данных, которая напрямую отображается здесь, а аннотации написаны очень четко.
3. Процесс реализации некоторых функций и ключевых фрагментов кода
Код написан в каше, а мелкие функции не особо, посмотрим.
Введение в архитектурную среду: все разработано на основе jfinal_cms, структура mvc основана на jfinal, механизм шаблонов — beetl, а стойка регистрации — традиционный бутстрап и jquery.
3.1 Управление банком вопросов
Здесь проще, никакой логики
3.2 Управление темами
Ниже приведен код установки правильных вариантов, здесь отдельно добавлена логика обработки вопросов с несколькими вариантами ответов, идентификаторы правильных вариантов разделяются запятыми и сохраняются.
private void set_right(TbExamAnswer model,TbExamQuestions questionsModel) {
if(questionsModel.getQuestionsType()!=111) {//单选和判断题准确答案设置
questionsModel.setRightAnswerId(model.getId().toString());
questionsModel.setRightAnswerTitle(model.getAnswerTitle());
}else {
List<TbExamAnswer> answerList=TbExamAnswer.dao.findByWhere(" where questions_id=? and answer_right=1 order by id asc",questionsModel.getId());
StringBuffer right_ids=new StringBuffer("");
StringBuffer right_title=new StringBuffer("");
for(int i=0;i<answerList.size();i++) {
TbExamAnswer answer=answerList.get(i);
right_ids.append(answer.getId().toString());
right_title.append(answer.getAnswerTitle());
if(i<answerList.size()-1) {
right_ids.append(",");
right_title.append(",");
}
}
questionsModel.setRightAnswerId(right_ids.toString());
questionsModel.setRightAnswerTitle(right_title.toString());
}
questionsModel.update();
}
3.3 Выпуск экзамена
Вот главная страница после выпуска экзамена, пользователи могут войти на страницу экзамена по этой ссылке
Операция тестовой публикации должна установить поле общего количества основных информационных вопросов, чтобы контролировать количество вопросов, которые должны быть отображены в бланке ответов каждого пользователя.Количество вопросов, которые должны быть составлены для каждой главы, должно быть установлено в правилах.
public void index() {
// 数据列表
SysUser user = (SysUser) getSessionUser();
if (user == null) {
redirect(CommonController.firstPage);
return;
}
int examPublishId = getParaToInt();
TbExamPublish examPublish=TbExamPublish.dao.findById(examPublishId);
TbExamPaper paper=new TbExamPaper();
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Calendar nowTime=Calendar.getInstance();
if(examPublish.getExamTimeLength()==null) {
nowTime.add(Calendar.MINUTE, 60);
}else {
nowTime.add(Calendar.MINUTE, examPublish.getExamTimeLength());
}
paper.setUserId(user.getUserid());//用户id
paper.setUserName(user.getUserName());//用户名称
paper.setExamPublishId(examPublish.getId());//考试发布id
paper.setExamName(examPublish.getExamName());
paper.setExamCode(examPublish.getExamCode());//考试编号
paper.setExamStatus(1);//考试中
paper.setExamStartDate(sdf.format(new Date()));
paper.setExamEndDate(sdf.format(nowTime.getTime()));
paper.save();
List<TbExamPublishRule> ruleList =TbExamPublishRule.dao.findByWhere(" where exam_publish_id="+examPublish.getId());
String questionWhere="tb_exam_questions where tk_id=? and chapter_id=? and questions_type=? ORDER BY RAND() LIMIT ?";
for(int i=0;i<ruleList.size();i++) {
TbExamPublishRule rule=ruleList.get(i);
List<TbExamQuestions> singleChoiceQuestions=TbExamQuestions.dao.findByWhere(questionWhere, rule.getExamTkId(),rule.getExamChapterId(),109,rule.getSingleChoiceCount());//抽取单选题
List<TbExamQuestions> multipleChoiceQuestions=TbExamQuestions.dao.findByWhere(questionWhere, rule.getExamTkId(),rule.getExamChapterId(),111,rule.getMultipleChoiceCount());//抽取多选题
List<TbExamQuestions> judgeQuestions=TbExamQuestions.dao.findByWhere(questionWhere, rule.getExamTkId(),rule.getExamChapterId(),110,rule.getJudgeCount());//抽取判断题
singleChoiceQuestions.addAll(multipleChoiceQuestions);//合并单选和多选list
for(TbExamQuestions q:singleChoiceQuestions) {
TbExamPaperQuestions paperQuestion=new TbExamPaperQuestions();
paperQuestion.setPaperId(paper.getId());//试卷id
paperQuestion.setQuestionsId(q.getId());//题目id
paperQuestion.setQuestionsTitle(q.getQuestionsTitle());//题目
paperQuestion.setQuestionsType(q.getQuestionsType());//题目类型
paperQuestion.setRightAnswerId(q.getRightAnswerId());//准确选项id
paperQuestion.setRightAnswerTitle(q.getRightAnswerTitle());//准确选项标题
paperQuestion.save();
List<TbExamAnswer> answers=TbExamAnswer.dao.findByWhere(" where questions_id=? order by id asc", q.getId());//查询选项列表
for(TbExamAnswer a:answers) {
TbExamPaperAnswer paperAnswer=new TbExamPaperAnswer();
paperAnswer.setPaperId(paper.getId());//试卷id
paperAnswer.setQuestionsId(q.getId());//题目id
paperAnswer.setAnswerId(a.getId().toString());//选项id
paperAnswer.setAnswerTitle(a.getAnswerTitle());//选项标题
paperAnswer.setAnswerContent(a.getAnswerContent());//选项内容
paperAnswer.setAnswerRight(a.getAnswerRight()==null?null:a.getAnswerRight().toString());//是否正确答案
paperAnswer.save();
}
}
for(TbExamQuestions q:judgeQuestions) {
TbExamPaperQuestions paperQuestion=new TbExamPaperQuestions();
paperQuestion.setPaperId(paper.getId());//试卷id
paperQuestion.setQuestionsId(q.getId());//题目id
paperQuestion.setQuestionsTitle(q.getQuestionsTitle());//题目
paperQuestion.setQuestionsType(q.getQuestionsType());//题目类型
paperQuestion.setRightAnswerId(q.getRightAnswerId());//准确选项id
paperQuestion.setRightAnswerTitle(q.getRightAnswerTitle());//准确选项标题
paperQuestion.save();
}
//BeanUtils.copyProperties(q,choiceQuestions.get(0));
//log.info(rule.getExamChapterName()+ " 选择题--"+choiceQuestions.size()+"判断题--"+judgeQuestions.size());
}
redirect("/front/onlineExam/toExam/"+paper.getId());
return;
}
public void toExam() {
log.info("开始考试啦");
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
SimpleDateFormat sdf1=new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
int paperId = getParaToInt();
TbExamPaper paper=TbExamPaper.dao.findById(paperId);//试卷实体
List<TbExamPaperQuestions> questionsList=TbExamPaperQuestions.dao.findByWhere(" where paper_id=? order by questions_type desc", paperId);//查询题目列表
Map<Integer,List<TbExamPaperAnswer>> answerMap=new HashMap<Integer,List<TbExamPaperAnswer>>();//试题选项map
for(TbExamPaperQuestions q:questionsList) {
List<TbExamPaperAnswer> answers=TbExamPaperAnswer.dao.findByWhere(" where paper_id=? and questions_id=?", paperId,q.getQuestionsId());
answerMap.put(q.getQuestionsId(), answers);
}
//try {
Date d=paper.getExamEndDate();
setAttr("examEndDate",sdf1.format(d));
setAttr("paper",paper);
setAttr("questionsList",questionsList);
setAttr("answerMap",answerMap);
renderAuto(path + "exam_page.html");
}
以下是考试页面,实现方式主要是遍历所以试题,根据题目类型渲染不同的dom标签。
这个js方法主要是为了在答题过程中,实时保存答题数据,防止页面刷新时丢失数据
function commitAnswer(paperId,questionsId,questionsType,answerId,domName){
if(questionsType==111){
var selAnswerId="";
$("input:checkbox[name='"+domName+"']:checked").each(function(index) { // 遍历name=test的多选框
size=$("input:checkbox[name='"+domName+"']:checked").length;
if(index==size-1){
selAnswerId+=$(this).val(); // 每一个被选中项的值
}else{
selAnswerId+=$(this).val()+","; // 每一个被选中项的值
}
});
answerId=selAnswerId;
}
var url = '${BASE_PATH }front/onlineExam/saveAnswer';
$.ajax({
type:'POST',
dataType:'json',
data:{
"paperId":paperId,
"questionsId":questionsId,
"questionsType":questionsType,
"answerId":answerId
},
url:url,
success:function(data){
//$("#chapter_id").empty();
//for(var i=0;i<data.length;i++){
// var item=data[i];
// $("#chapter_id").append("<option value='"+item.id+"'>"+item.chapterName+"</option>");
//}
},
error:function(html){
}
});
}
Этот код является методом подсчета баллов после подтверждения отправки.Логика очень проста, просто сравнивая варианты ответов и точные варианты ответов.
public void commitPaper() {
int paperId = getParaToInt();
int score=0;
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
TbExamPaper paper=TbExamPaper.dao.findById(paperId);//试卷实体
List<TbExamPaperQuestions> list=TbExamPaperQuestions.dao.findByWhere(" where paper_id=?",paperId);
for(int i=0;i<list.size();i++) {
TbExamPaperQuestions q=list.get(i);
if(q.getRightAnswerId()==null)continue;
if(q.getRightAnswerId().equals(q.getUserAnswerId()))score++;
}
int examTimeLength=getBetweenMinutes(paper.getExamStartDate(),new Date());
paper.setExamScore(score);
paper.setExamTimeLength(examTimeLength);
paper.setExamEndDate(sdf.format(new Date()));
paper.setExamStatus(-1);//置为交卷状态
paper.update();
log.info("总分数"+score);
redirect("/front/onlineExam/viewPaperResult/"+paper.getId());
}
Вот страница результатов теста, на которой могут отображаться правильные и неправильные вопросы.
Это страница, на которой администратор может просмотреть список экзаменов, что может улучшить условия фильтрации или другие персонализированные функции.Здесь реализована только функция запроса.
На данный момент полный набор системы онлайн-экзаменов в основном завершен, но есть много проблем с точки зрения дизайнерских идей и реализации кода.Я дам здесь несколько предложений.Если у вас есть идеи получше, вы также можете сообщить об этом в комментариях. .