判断章节练习是否重发试卷

beetlsql3-dev
Mlxa0324 2 years ago
parent 7f6155fba7
commit 64594551fa

@ -28750,7 +28750,7 @@ create table teacher_open_course_question_setting
teacher_open_course_question_setting_name varchar(100) comment '开课题目-名称',
teacher_open_course_question_start_time datetime comment '题目开始时间',
teacher_open_course_question_end_time datetime comment '题目结束时间',
teacher_open_course_question_setting_type varchar(100) comment '类型 枚举(TeacherOpenCourseQuestionSettingTypeEnum',
teacher_open_course_question_setting_type varchar(100) comment '类型 枚举(ResourcesQuestionSnapshotFromTypeEnum',
teacher_open_course_question_setting_file varchar(1000) comment '附件,老师上传附件(单文件)',
teacher_open_course_question_setting_push_status int comment '发布状态。 1发布2未发布',
teacher_open_course_question_setting_status int comment '状态 1正常 2删除',

@ -3,6 +3,8 @@ package com.ibeetl.jlw.dao;
import com.ibeetl.jlw.entity.GeneralQuestionLog;
import com.ibeetl.jlw.entity.GeneralQuestionLogScoreDetailsInfo;
import com.ibeetl.jlw.entity.TeacherOpenCourseQuestionLog;
import com.ibeetl.jlw.enums.QuestionLogAddTypeEnum;
import com.ibeetl.jlw.enums.ResourcesQuestionSnapshotFromTypeEnum;
import com.ibeetl.jlw.web.query.GeneralQuestionLogQuery;
import org.beetl.sql.core.engine.PageQuery;
import org.beetl.sql.mapper.BaseMapper;
@ -66,5 +68,16 @@ public interface GeneralQuestionLogDao extends BaseMapper<GeneralQuestionLog> {
* @return
*/
boolean validateQuestionLogAddTimeLatest(Long questionSettingId, String questionSnapshotIds, Long studentId, Date addTime);
/**
*
* @param questionSettingId ID
* @param studentId ID
* @param questionSettingType
* @param questionLogAddType
* @return boolean
*/
boolean verifyLogAddTypeIsReSend(Long questionSettingId, Long studentId, ResourcesQuestionSnapshotFromTypeEnum questionSettingType, QuestionLogAddTypeEnum questionLogAddType);
}

@ -2,6 +2,8 @@ package com.ibeetl.jlw.dao;
import com.ibeetl.jlw.entity.TeacherOpenCourseQuestionLog;
import com.ibeetl.jlw.entity.TeacherOpenCourseQuestionLogScoreDetailsInfo;
import com.ibeetl.jlw.enums.QuestionLogAddTypeEnum;
import com.ibeetl.jlw.enums.ResourcesQuestionSnapshotFromTypeEnum;
import com.ibeetl.jlw.web.query.TeacherOpenCourseQuestionLogQuery;
import org.beetl.sql.core.engine.PageQuery;
import org.beetl.sql.mapper.BaseMapper;
@ -71,4 +73,14 @@ public interface TeacherOpenCourseQuestionLogDao extends BaseMapper<TeacherOpenC
* @return
*/
boolean validateQuestionLogAddTimeLatest(Long questionSettingId, String questionSnapshotIds, Long studentId, Date addTime);
/**
*
* @param questionSettingId ID
* @param studentId ID
* @param questionSettingType
* @param questionLogAddType
* @return boolean
*/
boolean verifyLogAddTypeIsReSend(Long questionSettingId, Long studentId, ResourcesQuestionSnapshotFromTypeEnum questionSettingType, QuestionLogAddTypeEnum questionLogAddType);
}

