diff --git a/pom.xml b/pom.xml index 51f1328..987d679 100644 --- a/pom.xml +++ b/pom.xml @@ -145,6 +145,11 @@ fastjson 1.2.72 + + org.springframework.boot + spring-boot-configuration-processor + true + diff --git a/src/main/java/com/msdw/tms/api/EvaluationRecordControllerApi.java b/src/main/java/com/msdw/tms/api/EvaluationRecordControllerApi.java index 9e97f95..be053af 100644 --- a/src/main/java/com/msdw/tms/api/EvaluationRecordControllerApi.java +++ b/src/main/java/com/msdw/tms/api/EvaluationRecordControllerApi.java @@ -4,6 +4,8 @@ import com.msdw.tms.common.utils.R; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import java.util.concurrent.ExecutionException; + /** * 记录用户测评信息 @@ -42,13 +44,13 @@ public interface EvaluationRecordControllerApi { * 上一题 */ @ApiOperation(value = "上一题", notes = "上一题") - R previousQuestion(Integer evaluationRecordId, Integer currentQuestionSortNo, String userAnswer); + R previousQuestion(Integer evaluationRecordId, Integer currentQuestionSortNo, String userAnswer) throws ExecutionException, InterruptedException; /** * 下一题 */ @ApiOperation(value = "下一题", notes = "下一题") - R nextQuestion(Integer evaluationRecordId, Integer currentQuestionSortNo, String userAnswer); + R nextQuestion(Integer evaluationRecordId, Integer currentQuestionSortNo, String userAnswer) throws ExecutionException, InterruptedException; /** * 提交之前查询是否还有未做完的试题 @@ -60,13 +62,13 @@ public interface EvaluationRecordControllerApi { * 提交测评 */ @ApiOperation(value = "提交测评", notes = "提交测评") - R submitEvaluation(Integer evaluationRecordId, Integer currentQuestionSortNo, String userAnswer, Integer userId); + R submitEvaluation(Integer evaluationRecordId, Integer currentQuestionSortNo, String userAnswer, Integer userId) throws ExecutionException, InterruptedException; /** * 成绩详情 */ @ApiOperation(value = "成绩详情", notes = "成绩详情") - R evaluationScoreDetail(Integer evaluationRecordId); + R evaluationScoreDetail(Integer evaluationRecordId) throws ExecutionException, InterruptedException; /** * 查询是否能够开启实验 diff --git a/src/main/java/com/msdw/tms/config/MyThreadConfig.java b/src/main/java/com/msdw/tms/config/MyThreadConfig.java new file mode 100644 index 0000000..b7243eb --- /dev/null +++ b/src/main/java/com/msdw/tms/config/MyThreadConfig.java @@ -0,0 +1,25 @@ +package com.msdw.tms.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +//@EnableConfigurationProperties(ThreadPoolConfigProperties.class) +@Configuration +public class MyThreadConfig { + + @Bean + public ThreadPoolExecutor threadPoolExecutor(ThreadPoolConfigProperties pool) { + return new ThreadPoolExecutor(pool.getCoreSize(), + pool.getMaxSize(), + pool.getKeepAliveTime(), + TimeUnit.SECONDS, + new LinkedBlockingDeque<>(100000), + Executors.defaultThreadFactory(), + new ThreadPoolExecutor.AbortPolicy()); + } +} diff --git a/src/main/java/com/msdw/tms/config/ThreadPoolConfigProperties.java b/src/main/java/com/msdw/tms/config/ThreadPoolConfigProperties.java new file mode 100644 index 0000000..a704f0a --- /dev/null +++ b/src/main/java/com/msdw/tms/config/ThreadPoolConfigProperties.java @@ -0,0 +1,14 @@ +package com.msdw.tms.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@ConfigurationProperties(prefix = "tms.thread") +@Component +@Data +public class ThreadPoolConfigProperties { + private Integer coreSize; + private Integer maxSize; + private Integer keepAliveTime; +} diff --git a/src/main/java/com/msdw/tms/controller/EvaluationRecordController.java b/src/main/java/com/msdw/tms/controller/EvaluationRecordController.java index 282010a..2335175 100644 --- a/src/main/java/com/msdw/tms/controller/EvaluationRecordController.java +++ b/src/main/java/com/msdw/tms/controller/EvaluationRecordController.java @@ -10,6 +10,7 @@ import com.msdw.tms.service.QuestionsService; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; +import java.util.concurrent.ExecutionException; /** @@ -60,7 +61,7 @@ public class EvaluationRecordController implements EvaluationRecordControllerApi @PostMapping("/previous") public R previousQuestion(@RequestParam("evaluationRecordId") Integer evaluationRecordId, @RequestParam("currentQuestionSortNo") Integer currentQuestionSortNo, - @RequestParam(value = "userAnswer", required = false) String userAnswer) { + @RequestParam(value = "userAnswer", required = false) String userAnswer) throws ExecutionException, InterruptedException { EvaluationRecordVO evaluationRecordVO = evaluationRecordService.convertQuestion(evaluationRecordId, currentQuestionSortNo, userAnswer, currentQuestionSortNo - 1); return R.ok().put("data", evaluationRecordVO); } @@ -69,7 +70,7 @@ public class EvaluationRecordController implements EvaluationRecordControllerApi @PostMapping("/next") public R nextQuestion(@RequestParam("evaluationRecordId") Integer evaluationRecordId, @RequestParam("currentQuestionSortNo") Integer currentQuestionSortNo, - @RequestParam(value = "userAnswer", required = false) String userAnswer) { + @RequestParam(value = "userAnswer", required = false) String userAnswer) throws ExecutionException, InterruptedException { EvaluationRecordVO evaluationRecordVO = evaluationRecordService.convertQuestion(evaluationRecordId, currentQuestionSortNo, userAnswer, currentQuestionSortNo + 1); return R.ok().put("data", evaluationRecordVO); } @@ -86,14 +87,14 @@ public class EvaluationRecordController implements EvaluationRecordControllerApi public R submitEvaluation(@RequestParam("evaluationRecordId") Integer evaluationRecordId, @RequestParam("currentQuestionSortNo") Integer currentQuestionSortNo, @RequestParam(value = "userAnswer", required = false) String userAnswer, - @RequestParam("userId") Integer userId) { + @RequestParam("userId") Integer userId) throws ExecutionException, InterruptedException { EvaluationRecordSubmitVO recordSubmitVO = evaluationRecordService.submitEvaluation(evaluationRecordId, currentQuestionSortNo, userAnswer, userId); return R.ok().put("data", recordSubmitVO); } @Override @GetMapping("/detail") - public R evaluationScoreDetail(Integer evaluationRecordId) { + public R evaluationScoreDetail(Integer evaluationRecordId) throws ExecutionException, InterruptedException { EvaluationRecordDetailVO detailVO = evaluationRecordService.evaluationDetail(evaluationRecordId); return R.ok().put("data", detailVO); } diff --git a/src/main/java/com/msdw/tms/service/EvaluationRecordService.java b/src/main/java/com/msdw/tms/service/EvaluationRecordService.java index e660664..6db5ab8 100644 --- a/src/main/java/com/msdw/tms/service/EvaluationRecordService.java +++ b/src/main/java/com/msdw/tms/service/EvaluationRecordService.java @@ -6,6 +6,8 @@ import com.msdw.tms.entity.vo.EvaluationRecordDetailVO; import com.msdw.tms.entity.vo.EvaluationRecordSubmitVO; import com.msdw.tms.entity.vo.EvaluationRecordVO; +import java.util.concurrent.ExecutionException; + /** * 记录用户测评信息 * @@ -20,14 +22,14 @@ public interface EvaluationRecordService extends IService().eq("user_id", userId) - .eq("evaluation_status", Constant.Submit.SUBMIT.getType())); + .eq("evaluation_status", Constant.Submit.NOT_SUBMIT.getType())); if (one == null) { //随机抽取试题数据 @@ -70,8 +76,6 @@ public class EvaluationRecordServiceImpl extends ServiceImpl this.getById(evaluationRecordId).getTotalQuestionNum() || changeSortNo < 1 || changeSortNo > this.getById(evaluationRecordId).getTotalQuestionNum()) { ExceptionCast.cast(CommonCode.INVALID_PARAM); } - - //TODO 异步调用。。。 //提交当前试题信息 - boolean result = submitCurrentQuestion(evaluationRecordId, - currentQuestionSortNo, - userAnswer, - changeSortNo); - if (!result) { - ExceptionCast.cast(CommonCode.FAIL); - } + CompletableFuture submitCurrentQuestionFuture = CompletableFuture.runAsync(() + -> submitCurrentQuestion(evaluationRecordId, currentQuestionSortNo, userAnswer), executor); + + //修改测评记录表当前题目顺序号 + CompletableFuture updateCurrentSortNoFuture = CompletableFuture.runAsync(() + -> updateCurrentSortNo(changeSortNo, evaluationRecordId), executor); + + CompletableFuture future = CompletableFuture.supplyAsync(() + -> this.getBaseMapper().selectVOByInfo(evaluationRecordId, changeSortNo), executor); + + + CompletableFuture.allOf(submitCurrentQuestionFuture, updateCurrentSortNoFuture, future).get(); + EvaluationRecordVO evaluationRecordVO = future.get(); //查询下一题信息 - EvaluationRecordVO evaluationRecordVO = this.getBaseMapper().selectVOByInfo(evaluationRecordId, changeSortNo); evaluationRecordVO.setQuestionTypeName(getQuestionTypeName(evaluationRecordVO.getQuestionType())); return evaluationRecordVO; } @@ -170,67 +178,81 @@ public class EvaluationRecordServiceImpl extends ServiceImpl deleteKeyFuture = CompletableFuture.runAsync(() -> { + String key = REMAINING_TINE_KEY + userId; + redisTemplate.delete(key); + }, executor); + + CompletableFuture submitCurrentQuestionFuture = CompletableFuture.runAsync(() + -> submitCurrentQuestion(evaluationRecordId, currentQuestionSortNo, userAnswer), executor); + + //修改提交时间和测评记录状态 + CompletableFuture updateEvaluationFuture = CompletableFuture.runAsync(() -> { + EvaluationRecordEntity entity = new EvaluationRecordEntity(); + entity.setId(evaluationRecordId); + entity.setEvaluationStatus(Constant.Submit.SUBMIT.getType()); + entity.setSubmitTime(new Date()); + this.updateById(entity); + }, executor); - //TODO 优化,使用多线程异步调用 - //修改提交时间 - EvaluationRecordEntity entity = new EvaluationRecordEntity(); - entity.setId(evaluationRecordId); - entity.setEvaluationStatus(Constant.Submit.SUBMIT.getType()); - entity.setSubmitTime(new Date()); - this.updateById(entity); + EvaluationRecordSubmitVO submitVO = new EvaluationRecordSubmitVO(); //查询总成绩 - int sumScore = evaluationQuestionDao.sumScore(evaluationRecordId); - - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("evaluation_record_id", evaluationRecordId) - .eq("is_ture", Constant.QuestionIsTure.TRUE.getType()); - - //查询答对几题 - int count = evaluationQuestionService.count(queryWrapper); - - EvaluationRecordEntity evaluationRecord = this.getById(evaluationRecordId); - - EvaluationRecordSubmitVO submitVO = new EvaluationRecordSubmitVO(); - BeanUtils.copyProperties(evaluationRecord, submitVO); - //正确率 - // 创建一个数值格式化对象 - NumberFormat numberFormat = NumberFormat.getInstance(); - // 设置精确到小数点后2位 - numberFormat.setMaximumFractionDigits(2); - submitVO.setCorrectRate(numberFormat.format((float) count / (float) evaluationRecord.getTotalQuestionNum() * 100) + "%"); - //是否通过 - submitVO.setIsPassed(sumScore > Constant.PASSING_SCORE ? Constant.EVALUATIONN_PASSED : Constant.EVALUATIONN_NOT_PASSED); - //得分 - submitVO.setTotalScore(sumScore); - //答对几道 - submitVO.setCorrectQuestionNum(count); + CompletableFuture sumScoreFuture = CompletableFuture.runAsync(() -> { + int sumScore = evaluationQuestionDao.sumScore(evaluationRecordId); + //得分 + submitVO.setTotalScore(sumScore); + //是否通过 + submitVO.setIsPassed(sumScore > Constant.PASSING_SCORE ? Constant.EVALUATIONN_PASSED : Constant.EVALUATIONN_NOT_PASSED); + }, executor); + + CompletableFuture getByIdFuture = CompletableFuture.supplyAsync(() -> { + EvaluationRecordEntity evaluationRecord = this.getById(evaluationRecordId); + BeanUtils.copyProperties(evaluationRecord, submitVO); + return evaluationRecord; + }, executor); + + CompletableFuture countFuture = getByIdFuture.thenAcceptAsync((res) -> { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("evaluation_record_id", evaluationRecordId) + .eq("is_ture", Constant.QuestionIsTure.TRUE.getType()); + //查询答对几题 + int count = evaluationQuestionService.count(queryWrapper); + //答对几道 + submitVO.setCorrectQuestionNum(count); + //正确率 + // 创建一个数值格式化对象 + NumberFormat numberFormat = NumberFormat.getInstance(); + // 设置精确到小数点后2位 + numberFormat.setMaximumFractionDigits(2); + submitVO.setCorrectRate(numberFormat.format((float) count / (float) res.getTotalQuestionNum() * 100) + "%"); + + }, executor); + + CompletableFuture.allOf(deleteKeyFuture, submitCurrentQuestionFuture, updateEvaluationFuture, + sumScoreFuture, getByIdFuture, countFuture).get(); return submitVO; } @Override - public EvaluationRecordDetailVO evaluationDetail(Integer evaluationRecordId) { - //TODO 异步查询 - //查询总成绩 - int sumScore = evaluationQuestionDao.sumScore(evaluationRecordId); - List evaluationDetailVOS = evaluationQuestionDao.selectDetailByInfo(evaluationRecordId); - + public EvaluationRecordDetailVO evaluationDetail(Integer evaluationRecordId) throws ExecutionException, InterruptedException { EvaluationRecordDetailVO evaluationRecordDetailVO = new EvaluationRecordDetailVO(); - evaluationRecordDetailVO.setTotalScore(sumScore); - evaluationRecordDetailVO.setEvaluationDetailVOS(evaluationDetailVOS); + + CompletableFuture sumScoreFuture = CompletableFuture.runAsync(() -> { + //查询总成绩 + int sumScore = evaluationQuestionDao.sumScore(evaluationRecordId); + evaluationRecordDetailVO.setTotalScore(sumScore); + }, executor); + + CompletableFuture evaluationDetailVOSFuture = CompletableFuture.runAsync(() -> { + List evaluationDetailVOS = evaluationQuestionDao.selectDetailByInfo(evaluationRecordId); + evaluationRecordDetailVO.setEvaluationDetailVOS(evaluationDetailVOS); + }, executor); + + CompletableFuture.allOf(sumScoreFuture, evaluationDetailVOSFuture).get(); return evaluationRecordDetailVO; } @@ -242,7 +264,7 @@ public class EvaluationRecordServiceImpl extends ServiceImpl list = evaluationQuestionService.list(queryWrapper); - List collect = list.stream().map(item -> item.getQuestionSortNo()).collect(Collectors.toList()); + List collect = list.stream().map(EvaluationQuestionEntity::getQuestionSortNo).collect(Collectors.toList()); if (collect.size() == 0) { return "已完成全部题目"; } @@ -284,11 +306,9 @@ public class EvaluationRecordServiceImpl extends ServiceImpl 0 && updateRecord; - } + evaluationQuestionDao.updateById(evaluationQuestion); - return updateQuestion > 0; } - + private void updateCurrentSortNo(Integer changeSortNo, Integer evaluationRecordId) { + //修改测评记录表 + EvaluationRecordEntity evaluationRecordEntity = new EvaluationRecordEntity(); + evaluationRecordEntity.setCurrentQuestionSortNo(changeSortNo); + evaluationRecordEntity.setId(evaluationRecordId); + this.updateById(evaluationRecordEntity); + } } \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 8e3c54e..266eacf 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -23,3 +23,8 @@ mybatis-plus: server: port: 7000 +tms: + thread: + core-size: 20 + max-size: 200 + keep-alive-time: 10