答题情况和每题得分

news2024/11/24 16:21:06

文章目录

    • 1.提交答题情况
        • 1.PracticeDetailController.java
        • 2.PracticeDetailService.java
        • 3.PracticeDetailServiceImpl.java
        • 4.PracticeDetailDao.java
        • 5.PracticeDetailDao.xml
        • 6.req
          • SubmitSubjectDetailReq.java
        • 7.dto
          • 1.SubjectDetailDTO.java
          • 2.SubjectDTO.java
          • 3.SubjectOptionDTO.java
        • 8.测试
          • 1.接口设计
          • 2.db
            • 1.更新提交时间和用时 practice_info
            • 2.练习细节如果有的话就更新记录 practice_detail
            • 3.测试遇到一个bug,即使题目正确也会插入答案状态为0,状态设置的时候有问题
    • 2.答案解析-每题得分
        • 1.GetScoreDetailReq.java
        • 2.ScoreDetailVO.java
        • 3.PracticeDetailController.java
        • 4.PracticeDetailService.java
        • 5.PracticeDetailServiceImpl.java
        • 6.PracticeDetailDao.xml
        • 7.测试

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2050445.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法的学习笔记—合并两个排序的链表(牛客JZ25)

&#x1f600;前言 在算法面试中&#xff0c;链表问题是经常遇到的考点之一&#xff0c;其中合并两个排序链表是一个非常经典的问题。本文将详细介绍如何通过递归和迭代两种方式实现两个有序链表的合并。 &#x1f3e0;个人主页&#xff1a;尘觉主页 文章目录 &#x1f600;合并…

大厂高频软件测试面试题和答案都帮你准备好啦,备战金九银十

还有两周时间就是金九银十求职招聘季了&#xff0c;每年的9月和10月&#xff0c;都是毕业生求职的大好时机&#xff0c;很多企业为招揽人才&#xff0c;会在每年的九十月份举办针对应届生的招聘会。接下来小编已为大家备好了多家大厂高频软件测试面试题和答案&#xff0c; 说下…

Zookeeper应用场景实战一

目录 1. Zookeeper Java客户端实战 1.1 Zookeeper 原生Java客户端使用 ZooKeeper常用构造器 示例代码&#xff1a; Zookeeper主要方法 1.2 Curator开源客户端使用 引入依赖 示例代码&#xff1a; 创建一个客户端实例 创建节点 一次性创建带层级结构的节点 获取数据 …

RTC时钟测试