@ -79,7 +79,7 @@ public class TeacherOpenCourseQuestionSetting extends BaseEntity {
private Date teacherOpenCourseQuestionEndTime ;
//类型 枚举(TeacherOpenCourseQuestionSettingTypeEnum
//类型 枚举(ResourcesQuestionSnapshotFromTypeEnum
@DictEnum
private ResourcesQuestionSnapshotFromTypeEnum teacherOpenCourseQuestionSettingType ;

@ -14,7 +14,7 @@ import org.beetl.sql.annotation.entity.EnumMapping;
@EnumMapping("name")
public enum QuestionLogAddTypeEnum {
FINALLY_SUBMIT("最终提交"),
FINALLY_SUBMIT("最终提交(交卷)"),
PRE_SUBMIT("预提交");
private String text;

@ -5,6 +5,7 @@ import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReUtil;
import cn.jlw.util.ToolUtils;
import com.alibaba.fastjson.JSON;
@ -20,6 +21,7 @@ import com.ibeetl.jlw.dao.StudentDao;
import com.ibeetl.jlw.entity.*;
import com.ibeetl.jlw.entity.dto.QuestionLogAddDTO;
import com.ibeetl.jlw.enums.QuestionLogAddTypeEnum;
import com.ibeetl.jlw.enums.ResourcesQuestionSnapshotFromTypeEnum;
import com.ibeetl.jlw.web.query.GeneralQuestionLogQuery;
import com.ibeetl.jlw.web.query.GeneralQuestionSettingQuery;
import org.apache.commons.lang3.StringUtils;
@ -51,6 +53,8 @@ import static cn.hutool.core.util.ArrayUtil.join;
import static cn.jlw.util.CacheUserUtil.getStudent;
import static com.ibeetl.admin.core.util.ExcelUtil.getCellFormatValue;
import static com.ibeetl.jlw.enums.QuestionLogAddTypeEnum.PRE_SUBMIT;
import static com.ibeetl.jlw.enums.ResourcesQuestionSnapshotFromTypeEnum.CHAPTER_EXERCISE;
import static com.ibeetl.jlw.enums.ResourcesQuestionSnapshotFromTypeEnum.EXAM;
import static java.util.stream.Collectors.groupingBy;
/**
@ -622,16 +626,32 @@ public class GeneralQuestionLogService extends CoreBaseService<GeneralQuestionLo
return;
}
// 不是强制发题,则不覆盖现有的题目日志,则继续做题
// 验证题目日志,是否已经存在试卷
if(!isReSend) {
GeneralQuestionLogQuery questionLogQuery = new GeneralQuestionLogQuery();
questionLogQuery.setStudentId(studentId);
questionLogQuery.setGeneralQuestionSettingId(setting.getGeneralQuestionSettingId());
questionLogQuery.setGeneralQuestionLogStatus(1);
List<GeneralQuestionLog> existsList = getValuesByQueryNotWithPermission(questionLogQuery);
// 如果题目日志里存在预先布置的题目,则直接返回
if (CollectionUtil.isNotEmpty(existsList)) {
return;
}
}
// generalQuestionSettingId类似试卷ID题目日志里会出现重复的试卷ID
// 逻辑删除之前的题目日志,防止学生做题统计数据异常
// 保证试卷是最新的
// 考试逻辑删除记录,作业或者章节测试都是直接删除记录。
// if (setting.getGeneralQuestionSettingType().equals(EXAM)) {
// logicDeleteBySettingIds(setting.getGeneralQuestionSettingId().toString());
// }
// else {
// deleteBySettingIds(setting.getGeneralQuestionSettingId().toString());
// }
Long teacherOpenCourseQuestionSettingId = setting.getGeneralQuestionSettingId();
// 强制发题
if (isReSend) {
if (setting.getGeneralQuestionSettingType().equals(EXAM)) {
logicDeleteBySettingIds(teacherOpenCourseQuestionSettingId.toString());
}
}
// 断言
Assert.notBlank(resourcesQuestionSnapshots.get(0).getQuestionAnswer(), "题目快照选项不能为空!");
@ -764,4 +784,26 @@ public class GeneralQuestionLogService extends CoreBaseService<GeneralQuestionLo
public PageQuery<GeneralQuestionLogScoreDetailsInfo> getQuestionLogScoreDetailsInfo(PageQuery query) {
return generalQuestionLogDao.getQuestionLogScoreDetailsInfo(query);
}
/**
*
* @param questionSettingId ID
* @param studentId ID
* @param questionSettingType
* @param questionLogAddType
* @return boolean
*/
public boolean verifyLogAddTypeIsReSend(Long questionSettingId,
Long studentId, ResourcesQuestionSnapshotFromTypeEnum questionSettingType,
QuestionLogAddTypeEnum questionLogAddType) {
// 只有章节练习,才能进行重发试题的操作
if (!questionSettingType.equals(CHAPTER_EXERCISE)) {
return false;
}
if (ObjectUtil.isAllNotEmpty(questionSettingId, studentId, questionSettingType, questionLogAddType)) {
return generalQuestionLogDao.verifyLogAddTypeIsReSend(questionSettingId, studentId, questionSettingType, questionLogAddType);
}
return false;
}
}

@ -49,6 +49,7 @@ import static cn.jlw.util.CacheUserUtil.getStudent;
import static cn.jlw.util.QuestionUtil.shuffleQuestion;
import static com.ibeetl.admin.core.util.ExcelUtil.getCellFormatValue;
import static com.ibeetl.jlw.enums.BusinessCourseInfoEnum.SYSTEM_QUESTION;
import static com.ibeetl.jlw.enums.QuestionLogAddTypeEnum.FINALLY_SUBMIT;
import static com.ibeetl.jlw.enums.ResourcesQuestionSnapshotFromTypeEnum.CHAPTER_EXERCISE;
import static com.ibeetl.jlw.enums.ResourcesQuestionSnapshotFromTypeEnum.HOMEWORK_FILE;
@ -465,7 +466,8 @@ public class GeneralQuestionSettingService extends CoreBaseService<GeneralQuesti
final Student student = getStudent();
Assert.notNull(student, "非学生身份,无法获取题目!");
Assert.isTrue(!fromTypeEnum.equals(HOMEWORK_FILE), "作业-附件类型 不需要获取题目快照!");
// 学生ID
final Long studentId = student.getStudentId();
// 常量 True的Integer表现
final Integer TRUE_CONST = 1;
List<GeneralResourcesQuestionSnapshot> resourcesQuestionSnapshots;
@ -480,7 +482,7 @@ public class GeneralQuestionSettingService extends CoreBaseService<GeneralQuesti
Assert.isTrue(generalQuestionSettingSettingDoCount > 1, "作答次数设置有误,请联系管理员!");
// 数据库查询该学生已经做过的次数
GeneralQuestionLog generalQuestionLog = new GeneralQuestionLog();
generalQuestionLog.setStudentId(student.getStudentId());
generalQuestionLog.setStudentId(studentId);
long doCount = generalQuestionLogDao.templateCount(generalQuestionLog);
// 断言判断最大作答次数
Assert.isTrue(doCount < generalQuestionSettingSettingDoCount, "已超过最大作答次数!");
@ -520,8 +522,10 @@ public class GeneralQuestionSettingService extends CoreBaseService<GeneralQuesti
// 学生身份屏蔽答案,且记录在做题日志表中,这里不为空的判断有点多余
if (student != null) {
// 判断章节练习是否需要重发试卷的题目
boolean selectIsReSend = generalQuestionLogService.verifyLogAddTypeIsReSend(generalQuestionSettingId, studentId, fromTypeEnum, FINALLY_SUBMIT);
// 做题日志关联学生, 初步提交做题日志信息,不包含学生提交的答案和得分情况
generalQuestionLogService.preSubmitStudentQuestionLog(student.getStudentId(), hwSetting, resourcesQuestionSnapshots, false);
generalQuestionLogService.preSubmitStudentQuestionLog(studentId, hwSetting, resourcesQuestionSnapshots, selectIsReSend);
// 学生身份,需要屏蔽答案,再丢给前端
resourcesQuestionSnapshots.forEach(GeneralResourcesQuestionSnapshot::hideAnswer);
}

@ -21,6 +21,7 @@ import com.ibeetl.jlw.dao.TeacherOpenCourseQuestionLogDao;
import com.ibeetl.jlw.entity.*;
import com.ibeetl.jlw.entity.dto.QuestionLogAddDTO;
import com.ibeetl.jlw.enums.QuestionLogAddTypeEnum;
import com.ibeetl.jlw.enums.ResourcesQuestionSnapshotFromTypeEnum;
import com.ibeetl.jlw.web.query.TeacherOpenCourseQuestionLogQuery;
import com.ibeetl.jlw.web.query.TeacherOpenCourseQuestionSettingQuery;
import lombok.extern.slf4j.Slf4j;
@ -48,6 +49,7 @@ import static cn.jlw.util.CacheUserUtil.getStudent;
import static com.ibeetl.admin.core.util.user.CacheUserUtil.getUserId;
import static com.ibeetl.jlw.enums.QuestionLogAddTypeEnum.FINALLY_SUBMIT;
import static com.ibeetl.jlw.enums.QuestionLogAddTypeEnum.PRE_SUBMIT;
import static com.ibeetl.jlw.enums.ResourcesQuestionSnapshotFromTypeEnum.CHAPTER_EXERCISE;
import static com.ibeetl.jlw.enums.ResourcesQuestionSnapshotFromTypeEnum.EXAM;
import static java.util.stream.Collectors.groupingBy;
@ -438,6 +440,7 @@ public class TeacherOpenCourseQuestionLogService extends CoreBaseService<Teacher
}
// 不是强制发题,则不覆盖现有的题目日志,则继续做题
// 验证题目日志,是否已经存在试卷
if(!isReSend) {
TeacherOpenCourseQuestionLogQuery questionLogQuery = new TeacherOpenCourseQuestionLogQuery();
questionLogQuery.setStudentId(studentId);
@ -461,9 +464,6 @@ public class TeacherOpenCourseQuestionLogService extends CoreBaseService<Teacher
if (setting.getTeacherOpenCourseQuestionSettingType().equals(EXAM)) {
logicDeleteBySettingIds(teacherOpenCourseQuestionSettingId.toString());
}
else {
deleteBySettingIds(teacherOpenCourseQuestionSettingId.toString());
}
}
// 断言
@ -637,4 +637,27 @@ public class TeacherOpenCourseQuestionLogService extends CoreBaseService<Teacher
return teacherOpenCourseQuestionLogDao.getQuestionLogScoreDetailsInfo(query);
}
/**
*
* @param questionSettingId ID
* @param studentId ID
* @param questionSettingType
* @param questionLogAddType
* @return boolean
*/
public boolean verifyLogAddTypeIsReSend(Long questionSettingId,
Long studentId, ResourcesQuestionSnapshotFromTypeEnum questionSettingType,
QuestionLogAddTypeEnum questionLogAddType) {
// 只有章节练习,才能进行重发试题的操作
if (!questionSettingType.equals(CHAPTER_EXERCISE)) {
return false;
}
if (ObjectUtil.isAllNotEmpty(questionSettingId, studentId, questionSettingType, questionLogAddType)) {
return teacherOpenCourseQuestionLogDao.verifyLogAddTypeIsReSend(questionSettingId,studentId, questionSettingType, questionLogAddType);
}
return false;
}
}

