|
|
@ -18,10 +18,7 @@ import com.msdw.tms.entity.request.QuestionsImportRequest; |
|
|
|
import com.msdw.tms.entity.request.QuestionsQueryRequest; |
|
|
|
import com.msdw.tms.entity.request.QuestionsQueryRequest; |
|
|
|
import com.msdw.tms.entity.request.QuestionsUpdateRequest; |
|
|
|
import com.msdw.tms.entity.request.QuestionsUpdateRequest; |
|
|
|
import com.msdw.tms.entity.response.CommonCode; |
|
|
|
import com.msdw.tms.entity.response.CommonCode; |
|
|
|
import com.msdw.tms.entity.vo.EvaluationRulesVO; |
|
|
|
import com.msdw.tms.entity.vo.*; |
|
|
|
import com.msdw.tms.entity.vo.EvaluationVO; |
|
|
|
|
|
|
|
import com.msdw.tms.entity.vo.QuestionsDetailVO; |
|
|
|
|
|
|
|
import com.msdw.tms.entity.vo.QuestionsVO; |
|
|
|
|
|
|
|
import com.msdw.tms.service.AliyunOssService; |
|
|
|
import com.msdw.tms.service.AliyunOssService; |
|
|
|
import com.msdw.tms.service.EvaluationRulesService; |
|
|
|
import com.msdw.tms.service.EvaluationRulesService; |
|
|
|
import com.msdw.tms.service.QuestionsService; |
|
|
|
import com.msdw.tms.service.QuestionsService; |
|
|
@ -29,6 +26,8 @@ import com.msdw.tms.service.XlsxTemplateService; |
|
|
|
import org.apache.commons.lang.StringUtils; |
|
|
|
import org.apache.commons.lang.StringUtils; |
|
|
|
import org.springframework.beans.BeanUtils; |
|
|
|
import org.springframework.beans.BeanUtils; |
|
|
|
import org.springframework.core.io.ClassPathResource; |
|
|
|
import org.springframework.core.io.ClassPathResource; |
|
|
|
|
|
|
|
import org.springframework.data.redis.core.StringRedisTemplate; |
|
|
|
|
|
|
|
import org.springframework.data.redis.core.ValueOperations; |
|
|
|
import org.springframework.stereotype.Service; |
|
|
|
import org.springframework.stereotype.Service; |
|
|
|
import org.springframework.transaction.annotation.Transactional; |
|
|
|
import org.springframework.transaction.annotation.Transactional; |
|
|
|
import org.springframework.web.multipart.MultipartFile; |
|
|
|
import org.springframework.web.multipart.MultipartFile; |
|
|
@ -42,6 +41,7 @@ import java.time.LocalDateTime; |
|
|
|
import java.time.ZoneId; |
|
|
|
import java.time.ZoneId; |
|
|
|
import java.time.format.DateTimeFormatter; |
|
|
|
import java.time.format.DateTimeFormatter; |
|
|
|
import java.util.*; |
|
|
|
import java.util.*; |
|
|
|
|
|
|
|
import java.util.concurrent.TimeUnit; |
|
|
|
import java.util.stream.Collectors; |
|
|
|
import java.util.stream.Collectors; |
|
|
|
|
|
|
|
|
|
|
|
@Service("questionsService") |
|
|
|
@Service("questionsService") |
|
|
@ -56,6 +56,11 @@ public class QuestionsServiceImpl extends ServiceImpl<QuestionsDao, QuestionsEnt |
|
|
|
@Resource |
|
|
|
@Resource |
|
|
|
EvaluationRulesService evaluationRulesService; |
|
|
|
EvaluationRulesService evaluationRulesService; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Resource |
|
|
|
|
|
|
|
StringRedisTemplate stringRedisTemplate; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private String REMAINING_TINE_KEY = "REMAINING_TINE"; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* 条件加分页查询,题干模糊查询,未删除,修改时间降序 |
|
|
|
* 条件加分页查询,题干模糊查询,未删除,修改时间降序 |
|
|
|
*/ |
|
|
|
*/ |
|
|
@ -74,14 +79,10 @@ public class QuestionsServiceImpl extends ServiceImpl<QuestionsDao, QuestionsEnt |
|
|
|
queryWrapper.like("question_stem", request.getQuestionStem()); |
|
|
|
queryWrapper.like("question_stem", request.getQuestionStem()); |
|
|
|
} |
|
|
|
} |
|
|
|
// 题型:判断题型是否为空,不为空则加入搜索条件
|
|
|
|
// 题型:判断题型是否为空,不为空则加入搜索条件
|
|
|
|
if (request.getQuestionTypeNo() != null) { |
|
|
|
if (request.getQuestionType() != null) { |
|
|
|
queryWrapper.eq("question_type_no", request.getQuestionTypeNo()); |
|
|
|
queryWrapper.eq("question_type", request.getQuestionType()); |
|
|
|
} |
|
|
|
} |
|
|
|
//TODO 扩展搜索条件
|
|
|
|
//扩展其他搜索条件...
|
|
|
|
// 修改时间:判断修改时间是否为空,不为空则加入搜索条件
|
|
|
|
|
|
|
|
// if (request.getModifyTime() != null) {
|
|
|
|
|
|
|
|
// queryWrapper.eq("modify_time", request.getModifyTime());
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 修改时间降序
|
|
|
|
// 修改时间降序
|
|
|
@ -91,24 +92,20 @@ public class QuestionsServiceImpl extends ServiceImpl<QuestionsDao, QuestionsEnt |
|
|
|
new Query<QuestionsEntity>().getPage(page, size), |
|
|
|
new Query<QuestionsEntity>().getPage(page, size), |
|
|
|
queryWrapper |
|
|
|
queryWrapper |
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
List<QuestionsEntity> records = questionsIPage.getRecords(); |
|
|
|
List<QuestionsEntity> records = questionsIPage.getRecords(); |
|
|
|
|
|
|
|
|
|
|
|
List<QuestionsVO> questions = records.stream().map(question -> { |
|
|
|
List<QuestionsListVO> questions = records.stream().map(question -> { |
|
|
|
QuestionsVO questionsVO = new QuestionsVO(); |
|
|
|
QuestionsListVO questionsListVO = new QuestionsListVO(); |
|
|
|
BeanUtils.copyProperties(question, questionsVO); |
|
|
|
BeanUtils.copyProperties(question, questionsListVO); |
|
|
|
|
|
|
|
//处理试题类型
|
|
|
|
|
|
|
|
String questionTypeName = getQuestionTypeName(question.getQuestionType()); |
|
|
|
|
|
|
|
questionsListVO.setQuestionTypeName(questionTypeName); |
|
|
|
//处理时间格式
|
|
|
|
//处理时间格式
|
|
|
|
questionsVO.setCreateTime(handleTime(question.getCreateTime())); |
|
|
|
questionsListVO.setModifyTime(handleTime(question.getModifyTime())); |
|
|
|
questionsVO.setModifyTime(handleTime(question.getModifyTime())); |
|
|
|
return questionsListVO; |
|
|
|
|
|
|
|
|
|
|
|
return questionsVO; |
|
|
|
|
|
|
|
}).collect(Collectors.toList()); |
|
|
|
}).collect(Collectors.toList()); |
|
|
|
|
|
|
|
|
|
|
|
PageUtils questionsPage = new PageUtils(questionsIPage); |
|
|
|
PageUtils questionsPage = new PageUtils(questionsIPage); |
|
|
|
|
|
|
|
|
|
|
|
questionsPage.setList(questions); |
|
|
|
questionsPage.setList(questions); |
|
|
|
|
|
|
|
|
|
|
|
return questionsPage; |
|
|
|
return questionsPage; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -127,11 +124,9 @@ public class QuestionsServiceImpl extends ServiceImpl<QuestionsDao, QuestionsEnt |
|
|
|
//查询试题信息
|
|
|
|
//查询试题信息
|
|
|
|
QuestionsEntity questionsEntity = this.getById(id); |
|
|
|
QuestionsEntity questionsEntity = this.getById(id); |
|
|
|
BeanUtils.copyProperties(questionsEntity, questionsDetailVO); |
|
|
|
BeanUtils.copyProperties(questionsEntity, questionsDetailVO); |
|
|
|
|
|
|
|
//处理试题类型
|
|
|
|
//处理时间
|
|
|
|
String questionTypeName = getQuestionTypeName(questionsEntity.getQuestionType()); |
|
|
|
//处理时间格式
|
|
|
|
questionsDetailVO.setQuestionTypeName(questionTypeName); |
|
|
|
questionsDetailVO.setCreateTime(handleTime(questionsEntity.getCreateTime())); |
|
|
|
|
|
|
|
questionsDetailVO.setModifyTime(handleTime(questionsEntity.getModifyTime())); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//处理每个选项是否为被设置为答案
|
|
|
|
//处理每个选项是否为被设置为答案
|
|
|
|
String answer = questionsEntity.getAnswer(); |
|
|
|
String answer = questionsEntity.getAnswer(); |
|
|
@ -158,29 +153,56 @@ public class QuestionsServiceImpl extends ServiceImpl<QuestionsDao, QuestionsEnt |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private String getQuestionTypeName(Integer questionType) { |
|
|
|
|
|
|
|
String questionTypeName = ""; |
|
|
|
|
|
|
|
//处理试题类型
|
|
|
|
|
|
|
|
if (questionType.equals(Constant.QuestionType.SINGLE_CHOICE.getType())) { |
|
|
|
|
|
|
|
//单选题
|
|
|
|
|
|
|
|
questionTypeName = Constant.QuestionType.SINGLE_CHOICE.getDesc(); |
|
|
|
|
|
|
|
} else if (questionType.equals(Constant.QuestionType.MULTIPLE_CHOICE.getType())) { |
|
|
|
|
|
|
|
//多选题
|
|
|
|
|
|
|
|
questionTypeName = Constant.QuestionType.MULTIPLE_CHOICE.getDesc(); |
|
|
|
|
|
|
|
} else if (questionType.equals(Constant.QuestionType.TRUE_OR_FALSE.getType())) { |
|
|
|
|
|
|
|
//判断题
|
|
|
|
|
|
|
|
questionTypeName = Constant.QuestionType.TRUE_OR_FALSE.getDesc(); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
ExceptionCast.cast(CommonCode.QUESTIONTYPE_INVALID); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return questionTypeName; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* 保存试题,根据题型名称得到题型号,设置创建时间和修改时间 |
|
|
|
* 保存试题 |
|
|
|
|
|
|
|
* 1、检验题型是否正确 |
|
|
|
|
|
|
|
* 2、检验题干和选项是否有重复 |
|
|
|
|
|
|
|
* 3、设置创建时间和修改时间 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
@Override |
|
|
|
@Override |
|
|
|
@Transactional |
|
|
|
@Transactional |
|
|
|
public boolean saveQuestion(QuestionsAddRequest questions) { |
|
|
|
public boolean saveQuestion(QuestionsAddRequest questions) { |
|
|
|
if (questions == null || StringUtils.isEmpty(questions.getQuestionStem())) { |
|
|
|
//试题对象为空或题干内容为空,抛出参数不合法异常
|
|
|
|
|
|
|
|
if (questions == null |
|
|
|
|
|
|
|
|| StringUtils.isEmpty(questions.getQuestionStem()) |
|
|
|
|
|
|
|
|| questions.getQuestionType() == null) { |
|
|
|
ExceptionCast.cast(CommonCode.INVALID_PARAM); |
|
|
|
ExceptionCast.cast(CommonCode.INVALID_PARAM); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 判断是否题干重复,
|
|
|
|
//校验题型是否正确
|
|
|
|
QueryWrapper<QuestionsEntity> queryWrapper = new QueryWrapper<>(); |
|
|
|
checkType(questions.getQuestionType()); |
|
|
|
queryWrapper.eq("is_del", Constant.IsDel.NOT_DEL.getType()) |
|
|
|
|
|
|
|
.eq("question_stem", questions.getQuestionStem()); |
|
|
|
// 校验重复,不仅要校验题干,还要校验选项
|
|
|
|
|
|
|
|
QuestionsEntity questionsEntity = new QuestionsEntity(); |
|
|
|
|
|
|
|
BeanUtils.copyProperties(questions, questionsEntity); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//构造根据内容查询试题数量的Wrapper
|
|
|
|
|
|
|
|
QueryWrapper<QuestionsEntity> queryWrapper = constructDistinctWrapper(questionsEntity); |
|
|
|
|
|
|
|
|
|
|
|
int count = this.count(queryWrapper); |
|
|
|
int count = this.count(queryWrapper); |
|
|
|
if (count > 0) {//说明已存在
|
|
|
|
if (count > 0) {//说明已存在
|
|
|
|
//抛出题目已存在异常
|
|
|
|
//抛出题目已存在异常
|
|
|
|
ExceptionCast.cast(CommonCode.QUESTION_EXISTS); |
|
|
|
ExceptionCast.cast(CommonCode.QUESTION_EXISTS); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 将传入的对象内容拷贝到QuestionsEntity并返回
|
|
|
|
// 将传入的对象内容拷贝到QuestionsEntity并返回
|
|
|
|
QuestionsEntity questionsEntity = getQuestionsEntity(questions); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
questionsEntity.setCreateTime(new Date()); |
|
|
|
questionsEntity.setCreateTime(new Date()); |
|
|
|
questionsEntity.setModifyTime(new Date()); |
|
|
|
questionsEntity.setModifyTime(new Date()); |
|
|
|
//TODO 创建者和修改者。。。
|
|
|
|
//TODO 创建者和修改者。。。
|
|
|
@ -191,28 +213,33 @@ public class QuestionsServiceImpl extends ServiceImpl<QuestionsDao, QuestionsEnt |
|
|
|
@Override |
|
|
|
@Override |
|
|
|
@Transactional |
|
|
|
@Transactional |
|
|
|
public boolean updateQuestionById(QuestionsUpdateRequest questions) { |
|
|
|
public boolean updateQuestionById(QuestionsUpdateRequest questions) { |
|
|
|
if (questions == null || questions.getId() == null || StringUtils.isEmpty(questions.getQuestionStem())) { |
|
|
|
if (questions == null |
|
|
|
|
|
|
|
|| questions.getId() == null |
|
|
|
|
|
|
|
|| StringUtils.isEmpty(questions.getQuestionStem())) { |
|
|
|
ExceptionCast.cast(CommonCode.INVALID_PARAM); |
|
|
|
ExceptionCast.cast(CommonCode.INVALID_PARAM); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 判断是否题干重复,除了自己之外还有没有重复的题干,因为自己的题干可以不做修改
|
|
|
|
|
|
|
|
QueryWrapper<QuestionsEntity> queryWrapper = new QueryWrapper<>(); |
|
|
|
|
|
|
|
queryWrapper.eq("id", questions.getId()) |
|
|
|
|
|
|
|
.eq("question_stem", questions.getQuestionStem()) |
|
|
|
|
|
|
|
.eq("is_del", Constant.IsDel.NOT_DEL.getType()); |
|
|
|
|
|
|
|
int count = this.count(queryWrapper); |
|
|
|
|
|
|
|
if (count > 0) {//说明除了本题之外题干已存在
|
|
|
|
|
|
|
|
//抛出题目已存在异常
|
|
|
|
|
|
|
|
ExceptionCast.cast(CommonCode.QUESTION_EXISTS); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 判断id是否存在
|
|
|
|
// 判断id是否存在
|
|
|
|
if (this.getById(questions.getId()) == null) { |
|
|
|
if (this.getById(questions.getId()) == null) { |
|
|
|
ExceptionCast.cast(CommonCode.INVALID_PARAM); |
|
|
|
ExceptionCast.cast(CommonCode.INVALID_PARAM); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 将传入的对象内容拷贝到QuestionsEntity并返回
|
|
|
|
//校验题型是否正确
|
|
|
|
QuestionsEntity questionsEntity = getQuestionsEntity(questions); |
|
|
|
checkType(questions.getQuestionType()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//校验题干和内容重复
|
|
|
|
|
|
|
|
QuestionsEntity questionsEntity = new QuestionsEntity(); |
|
|
|
|
|
|
|
BeanUtils.copyProperties(questions, questionsEntity); |
|
|
|
|
|
|
|
//构造根据内容查询试题数量的Wrapper
|
|
|
|
|
|
|
|
QueryWrapper<QuestionsEntity> queryWrapper = constructDistinctWrapper(questionsEntity); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
queryWrapper.notIn("id", questions.getId()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int count = this.count(queryWrapper); |
|
|
|
|
|
|
|
if (count > 0) {//说明除了本题之外题干已存在
|
|
|
|
|
|
|
|
//抛出题目已存在异常
|
|
|
|
|
|
|
|
ExceptionCast.cast(CommonCode.QUESTION_EXISTS); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
questionsEntity.setModifyTime(new Date()); |
|
|
|
questionsEntity.setModifyTime(new Date()); |
|
|
|
//TODO 设置修改者。。。
|
|
|
|
//TODO 设置修改者。。。
|
|
|
@ -220,42 +247,55 @@ public class QuestionsServiceImpl extends ServiceImpl<QuestionsDao, QuestionsEnt |
|
|
|
return this.updateById(questionsEntity); |
|
|
|
return this.updateById(questionsEntity); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 将传入的对象内容拷贝到QuestionsEntity并返回
|
|
|
|
private void checkType(int type) { |
|
|
|
private <T> QuestionsEntity getQuestionsEntity(T questions) { |
|
|
|
boolean include = false; |
|
|
|
QuestionsEntity questionsEntity = new QuestionsEntity(); |
|
|
|
for (Constant.QuestionType value : Constant.QuestionType.values()) { |
|
|
|
|
|
|
|
if (value.getType().equals(type)) { |
|
|
|
BeanUtils.copyProperties(questions, questionsEntity); |
|
|
|
include = true; |
|
|
|
|
|
|
|
} |
|
|
|
String questionType = questionsEntity.getQuestionType(); |
|
|
|
} |
|
|
|
//根据题型名称得到题型号
|
|
|
|
if (!include) {//题型不在枚举类中,不正确
|
|
|
|
if (questionType.equals(Constant.QuestionType.SINGLE_CHOICE.getDesc())) { |
|
|
|
|
|
|
|
//单选题
|
|
|
|
|
|
|
|
questionsEntity.setQuestionTypeNo(Constant.QuestionType.SINGLE_CHOICE.getType()); |
|
|
|
|
|
|
|
} else if (questionType.equals(Constant.QuestionType.MULTIPLE_CHOICE.getDesc())) { |
|
|
|
|
|
|
|
//多选题
|
|
|
|
|
|
|
|
questionsEntity.setQuestionTypeNo(Constant.QuestionType.MULTIPLE_CHOICE.getType()); |
|
|
|
|
|
|
|
} else if (questionType.equals(Constant.QuestionType.TRUE_OR_FALSE.getDesc())) { |
|
|
|
|
|
|
|
//判断题
|
|
|
|
|
|
|
|
questionsEntity.setQuestionTypeNo(Constant.QuestionType.TRUE_OR_FALSE.getType()); |
|
|
|
|
|
|
|
} else {// 判断题型是否不存在
|
|
|
|
|
|
|
|
//说明题型不正确
|
|
|
|
|
|
|
|
ExceptionCast.cast(CommonCode.QUESTIONTYPE_INVALID); |
|
|
|
ExceptionCast.cast(CommonCode.QUESTIONTYPE_INVALID); |
|
|
|
} |
|
|
|
} |
|
|
|
return questionsEntity; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private QueryWrapper<QuestionsEntity> constructDistinctWrapper(QuestionsEntity questions) { |
|
|
|
|
|
|
|
QueryWrapper<QuestionsEntity> queryWrapper = new QueryWrapper<>(); |
|
|
|
|
|
|
|
queryWrapper.eq("is_del", Constant.IsDel.NOT_DEL.getType()) |
|
|
|
|
|
|
|
.eq("question_stem", questions.getQuestionStem()); |
|
|
|
|
|
|
|
if (StringUtils.isNotEmpty(questions.getOptionA())) { |
|
|
|
|
|
|
|
queryWrapper.eq("option_a", questions.getOptionA()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (StringUtils.isNotEmpty(questions.getOptionB())) { |
|
|
|
|
|
|
|
queryWrapper.eq("option_b", questions.getOptionB()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (StringUtils.isNotEmpty(questions.getOptionC())) { |
|
|
|
|
|
|
|
queryWrapper.eq("option_c", questions.getOptionC()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (StringUtils.isNotEmpty(questions.getOptionD())) { |
|
|
|
|
|
|
|
queryWrapper.eq("option_d", questions.getOptionD()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (StringUtils.isNotEmpty(questions.getOptionE())) { |
|
|
|
|
|
|
|
queryWrapper.eq("option_e", questions.getOptionE()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (StringUtils.isNotEmpty(questions.getOptionF())) { |
|
|
|
|
|
|
|
queryWrapper.eq("option_f", questions.getOptionF()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return queryWrapper; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
@Transactional |
|
|
|
@Transactional |
|
|
|
public boolean isnable(Integer id) { |
|
|
|
public boolean isEnable(Integer id) { |
|
|
|
QuestionsEntity questionsEntity = new QuestionsEntity(); |
|
|
|
QuestionsEntity questionsEntity = new QuestionsEntity(); |
|
|
|
questionsEntity.setId(id); |
|
|
|
questionsEntity.setId(id); |
|
|
|
QuestionsEntity byId = this.getById(id); |
|
|
|
QuestionsEntity byId = this.getById(id); |
|
|
|
if (byId.getIsEnable().equals(Constant.IsEnable.ENABLE.getType())) { |
|
|
|
if (byId.getIsEnable().equals(Constant.IsEnable.ENABLE.getType())) { |
|
|
|
questionsEntity.setIsEnable(Constant.IsEnable.NOT_ENABLE.getType()); |
|
|
|
questionsEntity.setIsEnable(Constant.IsEnable.NOT_ENABLE.getType()); |
|
|
|
} |
|
|
|
} else if (byId.getIsEnable().equals(Constant.IsEnable.NOT_ENABLE.getType())) { |
|
|
|
|
|
|
|
|
|
|
|
if (byId.getIsEnable().equals(Constant.IsEnable.NOT_ENABLE.getType())) { |
|
|
|
|
|
|
|
questionsEntity.setIsEnable(Constant.IsEnable.ENABLE.getType()); |
|
|
|
questionsEntity.setIsEnable(Constant.IsEnable.ENABLE.getType()); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
ExceptionCast.cast(CommonCode.INVALID_PARAM); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return this.updateById(questionsEntity); |
|
|
|
return this.updateById(questionsEntity); |
|
|
@ -275,53 +315,62 @@ public class QuestionsServiceImpl extends ServiceImpl<QuestionsDao, QuestionsEnt |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* 校验题干重复和题型不对的,从列表中将该题剔除,名称相同的要去重 |
|
|
|
* 1、校验题干重复和题型不对的, |
|
|
|
|
|
|
|
* 2、从列表中将该题剔除并记录index和导入失败的原因, |
|
|
|
|
|
|
|
* 3、名称和选项内容都相同的要去重 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
@Override |
|
|
|
@Override |
|
|
|
@Transactional |
|
|
|
@Transactional |
|
|
|
public boolean importQuestion(MultipartFile file) throws IOException { |
|
|
|
public List<String> importQuestion(MultipartFile file) throws IOException { |
|
|
|
// 使用excel导入工具类获取试题数据列表
|
|
|
|
// 使用excel导入工具类获取试题数据列表
|
|
|
|
List<QuestionsImportRequest> list = new ExcelImportUtil(QuestionsImportRequest.class) |
|
|
|
List<QuestionsImportRequest> list = new ExcelImportUtil(QuestionsImportRequest.class) |
|
|
|
.readExcel(file.getInputStream(), Constant.STARTING_ROW, Constant.STARTING_CELL); |
|
|
|
.readExcel(file.getInputStream(), Constant.STARTING_ROW, Constant.STARTING_CELL); |
|
|
|
|
|
|
|
|
|
|
|
if (list == null || list.size() == 0) { |
|
|
|
if (list == null || list.size() == 0) { |
|
|
|
ExceptionCast.cast(CommonCode.INVALID_PARAM); |
|
|
|
ExceptionCast.cast(CommonCode.EXCEL_INVALID); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
List<QuestionsEntity> collect = list.stream().map(item -> { |
|
|
|
List<String> failureRecord = new ArrayList<>(); |
|
|
|
int count = this.count(new QueryWrapper<QuestionsEntity>().eq("question_stem", item.getQuestionStem())); |
|
|
|
|
|
|
|
if (count > 0) {//说明已存在
|
|
|
|
for (int i = 0; i < list.size(); i++) { |
|
|
|
return null; |
|
|
|
QuestionsImportRequest question = list.get(i); |
|
|
|
} |
|
|
|
//校验题干和内容重复
|
|
|
|
QuestionsEntity questionsEntity = new QuestionsEntity(); |
|
|
|
QuestionsEntity questionsEntity = new QuestionsEntity(); |
|
|
|
BeanUtils.copyProperties(item, questionsEntity); |
|
|
|
BeanUtils.copyProperties(question, questionsEntity); |
|
|
|
String questionType = item.getQuestionType(); |
|
|
|
String questionTypeName = question.getQuestionTypeName(); |
|
|
|
//根据题型名称得到题型号
|
|
|
|
//根据题型名称得到题型号
|
|
|
|
if (questionType.equals(Constant.QuestionType.SINGLE_CHOICE.getDesc())) { |
|
|
|
if (questionTypeName.equals(Constant.QuestionType.SINGLE_CHOICE.getDesc())) { |
|
|
|
//单选题
|
|
|
|
//单选题
|
|
|
|
questionsEntity.setQuestionTypeNo(Constant.QuestionType.SINGLE_CHOICE.getType()); |
|
|
|
questionsEntity.setQuestionType(Constant.QuestionType.SINGLE_CHOICE.getType()); |
|
|
|
} else if (questionType.equals(Constant.QuestionType.MULTIPLE_CHOICE.getDesc())) { |
|
|
|
} else if (questionTypeName.equals(Constant.QuestionType.MULTIPLE_CHOICE.getDesc())) { |
|
|
|
//多选题
|
|
|
|
//多选题
|
|
|
|
questionsEntity.setQuestionTypeNo(Constant.QuestionType.MULTIPLE_CHOICE.getType()); |
|
|
|
questionsEntity.setQuestionType(Constant.QuestionType.MULTIPLE_CHOICE.getType()); |
|
|
|
} else if (questionType.equals(Constant.QuestionType.TRUE_OR_FALSE.getDesc())) { |
|
|
|
} else if (questionTypeName.equals(Constant.QuestionType.TRUE_OR_FALSE.getDesc())) { |
|
|
|
//判断题
|
|
|
|
//判断题
|
|
|
|
questionsEntity.setQuestionTypeNo(Constant.QuestionType.TRUE_OR_FALSE.getType()); |
|
|
|
questionsEntity.setQuestionType(Constant.QuestionType.TRUE_OR_FALSE.getType()); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
// 题型不正确
|
|
|
|
// 题型不正确
|
|
|
|
return null; |
|
|
|
failureRecord.add("第 " + question.getIndex() + " 行导入失败," + "题干:" + question.getQuestionStem() + ",失败信息:" + CommonCode.QUESTIONTYPE_INVALID.message()); |
|
|
|
|
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//构造根据内容查询试题数量的Wrapper
|
|
|
|
|
|
|
|
QueryWrapper<QuestionsEntity> queryWrapper = constructDistinctWrapper(questionsEntity); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int count = this.count(queryWrapper); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (count > 0) {//说明已存在
|
|
|
|
|
|
|
|
failureRecord.add("第 " + question.getIndex() + " 行导入失败," + "题干:" + question.getQuestionStem() + ",失败信息:" + CommonCode.QUESTION_EXISTS.message()); |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
questionsEntity.setCreateTime(new Date()); |
|
|
|
questionsEntity.setCreateTime(new Date()); |
|
|
|
questionsEntity.setModifyTime(new Date()); |
|
|
|
questionsEntity.setModifyTime(new Date()); |
|
|
|
//TODO 创建者和修改者。。。
|
|
|
|
|
|
|
|
return questionsEntity; |
|
|
|
this.save(questionsEntity); |
|
|
|
}).filter(Objects::nonNull)// 过滤掉为null的对象
|
|
|
|
} |
|
|
|
.collect(Collectors.collectingAndThen(// 去重收集
|
|
|
|
|
|
|
|
Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(QuestionsEntity::getQuestionStem))), |
|
|
|
return failureRecord; |
|
|
|
ArrayList::new |
|
|
|
|
|
|
|
)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 批量新增
|
|
|
|
|
|
|
|
return this.saveBatch(collect); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
@ -347,14 +396,12 @@ public class QuestionsServiceImpl extends ServiceImpl<QuestionsDao, QuestionsEnt |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public EvaluationVO evaluation() { |
|
|
|
public EvaluationVO evaluation(Integer userId) { |
|
|
|
|
|
|
|
|
|
|
|
QueryWrapper<QuestionsEntity> queryWrapper = new QueryWrapper<>(); |
|
|
|
QueryWrapper<QuestionsEntity> queryWrapper = new QueryWrapper<>(); |
|
|
|
queryWrapper.eq("is_del", Constant.IsDel.NOT_DEL.getType()) //未删除
|
|
|
|
queryWrapper.eq("is_del", Constant.IsDel.NOT_DEL.getType()) //未删除
|
|
|
|
.eq("is_enable", Constant.IsEnable.ENABLE.getType()); //启用
|
|
|
|
.eq("is_enable", Constant.IsEnable.ENABLE.getType()); //启用
|
|
|
|
|
|
|
|
|
|
|
|
Set<QuestionsEntity> set = new HashSet<>(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 查询测评规则类型
|
|
|
|
// 查询测评规则类型
|
|
|
|
EvaluationRulesVO evaluationRules = evaluationRulesService.getEvaluationRules(); |
|
|
|
EvaluationRulesVO evaluationRules = evaluationRulesService.getEvaluationRules(); |
|
|
|
|
|
|
|
|
|
|
@ -362,17 +409,46 @@ public class QuestionsServiceImpl extends ServiceImpl<QuestionsDao, QuestionsEnt |
|
|
|
|
|
|
|
|
|
|
|
BeanUtils.copyProperties(evaluationRules, evaluation); |
|
|
|
BeanUtils.copyProperties(evaluationRules, evaluation); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//TODO 处理时长,获取当前登录用户id,将用户剩余的时长实时计算,存在Redis中
|
|
|
|
|
|
|
|
//时长转成秒来计算
|
|
|
|
|
|
|
|
//先查询该用户有没有开始考试,既redis中有没有跟该用户id相关联的key
|
|
|
|
|
|
|
|
//如果没有,表示是开始测评,向redis中插入一条数据,key是前缀加用户id,value是当前时间,过期时间是测评时长加三十秒
|
|
|
|
|
|
|
|
//如果有,则得到value,既开始测评的时间,用当前时间和开始测评时间做差,测评时长减去该差值
|
|
|
|
|
|
|
|
//TODO 提交测评时删除redis中的该条数据
|
|
|
|
|
|
|
|
//得到总时长
|
|
|
|
|
|
|
|
Integer duration = evaluation.getDuration(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ValueOperations<String, String> ops = stringRedisTemplate.opsForValue(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
String key = REMAINING_TINE_KEY + userId; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
String startTime = ops.get(key); |
|
|
|
|
|
|
|
int remainingTime = duration; |
|
|
|
|
|
|
|
if (StringUtils.isEmpty(startTime)) { |
|
|
|
|
|
|
|
//如果没有,表示是开始测评,向redis中插入一条数据,key是前缀加用户id,value是当前时间,过期时间是测评时长加十秒
|
|
|
|
|
|
|
|
ops.set(key, getSecondTimestamp(new Date()) + "", duration * 60 + 10, TimeUnit.SECONDS); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
int difference = getSecondTimestamp(new Date()) - Integer.valueOf(startTime); |
|
|
|
|
|
|
|
remainingTime = duration - difference; |
|
|
|
|
|
|
|
if (remainingTime < 0) { |
|
|
|
|
|
|
|
ExceptionCast.cast(CommonCode.EVALUATION_TIME_INVALID); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
evaluation.setRemainingDuration(formatDateTime(remainingTime)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//搜集随机抽取的试题
|
|
|
|
|
|
|
|
Set<QuestionsVO> set = new HashSet<>(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//根据测评规则的类型不同
|
|
|
|
Integer evaluationType = evaluationRules.getEvaluationType(); |
|
|
|
Integer evaluationType = evaluationRules.getEvaluationType(); |
|
|
|
if (evaluationType.equals(Constant.RulesType.RANDOM.getType())) {//随机
|
|
|
|
if (evaluationType.equals(Constant.RulesType.RANDOM.getType())) {//随机
|
|
|
|
// 类型为随机,直接用题目数量
|
|
|
|
// 类型为随机,直接用题目数量
|
|
|
|
Integer questionNum = evaluationRules.getQuestionNum(); |
|
|
|
Integer questionNum = evaluationRules.getQuestionNum(); |
|
|
|
// 查询题库所有未删除,未禁用的题目id
|
|
|
|
// 查询题库所有未删除,未禁用的题目id
|
|
|
|
List<QuestionsEntity> questions = this.list(queryWrapper); |
|
|
|
List<QuestionsEntity> questions = this.list(queryWrapper); |
|
|
|
|
|
|
|
|
|
|
|
set = getRandomList(questionNum, questions); |
|
|
|
set = getRandomList(questionNum, questions); |
|
|
|
|
|
|
|
|
|
|
|
} else if (evaluationType.equals(Constant.RulesType.CUSTOMIZE.getType())) {//自定义
|
|
|
|
} else if (evaluationType.equals(Constant.RulesType.CUSTOMIZE.getType())) {//自定义
|
|
|
|
|
|
|
|
|
|
|
|
// 单选题数量
|
|
|
|
// 单选题数量
|
|
|
|
int singleNum = 0; |
|
|
|
int singleNum = 0; |
|
|
|
// 多选题数量
|
|
|
|
// 多选题数量
|
|
|
@ -405,22 +481,51 @@ public class QuestionsServiceImpl extends ServiceImpl<QuestionsDao, QuestionsEnt |
|
|
|
// 总题数等于各类题目数量之和
|
|
|
|
// 总题数等于各类题目数量之和
|
|
|
|
evaluation.setQuestionNum(singleNum + multipleNum + judgmentNum); |
|
|
|
evaluation.setQuestionNum(singleNum + multipleNum + judgmentNum); |
|
|
|
} |
|
|
|
} |
|
|
|
Set<QuestionsVO> collect = set.stream().map(item -> { |
|
|
|
// Set<QuestionsVO> collect = set.stream().map(item -> {
|
|
|
|
QuestionsVO questionsVO = new QuestionsVO(); |
|
|
|
// QuestionsVO questionsVO = new QuestionsVO();
|
|
|
|
BeanUtils.copyProperties(item, questionsVO); |
|
|
|
// BeanUtils.copyProperties(item, questionsVO);
|
|
|
|
questionsVO.setCreateTime(handleTime(item.getCreateTime())); |
|
|
|
// return questionsVO;
|
|
|
|
questionsVO.setModifyTime(handleTime(item.getModifyTime())); |
|
|
|
// }).collect(Collectors.toSet());
|
|
|
|
return questionsVO; |
|
|
|
evaluation.setQuestions(set); |
|
|
|
}).collect(Collectors.toSet()); |
|
|
|
|
|
|
|
evaluation.setQuestions(collect); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return evaluation; |
|
|
|
return evaluation; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private int getSecondTimestamp(Date date) { |
|
|
|
|
|
|
|
if (null == date) { |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
String timestamp = String.valueOf(date.getTime() / 1000 / 60); |
|
|
|
|
|
|
|
return Integer.valueOf(timestamp); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private String formatDateTime(long mss) { |
|
|
|
|
|
|
|
String DateTimes; |
|
|
|
|
|
|
|
long hours = (mss % (60 * 24)) / (60); |
|
|
|
|
|
|
|
long minutes = (mss % (60)); |
|
|
|
|
|
|
|
//long seconds = mss % 60;
|
|
|
|
|
|
|
|
if (hours > 0) { |
|
|
|
|
|
|
|
if (hours < 10) { |
|
|
|
|
|
|
|
DateTimes = "0" + hours + ":" + minutes; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
DateTimes = hours + ":" + minutes; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
DateTimes = "00:" + minutes; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return DateTimes; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void exportQuestion(HttpServletResponse response) throws Exception { |
|
|
|
public void exportQuestion(HttpServletResponse response) throws Exception { |
|
|
|
|
|
|
|
// 请求包装类
|
|
|
|
|
|
|
|
QueryWrapper<QuestionsEntity> queryWrapper = new QueryWrapper<>(); |
|
|
|
|
|
|
|
// 只查询未被删除且启用的试题
|
|
|
|
|
|
|
|
queryWrapper.eq("is_del", Constant.IsDel.NOT_DEL.getType()) |
|
|
|
|
|
|
|
.eq("is_enable", Constant.IsEnable.ENABLE.getType()); //启用
|
|
|
|
//1.构造数据
|
|
|
|
//1.构造数据
|
|
|
|
List<QuestionsImportRequest> list = this.list().stream().map(item -> { |
|
|
|
List<QuestionsImportRequest> list = this.list(queryWrapper).stream().map(item -> { |
|
|
|
QuestionsImportRequest importRequest = new QuestionsImportRequest(); |
|
|
|
QuestionsImportRequest importRequest = new QuestionsImportRequest(); |
|
|
|
BeanUtils.copyProperties(item, importRequest); |
|
|
|
BeanUtils.copyProperties(item, importRequest); |
|
|
|
return importRequest; |
|
|
|
return importRequest; |
|
|
@ -436,13 +541,16 @@ public class QuestionsServiceImpl extends ServiceImpl<QuestionsDao, QuestionsEnt |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private Set<QuestionsEntity> getRandomList(int len, List<QuestionsEntity> list) { |
|
|
|
private Set<QuestionsVO> getRandomList(int len, List<QuestionsEntity> list) { |
|
|
|
Set<QuestionsEntity> set = new HashSet<>(); |
|
|
|
Set<QuestionsVO> set = new HashSet<>(); |
|
|
|
Random random = new Random(); |
|
|
|
Random random = new Random(); |
|
|
|
int i; |
|
|
|
int i; |
|
|
|
while (true) { |
|
|
|
while (true) { |
|
|
|
i = random.nextInt(list.size()); |
|
|
|
i = random.nextInt(list.size()); |
|
|
|
set.add(list.get(i)); |
|
|
|
QuestionsVO questionsVO = new QuestionsVO(); |
|
|
|
|
|
|
|
BeanUtils.copyProperties(list.get(i), questionsVO); |
|
|
|
|
|
|
|
questionsVO.setQuestionTypeName(getQuestionTypeName(list.get(i).getQuestionType())); |
|
|
|
|
|
|
|
set.add(questionsVO); |
|
|
|
if (set.size() >= len) { |
|
|
|
if (set.size() >= len) { |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|