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()); } }