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/ExcelExportUtil.java b/src/main/java/com/msdw/tms/common/utils/poi/ExcelExportUtil.java
index d4d9551..ffe4899 100644
--- a/src/main/java/com/msdw/tms/common/utils/poi/ExcelExportUtil.java
+++ b/src/main/java/com/msdw/tms/common/utils/poi/ExcelExportUtil.java
@@ -74,52 +74,6 @@ public class ExcelExportUtil {
workbook.write(response.getOutputStream());
}
- /**
- * 基于注解导出
- * 参数:
- * response:
- * objs:数据
- * fileName:生成的文件名
- */
-// public void export(HttpServletResponse response, List objs, String fileName) throws Exception {
-//
-// //1.根据模板创建工作簿
-// Workbook workbook = new XSSFWorkbook(); //2007版本
-//
-// fileName = URLEncoder.encode(fileName, "UTF-8");
-//
-// Sheet sheet = workbook.createSheet(fileName);
-//
-// //3.提取公共的样式
-// // CellStyle[] styles = getTemplateStyles(sheet.getRow(styleIndex));
-// //4.根据数据创建每一行和每一个单元格的数据2
-// AtomicInteger datasAi = new AtomicInteger(rowIndex); //数字
-// for (T t : objs) {
-// //datasAi.getAndIncrement() :获取数字,并++ i++
-// Row row = sheet.createRow(datasAi.getAndIncrement());
-// for (int i = 0; i < styles.length; i++) {
-// Cell cell = row.createCell(i);
-// cell.setCellStyle(styles[i]);
-// for (Field field : fields) {
-// if (field.isAnnotationPresent(ExcelAttribute.class)) {
-// field.setAccessible(true);
-// ExcelAttribute ea = field.getAnnotation(ExcelAttribute.class);
-// if (i == ea.sort()) {
-// if (field.get(t) != null) {
-// cell.setCellValue(field.get(t).toString());
-// }
-// }
-// }
-// }
-// }
-// }
-//
-// response.setContentType("application/octet-stream");
-// response.setHeader("content-disposition", "attachment;filename=" + new String(fileName.getBytes("ISO8859-1")));
-// response.setHeader("filename", fileName);
-// workbook.write(response.getOutputStream());
-// }
-
CellStyle[] getTemplateStyles(Row row) {
CellStyle[] styles = new CellStyle[row.getLastCellNum()];
for (int i = 0; i < row.getLastCellNum(); i++) {
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 57c5627..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
@@ -29,7 +29,7 @@ public class ExcelImportUtil {
* 基于注解读取excel
*/
public List readExcel(InputStream is, int rowIndex, int cellIndex) {
- List list = new ArrayList();
+ List list = new ArrayList<>();
T entity = null;
try {
XSSFWorkbook workbook = new XSSFWorkbook(is);
@@ -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 86b767c..1763e08 100644
--- a/src/main/java/com/msdw/tms/controller/QuestionsController.java
+++ b/src/main/java/com/msdw/tms/controller/QuestionsController.java
@@ -88,10 +88,10 @@ public class QuestionsController implements QuestionsControllerApi {
* 是否禁用试题
*/
@Override
- @PutMapping("/isnable")
- //@RequiresPermissions("qms:questions:isnable")
+ @PutMapping("/isenable")
+ //@RequiresPermissions("qms:questions:isenable")
public R isNable(Integer id) {
- boolean b = questionsService.isnable(id);
+ boolean b = questionsService.isEnable(id);
return b ? R.ok() : R.error();
}
@@ -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
new file mode 100644
index 0000000..f6af3d1
--- /dev/null
+++ b/src/main/java/com/msdw/tms/entity/vo/QuestionsListVO.java
@@ -0,0 +1,46 @@
+package com.msdw.tms.entity.vo;
+
+import lombok.Data;
+import lombok.ToString;
+
+import java.io.Serializable;
+
+/**
+ * 试题列表展示信息
+ *
+ * @author gongsj
+ */
+@Data
+@ToString
+public class QuestionsListVO implements Serializable {
+
+ /**
+ * 主键
+ */
+ private Integer id;
+ /**
+ * 题型:1、单选题,2、多选题,3、判断题
+ */
+ private String questionTypeName;
+ /**
+ * 题干信息
+ */
+ private String questionStem;
+ /**
+ * 正确答案
+ */
+ private String answer;
+ /**
+ * 答案解析
+ */
+ private String answerAnalysis;
+ /**
+ * 是否禁用:1:启用,0:禁用,默认是1启用
+ */
+ private Integer isEnable;
+ /**
+ * 修改时间,用于排序,创建时,修改时间等于创建时间
+ */
+ private String modifyTime;
+
+}
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 b1f5fec..a55d45a 100644
--- a/src/main/java/com/msdw/tms/service/QuestionsService.java
+++ b/src/main/java/com/msdw/tms/service/QuestionsService.java
@@ -34,17 +34,17 @@ public interface QuestionsService extends IService {
boolean updateQuestionById(QuestionsUpdateRequest questions);
- boolean isnable(Integer id);
+ boolean isEnable(Integer id);
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 049aa69..343c911 100644
--- a/src/main/java/com/msdw/tms/service/impl/QuestionsServiceImpl.java
+++ b/src/main/java/com/msdw/tms/service/impl/QuestionsServiceImpl.java
@@ -18,10 +18,7 @@ import com.msdw.tms.entity.request.QuestionsImportRequest;
import com.msdw.tms.entity.request.QuestionsQueryRequest;
import com.msdw.tms.entity.request.QuestionsUpdateRequest;
import com.msdw.tms.entity.response.CommonCode;
-import com.msdw.tms.entity.vo.EvaluationRulesVO;
-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.entity.vo.*;
import com.msdw.tms.service.AliyunOssService;
import com.msdw.tms.service.EvaluationRulesService;
import com.msdw.tms.service.QuestionsService;
@@ -29,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;
@@ -42,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")
@@ -56,6 +56,11 @@ public class QuestionsServiceImpl extends ServiceImpl().getPage(page, size),
queryWrapper
);
-
List records = questionsIPage.getRecords();
- List questions = records.stream().map(question -> {
- QuestionsVO questionsVO = new QuestionsVO();
- BeanUtils.copyProperties(question, questionsVO);
-
+ List questions = records.stream().map(question -> {
+ QuestionsListVO questionsListVO = new QuestionsListVO();
+ BeanUtils.copyProperties(question, questionsListVO);
+ //处理试题类型
+ String questionTypeName = getQuestionTypeName(question.getQuestionType());
+ questionsListVO.setQuestionTypeName(questionTypeName);
//处理时间格式
- questionsVO.setCreateTime(handleTime(question.getCreateTime()));
- questionsVO.setModifyTime(handleTime(question.getModifyTime()));
-
- return questionsVO;
+ questionsListVO.setModifyTime(handleTime(question.getModifyTime()));
+ return questionsListVO;
}).collect(Collectors.toList());
-
PageUtils questionsPage = new PageUtils(questionsIPage);
-
questionsPage.setList(questions);
-
return questionsPage;
}
@@ -127,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 创建者和修改者。。。
@@ -191,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 设置修改者。。。
@@ -220,42 +247,55 @@ 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
@Transactional
- public boolean isnable(Integer id) {
+ public boolean isEnable(Integer id) {
QuestionsEntity questionsEntity = new QuestionsEntity();
questionsEntity.setId(id);
QuestionsEntity byId = this.getById(id);
if (byId.getIsEnable().equals(Constant.IsEnable.ENABLE.getType())) {
questionsEntity.setIsEnable(Constant.IsEnable.NOT_ENABLE.getType());
- }
-
- if (byId.getIsEnable().equals(Constant.IsEnable.NOT_ENABLE.getType())) {
+ } else if (byId.getIsEnable().equals(Constant.IsEnable.NOT_ENABLE.getType())) {
questionsEntity.setIsEnable(Constant.IsEnable.ENABLE.getType());
+ } else {
+ ExceptionCast.cast(CommonCode.INVALID_PARAM);
}
return this.updateById(questionsEntity);
@@ -275,53 +315,62 @@ 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;
}
/**
@@ -347,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();
@@ -362,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;
// 多选题数量
@@ -405,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;
@@ -436,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 61960a6..e392191 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 {
@@ -82,7 +93,84 @@ class TmsApplicationTests {
return instance;
}
- public T TestG(T t){
- return t;
+ public K t2(T t, K k) {
+ k = (K) "haha";
+ 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;
+ }
+
}
diff --git a/src/test/java/com/msdw/tms/service/QuestionsServiceTest.java b/src/test/java/com/msdw/tms/service/QuestionsServiceTest.java
index cf15c5f..5493328 100644
--- a/src/test/java/com/msdw/tms/service/QuestionsServiceTest.java
+++ b/src/test/java/com/msdw/tms/service/QuestionsServiceTest.java
@@ -70,7 +70,7 @@ class QuestionsServiceTest {
@Transactional
void isnable() {
Integer id = 1;
- System.out.println(questionsService.isnable(id));
+ System.out.println(questionsService.isEnable(id));
}
@Test
@@ -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());
}
}