首页 > 其他分享 >答题情况和每题得分

答题情况和每题得分

时间:2024-08-18 10:54:46浏览次数:12  
标签:得分 practice java 答题 req private 每题 import id

文章目录

1.提交答题情况

1.PracticeDetailController.java
    /**
     * 提交题目,每一次点下一题,都会调用这个接口
     */
    @PostMapping(value = "/submitSubject")
    public Result<Boolean> submitSubject(@RequestBody SubmitSubjectDetailReq req) {
        try {
            if (log.isInfoEnabled()) {
                log.info("练习提交题目入参{}", JSON.toJSONString(req));
            }
            Preconditions.checkArgument(!Objects.isNull(req), "参数不能为空!");
            Preconditions.checkArgument(!Objects.isNull(req.getPracticeId()), "练习id不能为空!");
            Preconditions.checkArgument(!Objects.isNull(req.getSubjectId()), "题目id不能为空!");
            Preconditions.checkArgument(!Objects.isNull(req.getSubjectType()), "题目类型不能为空!");
            Preconditions.checkArgument(!StringUtils.isBlank(req.getTimeUse()), "用时不能为空!");
            Boolean result = practiceDetailService.submitSubject(req);
            log.info("练习提交题目出参{}", result);
            return Result.ok(result);
        } catch (IllegalArgumentException e) {
            log.error("参数异常!错误原因{}", e.getMessage(), e);
            return Result.fail(e.getMessage());
        } catch (Exception e) {
            log.error("练习提交题目异常!错误原因{}", e.getMessage(), e);
            return Result.fail("练习提交题目异常!");
        }
    }
2.PracticeDetailService.java
package com.sunxiansheng.practice.server.service;

import com.sunxiansheng.practice.api.req.SubmitSubjectDetailReq;

/**
 * Description:
 * @Author sun
 * @Create 2024/7/8 12:28
 * @Version 1.0
 */
public interface PracticeDetailService {

    /**
     * 练习提交题目
     */
    Boolean submitSubject(SubmitSubjectDetailReq req);

}

3.PracticeDetailServiceImpl.java
package com.sunxiansheng.practice.server.service.impl;

import com.sunxiansheng.practice.api.enums.SubjectInfoTypeEnum;
import com.sunxiansheng.practice.api.req.SubmitSubjectDetailReq;
import com.sunxiansheng.practice.server.dao.*;
import com.sunxiansheng.practice.server.entity.dto.SubjectDTO;
import com.sunxiansheng.practice.server.entity.po.PracticeDetailPO;
import com.sunxiansheng.practice.server.entity.po.PracticePO;
import com.sunxiansheng.practice.server.entity.po.SubjectMultiplePO;
import com.sunxiansheng.practice.server.entity.po.SubjectRadioPO;
import com.sunxiansheng.practice.server.service.PracticeDetailService;
import com.sunxiansheng.practice.server.util.LoginUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * Description:
 * @Author sun
 * @Create 2024/6/25 17:08
 * @Version 1.0
 */
@Service
@Slf4j
public class PracticeDetailServiceImpl implements PracticeDetailService {

    @Resource
    private PracticeDao practiceDao;

    @Resource
    private SubjectDao subjectDao;

    @Resource
    private SubjectRadioDao subjectRadioDao;

    @Resource
    private SubjectMultipleDao subjectMultipleDao;