@ -47,6 +47,7 @@ import java.util.stream.Collectors;
import static cn.hutool.core.text.CharSequenceUtil.join;
import static cn.jlw.util.CacheUserUtil.getStudent;
import static cn.jlw.util.QuestionUtil.shuffleQuestion;
import static com.ibeetl.jlw.enums.QuestionLogAddTypeEnum.FINALLY_SUBMIT;
import static com.ibeetl.jlw.enums.ResourcesQuestionSnapshotFromTypeEnum.CHAPTER_EXERCISE;
import static com.ibeetl.jlw.enums.ResourcesQuestionSnapshotFromTypeEnum.HOMEWORK_FILE;
import static java.util.stream.Collectors.joining;
@ -656,7 +657,8 @@ public class TeacherOpenCourseQuestionSettingService extends CoreBaseService<Tea
final Student student = getStudent();
Assert.notNull(student, "非学生身份,无法获取题目!");
Assert.isTrue(!fromTypeEnum.equals(HOMEWORK_FILE), "作业-附件类型 不需要获取题目快照!");
// 学生ID
final Long studentId = student.getStudentId();
// 常量 True的Integer表现
final Integer TRUE_CONST = 1;
List<ResourcesQuestionSnapshot> resourcesQuestionSnapshots;
@ -671,7 +673,7 @@ public class TeacherOpenCourseQuestionSettingService extends CoreBaseService<Tea
Assert.isTrue(teacherOpenCourseQuestionSettingSettingDoCount > 1, "作答次数设置有误,请联系管理员!");
// 数据库查询该学生已经做过的次数
TeacherOpenCourseQuestionLog teacherOpenCourseQuestionLog = new TeacherOpenCourseQuestionLog();
teacherOpenCourseQuestionLog.setStudentId(student.getStudentId());
teacherOpenCourseQuestionLog.setStudentId(studentId);
long doCount = teacherOpenCourseQuestionLogDao.templateCount(teacherOpenCourseQuestionLog);
// 断言判断最大作答次数
Assert.isTrue(doCount < teacherOpenCourseQuestionSettingSettingDoCount, "已超过最大作答次数!");
@ -680,7 +682,7 @@ public class TeacherOpenCourseQuestionSettingService extends CoreBaseService<Tea
ResourcesQuestionSnapshotQuery questionSnapshotQuery = new ResourcesQuestionSnapshotQuery();
questionSnapshotQuery.setTeacherOpenCourseQuestionSettingId(teacherOpenCourseQuestionSettingId);
// 学生ID
questionSnapshotQuery.setStudentId(student.getStudentId());
questionSnapshotQuery.setStudentId(studentId);
// 答卷后显示答案解析
if (TRUE_CONST.equals(hwSetting.getTeacherOpenCourseQuestionSettingEndShowQa())) {
@ -713,12 +715,15 @@ public class TeacherOpenCourseQuestionSettingService extends CoreBaseService<Tea
// 学生身份屏蔽答案,且记录在做题日志表中,这里不为空的判断有点多余
if (student != null) {
// 判断章节练习是否需要重发试卷的题目
boolean selectIsReSend = teacherOpenCourseQuestionLogService.verifyLogAddTypeIsReSend(teacherOpenCourseQuestionSettingId, studentId, fromTypeEnum, FINALLY_SUBMIT);
// 做题日志关联学生, 初步提交做题日志信息,不包含学生提交的答案和得分情况
teacherOpenCourseQuestionLogService.preSubmitStudentQuestionLog(student.getStudentId(), hwSetting, resourcesQuestionSnapshots, false);
teacherOpenCourseQuestionLogService.preSubmitStudentQuestionLog(studentId, hwSetting, resourcesQuestionSnapshots, selectIsReSend);
// 学生身份,需要屏蔽答案,再丢给前端
resourcesQuestionSnapshots.forEach(ResourcesQuestionSnapshot::hideAnswer);
}
return resourcesQuestionSnapshots;
}
}