1. 基础知识 Linux 的系统时间有时跟硬件时间是不同步的。 Linux时钟分为系统时钟(System Clock)和硬件(Real Time Clock&#xff0c;简称RTC)时钟。系统时钟是指当前Linux Kernel中的时钟&#xff0c;而硬件时钟则是主板上由电池供电的时钟&#xff0c;这个硬件时钟可以在BIO…

编译aws并访问minio

Aws amazon (S3) 是一个公开的服务&#xff0c;Web 应用程序开发人员可以使用它存储数字资产&#xff0c;包括图片、视频、音乐和文档。 S3 提供一个 RESTful API 以编程方式实现与该服务的交互. MinIO是兼容AWS SDK,所以可以通过aws访问minio文件系统。 指导文档&#xff1…

CSS知识点详解:display+float

display&#xff1a;浮动 1.block&#xff1a;使元素呈现为块级元素&#xff0c;可设置宽高 display: block; 特点&#xff1a;使元素呈现为块级元素&#xff0c;即该元素会以新行开始&#xff0c;占据整行的宽度&#xff0c;即使其宽度未满。 例子&#xff1a; 2.inline&a…

队列(笔记)

文章目录 1. 概念2. 实现方式3. 复杂度其他 4. 实际应用5. 内容出处 1. 概念 队列&#xff1a;其实就是排队。像我们在银行窗口取钱、车站买车票等都可以叫队列。 特点&#xff1a;队列只允许在后端(rear)进行插入操作&#xff0c;在前端(front)进行删除操作(即先进先出…

算法刷题记录 八十五【图论的广度优先搜索理论基础】

前言 图论章节第2篇。 第1篇&#xff1a;记录 八十二【图论理论基础及深度优先搜索算法】&#xff1b; 本文&#xff1a;记录 八十五【图论的广度优先搜索理论基础】 一、广度优先搜索理论基础 广度优先搜索理论基础 参考链接 1.1 知识点框架 1.2 模拟广度搜索的过程 在有向…

Llama 3.1深度解析:405B、70B及8B模型的多语言与长上下文处理能力

Llama 3.1 发布了&#xff01;今天我们迎来了 Llama 家族的新成员 Llama 3.1 进入 Hugging Face 平台。我们很高兴与 Meta 合作&#xff0c;确保在 Hugging Face 生态系统中实现最佳集成。Hub 上现有八个开源权重模型 (3 个基础模型和 5 个微调模型)。 Llama 3.1 有三种规格: …

字符串拼接和反转

定义一个方法&#xff0c;把int数组中的数据按照指定的格式拼接成一个字符串 调用该方法&#xff0c;并在控制台输出结果 例如&#xff1a; 数组为 int[] arr [1,2,3]; 执行方法后的输出结果为:[1,2,3] package stringdemo;public class StringDemo3 {public static void…

洋牡丹:多彩花语与深邃寓意

一、洋牡丹概述 洋牡丹&#xff0c;学名为花毛茛&#xff0c;其名称的由来颇为有趣。因花型酷似牡丹花&#xff0c;且从国外引入栽培&#xff0c;故得 “洋牡丹” 这一亲切的称呼。 洋牡丹的常见品种繁多&#xff0c;有单瓣和重瓣之分。单瓣的洋牡丹清新雅致&#xff0c;花瓣舒…

docker 最新可用镜像源地址

无论是docker桌布版本&#xff0c;还是linux版本通用 直接更换镜像源地址即可&#xff1a;亲测目前可用 { "registry-mirrors": ["https://0c105db5188026850f80c001def654a0.mirror.swr.myhuaweicloud.com","https://5tqw56kt.mirror.aliyuncs.com&…

大模型基于指令的知识编辑:InstructEdit技术

人工智能咨询培训老师叶梓 转载标明出处 在知识更新和编辑方面&#xff0c;大模型在特定任务上表现出色&#xff0c;但在面对不同任务时往往力不从心&#xff0c;需要为每个任务单独设计编辑器&#xff0c;这在一定程度上限制了其应用范围。为了解决这一问题&#xff0c;浙江大…

二十二、状态模式

文章目录 1 基本介绍2 案例2.1 Season 接口2.2 Spring 类2.3 Summer 类2.4 Autumn 类2.5 Winter 类2.6 Person 类2.7 Client 类2.8 Client 类的运行结果2.9 总结 3 各角色之间的关系3.1 角色3.1.1 State ( 状态 )3.1.2 ConcreteState ( 具体的状态 )3.1.3 Context ( 上下文 )3.…

【ARM+Codesys 客户案例 】 基于RK3568/A40i/STM32+CODESYS开发AGV运动控制器,支持国产定制

在过去&#xff0c;步科更多的是为AGV客户提供单一、高性能的低压伺服核心部件产品&#xff0c;而现在&#xff0c;步科基于 CODESYS 开发了一款面向AGV机器人的特种控制器 - 青龙1号&#xff0c;开始提供以步科AGV运动控制器FD1X4S系列低压伺服Green系列HMI等为核心的AGV总线控…

keepalived理论--实验

一 . 高可用集群 1.1 集群类型 LB &#xff1a; Load Balance 负载均衡 LVS/HAProxy/nginx &#xff08; http/upstream, stream/upstream &#xff09; HA &#xff1a; High Availability 高可用集群 数据库、 Redis SPoF: Single Point of Failure &#xff0c;解决…

2004-2023华为杯数学建模优秀参考论文

笔者整理了2004-2023年华为杯研究生数学建模全部优秀论文和赛题&#xff0c;内容齐全&#xff0c;适合将要参加建模比赛的朋友学习使用。 免费优秀论文获取联系&#xff1a; 建模忠哥小师妹 2004-2023历届华为杯研究生数学建模优秀论文合集&#xff1a;

【数学分析笔记】第2章第1节实数系的连续性(2)

2. 数列极限 2.1 实数系的连续性 2.1.3 确界存在定理 【定理2.1.1】&#xff08;确界存在定理——实数系连续性定理&#xff09;非空有上界的数集必有上确界&#xff0c;非空有下界的数集必有下确界。 【证】&#xff08;写了一些我自己的理解&#xff0c;欢迎数院大神批评指…

Linux基础知识学习(二)

一. 常用基本命令 1. 目录管理 1> 绝对路径、相对路径 绝对路径路径的全称&#xff1a;C:\ProgramData\360safe\xxx.xx 比如说 360safe 目录下&#xff0c;那这个 xxx.xx 文件&#xff0c;对应我们的相对配置就 /xxx.xx cd &#xff1a; 切换目录命令&#xff01; ./ &…

【html+css 绚丽Loading】-000001 双极乾坤盘

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享htmlcss 绚丽Loading&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495…