    @Resource
    private PracticeDetailDao practiceDetailDao;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean submitSubject(SubmitSubjectDetailReq req) {
        // 获取req的信息
        Long practiceId = req.getPracticeId();
        Long subjectId = req.getSubjectId();
        List<Integer> answerContents = req.getAnswerContents();
        Integer subjectType = req.getSubjectType();
        String timeUse = req.getTimeUse();
        // ============================== 处理用时 ==============================
        if (timeUse.equals("0")) {
            timeUse = "000000";
        }
        String hour = timeUse.substring(0, 2);
        String minute = timeUse.substring(2, 4);
        String second = timeUse.substring(4, 6);
        // ============================== 处理用时 ==============================

        // ============================== 根据id更新时间 ==============================
        PracticePO practicePO = new PracticePO();
        practicePO.setId(practiceId);
        practicePO.setTimeUse(hour + ":" + minute + ":" + second);
        practicePO.setSubmitTime(new Date());
        practiceDao.update(practicePO);
        // ============================== 根据id更新时间 ==============================

        // ============================== 给练习的细节插入一条记录 ==============================
        PracticeDetailPO practiceDetailPO = new PracticeDetailPO();
        // 基本信息填充
        practiceDetailPO.setPracticeId(practiceId);
        practiceDetailPO.setSubjectId(subjectId);
        practiceDetailPO.setSubjectType(subjectType);
        String loginId = LoginUtil.getLoginId();
        practiceDetailPO.setCreatedBy(loginId);
        practiceDetailPO.setCreatedTime(new Date());
        practiceDetailPO.setIsDeleted(0);
        // 修改答案数组,将答案变成1,2,3...这种格式的
        String answerContent = getAnswerContent(answerContents);
        practiceDetailPO.setAnswerContent(answerContent);
        // 从数据库中获取正确答案,并判断答案是否正确
        SubjectDTO subjectDTO = new SubjectDTO();
        subjectDTO.setSubjectId(req.getSubjectId());
        subjectDTO.setSubjectType(req.getSubjectType());
        // 根据subjectId和subjectType来获取题目答案
        // 初始化为0
        Integer answerStatus = 0;
        StringBuffer correctAnswer = new StringBuffer();
        // 获得正确答案的字符串
        extracted(subjectType, subjectId, correctAnswer);
        // 如果答案正确,则答案的状态就会是1,否则是0
        if (Objects.equals(correctAnswer.toString(), answerContent)) {
            // practiceDetailPO.setAnswerStatus(1);
            answerStatus = 1;
        }
        practiceDetailPO.setAnswerStatus(answerStatus);
        // 到此练习的细节就构建完毕了

        // 查询练习细节是否已经存在了,如果存在就更新,不存在就插入
        PracticeDetailPO existDetail = practiceDetailDao.selectDetail(practiceId, subjectId, loginId);
        if (Objects.isNull(existDetail)) {
            practiceDetailDao.insertSingle(practiceDetailPO);
        } else {
            practiceDetailPO.setId(existDetail.getId());
            practiceDetailDao.update(practiceDetailPO);
        }
        // ============================== 给练习的细节插入一条记录 ==============================

        return true;
    }

    /**
     * 根据题目id和类型,得到正确答案的字符串
     * @param subjectType
     * @param subjectId
     * @param correctAnswer
     */
    private void extracted(Integer subjectType, Long subjectId, StringBuffer correctAnswer) {
        // 单选
        if (subjectType == SubjectInfoTypeEnum.RADIO.getCode()) {
            // 查询单选题目细节
            List<SubjectRadioPO> subjectRadioPOS = subjectRadioDao.selectBySubjectId(subjectId);
            // 得到对的那个的选项类型
            subjectRadioPOS.forEach(
                    radio -> {
                        if (Objects.equals(radio.getIsCorrect(), 1)) {
                            correctAnswer.append(radio.getOptionType());
                        }
                    }
            );
        }
        // 多选
        if (subjectType == SubjectInfoTypeEnum.MULTIPLE.getCode()) {
            // 查询多选题目细节
            List<SubjectMultiplePO> subjectMultiplePOS = subjectMultipleDao.selectBySubjectId(subjectId);
            // 得到所有的对的选项类型
            subjectMultiplePOS.forEach(
                    multiple -> {
                        if (Objects.equals(multiple.getIsCorrect(), 1)) {
                            correctAnswer.append(multiple.getOptionType()).append(",");
                        }
                    }
            );
            // 去掉最后一个逗号
            if (correctAnswer.length() > 0) {
                correctAnswer.deleteCharAt(correctAnswer.length() - 1);
            }
        }
        // 判断
        if (subjectType == SubjectInfoTypeEnum.JUDGE.getCode()) {
            // 查询判断题目细节
            List<SubjectMultiplePO> subjectMultiplePOS = subjectMultipleDao.selectBySubjectId(subjectId);
            // 判断题只能有一条细节,所以取第一个就可以
            Integer isCorrect = subjectMultiplePOS.get(0).getIsCorrect();
            correctAnswer.append(isCorrect);
        }
    }

