| | |
| | | return selfPracticeService.page(vo); |
| | | } |
| | | |
| | | /** |
| | | * 获取所选课目下的题目数量 |
| | | * |
| | | * @param subjectIds |
| | | * @return |
| | | */ |
| | | @PostMapping("/subject/questionNum") |
| | | public RestResponse subjectQuestionNum(@RequestBody List<Integer> subjectIds) { |
| | | return selfPracticeService.subjectQuestionNum(subjectIds); |
| | | } |
| | | |
| | | @PostMapping("/remove") |
| | | public RestResponse remove(@RequestBody @NotEmpty(message = "请选择要删除的数据") List<Integer> ids) { |
| | | return selfPracticeService.remove(ids); |
| | | } |
| | | |
| | | /** |
| | | * 开始练习 |
| | | * |
| | | * @param id 练习id |
| | | * @return |
| | | */ |
| | | @PostMapping("/start/{id}") |
| | | public RestResponse startPractice(@PathVariable("id") Integer id) { |
| | | return selfPracticeService.startPractice(id); |
| | | } |
| | | |
| | | } |
| | |
| | | /** 备注 */ |
| | | private String remark; |
| | | |
| | | /** 题目数量 */ |
| | | private Integer questionNum; |
| | | |
| | | /** 练习类型 */ |
| | | private String practiceType; |
| | | |
| | |
| | | /** 已做题数 */ |
| | | private Integer doNum; |
| | | |
| | | /** 题目ID JSON */ |
| | | private String questionIds; |
| | | |
| | | } |
New file |
| | |
| | | package com.mindskip.xzs.domain.enums; |
| | | |
| | | import lombok.Getter; |
| | | |
| | | /** |
| | | * 个人练习类型 |
| | | * |
| | | * @author:xp |
| | | * @date:2024/5/10 9:52 |
| | | */ |
| | | @Getter |
| | | public enum PracticeTypeEnum { |
| | | |
| | | RANDOM("random"), |
| | | ORDERED("ordered"), |
| | | ; |
| | | |
| | | private final String value; |
| | | |
| | | PracticeTypeEnum(String value) { |
| | | this.value = value; |
| | | } |
| | | } |
New file |
| | |
| | | package com.mindskip.xzs.domain.vo; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author:xp |
| | | * @date:2024/5/11 15:04 |
| | | */ |
| | | @Data |
| | | public class QuestionContentVO { |
| | | |
| | | /** 题干 */ |
| | | private String titleContent; |
| | | |
| | | /** 解析 */ |
| | | private String analyze; |
| | | |
| | | /** 选项 */ |
| | | private List<OptionItem> questionItemObjects; |
| | | |
| | | @Data |
| | | public class OptionItem { |
| | | |
| | | /** 选项 */ |
| | | private String prefix; |
| | | |
| | | /** 选项内容 */ |
| | | private String content; |
| | | |
| | | /** 选项顺序 */ |
| | | private Integer itemOrder; |
| | | |
| | | /** id */ |
| | | private String itemUuid; |
| | | |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.mindskip.xzs.domain.vo; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author:xp |
| | | * @date:2024/5/10 11:07 |
| | | */ |
| | | @Data |
| | | public class QuestionVO { |
| | | |
| | | private Integer id; |
| | | |
| | | /** 题目内容JSON */ |
| | | private String contentJson; |
| | | |
| | | /** 题目类型 */ |
| | | private Integer questionType; |
| | | |
| | | /** 难度 */ |
| | | private Integer difficult; |
| | | |
| | | /** 内容对象 */ |
| | | private QuestionContentVO content; |
| | | |
| | | /** 普通题目答案:单选、判断、问答 */ |
| | | private String correct; |
| | | |
| | | /** 多选题答案 */ |
| | | private List<String> correctList; |
| | | |
| | | } |
| | |
| | | /** 做题总数 */ |
| | | private Integer totalQuestionNum; |
| | | |
| | | /** 题目总数 */ |
| | | @NotBlank(message = "题目数量不能为空") |
| | | private Integer questionNum; |
| | | |
| | | private String questionIds; |
| | | |
| | | |
| | | private Integer pageSize = 10; |
| | | private Integer pageNum = 1; |
| | | } |
| | |
| | | |
| | | import com.mindskip.xzs.domain.other.KeyValue; |
| | | import com.mindskip.xzs.domain.Question; |
| | | import com.mindskip.xzs.domain.vo.QuestionVO; |
| | | import com.mindskip.xzs.viewmodel.admin.question.QuestionPageRequestVM; |
| | | import com.mindskip.xzs.vo.QuestionExportVO; |
| | | import com.mindskip.xzs.vo.QuestionImportVO; |
| | |
| | | List<Question> page(QuestionPageRequestVM requestVM); |
| | | |
| | | List<Question> selectByIds(@Param("ids") List<Integer> ids); |
| | | List<QuestionVO> getVoByIds(@Param("ids") List<Integer> ids); |
| | | |
| | | Integer selectAllCount(); |
| | | |
| | |
| | | package com.mindskip.xzs.repository; |
| | | |
| | | import com.mindskip.xzs.domain.QuestionSubject; |
| | | import com.mindskip.xzs.domain.vo.QuestionVO; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | import org.apache.ibatis.annotations.Param; |
| | | |
| | |
| | | |
| | | /** 统计课目的题目数 */ |
| | | Integer countQuestionNum(@Param("subjects") List<Integer> subjects); |
| | | |
| | | /** 随机题目 */ |
| | | List<QuestionVO> getRandomQuestionId(@Param("subjectIds") List<Integer> subjectIds, @Param("questionNum") Integer questionNum); |
| | | } |
| | |
| | | * @param ids |
| | | */ |
| | | void remove(List<Integer> ids); |
| | | |
| | | /** |
| | | * id查详情 |
| | | * |
| | | * @param id |
| | | * @return |
| | | */ |
| | | SelfPractice selectById(Integer id); |
| | | |
| | | /** |
| | | * 设置题目id |
| | | * |
| | | * @param id |
| | | * @param questionIds |
| | | */ |
| | | void setQuestionIds(@Param("id") Integer id, @Param("questionIds") String questionIds); |
| | | } |
| | |
| | | */ |
| | | RestResponse remove(List<Integer> ids); |
| | | |
| | | /** |
| | | * 开始练习 |
| | | * |
| | | * @param id |
| | | * @return |
| | | */ |
| | | RestResponse startPractice(Integer id); |
| | | |
| | | /** |
| | | * 查询课目下的题目数量 |
| | | * |
| | | * @param subjectIds |
| | | * @return |
| | | */ |
| | | RestResponse subjectQuestionNum(List<Integer> subjectIds); |
| | | } |
| | |
| | | import com.mindskip.xzs.base.RestResponse; |
| | | import com.mindskip.xzs.context.WebContext; |
| | | import com.mindskip.xzs.domain.ExamPaperAnswer; |
| | | import com.mindskip.xzs.domain.Question; |
| | | import com.mindskip.xzs.domain.SelfPractice; |
| | | 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.repository.QuestionMapper; |
| | | import com.mindskip.xzs.repository.QuestionSubjectMapper; |
| | | import com.mindskip.xzs.repository.SelfPracticeMapper; |
| | | import com.mindskip.xzs.repository.SubjectMapper; |
| | | import com.mindskip.xzs.service.QuestionSubjectService; |
| | | import com.mindskip.xzs.service.SelfPracticeService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.util.CollectionUtils; |
| | | import org.springframework.util.StringUtils; |
| | | |
| | | import java.util.Date; |
| | | import java.util.List; |
| | |
| | | private final WebContext webContext; |
| | | private final QuestionSubjectMapper questionSubjectMapper; |
| | | private final SubjectMapper subjectMapper; |
| | | private final QuestionMapper questionMapper; |
| | | |
| | | @Override |
| | | public RestResponse add(SelfPracticeVO vo) { |
| | |
| | | selfPracticeMapper.remove(ids); |
| | | return RestResponse.ok("删除成功"); |
| | | } |
| | | |
| | | @Override |
| | | public RestResponse startPractice(Integer id) { |
| | | SelfPractice en = selfPracticeMapper.selectById(id); |
| | | 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<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); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public RestResponse subjectQuestionNum(List<Integer> subjectIds) { |
| | | Integer num = questionSubjectMapper.countQuestionNum(subjectIds); |
| | | return RestResponse.ok(num); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 处理题目内容JSON |
| | | * |
| | | * @param vos |
| | | */ |
| | | public void jsonQuestion(List<QuestionVO> vos) { |
| | | vos.stream().forEach(vo -> { |
| | | if (StringUtils.hasText(vo.getContentJson())) { |
| | | QuestionContentVO questionContent = JSON.parseObject(vo.getContentJson(), QuestionContentVO.class); |
| | | vo.setContent(questionContent); |
| | | } |
| | | }); |
| | | } |
| | | } |
| | |
| | | <result column="deleted" jdbcType="BIT" property="deleted" /> |
| | | </resultMap> |
| | | <sql id="Base_Column_List"> |
| | | id, question_type, subject_id, score, grade_level, difficult, correct, info_text_content_id, |
| | | id |
| | | , question_type, subject_id, score, grade_level, difficult, correct, info_text_content_id, |
| | | create_user, status, create_time, deleted |
| | | </sql> |
| | | <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap"> |
| | |
| | | where id = #{id,jdbcType=INTEGER} |
| | | </select> |
| | | <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer"> |
| | | delete from t_question |
| | | delete |
| | | from t_question |
| | | where id = #{id,jdbcType=INTEGER} |
| | | </delete> |
| | | <insert id="insert" parameterType="com.mindskip.xzs.domain.Question" useGeneratedKeys="true" keyProperty="id"> |
| | | insert into t_question (id, question_type, subject_id, |
| | | score, grade_level, difficult, |
| | | correct, info_text_content_id, create_user, |
| | | status, create_time, deleted |
| | | ) |
| | | status, create_time, deleted) |
| | | values (#{id,jdbcType=INTEGER}, #{questionType,jdbcType=INTEGER}, #{subjectId,jdbcType=INTEGER}, |
| | | #{score,jdbcType=INTEGER}, #{gradeLevel,jdbcType=INTEGER}, #{difficult,jdbcType=INTEGER}, |
| | | #{correct,jdbcType=VARCHAR}, #{infoTextContentId,jdbcType=INTEGER}, #{createUser,jdbcType=INTEGER}, |
| | | #{status,jdbcType=INTEGER}, #{createTime,jdbcType=TIMESTAMP}, #{deleted,jdbcType=BIT} |
| | | ) |
| | | #{status,jdbcType=INTEGER}, #{createTime,jdbcType=TIMESTAMP}, #{deleted,jdbcType=BIT}) |
| | | </insert> |
| | | <insert id="insertSelective" parameterType="com.mindskip.xzs.domain.Question" useGeneratedKeys="true" keyProperty="id"> |
| | | <insert id="insertSelective" parameterType="com.mindskip.xzs.domain.Question" useGeneratedKeys="true" |
| | | keyProperty="id"> |
| | | insert into t_question |
| | | <trim prefix="(" suffix=")" suffixOverrides=","> |
| | | <if test="id != null"> |
| | |
| | | </update> |
| | | |
| | | |
| | | |
| | | |
| | | <select id="page" resultMap="BaseResultMap" parameterType="com.mindskip.xzs.viewmodel.admin.question.QuestionPageRequestVM"> |
| | | <select id="page" resultMap="BaseResultMap" |
| | | parameterType="com.mindskip.xzs.viewmodel.admin.question.QuestionPageRequestVM"> |
| | | SELECT |
| | | q.* |
| | | FROM t_question q |
| | |
| | | and t.content->'$."titleContent"' LIKE concat('%',#{questionName},'%') |
| | | </if> |
| | | <if test="content != null"> |
| | | and q.info_text_content_id in (SELECT id FROM t_text_content WHERE content like concat('%',#{content},'%') ) |
| | | and q.info_text_content_id in (SELECT id FROM t_text_content WHERE content like |
| | | concat('%',#{content},'%') ) |
| | | </if> |
| | | </where> |
| | | group by q.id |
| | | </select> |
| | | |
| | | |
| | | |
| | | <select id="selectByIds" resultMap="BaseResultMap" > |
| | |
| | | |
| | | |
| | | <select id="selectAllCount" resultType="java.lang.Integer"> |
| | | SELECT count(*) from t_question where deleted=0 |
| | | SELECT count(*) |
| | | from t_question |
| | | where deleted = 0 |
| | | </select> |
| | | |
| | | <select id="selectCountByDate" resultType="com.mindskip.xzs.domain.other.KeyValue"> |
| | | SELECT create_time as name,COUNT(create_time) as value from |
| | | SELECT create_time as name, COUNT(create_time) as value |
| | | from |
| | | ( |
| | | SELECT DATE_FORMAT(create_time,'%Y-%m-%d') as create_time from t_question |
| | | WHERE deleted=0 and create_time between #{startTime} and #{endTime} |
| | |
| | | </select> |
| | | |
| | | <select id="getAll" resultMap="BaseResultMap"> |
| | | SELECT <include refid="Base_Column_List"/> |
| | | SELECT |
| | | <include refid="Base_Column_List"/> |
| | | from t_question where deleted=0 |
| | | </select> |
| | | |
| | |
| | | </resultMap> |
| | | |
| | | <select id="selectSubjects" resultType="string"> |
| | | SELECT ts.name |
| | | FROM t_question_subject tqs |
| | | INNER JOIN t_subject ts |
| | | ON tqs.subject_id = ts.id AND tqs.question_id = #{id} AND tqs.deleted = 0 AND ts.deleted = 0 |
| | | </select> |
| | | |
| | | <select id="getVoByIds" resultType="com.mindskip.xzs.domain.vo.QuestionVO"> |
| | | SELECT |
| | | ts.name |
| | | tq.id, |
| | | tq.question_type as questionType, |
| | | tq.difficult, |
| | | ttc.content as contentJson |
| | | FROM |
| | | t_question_subject tqs |
| | | INNER JOIN t_subject ts ON tqs.subject_id = ts.id AND tqs.question_id = #{id} AND tqs.deleted = 0 AND ts.deleted = 0 |
| | | t_question tq |
| | | INNER JOIN t_text_content ttc ON tq.info_text_content_id = ttc.id AND tq.deleted = 0 AND tq.id IN |
| | | <foreach |
| | | collection="ids" open="(" separator="," close=")" item="id"> |
| | | #{id} |
| | | </foreach> |
| | | </select> |
| | | |
| | | </mapper> |
| | |
| | | subject_id IN <foreach collection="subjects" open="(" separator="," close=")" item="subjectId">#{subjectId}</foreach> |
| | | </select> |
| | | |
| | | <select id="getRandomQuestionId" resultType="com.mindskip.xzs.domain.vo.QuestionVO"> |
| | | SELECT |
| | | distinct |
| | | tq.id, |
| | | tq.question_type as questionType, |
| | | tq.difficult, |
| | | ttc.content as contentJson |
| | | FROM |
| | | t_question_subject tqs |
| | | INNER JOIN t_question tq ON tqs.question_id = tq.id AND tq.deleted = 0 AND tqs.subject_id IN <foreach collection="subjectIds" open="(" separator="," close=")" item="subjectId">#{subjectId}</foreach> |
| | | INNER JOIN t_text_content ttc ON tq.info_text_content_id = ttc.id |
| | | ORDER BY |
| | | RAND() LIMIT #{questionNum} |
| | | </select> |
| | | |
| | | </mapper> |
| | |
| | | |
| | | <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, deleted) |
| | | t_self_practice(user_id, remark, subjects, practice_type, create_time, update_time, question_num, deleted) |
| | | VALUE |
| | | (#{userId}, #{remark}, #{subjects}, #{practiceType}, #{createTime}, #{updateTime}, #{deleted}) |
| | | (#{userId}, #{remark}, #{subjects}, #{practiceType}, #{createTime}, #{updateTime}, #{questionNum}, #{deleted}) |
| | | </insert> |
| | | |
| | | <select id="page" resultType="com.mindskip.xzs.domain.vo.SelfPracticeVO"> |
| | |
| | | subjects as subjectString, |
| | | practice_type as practiceType, |
| | | create_time createTime, |
| | | update_time as updateTime |
| | | update_time as updateTime, |
| | | question_num as questionNum, |
| | | question_ids as questionIds |
| | | FROM |
| | | t_self_practice |
| | | <where> |
| | |
| | | id IN <foreach collection="ids" open="(" separator="," close=")" item="id">#{id}</foreach> |
| | | </update> |
| | | |
| | | <select id="selectById" resultType="com.mindskip.xzs.domain.SelfPractice"> |
| | | SELECT |
| | | id, |
| | | user_id as userId, |
| | | remark, |
| | | subjects as subjects, |
| | | practice_type as practiceType, |
| | | create_time createTime, |
| | | update_time as updateTime, |
| | | question_num as questionNum, |
| | | question_ids as questionIds |
| | | FROM |
| | | t_self_practice |
| | | WHERE |
| | | id = #{id} |
| | | </select> |
| | | |
| | | <update id="setQuestionIds"> |
| | | UPDATE t_self_practice SET question_ids = #{questionIds} WHERE id = #{id} |
| | | </update> |
| | | |
| | | |
| | | </mapper> |