xiangpei
2024-05-14 d5f80c24adbef34f8e66cedb46a72a6395134445
题目练习
14个文件已修改
2个文件已添加
280 ■■■■ 已修改文件
src/main/java/com/mindskip/xzs/controller/student/QuestionController.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mindskip/xzs/domain/SelfPractice.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mindskip/xzs/domain/enums/PracticeQuestionTypeEnum.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mindskip/xzs/domain/vo/QuestionContentVO.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mindskip/xzs/domain/vo/SelfPracticeVO.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mindskip/xzs/domain/vo/SubjectQuestionVO.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mindskip/xzs/repository/QuestionMapper.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mindskip/xzs/repository/QuestionSubjectMapper.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mindskip/xzs/repository/SubjectMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mindskip/xzs/service/QuestionService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mindskip/xzs/service/impl/QuestionServiceImpl.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mindskip/xzs/service/impl/SelfPracticeServiceImpl.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/QuestionMapper.xml 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/QuestionSubjectMapper.xml 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/SelfPracticeMapper.xml 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/SubjectMapper.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/mindskip/xzs/controller/student/QuestionController.java
@@ -38,4 +38,14 @@
        return RestResponse.ok(vm);
    }
    @GetMapping("/{id}")
    public RestResponse getById(@PathVariable("id") Integer id) {
        return questionService.selectContentById(id);
    }
    @GetMapping("/answer/{id}")
    public RestResponse getAnswer(@PathVariable("id") Integer id) {
        return questionService.getAnswer(id);
    }
}
src/main/java/com/mindskip/xzs/domain/SelfPractice.java
@@ -21,9 +21,6 @@
    /** 备注 */
    private String remark;
    /** 题目数量 */
    private Integer questionNum;
    /** 练习类型 */
    private String practiceType;
@@ -42,7 +39,7 @@
    /** 已做题数 */
    private Integer doNum;
    /** 题目ID JSON */
    private String questionIds;
    /** 题目类型 */
    private String questionType;
}
src/main/java/com/mindskip/xzs/domain/enums/PracticeQuestionTypeEnum.java
New file
@@ -0,0 +1,44 @@
package com.mindskip.xzs.domain.enums;
import lombok.Getter;
/**
 * @author:xp
 * @date:2024/5/14 9:16
 */
@Getter
public enum PracticeQuestionTypeEnum {
    ALL("all", -99,"不限类型"),
    SINGLE("single", 1,"单选"),
    MULTIPLE("multiple", 2,"多选"),
    JUDGE("judge", 3,"判断"),
    ;
    private final String value;
    /** 题目表中的值 */
    private final Integer dataBaseValue;
    private final String desc;
    PracticeQuestionTypeEnum(String value, Integer dataBaseValue, String desc) {
        this.value = value;
        this.dataBaseValue = dataBaseValue;
        this.desc = desc;
    }
    /**
     * 根据值获取数据库值
     *
     * @param value
     * @return
     */
    public static Integer getDataBaseValueByValue(String value) {
        for (PracticeQuestionTypeEnum practiceQuestionTypeEnum : PracticeQuestionTypeEnum.values()) {
            if (practiceQuestionTypeEnum.getValue().equals(value)) {
                return practiceQuestionTypeEnum.dataBaseValue;
            }
        }
        return -1;
    }
}
src/main/java/com/mindskip/xzs/domain/vo/QuestionContentVO.java
@@ -17,6 +17,9 @@
    /** 解析 */
    private String analyze;
    /** 答案 */
    private String correct;
    /** 选项 */
    private List<OptionItem> questionItemObjects;
src/main/java/com/mindskip/xzs/domain/vo/SelfPracticeVO.java
@@ -37,6 +37,10 @@
    @NotBlank(message = "请选择练习类型")
    private String practiceType;
    /** 题型 */
    @NotBlank(message = "请选择练习题型")
    private String questionType;
    /** 创建时间 */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;
@@ -50,12 +54,6 @@
    /** 做题总数 */
    private Integer totalQuestionNum;
    /** 题目总数 */
    @NotBlank(message = "题目数量不能为空")
    private Integer questionNum;
    private String questionIds;
    private Integer pageSize = 10;
src/main/java/com/mindskip/xzs/domain/vo/SubjectQuestionVO.java
New file
@@ -0,0 +1,31 @@
package com.mindskip.xzs.domain.vo;
import lombok.Data;
import java.util.List;
/**
 * @author:xp
 * @date:2024/5/14 9:50
 */