    /**
     * 修改答案数组,将答案变成1,2,3...这种格式的
     * @param answerContents
     * @return
     */
    private static String getAnswerContent(List<Integer> answerContents) {
        String answerContent = "";
        // 判空
        if (!CollectionUtils.isEmpty(answerContents)) {
            // 排序
            Collections.sort(answerContents);
            // 拼接
            answerContent = StringUtils.join(answerContents, ",");
        }
        return answerContent;
    }

}

4.PracticeDetailDao.java
    /**
     * 更新练习详情
     */
    int update(PracticeDetailPO practiceDetailPO);
5.PracticeDetailDao.xml
    <update id="update">
        update practice_detail
        <set>
            <if test="answerStatus != null">
                answer_status = #{answerStatus},
            </if>
            <if test="answerContent != null">
                answer_content = #{answerContent},
            </if>
        </set>
        where id = #{id,jdbcType=BIGINT}
    </update>
6.req
SubmitSubjectDetailReq.java
package com.sunxiansheng.practice.api.req;

import lombok.Data;

import java.io.Serializable;
import java.util.List;

@Data
public class SubmitSubjectDetailReq implements Serializable {

    /**
     * 练习id
     */
    private Long practiceId;

    /**
     * 题目id
     */
    private Long subjectId;

    /**
     * 题目答案
     */
    private List<Integer> answerContents;

    /**
     * 题目类型
     */
    private Integer subjectType;

    /**
     * 用时
     */
    private String timeUse;

}
7.dto
1.SubjectDetailDTO.java
package com.sunxiansheng.practice.server.entity.dto;

import lombok.Data;

import java.io.Serializable;
import java.util.List;

@Data
public class SubjectDetailDTO implements Serializable {

    /**
     * 题目id
     */
    private Long id;

    /**
     * 题目名称
     */
    private String subjectName;

    /**
     * 判断题答案
     */
    private Integer isCorrect;

    /**
     * 题目解析
     */
    private String subjectParse;

    /**
     * 单选、多选、判断题目答案
     */
    private List<SubjectOptionDTO> optionList;


}
2.SubjectDTO.java
package com.sunxiansheng.practice.server.entity.dto;

import lombok.Data;

import java.io.Serializable;

@Data
public class SubjectDTO implements Serializable {

    /**
     * 题目id
     */
    private Long id;

    /**
     * 题目id
     */
    private Long subjectId;

    /**
     * 题目名称
     */
    private String subjectName;

    /**
     * 题目类型
     */
    private Integer subjectType;

}
3.SubjectOptionDTO.java
package com.sunxiansheng.practice.server.entity.dto;

import lombok.Data;

import java.io.Serializable;

@Data
public class SubjectOptionDTO implements Serializable {

    /**
     * 答案类型
     */
    private Integer optionType;

    /**
     * 答案内容
     */
    private String optionContent;

    /**
     * 是否为正确答案
     */
    private Integer isCorrect;

}
8.测试
1.接口设计

CleanShot 2024-07-08 at 15.57.58@2x

2.db
1.更新提交时间和用时 practice_info

CleanShot 2024-07-08 at 15.59.47@2x

2.练习细节如果有的话就更新记录 practice_detail

CleanShot 2024-07-08 at 16.01.05@2x

3.测试遇到一个bug,即使题目正确也会插入答案状态为0,状态设置的时候有问题

CleanShot 2024-07-08 at 16.02.44@2x

