From 0fd60e01f9a268de9ae6e7bc5c5d8192ae844cfc Mon Sep 17 00:00:00 2001
From: shijie <648688341@qq.com>
Date: Wed, 26 Aug 2020 11:49:35 +0800
Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=EF=BC=8C=E4=BF=AE=E6=94=B9?=
=?UTF-8?q?=EF=BC=8C=E6=89=B9=E9=87=8F=E5=AF=BC=E5=85=A5=E8=AF=95=E9=A2=98?=
=?UTF-8?q?=EF=BC=8C=E9=87=8D=E5=A4=8D=E6=A0=A1=E9=AA=8C=E4=BF=AE=E6=94=B9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 10 +
.../msdw/tms/api/QuestionsControllerApi.java | 2 +-
.../tms/common/utils/poi/ExcelImportUtil.java | 3 +
.../tms/controller/QuestionsController.java | 9 +-
.../java/com/msdw/tms/dao/QuestionsDao.java | 3 +-
.../com/msdw/tms/entity/QuestionsEntity.java | 9 +-
.../entity/request/QuestionsAddRequest.java | 13 +-
.../request/QuestionsImportRequest.java | 6 +-
.../entity/request/QuestionsQueryRequest.java | 6 +-
.../request/QuestionsUpdateRequest.java | 6 +-
.../msdw/tms/entity/response/CommonCode.java | 6 +-
.../com/msdw/tms/entity/vo/EvaluationVO.java | 4 +
.../msdw/tms/entity/vo/QuestionsDetailVO.java | 35 +-
.../msdw/tms/entity/vo/QuestionsListVO.java | 8 +-
.../com/msdw/tms/entity/vo/QuestionsVO.java | 43 +--
.../msdw/tms/service/QuestionsService.java | 4 +-
.../service/impl/QuestionsServiceImpl.java | 330 ++++++++++++------
src/main/resources/application.yml | 7 +-
.../resources/mapper/tms/QuestionsDao.xml | 5 +-
.../com/msdw/tms/TmsApplicationTests.java | 128 +++++++
.../tms/service/QuestionsServiceTest.java | 6 +-
21 files changed, 413 insertions(+), 230 deletions(-)
diff --git a/pom.xml b/pom.xml
index 5d3a89c..802b602 100644
--- a/pom.xml
+++ b/pom.xml
@@ -118,6 +118,16 @@
1.4
test
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
diff --git a/src/main/java/com/msdw/tms/api/QuestionsControllerApi.java b/src/main/java/com/msdw/tms/api/QuestionsControllerApi.java
index e4bc664..82b731d 100644
--- a/src/main/java/com/msdw/tms/api/QuestionsControllerApi.java
+++ b/src/main/java/com/msdw/tms/api/QuestionsControllerApi.java
@@ -81,7 +81,7 @@ public interface QuestionsControllerApi {
* 抽题测评
*/
@ApiOperation(value = "抽题测评", notes = "抽题测评")
- R evaluation ();
+ R evaluation (Integer userId);
/**
* 通过excel批量导出
diff --git a/src/main/java/com/msdw/tms/common/utils/poi/ExcelImportUtil.java b/src/main/java/com/msdw/tms/common/utils/poi/ExcelImportUtil.java
index bbcc8ba..1ad8ec6 100644
--- a/src/main/java/com/msdw/tms/common/utils/poi/ExcelImportUtil.java
+++ b/src/main/java/com/msdw/tms/common/utils/poi/ExcelImportUtil.java
@@ -53,6 +53,9 @@ public class ExcelImportUtil {
}
}
}
+ Field field = entity.getClass().getDeclaredField("index");
+ field.setAccessible(true);
+ field.set(entity, rowNum);
list.add(entity);
}
} catch (Exception e) {
diff --git a/src/main/java/com/msdw/tms/controller/QuestionsController.java b/src/main/java/com/msdw/tms/controller/QuestionsController.java
index 7b0e97b..1763e08 100644
--- a/src/main/java/com/msdw/tms/controller/QuestionsController.java
+++ b/src/main/java/com/msdw/tms/controller/QuestionsController.java
@@ -115,9 +115,10 @@ public class QuestionsController implements QuestionsControllerApi {
@PostMapping("/import")
//@RequiresPermissions("qms:questions:import")
public R importQuestion(@RequestParam(name = "file") MultipartFile file) throws IOException {
- boolean b = questionsService.importQuestion(file);
+ //TODO boolean b = questionsService.importQuestion(file);
- return b ? R.ok() : R.error();
+ //return b ? R.ok() : R.error();
+ return null;
}
/**
@@ -144,8 +145,8 @@ public class QuestionsController implements QuestionsControllerApi {
@Override
@GetMapping("/evaluation")
- public R evaluation() {
- EvaluationVO evaluation = questionsService.evaluation();
+ public R evaluation(Integer userId) {
+ EvaluationVO evaluation = questionsService.evaluation(userId);
return R.ok().put("data", evaluation);
}
diff --git a/src/main/java/com/msdw/tms/dao/QuestionsDao.java b/src/main/java/com/msdw/tms/dao/QuestionsDao.java
index 6775d13..036c9e6 100644
--- a/src/main/java/com/msdw/tms/dao/QuestionsDao.java
+++ b/src/main/java/com/msdw/tms/dao/QuestionsDao.java
@@ -1,7 +1,7 @@
package com.msdw.tms.dao;
-import com.msdw.tms.entity.QuestionsEntity;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.msdw.tms.entity.QuestionsEntity;
import org.apache.ibatis.annotations.Mapper;
/**
@@ -13,5 +13,4 @@ import org.apache.ibatis.annotations.Mapper;
*/
@Mapper
public interface QuestionsDao extends BaseMapper {
-
}
diff --git a/src/main/java/com/msdw/tms/entity/QuestionsEntity.java b/src/main/java/com/msdw/tms/entity/QuestionsEntity.java
index 20cc204..a536930 100644
--- a/src/main/java/com/msdw/tms/entity/QuestionsEntity.java
+++ b/src/main/java/com/msdw/tms/entity/QuestionsEntity.java
@@ -23,13 +23,9 @@ public class QuestionsEntity implements Serializable {
@TableId
private Integer id;
/**
- * 题型号:1、单选题,2、多选题,3、判断题
+ * 题型:1、单选题,2、多选题,3、判断题
*/
- private Integer questionTypeNo;
- /**
- * 题型名称
- */
- private String questionType;
+ private Integer questionType;
/**
* 题干信息
*/
@@ -94,5 +90,4 @@ public class QuestionsEntity implements Serializable {
* 试题科目
*/
private String subjects;
-
}
diff --git a/src/main/java/com/msdw/tms/entity/request/QuestionsAddRequest.java b/src/main/java/com/msdw/tms/entity/request/QuestionsAddRequest.java
index 8c52299..5da4a57 100644
--- a/src/main/java/com/msdw/tms/entity/request/QuestionsAddRequest.java
+++ b/src/main/java/com/msdw/tms/entity/request/QuestionsAddRequest.java
@@ -4,6 +4,8 @@ import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
+import javax.validation.constraints.NotNull;
+
/**
* 试题的基本信息表
*
@@ -13,10 +15,10 @@ import lombok.Data;
@ApiModel(value = "QuestionsAddRequest", description = "添加试题请求体对象")
public class QuestionsAddRequest {
/**
- * 题型名称
+ * 题型:1、单选题,2、多选题,3、判断题
*/
- @ApiModelProperty(value = "题型名称", name = "questionType", example = "单选题", required = true)
- private String questionType;
+ @ApiModelProperty(value = "题型:1、单选题,2、多选题,3、判断题", name = "questionType", example = "1", required = true)
+ private Integer questionType;
/**
* 题干信息
*/
@@ -62,9 +64,4 @@ public class QuestionsAddRequest {
*/
@ApiModelProperty(value = "答案解析", name = "answerAnalysis", example = "鲸鱼是最大的哺乳动物")
private String answerAnalysis;
- /**
- * 试题科目
- */
- @ApiModelProperty(value = "试题科目", name = "subjects", example = "基础通识")
- private String subjects;
}
diff --git a/src/main/java/com/msdw/tms/entity/request/QuestionsImportRequest.java b/src/main/java/com/msdw/tms/entity/request/QuestionsImportRequest.java
index e671e12..7dcb5e1 100644
--- a/src/main/java/com/msdw/tms/entity/request/QuestionsImportRequest.java
+++ b/src/main/java/com/msdw/tms/entity/request/QuestionsImportRequest.java
@@ -10,6 +10,10 @@ import lombok.Data;
*/
@Data
public class QuestionsImportRequest {
+ /**
+ * 第几行
+ */
+ private Integer index;
/**
* 题干,问题描述
@@ -20,7 +24,7 @@ public class QuestionsImportRequest {
* 题型
*/
@ExcelAttribute(sort = 1)
- private String questionType;
+ private String questionTypeName;
/**
* 选项A
*/
diff --git a/src/main/java/com/msdw/tms/entity/request/QuestionsQueryRequest.java b/src/main/java/com/msdw/tms/entity/request/QuestionsQueryRequest.java
index f73f4a3..0e96b33 100644
--- a/src/main/java/com/msdw/tms/entity/request/QuestionsQueryRequest.java
+++ b/src/main/java/com/msdw/tms/entity/request/QuestionsQueryRequest.java
@@ -20,10 +20,10 @@ public class QuestionsQueryRequest {
private String questionStem;
/**
- * 题型id
+ * 题型
*/
- @ApiModelProperty(value = "题型号:1、单选题,2、多选题,3、判断题", name = "questionTypeNo", example = "1")
- private Integer questionTypeNo;
+ @ApiModelProperty(value = "题型:1、单选题,2、多选题,3、判断题", name = "questionType", example = "1")
+ private Integer questionType;
// /**
// * 参考答案
// */
diff --git a/src/main/java/com/msdw/tms/entity/request/QuestionsUpdateRequest.java b/src/main/java/com/msdw/tms/entity/request/QuestionsUpdateRequest.java
index 494a20c..c84895a 100644
--- a/src/main/java/com/msdw/tms/entity/request/QuestionsUpdateRequest.java
+++ b/src/main/java/com/msdw/tms/entity/request/QuestionsUpdateRequest.java
@@ -18,10 +18,10 @@ public class QuestionsUpdateRequest {
@ApiModelProperty(value = "主键", name = "id", example = "1", required = true)
private Integer id;
/**
- * 题型名称
+ * 题型:1、单选题,2、多选题,3、判断题
*/
- @ApiModelProperty(value = "题型名称", name = "questionType", example = "单选题", required = true)
- private String questionType;
+ @ApiModelProperty(value = "题型:1、单选题,2、多选题,3、判断题", name = "questionType", example = "1", required = true)
+ private Integer questionType;
/**
* 题干信息
*/
diff --git a/src/main/java/com/msdw/tms/entity/response/CommonCode.java b/src/main/java/com/msdw/tms/entity/response/CommonCode.java
index 19b0501..23b65c5 100644
--- a/src/main/java/com/msdw/tms/entity/response/CommonCode.java
+++ b/src/main/java/com/msdw/tms/entity/response/CommonCode.java
@@ -10,8 +10,10 @@ public enum CommonCode implements ResultCode {
UNAUTHORISE(false, 10002, "权限不足,无权操作!"),
INVALID_PARAM(false, 10003, "非法参数!"),
QUESTION_NUM_INVALID(false, 10004, "测评题目数量设置超出范围!"),
- QUESTION_EXISTS(false, 10005, "此题目已存在!"),
- QUESTIONTYPE_INVALID(false, 10005, "题型错误!"),
+ QUESTION_EXISTS(false, 10005, "此题已存在!"),
+ QUESTIONTYPE_INVALID(false, 10006, "题型错误!"),
+ EXCEL_INVALID(false, 10007, "excel表内容错误!"),
+ EVALUATION_TIME_INVALID(false, 10008, "测评时间错误!"),
FAIL(false, 11111, "操作失败!"),
SERVER_ERROR(false, 99999, "抱歉,系统繁忙,请稍后重试!");
//操作是否成功
diff --git a/src/main/java/com/msdw/tms/entity/vo/EvaluationVO.java b/src/main/java/com/msdw/tms/entity/vo/EvaluationVO.java
index 68a8172..e6e0b07 100644
--- a/src/main/java/com/msdw/tms/entity/vo/EvaluationVO.java
+++ b/src/main/java/com/msdw/tms/entity/vo/EvaluationVO.java
@@ -27,6 +27,10 @@ public class EvaluationVO implements Serializable {
* 测评时长,单位:分钟
*/
private Integer duration;
+ /**
+ * 当前用户的剩余时长,格式 HH:ss
+ */
+ private String remainingDuration;
/**
* 测评总题数
*/
diff --git a/src/main/java/com/msdw/tms/entity/vo/QuestionsDetailVO.java b/src/main/java/com/msdw/tms/entity/vo/QuestionsDetailVO.java
index 9851391..8c5bcfc 100644
--- a/src/main/java/com/msdw/tms/entity/vo/QuestionsDetailVO.java
+++ b/src/main/java/com/msdw/tms/entity/vo/QuestionsDetailVO.java
@@ -17,13 +17,13 @@ public class QuestionsDetailVO implements Serializable {
*/
private Integer id;
/**
- * 题型号:用于区分是什么题型,1:单选,2:多选,3:判断
+ * 题型:用于区分是什么题型,1:单选,2:多选,3:判断
*/
- private Integer questionTypeNo;
+ private Integer questionType;
/**
* 题型名称
*/
- private String questionType;
+ private String questionTypeName;
/**
* 题干信息
*/
@@ -84,33 +84,4 @@ public class QuestionsDetailVO implements Serializable {
* 答案解析
*/
private String answerAnalysis;
- /**
- * 是否禁用:1:启用,0:禁用,默认是1启用
- */
- private Integer isEnable;
- /**
- * 是否删除:0使用,1删除,默认0使用
- */
- private Integer isDel;
- /**
- * 创建人
- */
- private String createUser;
- /**
- * 创建时间
- */
- private String createTime;
- /**
- * 修改人
- */
- private String modifyUser;
- /**
- * 修改时间,用于排序,创建时,修改时间等于创建时间
- */
- private String modifyTime;
- /**
- * 试题科目
- */
- private String subjects;
-
}
diff --git a/src/main/java/com/msdw/tms/entity/vo/QuestionsListVO.java b/src/main/java/com/msdw/tms/entity/vo/QuestionsListVO.java
index 5987f22..f6af3d1 100644
--- a/src/main/java/com/msdw/tms/entity/vo/QuestionsListVO.java
+++ b/src/main/java/com/msdw/tms/entity/vo/QuestionsListVO.java
@@ -19,13 +19,9 @@ public class QuestionsListVO implements Serializable {
*/
private Integer id;
/**
- * 题型号:用于区分是什么题型
+ * 题型:1、单选题,2、多选题,3、判断题
*/
- private Integer questionTypeNo;
- /**
- * 题型名称
- */
- private String questionType;
+ private String questionTypeName;
/**
* 题干信息
*/
diff --git a/src/main/java/com/msdw/tms/entity/vo/QuestionsVO.java b/src/main/java/com/msdw/tms/entity/vo/QuestionsVO.java
index 9c7cf9c..6f15a95 100644
--- a/src/main/java/com/msdw/tms/entity/vo/QuestionsVO.java
+++ b/src/main/java/com/msdw/tms/entity/vo/QuestionsVO.java
@@ -18,14 +18,10 @@ public class QuestionsVO implements Serializable {
* 主键
*/
private Integer id;
- /**
- * 题型号:用于区分是什么题型
- */
- private Integer questionTypeNo;
/**
* 题型名称
*/
- private String questionType;
+ private String questionTypeName;
/**
* 题干信息
*/
@@ -54,41 +50,4 @@ public class QuestionsVO implements Serializable {
* F选项内容
*/
private String optionF;
- /**
- * 正确答案
- */
- private String answer;
- /**
- * 答案解析
- */
- private String answerAnalysis;
- /**
- * 是否禁用:1:启用,0:禁用,默认是1启用
- */
- private Integer isEnable;
- /**
- * 是否删除:0使用,1删除,默认0使用
- */
- private Integer isDel;
- /**
- * 创建人
- */
- private String createUser;
- /**
- * 创建时间
- */
- private String createTime;
- /**
- * 修改人
- */
- private String modifyUser;
- /**
- * 修改时间,用于排序,创建时,修改时间等于创建时间
- */
- private String modifyTime;
- /**
- * 试题科目
- */
- private String subjects;
-
}
diff --git a/src/main/java/com/msdw/tms/service/QuestionsService.java b/src/main/java/com/msdw/tms/service/QuestionsService.java
index 9da3bf7..a55d45a 100644
--- a/src/main/java/com/msdw/tms/service/QuestionsService.java
+++ b/src/main/java/com/msdw/tms/service/QuestionsService.java
@@ -38,13 +38,13 @@ public interface QuestionsService extends IService {
boolean deleteByIds(List asList);
- boolean importQuestion(MultipartFile file) throws IOException;
+ List importQuestion(MultipartFile file) throws IOException;
FilesResult uploadFiles(MultipartFile file) throws IOException;
void downloadFiles(HttpServletResponse response) throws IOException;
- EvaluationVO evaluation();
+ EvaluationVO evaluation(Integer userId);
void exportQuestion(HttpServletResponse response) throws Exception;
}
diff --git a/src/main/java/com/msdw/tms/service/impl/QuestionsServiceImpl.java b/src/main/java/com/msdw/tms/service/impl/QuestionsServiceImpl.java
index 77ab261..343c911 100644
--- a/src/main/java/com/msdw/tms/service/impl/QuestionsServiceImpl.java
+++ b/src/main/java/com/msdw/tms/service/impl/QuestionsServiceImpl.java
@@ -26,6 +26,8 @@ import com.msdw.tms.service.XlsxTemplateService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
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.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
@@ -39,6 +41,7 @@ import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
+import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@Service("questionsService")
@@ -53,6 +56,11 @@ public class QuestionsServiceImpl extends ServiceImpl().getPage(page, size),
queryWrapper
);
-
List records = questionsIPage.getRecords();
List questions = records.stream().map(question -> {
QuestionsListVO questionsListVO = new QuestionsListVO();
BeanUtils.copyProperties(question, questionsListVO);
-
+ //处理试题类型
+ String questionTypeName = getQuestionTypeName(question.getQuestionType());
+ questionsListVO.setQuestionTypeName(questionTypeName);
//处理时间格式
questionsListVO.setModifyTime(handleTime(question.getModifyTime()));
-
return questionsListVO;
}).collect(Collectors.toList());
-
PageUtils questionsPage = new PageUtils(questionsIPage);
-
questionsPage.setList(questions);
-
return questionsPage;
}
@@ -123,11 +124,9 @@ public class QuestionsServiceImpl extends ServiceImpl queryWrapper = new QueryWrapper<>();
- queryWrapper.eq("is_del", Constant.IsDel.NOT_DEL.getType())
- .eq("question_stem", questions.getQuestionStem());
+ //校验题型是否正确
+ checkType(questions.getQuestionType());
+
+ // 校验重复,不仅要校验题干,还要校验选项
+ QuestionsEntity questionsEntity = new QuestionsEntity();
+ BeanUtils.copyProperties(questions, questionsEntity);
+
+ //构造根据内容查询试题数量的Wrapper
+ QueryWrapper queryWrapper = constructDistinctWrapper(questionsEntity);
+
int count = this.count(queryWrapper);
if (count > 0) {//说明已存在
//抛出题目已存在异常
ExceptionCast.cast(CommonCode.QUESTION_EXISTS);
}
-
// 将传入的对象内容拷贝到QuestionsEntity并返回
- QuestionsEntity questionsEntity = getQuestionsEntity(questions);
-
questionsEntity.setCreateTime(new Date());
questionsEntity.setModifyTime(new Date());
//TODO 创建者和修改者。。。
@@ -187,28 +213,33 @@ public class QuestionsServiceImpl extends ServiceImpl 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是否存在
if (this.getById(questions.getId()) == null) {
ExceptionCast.cast(CommonCode.INVALID_PARAM);
}
- // 将传入的对象内容拷贝到QuestionsEntity并返回
- QuestionsEntity questionsEntity = getQuestionsEntity(questions);
+ //校验题型是否正确
+ checkType(questions.getQuestionType());
+
+ //校验题干和内容重复
+ QuestionsEntity questionsEntity = new QuestionsEntity();
+ BeanUtils.copyProperties(questions, questionsEntity);
+ //构造根据内容查询试题数量的Wrapper
+ QueryWrapper 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());
//TODO 设置修改者。。。
@@ -216,28 +247,41 @@ public class QuestionsServiceImpl extends ServiceImpl QuestionsEntity getQuestionsEntity(T questions) {
- QuestionsEntity questionsEntity = new QuestionsEntity();
-
- BeanUtils.copyProperties(questions, questionsEntity);
-
- String questionType = questionsEntity.getQuestionType();
- //根据题型名称得到题型号
- 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 {// 判断题型是否不存在
- //说明题型不正确
+ private void checkType(int type) {
+ boolean include = false;
+ for (Constant.QuestionType value : Constant.QuestionType.values()) {
+ if (value.getType().equals(type)) {
+ include = true;
+ }
+ }
+ if (!include) {//题型不在枚举类中,不正确
ExceptionCast.cast(CommonCode.QUESTIONTYPE_INVALID);
}
- return questionsEntity;
+ }
+
+ private QueryWrapper constructDistinctWrapper(QuestionsEntity questions) {
+ QueryWrapper 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
@@ -248,10 +292,10 @@ public class QuestionsServiceImpl extends ServiceImpl importQuestion(MultipartFile file) throws IOException {
// 使用excel导入工具类获取试题数据列表
List list = new ExcelImportUtil(QuestionsImportRequest.class)
.readExcel(file.getInputStream(), Constant.STARTING_ROW, Constant.STARTING_CELL);
if (list == null || list.size() == 0) {
- ExceptionCast.cast(CommonCode.INVALID_PARAM);
+ ExceptionCast.cast(CommonCode.EXCEL_INVALID);
}
- List collect = list.stream().map(item -> {
- int count = this.count(new QueryWrapper().eq("question_stem", item.getQuestionStem()));
- if (count > 0) {//说明已存在
- return null;
- }
+ List failureRecord = new ArrayList<>();
+
+ for (int i = 0; i < list.size(); i++) {
+ QuestionsImportRequest question = list.get(i);
+ //校验题干和内容重复
QuestionsEntity questionsEntity = new QuestionsEntity();
- BeanUtils.copyProperties(item, questionsEntity);
- String questionType = item.getQuestionType();
+ BeanUtils.copyProperties(question, questionsEntity);
+ 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());
- } else if (questionType.equals(Constant.QuestionType.MULTIPLE_CHOICE.getDesc())) {
+ questionsEntity.setQuestionType(Constant.QuestionType.SINGLE_CHOICE.getType());
+ } else if (questionTypeName.equals(Constant.QuestionType.MULTIPLE_CHOICE.getDesc())) {
//多选题
- questionsEntity.setQuestionTypeNo(Constant.QuestionType.MULTIPLE_CHOICE.getType());
- } else if (questionType.equals(Constant.QuestionType.TRUE_OR_FALSE.getDesc())) {
+ questionsEntity.setQuestionType(Constant.QuestionType.MULTIPLE_CHOICE.getType());
+ } 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 {
// 题型不正确
- return null;
+ failureRecord.add("第 " + question.getIndex() + " 行导入失败," + "题干:" + question.getQuestionStem() + ",失败信息:" + CommonCode.QUESTIONTYPE_INVALID.message());
+ continue;
}
+
+ //构造根据内容查询试题数量的Wrapper
+ QueryWrapper 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.setModifyTime(new Date());
- //TODO 创建者和修改者。。。
- return questionsEntity;
- }).filter(Objects::nonNull)// 过滤掉为null的对象
- .collect(Collectors.collectingAndThen(// 去重收集
- Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(QuestionsEntity::getQuestionStem))),
- ArrayList::new
- ));
-
- // 批量新增
- return this.saveBatch(collect);
+
+ this.save(questionsEntity);
+ }
+
+ return failureRecord;
}
/**
@@ -343,14 +396,12 @@ public class QuestionsServiceImpl extends ServiceImpl queryWrapper = new QueryWrapper<>();
queryWrapper.eq("is_del", Constant.IsDel.NOT_DEL.getType()) //未删除
.eq("is_enable", Constant.IsEnable.ENABLE.getType()); //启用
- Set set = new HashSet<>();
-
// 查询测评规则类型
EvaluationRulesVO evaluationRules = evaluationRulesService.getEvaluationRules();
@@ -358,17 +409,46 @@ public class QuestionsServiceImpl extends ServiceImpl 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 set = new HashSet<>();
+
+ //根据测评规则的类型不同
Integer evaluationType = evaluationRules.getEvaluationType();
if (evaluationType.equals(Constant.RulesType.RANDOM.getType())) {//随机
// 类型为随机,直接用题目数量
Integer questionNum = evaluationRules.getQuestionNum();
// 查询题库所有未删除,未禁用的题目id
List questions = this.list(queryWrapper);
-
set = getRandomList(questionNum, questions);
-
} else if (evaluationType.equals(Constant.RulesType.CUSTOMIZE.getType())) {//自定义
-
// 单选题数量
int singleNum = 0;
// 多选题数量
@@ -401,22 +481,51 @@ public class QuestionsServiceImpl extends ServiceImpl collect = set.stream().map(item -> {
- QuestionsVO questionsVO = new QuestionsVO();
- BeanUtils.copyProperties(item, questionsVO);
- questionsVO.setCreateTime(handleTime(item.getCreateTime()));
- questionsVO.setModifyTime(handleTime(item.getModifyTime()));
- return questionsVO;
- }).collect(Collectors.toSet());
- evaluation.setQuestions(collect);
+// Set collect = set.stream().map(item -> {
+// QuestionsVO questionsVO = new QuestionsVO();
+// BeanUtils.copyProperties(item, questionsVO);
+// return questionsVO;
+// }).collect(Collectors.toSet());
+ evaluation.setQuestions(set);
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
public void exportQuestion(HttpServletResponse response) throws Exception {
+ // 请求包装类
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ // 只查询未被删除且启用的试题
+ queryWrapper.eq("is_del", Constant.IsDel.NOT_DEL.getType())
+ .eq("is_enable", Constant.IsEnable.ENABLE.getType()); //启用
//1.构造数据
- List list = this.list().stream().map(item -> {
+ List list = this.list(queryWrapper).stream().map(item -> {
QuestionsImportRequest importRequest = new QuestionsImportRequest();
BeanUtils.copyProperties(item, importRequest);
return importRequest;
@@ -432,13 +541,16 @@ public class QuestionsServiceImpl extends ServiceImpl getRandomList(int len, List list) {
- Set set = new HashSet<>();
+ private Set getRandomList(int len, List list) {
+ Set set = new HashSet<>();
Random random = new Random();
int i;
while (true) {
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) {
break;
}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index a3214e8..a9643f9 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -4,6 +4,10 @@ spring:
username: super
password: huoran888
driver-class-name: com.mysql.jdbc.Driver
+ redis:
+ host: www.liuwanr.cn
+ port: 6379
+ password: huoran
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 这个配置会将执行的sql打印出来,在开发或测试的时候可以用
@@ -12,4 +16,5 @@ mybatis-plus:
db-config:
id-type: auto
server:
- port: 7000
\ No newline at end of file
+ port: 7000
+
diff --git a/src/main/resources/mapper/tms/QuestionsDao.xml b/src/main/resources/mapper/tms/QuestionsDao.xml
index 30a3679..e0a9504 100644
--- a/src/main/resources/mapper/tms/QuestionsDao.xml
+++ b/src/main/resources/mapper/tms/QuestionsDao.xml
@@ -3,10 +3,9 @@
-
+
-
@@ -25,6 +24,4 @@
-
-
\ No newline at end of file
diff --git a/src/test/java/com/msdw/tms/TmsApplicationTests.java b/src/test/java/com/msdw/tms/TmsApplicationTests.java
index 24d89f8..717bf72 100644
--- a/src/test/java/com/msdw/tms/TmsApplicationTests.java
+++ b/src/test/java/com/msdw/tms/TmsApplicationTests.java
@@ -1,10 +1,21 @@
package com.msdw.tms;
import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.data.redis.core.ValueOperations;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
@SpringBootTest
class TmsApplicationTests {
@@ -87,4 +98,121 @@ class TmsApplicationTests {
return k;
}
+ private String formatDateTime(long mss) {
+ String DateTimes = null;
+ long days = mss / (60 * 60 * 24);
+ long hours = (mss % (60 * 60 * 24)) / (60 * 60);
+ long minutes = (mss % (60 * 60)) / 60;
+ long seconds = mss % 60;
+ if (days > 0) {
+ DateTimes = days + "天" + hours + "小时" + minutes + "分钟"
+ + seconds + "秒";
+ } else if (hours > 0) {
+ DateTimes = hours + "小时" + minutes + "分钟"
+ + seconds + "秒";
+ } else if (minutes > 0) {
+ DateTimes = minutes + "分钟"
+ + seconds + "秒";
+ } else {
+ DateTimes = seconds + "秒";
+ }
+
+ return DateTimes;
+ }
+
+ private String formatDateTime2(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;
+ }
+
+ @Test
+ void t2() {
+ long mss = 150;
+ String ss = formatDateTime2(mss);
+ System.out.println(ss);
+ }
+
+ /**
+ * 获取精确到秒的时间戳
+ *
+ * @param date
+ * @return
+ */
+ private int getSecondTimestampTwo(Date date) {
+ if (null == date) {
+ return 0;
+ }
+ String timestamp = String.valueOf(date.getTime() / 1000 / 60);
+ return Integer.valueOf(timestamp);
+ }
+
+ @Test
+ void t3() {
+ String s = handleTime(new Date());
+ System.out.println("ssss" + s);
+
+ int secondTimestampTwo = getSecondTimestampTwo(new Date());
+ System.out.println(secondTimestampTwo);
+ long l = System.currentTimeMillis();
+ System.out.println("----" + new Date().getTime());
+ System.out.println("====" + System.currentTimeMillis());
+
+ // System.currentTimeMillis() / (long)1000 / (long)60;
+ }
+
+ @Test
+ void t4() throws ParseException {
+ Date date = getDate("2020-08-26 09:13:51");
+
+ int secondTimestampTwo = getSecondTimestampTwo(date);
+
+ int secondTimestampTwo1 = getSecondTimestampTwo(new Date());
+
+ int i = secondTimestampTwo1 - secondTimestampTwo;
+
+ System.out.println(i);
+ // System.currentTimeMillis() / (long)1000 / (long)60;
+ }
+
+ //处理时间格式
+ private String handleTime(Date date) {
+ Instant instant = date.toInstant();
+ ZoneId zoneId = ZoneId.systemDefault();
+ LocalDateTime localDateTime = instant.atZone(zoneId).toLocalDateTime();
+ return localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); // 当前日期和时间
+ }
+
+ private Date getDate(String dateStr) throws ParseException {
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//注意月份是MM
+ Date date = simpleDateFormat.parse(dateStr);
+ System.out.println(date); //Mon Sep 02 00:00:00 CST 2019
+ System.out.println(simpleDateFormat.format(date)); //2019-09-02
+ return date;
+ }
+
+
+ @Autowired
+ StringRedisTemplate stringRedisTemplate;
+
+
+ @Test
+ void t5() throws ParseException {
+
+ ValueOperations ops = stringRedisTemplate.opsForValue();
+
+ ops.set("aaa", "sss", 30, TimeUnit.SECONDS);
+ }
}
diff --git a/src/test/java/com/msdw/tms/service/QuestionsServiceTest.java b/src/test/java/com/msdw/tms/service/QuestionsServiceTest.java
index 8e84695..5493328 100644
--- a/src/test/java/com/msdw/tms/service/QuestionsServiceTest.java
+++ b/src/test/java/com/msdw/tms/service/QuestionsServiceTest.java
@@ -93,9 +93,9 @@ class QuestionsServiceTest {
IOUtils.copy(new FileInputStream(file), fileItem.getOutputStream());
MultipartFile multipartFile = new CommonsMultipartFile(fileItem);
- boolean b = questionsService.importQuestion(multipartFile);
+ List strings = questionsService.importQuestion(multipartFile);
- System.out.println(b);
+ System.out.println(strings.toString());
}
@Test
@@ -121,7 +121,7 @@ class QuestionsServiceTest {
@Test
void evaluation() {
- EvaluationVO evaluation = questionsService.evaluation();
+ EvaluationVO evaluation = questionsService.evaluation(1);
System.out.println(evaluation.toString());
}
}