| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- package com.xuekairui.quiz.service.impl;
- import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
- import com.xuekairui.quiz.dto.AnswerItem;
- import com.xuekairui.quiz.entity.QuizQuestion;
- import com.xuekairui.quiz.entity.QuizUserRecord;
- import com.xuekairui.quiz.mapper.QuizQuestionMapper;
- import com.xuekairui.quiz.mapper.QuizUserRecordMapper;
- import com.xuekairui.quiz.service.DailyPracticeService;
- import com.xuekairui.quiz.vo.DailyPracticeQuestionsVO;
- import com.xuekairui.quiz.vo.PracticeResultVO;
- import com.xuekairui.quiz.vo.PracticeSubmitVO;
- import lombok.RequiredArgsConstructor;
- import org.springframework.stereotype.Service;
- import org.springframework.transaction.annotation.Transactional;
- import java.math.BigDecimal;
- import java.math.RoundingMode;
- import java.time.LocalDate;
- import java.time.LocalDateTime;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.LinkedHashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.Random;
- import java.util.stream.Collectors;
- @Service
- @RequiredArgsConstructor
- public class DailyPracticeServiceImpl implements DailyPracticeService {
- private final QuizQuestionMapper questionMapper;
- private final QuizUserRecordMapper userRecordMapper;
- @Override
- public DailyPracticeQuestionsVO getQuestions(Long userId) {
- LocalDate today = LocalDate.now();
- LocalDateTime todayStart = today.atStartOfDay();
- // 检查今天是否已完成
- long doneCount = userRecordMapper.selectCount(
- new LambdaQueryWrapper<QuizUserRecord>()
- .eq(QuizUserRecord::getUserId, userId)
- .eq(QuizUserRecord::getAnswerType, 2)
- .ge(QuizUserRecord::getCreateTime, todayStart)
- .eq(QuizUserRecord::getStatus, 1)
- );
- boolean hasDone = doneCount > 0;
- // 按日期种子随机抽取10道题(同一天同一用户题目固定)
- long seed = today.toEpochDay() + userId;
- Random random = new Random(seed);
- List<QuizQuestion> allQuestions = questionMapper.selectList(
- new LambdaQueryWrapper<QuizQuestion>().eq(QuizQuestion::getIsReal, 0));
- Collections.shuffle(allQuestions, random);
- List<QuizQuestion> selected = allQuestions.stream().limit(10).collect(Collectors.toList());
- List<DailyPracticeQuestionsVO.DailyQuestionVO> questionList = new ArrayList<>();
- for (QuizQuestion q : selected) {
- questionList.add(DailyPracticeQuestionsVO.DailyQuestionVO.builder()
- .id(q.getId())
- .questionType(q.getQuestionType())
- .questionTypeName(getTypeName(q.getQuestionType()))
- .stem(q.getStem())
- .options(q.getOptions())
- .build());
- }
- return DailyPracticeQuestionsVO.builder()
- .date(today.toString())
- .questionCount(selected.size())
- .hasDone(hasDone)
- .questions(questionList)
- .build();
- }
- @Override
- @Transactional
- public PracticeSubmitVO submit(Long userId, List<AnswerItem> answers) {
- int correctCount = 0;
- int wrongCount = 0;
- List<PracticeResultVO> results = new ArrayList<>();
- List<Map<String, Object>> answerRecords = new ArrayList<>();
- for (AnswerItem ans : answers) {
- Long questionId = ans.getQuestionId();
- String userAnswer = ans.getUserAnswer();
- Integer timeSpent = ans.getTimeSpent() != null ? ans.getTimeSpent() : 0;
- QuizQuestion question = questionMapper.selectById(questionId);
- if (question == null) continue;
- boolean isCorrect = question.getAnswer().equalsIgnoreCase(userAnswer);
- if (isCorrect) correctCount++;
- else wrongCount++;
- results.add(PracticeResultVO.builder()
- .questionId(questionId)
- .isCorrect(isCorrect ? 1 : 0)
- .correctAnswer(question.getAnswer())
- .analysis(question.getAnalysis())
- .build());
- Map<String, Object> record = new LinkedHashMap<>();
- record.put("questionId", questionId);
- record.put("userAnswer", userAnswer);
- record.put("isCorrect", isCorrect ? 1 : 0);
- record.put("timeSpent", timeSpent);
- answerRecords.add(record);
- }
- int total = correctCount + wrongCount;
- BigDecimal correctRate = total > 0 ? BigDecimal.valueOf(correctCount * 100.0 / total).setScale(0, RoundingMode.HALF_UP) : BigDecimal.ZERO;
- // 保存做题记录
- QuizUserRecord record = QuizUserRecord.builder()
- .userId(userId)
- .answerType(2)
- .totalCount(total)
- .correctCount(correctCount)
- .wrongCount(wrongCount)
- .correctRate(correctRate)
- .answers(answerRecords)
- .status(1)
- .startTime(LocalDateTime.now())
- .endTime(LocalDateTime.now())
- .build();
- userRecordMapper.insert(record);
- return PracticeSubmitVO.builder()
- .correctCount(correctCount)
- .wrongCount(wrongCount)
- .correctRate(correctRate)
- .results(results)
- .build();
- }
- private String getTypeName(Integer type) {
- if (type == null) return "";
- return switch (type) {
- case 1 -> "最佳选择题";
- case 2 -> "多项选择题";
- case 3 -> "配伍选择题";
- case 4 -> "综合分析选择题";
- default -> "";
- };
- }
- }
|