2.答案解析-每题得分

1.GetScoreDetailReq.java
package com.sunxiansheng.practice.api.req;

import lombok.Data;

import java.io.Serializable;

@Data
public class GetScoreDetailReq implements Serializable {

    /**
     * 练习id
     */
    private Long practiceId;

}
2.ScoreDetailVO.java
package com.sunxiansheng.practice.api.vo;

import lombok.Data;

import java.io.Serializable;

@Data
public class ScoreDetailVO implements Serializable {

    /**
     * 题目id
     */
    private Long subjectId;

    /**
     * 题目类型
     */
    private Integer subjectType;

    /**
     * 是否正确
     */
    private Integer isCorrect;


}
3.PracticeDetailController.java
    /**
     * 答案解析-每题得分
     */
    @PostMapping(value = "/getScoreDetail")
    public Result<List<ScoreDetailVO>> getScoreDetail(@RequestBody GetScoreDetailReq req) {
        try {
            if (log.isInfoEnabled()) {
                log.info("每题得分入参{}", JSON.toJSONString(req));
            }
            Preconditions.checkArgument(!Objects.isNull(req), "参数不能为空!");
            Preconditions.checkArgument(!Objects.isNull(req.getPracticeId()), "练习id不能为空!");
            List<ScoreDetailVO> list = practiceDetailService.getScoreDetail(req);
            if (log.isInfoEnabled()) {
                log.info("每题得分出参{}", JSON.toJSONString(list));
            }
            return Result.ok(list);
        } catch (IllegalArgumentException e) {
            log.error("参数异常!错误原因{}", e.getMessage(), e);
            return Result.fail(e.getMessage());
        } catch (Exception e) {
            log.error("每题得分异常!错误原因{}", e.getMessage(), e);
            return Result.fail("每题得分异常!");
        }
    }

4.PracticeDetailService.java
    /**
     * 每题得分详情
     */
    List<ScoreDetailVO> getScoreDetail(GetScoreDetailReq req);

5.PracticeDetailServiceImpl.java
    @Override
    public List<ScoreDetailVO> getScoreDetail(GetScoreDetailReq req) {
        // 获取练习id
        Long practiceId = req.getPracticeId();
        // 根据练习id查询题目id,题目类型,题目状态
        List<PracticeDetailPO> practiceDetailPOList = practiceDetailDao.selectByPracticeId(practiceId);
        // 判空
        if (CollectionUtils.isEmpty(practiceDetailPOList)) {
            return Collections.emptyList();
        }
        // 将其map成要返回的结果
        List<ScoreDetailVO> res = practiceDetailPOList.stream().map(
                po -> {
                    // 将每一个practiceDetailPO都map成ScoreDetailVO
                    ScoreDetailVO scoreDetailVO = new ScoreDetailVO();
                    scoreDetailVO.setSubjectId(po.getSubjectId());
                    scoreDetailVO.setSubjectType(po.getSubjectType());
                    scoreDetailVO.setIsCorrect(po.getAnswerStatus());
                    return scoreDetailVO;
                }
        ).collect(Collectors.toList());
        return res;
    }
6.PracticeDetailDao.xml
    <select id="selectByPracticeId" resultType="com.sunxiansheng.practice.server.entity.po.PracticeDetailPO">
        select subject_id as subjectId, subject_type as subjectType, answer_status as answerStatus
        from practice_detail
        where practice_id = #{practiceId}
          and is_deleted = 0
    </select>
7.测试

CleanShot 2024-07-09 at 12.37.41@2x

标签:得分,practice,java,答题,req,private,每题,import,id
From: https://blog.csdn.net/m0_64637029/article/details/141296916