@Data
public class SubjectQuestionVO {
    private Integer subjectId;
    private String subjectName;
    private List<Integer> questionIds;
    @Data
    public static class QuestionPractice {
        private Integer questionId;
        /** 是否做过:0没有 1做了 */
        private Integer doIt;
    }
}
src/main/java/com/mindskip/xzs/repository/QuestionMapper.java
@@ -31,4 +31,8 @@
    List<QuestionImportVO> export(@Param("query") QuestionExportVO query);
    List<QuestionPageStudentResponseVM> selectQuestion(QuestionPageStudentRequestVM model);
    QuestionVO selectContentById(Integer id);
    String getAnswer(Integer id);
}
src/main/java/com/mindskip/xzs/repository/QuestionSubjectMapper.java
@@ -36,4 +36,13 @@
    /** 随机题目 */
    List<QuestionVO> getRandomQuestionId(@Param("subjectIds") List<Integer> subjectIds, @Param("questionNum") Integer questionNum);
    /** 查询题目ID,根据课目ids */
    List<Integer> questionsBySubjectIds(@Param("subjectIds") List<Integer> subjectIds);
    /** 查询题目ID根据课目id */
    List<Integer> questionsBySubjectId(Integer subjectId);
    /** 根据课目和题型查询题目ID */
    List<Integer> questionsBySubjectIdAndQuestionType(@Param("subjectId") Integer subjectId, @Param("questionType") Integer questionType);
}
src/main/java/com/mindskip/xzs/repository/SubjectMapper.java
@@ -23,4 +23,6 @@
    List<Subject> selectByIds(@Param("ids") Integer[] ids);
    List<String> selectSubjectName(@Param("ids") List<Integer> ids);
    String selectSubjectNameById(Integer id);
}
src/main/java/com/mindskip/xzs/service/QuestionService.java
@@ -1,10 +1,12 @@
package com.mindskip.xzs.service;
import com.github.pagehelper.PageInfo;
import com.mindskip.xzs.base.RestResponse;
import com.mindskip.xzs.domain.Question;
import com.mindskip.xzs.viewmodel.admin.question.ExamQuestionVO;
import com.mindskip.xzs.viewmodel.admin.question.QuestionEditRequestVM;
import com.mindskip.xzs.viewmodel.admin.question.QuestionPageRequestVM;
import com.mindskip.xzs.viewmodel.student.question.answer.QuestionAnswerVO;
import com.mindskip.xzs.viewmodel.student.question.answer.QuestionPageStudentRequestVM;
import com.mindskip.xzs.viewmodel.student.question.answer.QuestionPageStudentResponseVM;
import com.mindskip.xzs.vo.QuestionExportVO;
@@ -43,4 +45,10 @@
    List<QuestionImportVO> export(QuestionExportVO query);
    PageInfo<QuestionPageStudentResponseVM> selectQuestion(QuestionPageStudentRequestVM model);
    /** 查出题目主体内容 */
    RestResponse selectContentById(Integer id);
    /** 获取题目答案、解析 */
    RestResponse getAnswer(Integer id);
}
src/main/java/com/mindskip/xzs/service/impl/QuestionServiceImpl.java
@@ -1,5 +1,7 @@
package com.mindskip.xzs.service.impl;
import com.alibaba.fastjson.JSON;
import com.mindskip.xzs.base.RestResponse;
import com.mindskip.xzs.domain.QuestionSubject;
import com.mindskip.xzs.domain.other.KeyValue;
import com.mindskip.xzs.domain.Question;
@@ -8,6 +10,8 @@
import com.mindskip.xzs.domain.enums.QuestionTypeEnum;
import com.mindskip.xzs.domain.question.QuestionItemObject;
import com.mindskip.xzs.domain.question.QuestionObject;
import com.mindskip.xzs.domain.vo.QuestionContentVO;
import com.mindskip.xzs.domain.vo.QuestionVO;
import com.mindskip.xzs.repository.QuestionMapper;
import com.mindskip.xzs.repository.SubjectMapper;
import com.mindskip.xzs.service.QuestionService;
@@ -30,10 +34,12 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@Service
@@ -265,4 +271,35 @@
                ).collect(Collectors.toList())
        );
    }
    @Override
    public RestResponse selectContentById(Integer id) {
        QuestionVO vo = questionMapper.selectContentById(id);
        jsonQuestion(vo);
        return RestResponse.ok(vo);
    }
    @Override
    public RestResponse getAnswer(Integer id) {
        String content = questionMapper.getAnswer(id);
        if (StringUtils.hasText(content)) {
            QuestionContentVO vo = JSON.parseObject(content, QuestionContentVO.class);
            vo.setQuestionItemObjects(null);
            vo.setTitleContent(null);
            return RestResponse.ok(vo);
        }
        return RestResponse.ok(null);
    }
    /**
     * 处理题目内容JSON
     *
     * @param vo
     */
    public void jsonQuestion(QuestionVO vo) {
        if (StringUtils.hasText(vo.getContentJson())) {
            QuestionContentVO questionContent = JSON.parseObject(vo.getContentJson(), QuestionContentVO.class);
            vo.setContent(questionContent);
        }
    }
}
src/main/java/com/mindskip/xzs/service/impl/SelfPracticeServiceImpl.java
@@ -9,9 +9,13 @@
import com.mindskip.xzs.domain.ExamPaperAnswer;
import com.mindskip.xzs.domain.Question;
import com.mindskip.xzs.domain.SelfPractice;
import com.mindskip.xzs.domain.enums.PracticeQuestionTypeEnum;
import com.mindskip.xzs.domain.enums.PracticeTypeEnum;
import com.mindskip.xzs.domain.enums.QuestionTypeEnum;
import com.mindskip.xzs.domain.vo.QuestionContentVO;
import com.mindskip.xzs.domain.vo.QuestionVO;
import com.mindskip.xzs.domain.vo.SelfPracticeVO;
import com.mindskip.xzs.domain.vo.SubjectQuestionVO;
import com.mindskip.xzs.repository.QuestionMapper;
import com.mindskip.xzs.repository.QuestionSubjectMapper;
import com.mindskip.xzs.repository.SelfPracticeMapper;
@@ -23,6 +27,7 @@
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
@@ -87,26 +92,35 @@
        if (Objects.isNull(en)) {
            throw new RuntimeException("练习不存在");
        }
        if (StringUtils.hasText(en.getQuestionIds())) {
            // 生成了题目就直接查
            List<Integer> questionIdList = JSON.parseArray(en.getQuestionIds(), Integer.class);
            List<QuestionVO> vos = questionMapper.getVoByIds(questionIdList);
            jsonQuestion(vos);
            return RestResponse.ok(vos);
        } else {
            // 没生成过就随机生成题目
            List<Integer> subjectIds = JSON.parseArray(en.getSubjects(), Integer.class);
            Integer totalQuestionNum = questionSubjectMapper.countQuestionNum(subjectIds);
            if (totalQuestionNum < en.getQuestionNum()) {
                throw new RuntimeException("你所选的课目题目数量不足");
        List<Integer> subjectIds = JSON.parseArray(en.getSubjects(), Integer.class);
        if (PracticeTypeEnum.ORDERED.getValue().equals(en.getPracticeType())) {
            List<SubjectQuestionVO> list = new ArrayList<>(2);
            // 顺序做题,把选择的题库的题(id)全部查出来,前端有个序号面板,点击哪道题做哪道
            for (Integer subjectId : subjectIds) {
                String subjectName = subjectMapper.selectSubjectNameById(subjectId);
                // todo根据做题记录查询做没做过
                List<Integer> questionIds = new ArrayList<>();
                if (PracticeQuestionTypeEnum.ALL.getValue().equals(en.getQuestionType())) {
                    questionIds = questionSubjectMapper.questionsBySubjectId(subjectId);
                } else {
                    questionIds = questionSubjectMapper.questionsBySubjectIdAndQuestionType(subjectId, PracticeQuestionTypeEnum.getDataBaseValueByValue(en.getQuestionType()));
                }
                SubjectQuestionVO subjectQuestionVO = new SubjectQuestionVO();
                subjectQuestionVO.setSubjectId(subjectId);
                subjectQuestionVO.setSubjectName(subjectName);
                subjectQuestionVO.setQuestionIds(questionIds);
                list.add(subjectQuestionVO);
            }
            // 查询出课目下随机的设定数量题目
            List<QuestionVO> questionVOList = questionSubjectMapper.getRandomQuestionId(subjectIds, en.getQuestionNum());
            List<Integer> ids = questionVOList.stream().map(QuestionVO::getId).collect(Collectors.toList());
            selfPracticeMapper.setQuestionIds(en.getId(), JSON.toJSONString(ids));
            jsonQuestion(questionVOList);
            return RestResponse.ok(questionVOList);
            return RestResponse.ok(list);
        } else if (PracticeTypeEnum.RANDOM.getValue().equals(en.getPracticeType())) {
            // 随机练习,是一道题一道题练习
            List<QuestionVO> one = questionSubjectMapper.getRandomQuestionId(subjectIds, 1);
            if (one.size() < 1) {
                throw new RuntimeException("没有找到题目,可能所选课目包含题目不足");
            }
            return RestResponse.ok(one.get(0));
        }
        return RestResponse.ok();
    }
    @Override
src/main/resources/mapper/QuestionMapper.xml
@@ -312,4 +312,23 @@
        order by a.create_time
    </select>
    <select id="selectContentById" resultType="com.mindskip.xzs.domain.vo.QuestionVO">
        SELECT
            tq.id,
            tq.question_type as questionType,
            tq.difficult,
            ttc.content as contentJson
        FROM
            t_question tq
            INNER JOIN t_text_content ttc ON tq.info_text_content_id = ttc.id AND tq.id = #{id}
    </select>
    <select id="getAnswer" resultType="string">
        SELECT
            ttc.content
        FROM
            t_question tq
                INNER JOIN t_text_content ttc ON tq.info_text_content_id = ttc.id AND tq.id = #{id} AND tq.deleted = 0
    </select>
</mapper>
src/main/resources/mapper/QuestionSubjectMapper.xml
@@ -79,4 +79,36 @@
             RAND() LIMIT #{questionNum}
    </select>
    <select id="questionsBySubjectIds" resultType="integer">
        SELECT
               question_id
        FROM
             t_question_subject
        <where>
            subject_id IN <foreach collection="subjectIds" open="(" separator="," close=")" item="subjectId">#{subjectId}</foreach>
        </where>
        ORDER BY
            id DESC
    </select>
    <select id="questionsBySubjectId"  resultType="integer">
        SELECT
            tqs.question_id
        FROM
            t_question_subject tqs
                INNER JOIN t_question tq ON tqs.question_id = tq.id AND tqs.subject_id = #{subjectId}
        ORDER BY
            tqs.id DESC
    </select>
    <select id="questionsBySubjectIdAndQuestionType" resultType="integer">
        SELECT
            tqs.question_id
        FROM
            t_question_subject tqs
                INNER JOIN t_question tq ON tqs.question_id = tq.id AND tqs.subject_id = #{subjectId} AND tq.question_type = #{questionType}
        ORDER BY
            tqs.id DESC
    </select>
</mapper>
src/main/resources/mapper/SelfPracticeMapper.xml
@@ -5,9 +5,9 @@
    <insert id="add" keyColumn="id" useGeneratedKeys="true" parameterType="com.mindskip.xzs.domain.SelfPractice">
        INSERT INTO
            t_self_practice(user_id, remark, subjects, practice_type, create_time, update_time, question_num, deleted)
            t_self_practice(user_id, remark, subjects, practice_type, create_time, update_time, question_type, deleted)
        VALUE
            (#{userId}, #{remark}, #{subjects}, #{practiceType}, #{createTime}, #{updateTime}, #{questionNum}, #{deleted})
            (#{userId}, #{remark}, #{subjects}, #{practiceType}, #{createTime}, #{updateTime}, #{questionType}, #{deleted})
    </insert>
    <select id="page" resultType="com.mindskip.xzs.domain.vo.SelfPracticeVO">
@@ -19,8 +19,7 @@
               practice_type as practiceType,
               create_time createTime,
               update_time as updateTime,
               question_num as questionNum,
               question_ids as questionIds
               question_type as questionType
        FROM
             t_self_practice
        <where>
@@ -48,8 +47,7 @@
            practice_type as practiceType,
            create_time createTime,
            update_time as updateTime,
            question_num as questionNum,
            question_ids as questionIds
            question_type as questionType
        FROM
             t_self_practice
        WHERE
src/main/resources/mapper/SubjectMapper.xml
@@ -178,5 +178,9 @@
          id IN <foreach collection="ids" open="(" separator="," close=")" item="id">#{id}</foreach>
  </select>
  <select id="selectSubjectNameById" resultType="string">
    SELECT name FROM t_subject WHERE id = #{id} AND deleted = 0
  </select>
</mapper>