浏览代码

update content-service/exam

reghao 7 月之前
父节点
当前提交
03c7cfa4e2

+ 7 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/controller/ExamController.java

@@ -53,6 +53,13 @@ public class ExamController {
         return WebResult.success(list1);
     }
 
+    @Operation(summary = "暂存用户提交的答案", description = "N")
+    @PostMapping(value = "/cache", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String cacheExamPaper1(@RequestBody UserResult userResult) {
+        paperService.cacheUserAnswers(userResult);
+        return WebResult.success();
+    }
+
     @Operation(summary = "用户提交考试答案", description = "N")
     @PostMapping(value = "/submit", produces = MediaType.APPLICATION_JSON_VALUE)
     public String submitExamPaper1(@RequestBody UserResult userResult) {

+ 2 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/model/dto/PaperAddDto.java

@@ -2,6 +2,7 @@ package cn.reghao.tnb.content.app.exam.model.dto;
 
 import cn.reghao.tnb.content.app.exam.model.po.PaperQuestion;
 import lombok.Getter;
+import lombok.Setter;
 import org.springframework.format.annotation.DateTimeFormat;
 
 import javax.validation.constraints.NotBlank;
@@ -14,6 +15,7 @@ import java.util.List;
  * @author reghao
  * @date 2024-08-27 17:42:05
  */
+@Setter
 @Getter
 public class PaperAddDto {
     @NotBlank

+ 12 - 12
content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/model/dto/UserAnswer.java

@@ -1,29 +1,29 @@
 package cn.reghao.tnb.content.app.exam.model.dto;
 
-import cn.reghao.tnb.content.app.exam.model.po.PaperAnswer;
+import lombok.AllArgsConstructor;
 import lombok.Getter;
 import lombok.NoArgsConstructor;
 import lombok.Setter;
 
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+
 /**
  * @author reghao
  * @date 2024-08-28 13:07:23
  */
+@AllArgsConstructor
 @NoArgsConstructor
 @Setter
 @Getter
 public class UserAnswer {
-    private Integer pos;
-    private Long pid;
+    @NotNull
     private Long questionId;
-    private Integer questionType;
-    private String answer;
+    @Size(min = 1, max = 20)
+    private String[] answers;
 
-    public UserAnswer(PaperAnswer paperAnswer) {
-        this.pos = paperAnswer.getPos();
-        this.pid = paperAnswer.getPid();
-        this.questionId = paperAnswer.getQuestionId();
-        this.questionType = paperAnswer.getQuestionType();
-        this.answer = paperAnswer.getAnswer();
-    }
+    private long pid;
+    private int pos;
+    private int questionType;
+    private String answer;
 }

+ 10 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/model/dto/UserResult.java

@@ -1,23 +1,33 @@
 package cn.reghao.tnb.content.app.exam.model.dto;
 
+import lombok.AllArgsConstructor;
 import lombok.Getter;
 import lombok.NoArgsConstructor;
 import lombok.Setter;
 
 import javax.validation.constraints.NotNull;
 import javax.validation.constraints.Size;
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 /**
  * @author reghao
  * @date 2024-08-24 16:39:41
  */
+@AllArgsConstructor
 @NoArgsConstructor
 @Setter
 @Getter
 public class UserResult {
     @NotNull
     private Integer paperId;
+    private Map<Long, List<Object>> cachedUserAnswers;
     @Size(min = 1, max = 100)
     private List<UserAnswer> userAnswers;
+
+    public UserResult(int paperId, Map<Long, List<Object>> userAnswerMap) {
+        this.paperId = paperId;
+        this.cachedUserAnswers = userAnswerMap;
+    }
 }

+ 16 - 2
content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/model/po/PaperQuestion.java

@@ -1,12 +1,15 @@
 package cn.reghao.tnb.content.app.exam.model.po;
 
 import cn.reghao.jutil.jdk.db.BaseObject;
+import cn.reghao.tnb.content.app.exam.model.constant.QuestionType;
 import lombok.Getter;
 import lombok.Setter;
 
 import javax.validation.constraints.NotNull;
 import javax.validation.constraints.Size;
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * @author reghao
@@ -16,22 +19,33 @@ import java.util.List;
 @Getter
 public class PaperQuestion extends BaseObject<Integer> {
     private Integer paperId;
-    private Long pid;
     @NotNull
     private Integer pos;
     @NotNull
     private Long questionId;
     @NotNull
     private Integer score;
+
+    private Long pid;
+    private Integer type;
     private Boolean child;
     @Size(max = 20)
-    private transient List<PaperQuestion> children;
+    private transient List<PaperQuestion> children = new ArrayList<>();
 
     public PaperQuestion() {
         this.pid = 0L;
         this.child = false;
     }
 
+    public PaperQuestion(int pos, Question question, int score) {
+        this.pid = question.getPid();
+        this.questionId = question.getQuestionId();
+        this.type = question.getType();
+        this.child = Objects.equals(question.getType(), QuestionType.QUESTION8.getCode());
+        this.pos = pos;
+        this.score = score;
+    }
+
     public void setPaperId(Integer paperId) {
         this.paperId = paperId;
     }

+ 14 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/model/query/QuestionQuery.java

@@ -20,6 +20,8 @@ public class QuestionQuery {
     private Integer level;
 
     private QuestionQuery(Builder builder) {
+        this.pageNumber = builder.pageNumber;
+        this.pageSize = builder.pageSize;
         this.subjectId = builder.subjectId;
         this.type = builder.type;
         this.level = builder.level;
@@ -30,10 +32,22 @@ public class QuestionQuery {
     }
 
     public static final class Builder {
+        private Integer pageNumber;
+        private Integer pageSize;
         private Integer subjectId;
         private Integer type;
         private Integer level;
 
+        public Builder pageNumber(int pageNumber) {
+            this.pageNumber = pageNumber;
+            return this;
+        }
+
+        public Builder pageSize(int pageSize) {
+            this.pageSize = pageSize;
+            return this;
+        }
+
         public Builder subjectId(int subjectId) {
             this.subjectId = subjectId;
             return this;

+ 4 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/model/vo/PaperDetail.java

@@ -1,6 +1,8 @@
 package cn.reghao.tnb.content.app.exam.model.vo;
 
+import cn.reghao.tnb.content.app.exam.model.dto.UserResult;
 import cn.reghao.tnb.content.app.exam.model.po.Paper;
+import lombok.Setter;
 
 import java.util.List;
 import java.util.Map;
@@ -9,6 +11,7 @@ import java.util.Map;
  * @author reghao
  * @date 2024-08-29 17:48:51
  */
+@Setter
 public class PaperDetail {
     private int paperId;
     private String name;
@@ -17,6 +20,7 @@ public class PaperDetail {
     private int totalScore;
     private List<QuestionInfo> questions;
     private Map<Integer, List<QuestionInfo>> questionMap;
+    private UserResult userResult;
 
     public PaperDetail(Paper paper, List<QuestionInfo> questions, Map<Integer, List<QuestionInfo>> questionMap) {
         this.paperId = paper.getId();

+ 43 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/model/vo/PaperQuestionInfo.java

@@ -0,0 +1,43 @@
+package cn.reghao.tnb.content.app.exam.model.vo;
+
+import cn.reghao.tnb.content.app.exam.model.po.PaperQuestion;
+import cn.reghao.tnb.content.app.exam.model.po.Question;
+import cn.reghao.tnb.content.app.exam.model.po.QuestionOption;
+
+import java.util.List;
+
+/**
+ * @author reghao
+ * @date 2025-08-08 16:18:35
+ */
+public class PaperQuestionInfo {
+    private int pos;
+    private int type;
+    private long questionId;
+    private String questionContent;
+    private List<QuestionOptionInfo> questionOptions;
+    private int score;
+    private List<PaperQuestionInfo> children;
+
+    public PaperQuestionInfo(PaperQuestion paperQuestion, Question question) {
+        this.pos = paperQuestion.getPos();
+        this.type = question.getType();
+        this.questionId = question.getQuestionId();
+        this.questionContent = question.getContent();
+        this.score = paperQuestion.getScore();
+    }
+
+    class QuestionOptionInfo {
+        private Long questionId;
+        private Integer pos;
+        private String optionContent;
+        private Boolean correct;
+
+        public QuestionOptionInfo(QuestionOption questionOption) {
+            this.questionId = questionOption.getQuestionId();
+            this.pos = questionOption.getPos();
+            this.optionContent = questionOption.getContent();
+            this.correct = null;
+        }
+    }
+}

+ 84 - 2
content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/service/PaperService.java

@@ -3,12 +3,19 @@ package cn.reghao.tnb.content.app.exam.service;
 import cn.reghao.jutil.jdk.db.Page;
 import cn.reghao.jutil.jdk.db.PageList;
 import cn.reghao.jutil.jdk.result.Result;
+import cn.reghao.jutil.jdk.serializer.JsonConverter;
+import cn.reghao.tnb.common.auth.UserContext;
 import cn.reghao.tnb.common.db.KeyValue;
 import cn.reghao.tnb.content.app.exam.db.mapper.*;
+import cn.reghao.tnb.content.app.exam.model.constant.QuestionType;
 import cn.reghao.tnb.content.app.exam.model.dto.PaperAddDto;
+import cn.reghao.tnb.content.app.exam.model.dto.UserAnswer;
+import cn.reghao.tnb.content.app.exam.model.dto.UserResult;
 import cn.reghao.tnb.content.app.exam.model.po.*;
 import cn.reghao.tnb.content.app.exam.model.query.PaperQuery;
 import cn.reghao.tnb.content.app.exam.model.vo.*;
+import cn.reghao.tnb.content.app.util.redis.ds.RedisHash;
+import org.springframework.data.redis.support.collections.RedisMap;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -25,13 +32,17 @@ public class PaperService {
     private final PaperQuestionMapper paperQuestionMapper;
     private final QuestionMapper questionMapper;
     private final QuestionOptionMapper questionOptionMapper;
+    private final RedisHash redisHash;
+    private String keyPrefix = "tnb:exam:result";
 
     public PaperService(PaperMapper paperMapper, PaperQuestionMapper paperQuestionMapper,
-                        QuestionMapper questionMapper, QuestionOptionMapper questionOptionMapper) {
+                        QuestionMapper questionMapper, QuestionOptionMapper questionOptionMapper,
+                        RedisHash redisHash) {
         this.paperMapper = paperMapper;
         this.paperQuestionMapper = paperQuestionMapper;
         this.questionMapper = questionMapper;
         this.questionOptionMapper = questionOptionMapper;
+        this.redisHash = redisHash;
     }
 
     public Result createExamPaper(PaperAddDto paperAddDto) {
@@ -139,7 +150,78 @@ public class PaperService {
         List<QuestionInfo> questions = getPaperQuestions(paperId);
         Map<Integer, List<QuestionInfo>> groupMap = questions.stream()
                 .collect(Collectors.groupingBy(QuestionInfo::getQuestionType));
-        return new PaperDetail(paper, questions, groupMap);
+
+        Map<Long, List<Object>> cachedUserAnswers = getCachedUserAnswers(paperId);
+        UserResult userResult = new UserResult(1, cachedUserAnswers);
+
+        PaperDetail paperDetail=  new PaperDetail(paper, questions, groupMap);
+        paperDetail.setUserResult(userResult);
+        return paperDetail;
+    }
+
+    public void cacheUserAnswers(UserResult userResult) {
+        long loginUser = UserContext.getUser();
+        int paperId = userResult.getPaperId();
+        String key = String.format("%s:%s:%s", keyPrefix, paperId, loginUser);
+
+        List<UserAnswer> userAnswers = userResult.getUserAnswers();
+        for (UserAnswer userAnswer : userAnswers) {
+            long questionId = userAnswer.getQuestionId();
+            String[] answers = userAnswer.getAnswers();
+            //String answersJson = JsonConverter.objectToJson(answers);
+            redisHash.hset(key, ""+questionId, answers);
+        }
+        /*Map<Long, List<String>> cachedUserAnswers = userResult.getCachedUserAnswers();
+        cachedUserAnswers.forEach((k, v) -> {
+            redisHash.hset(key, ""+k, v);
+        });*/
+    }
+
+    private Map<Long, List<Object>> getCachedUserAnswers(int paperId) {
+        Map<Long, List<Object>> map = new HashMap<>();
+
+        long loginUser = UserContext.getUser();
+        String key = String.format("%s:%s:%s", keyPrefix, paperId, loginUser);
+        Map cachedMap = redisHash.hgetall(key);
+        cachedMap.forEach((k, v) -> {
+            long questionId = Long.parseLong((String) k);
+            Question question = questionMapper.findByQuestionId(questionId);
+            int type = question.getType();
+            String[] answers = (String[]) v;
+            List<Object> objectList;
+            if (type == QuestionType.QUESTION1.getCode() || type == QuestionType.QUESTION4.getCode()) {
+                objectList = Arrays.stream(answers)
+                        .map(val -> val.isBlank() ? -1 : Integer.parseInt(val))
+                        .collect(Collectors.toList());
+            } else {
+                objectList = Arrays.asList(answers);
+            }
+            map.put(questionId, objectList);
+        });
+        if (!map.isEmpty()) {
+            return map;
+        }
+
+        List<QuestionInfo> questions = getPaperQuestions(paperId);
+        for (QuestionInfo questionInfo : questions) {
+            long questionId = questionInfo.getQuestionId();
+            int type = questionInfo.getQuestionType();
+            List<QuestionOption> questionOptionList = questionOptionMapper.findByQuestionId(questionId);
+            long count = questionOptionList.stream().filter(QuestionOption::getCorrect).count();
+            List<Object> list = new ArrayList<>();
+            for (int i = 0; i < count; i++) {
+                if (type == QuestionType.QUESTION1.getCode() || type == QuestionType.QUESTION4.getCode()) {
+                    list.add(-1);
+                } else if (type == QuestionType.QUESTION2.getCode() || type == QuestionType.QUESTION3.getCode()) {
+                } else {
+                    list.add("");
+                }
+            }
+
+            map.putIfAbsent(questionId, list);
+        }
+
+        return map;
     }
 
     public List<KeyValue> getKeyValues() {

+ 265 - 14
content/content-service/src/test/java/cn/reghao/tnb/content/app/exam/service/ExamTest.java

@@ -1,5 +1,6 @@
 package cn.reghao.tnb.content.app.exam.service;
 
+import cn.reghao.jutil.jdk.db.Page;
 import cn.reghao.jutil.jdk.serializer.JsonConverter;
 import cn.reghao.jutil.jdk.text.TextFile;
 import cn.reghao.jutil.tool.id.SnowFlake;
@@ -7,15 +8,14 @@ import cn.reghao.tnb.content.app.ContentApplication;
 import cn.reghao.tnb.content.app.exam.db.mapper.*;
 import cn.reghao.tnb.content.app.exam.model.constant.QuestionType;
 import cn.reghao.tnb.content.app.exam.model.dto.PaperAddDto;
-import cn.reghao.tnb.content.app.exam.model.po.Paper;
-import cn.reghao.tnb.content.app.exam.model.po.PaperQuestion;
-import cn.reghao.tnb.content.app.exam.model.po.Question;
-import cn.reghao.tnb.content.app.exam.model.po.QuestionOption;
+import cn.reghao.tnb.content.app.exam.model.po.*;
+import cn.reghao.tnb.content.app.exam.model.query.QuestionQuery;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
 import lombok.Getter;
 import lombok.NoArgsConstructor;
 import lombok.Setter;
+import org.apache.commons.lang.StringUtils;
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
@@ -238,18 +238,245 @@ public class ExamTest {
     }
 
     @Test
-    public void paperTest() {
-        int paperId = 3;
-        Paper paper = paperMapper.findByPaperId(paperId);
-        List<PaperQuestion> paperQuestionList = paperQuestionMapper.findByPaperId(paperId);
-        paperQuestionList.forEach(paperQuestion -> {
-            long questionId = paperQuestion.getQuestionId();
-            List<Question> questionList = questionMapper.findByQuestionIds(List.of(questionId));
-            Question question = questionList.get(0);
-            int questionType = question.getType();
-        });
+    public void gaokaoQuestionTest() {
+        String baseDir = "/home/reghao/Downloads/gaokao/objective";
+        File dir = new File(baseDir);
+        for (File file : dir.listFiles()) {
+            parseQuestion(file.getAbsolutePath());
+        }
+
+        baseDir = "/home/reghao/Downloads/gaokao/subjective";
+        dir = new File(baseDir);
+        for (File file : dir.listFiles()) {
+            parseQuestion1(file.getAbsolutePath());
+        }
+    }
+
+    private void parseQuestion(String filePath) {
+        int subjectId = 1;
+        if (filePath.contains("Math")) {
+            subjectId = 2;
+        } else if (filePath.contains("English")) {
+            subjectId = 3;
+        } else if (filePath.contains("Physics")) {
+            subjectId = 4;
+        } else if (filePath.contains("Chemistry")) {
+            subjectId = 5;
+        } else if (filePath.contains("Biology")) {
+            subjectId = 6;
+        } else if (filePath.contains("Political")) {
+            subjectId = 7;
+        } else if (filePath.contains("History")) {
+            subjectId = 8;
+        } else if (filePath.contains("Geography")) {
+            subjectId = 9;
+        }
+
+        JsonElement jsonElement3 = JsonConverter.jsonFileToObject(new File(filePath), JsonElement.class);
+        JsonObject jsonObject = jsonElement3.getAsJsonObject();
+        for (JsonElement jsonElement0 : jsonObject.get("example").getAsJsonArray()) {
+            JsonObject jsonObject0 = jsonElement0.getAsJsonObject();
+            try {
+                int year = jsonObject0.get("year").getAsInt();
+                String category = jsonObject0.get("category").getAsString();
+                String question = jsonObject0.get("question").getAsString();
+                String questionContent0 = getHtml1(question);
+
+                String[] questionArr = question.split("\\n");
+                int len = questionArr.length;
+                StringBuilder sb = new StringBuilder();
+                for (int i = 0; i < len-4; i++) {
+                    sb.append(questionArr[i]).append(System.lineSeparator());
+                }
+
+                String questionContent = sb.toString();
+                if (questionContent.isBlank()) {
+                    System.out.printf("%s -> 单选题格式不正确\n", filePath);
+                    continue;
+                }
+                questionContent = getHtml1(questionContent);
+
+                List<String> questionOptions = new ArrayList<>();
+                for (int i = len-4; i < questionArr.length; i++) {
+                    String questionOption = getHtml1(questionArr[i]);
+                    questionOptions.add(questionOption);
+                }
+
+                List<String> answers = new ArrayList<>();
+                for (JsonElement answerElement : jsonObject0.get("answer").getAsJsonArray()) {
+                    answers.add(answerElement.getAsString());
+                }
+                int answerNum = 0;
+                if (answers.size() == 1) {
+                    String answer = jsonObject0.get("answer").getAsString();
+                    if (answer.equalsIgnoreCase("A")) {
+                        answerNum = 1;
+                    } else if (answer.equalsIgnoreCase("B")) {
+                        answerNum = 2;
+                    } else if (answer.equalsIgnoreCase("C")) {
+                        answerNum = 3;
+                    } else if (answer.equalsIgnoreCase("D")) {
+                        answerNum = 4;
+                    }
+                } else {
+                    System.out.printf("%s -> 单选题答案超过1个\n", filePath);
+                }
+
+                String analysis = jsonObject0.get("analysis").getAsString();
+                analysis = getHtml1(analysis);
+                int score = jsonObject0.get("score").getAsInt();
+
+                String extra = String.format("%s 分 | %s | %s", score, year, category);
+                int questionType = QuestionType.QUESTION1.getCode();
+                long questionId = idGenerator.nextId();
+
+                //Question question0 = new Question(questionId, questionContent, questionType, extra);
+                Question question0 = new Question(questionId, questionContent0, questionType, extra);
+                question0.setAnalysis(analysis);
+                question0.setSubjectId(subjectId);
+                List<QuestionOption> questionOptions0 = new ArrayList<>();
+                for (int i = 0; i < questionOptions.size(); i++) {
+                    String content0 = questionOptions.get(i);
+                    int pos = i + 1;
+                    boolean correct = pos == answerNum;
+                    QuestionOption questionOption0 = new QuestionOption(questionId, content0, pos, correct);
+                    questionOptions0.add(questionOption0);
+                }
+                question0.setQuestionOptions(questionOptions0);
+
+                questionMapper.save(question0);
+                questionOptionMapper.saveAll(questionOptions0);
+            } catch (Exception e) {
+                if (e instanceof ArrayIndexOutOfBoundsException) {
+                    System.out.printf("%s -> ArrayIndexOutOfBoundsException\n", filePath);
+                } else {
+                    System.out.println(filePath);
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    private void parseQuestion1(String filePath) {
+        int subjectId = 1;
+        if (filePath.contains("Math")) {
+            subjectId = 2;
+        } else if (filePath.contains("English")) {
+            subjectId = 3;
+        } else if (filePath.contains("Physics")) {
+            subjectId = 4;
+        } else if (filePath.contains("Chemistry")) {
+            subjectId = 5;
+        } else if (filePath.contains("Biology")) {
+            subjectId = 6;
+        } else if (filePath.contains("Political")) {
+            subjectId = 7;
+        } else if (filePath.contains("History")) {
+            subjectId = 8;
+        } else if (filePath.contains("Geography")) {
+            subjectId = 9;
+        }
+
+        JsonElement jsonElement3 = JsonConverter.jsonFileToObject(new File(filePath), JsonElement.class);
+        JsonObject jsonObject = jsonElement3.getAsJsonObject();
+        for (JsonElement jsonElement0 : jsonObject.get("example").getAsJsonArray()) {
+            JsonObject jsonObject0 = jsonElement0.getAsJsonObject();
+            try {
+                int year = jsonObject0.get("year").getAsInt();
+                String category = jsonObject0.get("category").getAsString();
+                String question = jsonObject0.get("question").getAsString();
+                String answer = jsonObject0.get("answer").getAsString();
+                String analysis = jsonObject0.get("analysis").getAsString();
+                int score = jsonObject0.get("score").getAsInt();
+
+                String extra = String.format("%s 分 | %s | %s", score, year, category);
+                int questionType = QuestionType.QUESTION6.getCode();
+                long questionId = idGenerator.nextId();
+
+                String questionContent0 = getHtml1(question);
+                Question question0 = new Question(questionId, questionContent0, questionType, extra);
+                question0.setAnalysis(analysis);
+                question0.setSubjectId(subjectId);
+                questionMapper.save(question0);
+            } catch (Exception e) {
+                if (e instanceof ArrayIndexOutOfBoundsException) {
+                    System.out.printf("%s -> ArrayIndexOutOfBoundsException\n", filePath);
+                } else {
+                    System.out.println(filePath);
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    private String getHtml1(String content) {
+        String tag1 = "<span class=\"math-tex\">\\(";
+        String tag2 = "\\)</span>";
+        int count = 1;
+        while (content.contains("$")) {
+            if (count%2 != 0) {
+                content = StringUtils.replaceOnce(content, "$", tag1);
+                //question1 = question1.replaceFirst("\\$", tag1);
+            } else {
+                content = StringUtils.replaceOnce(content, "$", tag2);
+                //question1 = question1.replaceFirst("\\$", tag2);
+            }
+            count++;
+        }
+        content = content.replace("\n", "<br>");
+        return content;
+    }
+
+    @Autowired
+    PaperService paperService;
+    @Test
+    public void createPaperTest() {
+        int questionType = QuestionType.QUESTION1.getCode();
+        QuestionQuery questionQuery = new QuestionQuery.Builder()
+                .pageNumber(1)
+                .pageSize(50)
+                .type(questionType)
+                .build();
+        Page page = questionQuery.getPage();
+        List<Question> questions = questionMapper.findQuestionByPage(page, questionQuery);
+        List<PaperQuestion> paperQuestions = new ArrayList<>();
+        for (int i = 0; i < questions.size(); i++) {
+            Question question = questions.get(i);
+            int pos = i + 1;
+            int score = 1;
+            paperQuestions.add(new PaperQuestion(pos, question, score));
+        }
+
+        questionType = QuestionType.QUESTION6.getCode();
+        questionQuery = new QuestionQuery.Builder()
+                .pageNumber(1)
+                .pageSize(50)
+                .type(questionType)
+                .build();
+        page = questionQuery.getPage();
+        questions = questionMapper.findQuestionByPage(page, questionQuery);
+        paperQuestions = new ArrayList<>();
+        for (int i = 0; i < questions.size(); i++) {
+            Question question = questions.get(i);
+            int pos = i + 1;
+            int score = 1;
+            paperQuestions.add(new PaperQuestion(pos, question, score));
+        }
+
+
+        int totalScore = paperQuestions.stream().mapToInt(PaperQuestion::getScore).sum();
+        Double passScoreDouble = totalScore * 0.6;
+        int passScore = passScoreDouble.intValue();
 
         PaperAddDto paperAddDto = new PaperAddDto();
+        paperAddDto.setExamName("Exam2025");
+        paperAddDto.setTotalScore(totalScore);
+        paperAddDto.setPassScore(passScore);
+        paperAddDto.setExamDuration(90);
+        paperAddDto.setStartTime(new Date());
+        paperAddDto.setEndTime(new Date());
+        paperAddDto.setQuestions(paperQuestions);
+        paperService.createExamPaper(paperAddDto);
     }
 
     private void getPaper(PaperAddDto paperAddDto) {
@@ -261,4 +488,28 @@ public class ExamTest {
             return question;
         }).filter(Objects::nonNull).collect(Collectors.toList());
     }
+
+    @Test
+    public void getPaperAnswerTest() {
+        int paperId = 1;
+        int resultId = 1;
+        List<PaperAnswer> paperAnswerList = paperAnswerMapper.findByResultId(resultId);
+
+        Map<Long, List<Object>> map = new HashMap<>();
+        paperAnswerList.forEach(paperAnswer -> {
+            long questionId = paperAnswer.getQuestionId();
+            int type = paperAnswer.getQuestionType();
+            List<String> answers = List.of(paperAnswer.getAnswer());
+            List<Object> objectList;
+            if (type == QuestionType.QUESTION1.getCode() || type == QuestionType.QUESTION4.getCode()) {
+                objectList = answers.stream()
+                        .map(val -> val.isBlank() ? -1 : Integer.parseInt(val))
+                        .collect(Collectors.toList());
+            } else {
+                objectList = Arrays.asList(answers);
+            }
+
+            map.put(questionId, objectList);
+        });
+    }
 }