相关文章

  • 微信答题小程序产品研发-前端开发
    开发一款答题小程序界面,涉及到的技术栈,主要包括微信小程序的WXML、WXSS、JavaScript等。由于时间有限,我先大致记录一下各个功能模块的基本开发概要,后面有空了再详细整理,分享给大家。1.首页(1)WXML:使用`<view>`标签构建页面结构,包含导航栏、轮播图容器和功能模块入口。(2)WXSS......
  • 倾向匹配得分模型 PSM 及 Stata 具体操作步骤
    目录一、引言二、文献综述三、理论原理四、实证模型五、程序代码及解释六、代码运行结果七、稳健性检验八、结论一、引言倾向匹配得分模型(PropensityScoreMatching,PSM)是一种在观察性研究中用于减少选择偏差的常用方法。通过估计个体接受某种处理(例如参与某个......
  • 【LeetCode:3148】矩阵中的最大得分(Java)
    题目链接3148.矩阵中的最大得分题目描述给你一个由正整数组成、大小为mxn的矩阵grid。你可以从矩阵中的任一单元格移动到另一个位于正下方或正右侧的任意单元格(不必相邻)。从值为c1的单元格移动到值为c2的单元格的得分为c2-c1。你可以从任一单元格开始......
  • 智林 - AI 答题应用平台介绍
    智林-AI答题应用平台一、项目介绍智林AI答题是一款基于Vue3+SpringBoot+Redis+ChatGLM+RxJava+SSE的AI答题应用平台。用户可以基于AI快速制作并发布答题应用,支持检索、分享、在线答题并基于AI得到回答总结;管理员可以集中管理和审核应用。什么是答题应......
  • 宁德时代社招SHL入职测评:语言理解数字推理测评及综合测评真题、高分攻略、答题技巧
    宁德时代的社招入职测评主要采用SHL的Verify系统,测评内容包括语言理解、数字推理、逻辑推理等部分。具体来说,语言理解部分包括阅读理解、逻辑填空和语句排序等题型,要求在限定时间内完成一定数量的题目。数字推理部分则包括数字序列、数学问题解决和图表分析等题型,同样需要在限......
  • 微信答题小程序产品研发-用户操作流程设计
    在答题小程序中,用户流程是指用户从进入小程序开始,到完成答题、查看结果、进行练习等一系列操作的步骤。这里我画了一张用户流程图,展示用户在小程序中的主要操作流程。以及对每个步骤的详细说明。这里分两种角色,用户和管理员(或运营者)。那么,它解决了什么问题?为用户提供了一个......
  • 题解:P10721 [GESP202406 六级] 计算得分(未成功)
    博客食用更佳:Myblog题目传送门分析:这道题是一个标准的dp。我们可以先预处理多个\(\texttt{abc}\)连成的字符串的最大值,之后可以按最长平台的方法处理。步骤:初值:这题不需要赋值,因为题目保证得分是正的,故初值为\(0\)。状态:\(dp_i\)表示连续\(i\)个\(\texttt{abc......
  • CSP - Junior 初赛备考手册 如何答题
    本文章将结合CSP2019-2023的题目,本蒟蒻将分享自己的拙见。网络CSP2019T1中国的国家顶级域名是______。A..cnB..chC..chnD..chinaAnswer:A常识问题。二进制运算CSP2019T2二进制数\(11~1011~1001~0111\)和\(01~0110~1110~1011\)进行按位与运算的结果......
  • C#简答题
    目录1.实现通用打印泛型类,可以打印各个集合中的值,方便调试。2.计算遍历目录的耗时。3.有哪些算术运算符,有哪些关系运算符,有哪些逻辑运算符,有哪些位运算符,有哪些赋值运算符。4.三目表达式举例。5.优先级口诀:有括号先括号,后乘除再加减,然后位移再关系,逻辑完后再条件。6.写个......
  • 【python爬虫实战】进阶天气虫虫(过程复盘 & 心得分享)
    程序设计过程里的一些心得:0.规模较大的程序,往往都是以更小的功能块搭建起来的。如此,为了提升总体程序的构建效率,笔者发现分“两步走”会比较高效:    A.遇到需要反复调试的功能块,可先在另一程序中逐一单独测试某一功能块(这有助于突出模块本身的细节问题)   ......