@ -1221,4 +1221,38 @@ getQuestionLogScoreDetailsInfo
ta.student_sn,
ta.class_id,
tb.class_name
) tz
) tz
validateQuestionLogAddTimeLatest
===
* 验证前端传递过来的添加时间是否是最新的
select
if(t.general_question_log_update_time is null, true, t.general_question_log_update_time < #addTime#)
from
general_question_log t
where 1 = 1
and t.general_question_setting_id = #questionSettingId#
and FIND_IN_SET(t.general_resources_question_snapshot_id, #questionSnapshotIds#)
and t.student_id = #studentId#
and t.general_question_log_status = 1
order by general_question_log_add_time desc
limit 1
verifyLogAddTypeIsReSend
===
* 如果查询题目日志,只要是交卷的状态 则返回重新发题的标记
SELECT
COUNT(1) > 0
FROM
general_question_setting t
LEFT JOIN general_question_log ta ON ta.general_question_setting_id = t.general_question_setting_id
AND t.general_question_setting_status = 1
AND t.general_question_setting_type = #questionSettingType#
AND t.general_question_setting_id = #questionSettingId#
AND ta.general_question_log_status = 1
AND ta.student_id = #studentId#
AND ta.question_log_add_type = #questionLogAddType#
LIMIT 1

@ -594,7 +594,9 @@ getQuestionTestSimpleInfo
(
SELECT
sum(
IFNULL( ta.student_score, 0 ))
@ // 已经交卷的状态才算分
CASE WHEN ta.question_log_add_type = 'FINALLY_SUBMIT' THEN IFNULL( ta.student_score, 0 ) ELSE 0 END
)
FROM
teacher_open_course_question_log ta
WHERE

@ -737,6 +737,7 @@ getQuestionLogScoreDetailsInfo
validateQuestionLogAddTimeLatest
===
* 验证前端传递过来的添加时间是否是最新的
select
if(t.teacher_open_course_question_log_update_time is null, true, t.teacher_open_course_question_log_update_time < #addTime#)
from
@ -748,3 +749,21 @@ validateQuestionLogAddTimeLatest
and t.teacher_open_course_question_log_status = 1
order by teacher_open_course_question_log_add_time desc
limit 1
verifyLogAddTypeIsReSend
===
* 如果查询题目日志,只要是交卷的状态 则返回重新发题的标记
SELECT
COUNT(1) > 0
FROM
teacher_open_course_question_setting t
LEFT JOIN teacher_open_course_question_log ta ON ta.teacher_open_course_question_setting_id = t.teacher_open_course_question_setting_id
AND t.teacher_open_course_question_setting_status = 1
AND t.teacher_open_course_question_setting_type = #questionSettingType#
AND t.teacher_open_course_question_setting_id = #questionSettingId#
AND ta.teacher_open_course_question_log_status = 1
AND ta.student_id = #studentId#
AND ta.question_log_add_type = #questionLogAddType#
LIMIT 1
Loading…
Cancel
Save