guoyu/Test/备份/_已清理文件备份_周六 22512/md/答案显示格式优化说明.md

9.0 KiB
Raw Blame History

答案显示格式优化说明

🎯 问题描述

当前显示

我的答案B. 阿萨德放到  ✅(有选项字母+内容)
正确答案A                ❌(只有选项字母)

期望显示

我的答案B. 阿萨德放到  ✅
正确答案A. 选项内容1    ✅(选项字母+内容)

解决方案

核心思路

在后端返回成绩详情时,将答案字母(如"A")转换为完整格式(如"A. 选项内容"

修改位置

文件: StudyScoreController.java


🔧 代码修改

修改1在返回成绩详情时格式化答案

位置: getScoreDetail 方法

if (question != null)
{
    detail.setQuestionContent(question.getQuestionContent());
    
    // 转换正确答案格式将字母A转换为完整格式A. 选项内容)
    String formattedCorrectAnswer = formatAnswerWithContent(
        question.getCorrectAnswer(), 
        question.getOptions(), 
        question.getQuestionType()
    );
    detail.setCorrectAnswer(formattedCorrectAnswer);
    
    // 转换学生答案格式(如果还没有完整格式)
    String studentAnswer = detail.getStudentAnswer();
    if (studentAnswer != null && !studentAnswer.contains(".")) {
        // 如果学生答案是纯字母(如"A"),转换为完整格式
        String formattedStudentAnswer = formatAnswerWithContent(
            studentAnswer,
            question.getOptions(),
            question.getQuestionType()
        );
        detail.setStudentAnswer(formattedStudentAnswer);
    }
    
    detail.setQuestionType(question.getQuestionType());
    detail.setQuestionScore(question.getScore());
    detail.setOptions(question.getOptions());
}

修改2添加格式化方法

/**
 * 将答案转换为完整格式(字母 + 选项内容)
 * @param answer 答案字母,如"A"或"A,B,C"
 * @param optionsJson 选项JSON如["选项1", "选项2"]
 * @param questionType 题目类型
 * @return 格式化后的答案,如"A. 选项1"或"A. 选项1, B. 选项2"
 */
private String formatAnswerWithContent(String answer, String optionsJson, String questionType)
{
    if (StringUtils.isBlank(answer))
    {
        return "";
    }
    
    // 判断题直接返回
    if ("judge".equals(questionType))
    {
        return answer;
    }
    
    // 填空题和简答题直接返回
    if ("fill".equals(questionType) || "essay".equals(questionType))
    {
        return answer;
    }
    
    // 解析选项列表
    java.util.List<String> optionsList = parseOptionsList(optionsJson);
    if (optionsList == null || optionsList.isEmpty())
    {
        return answer;
    }
    
    // 单选题或多选题
    String trimmedAnswer = answer.trim();
    
    // 如果答案已经包含".",说明已经是完整格式,直接返回
    if (trimmedAnswer.contains("."))
    {
        return trimmedAnswer;
    }
    
    // 处理多选题(答案可能是"A,B,C"
    if (trimmedAnswer.contains(","))
    {
        String[] answerParts = trimmedAnswer.split(",");
        java.util.List<String> formattedParts = new java.util.ArrayList<>();
        
        for (String part : answerParts)
        {
            String letter = part.trim();
            if (letter.length() == 1 && letter.matches("[A-Fa-f]"))
            {
                int index = letter.toUpperCase().charAt(0) - 'A';
                if (index >= 0 && index < optionsList.size())
                {
                    formattedParts.add(letter.toUpperCase() + ". " + optionsList.get(index));
                }
                else
                {
                    formattedParts.add(letter);
                }
            }
            else
            {
                formattedParts.add(part);
            }
        }
        
        return String.join(", ", formattedParts);
    }
    
    // 处理单选题(答案是单个字母,如"A"
    if (trimmedAnswer.length() == 1 && trimmedAnswer.matches("[A-Fa-f]"))
    {
        int index = trimmedAnswer.toUpperCase().charAt(0) - 'A';
        if (index >= 0 && index < optionsList.size())
        {
            return trimmedAnswer.toUpperCase() + ". " + optionsList.get(index);
        }
    }
    
    return answer;
}

📋 支持的题型

1. 单选题

输入: "A"
输出: "A. 选项内容1"

2. 多选题

输入: "A,B,C"
输出: "A. 选项1, B. 选项2, C. 选项3"

3. 判断题

输入: "正确"
输出: "正确"(不转换)

4. 填空题/简答题

输入: "答案内容"
输出: "答案内容"(不转换)


🔄 转换逻辑

转换规则

  1. 检查是否需要转换

    • 判断题、填空题、简答题:不转换,直接返回
    • 单选题、多选题:进行转换
  2. 检查是否已经是完整格式

    • 如果答案包含".":已是完整格式,直接返回
    • 如果答案不包含".":需要转换
  3. 解析选项列表

    • 从JSON字符串解析为List
    • 如果解析失败:返回原答案
  4. 转换单选题答案

    • 提取字母(如"A"
    • 计算索引:'A' - 'A' = 0
    • 获取选项:optionsList.get(0)
    • 拼接:"A. " + 选项内容
  5. 转换多选题答案

    • 分割答案:"A,B,C"["A", "B", "C"]
    • 逐个转换每个字母
    • 用逗号+空格连接:"A. 内容1, B. 内容2, C. 内容3"

🧪 测试案例

测试1单选题

题目:阿萨德发多少分
选项:["阿斯蒂芬都是阿凡达", "撒旦法的发"]
正确答案A
学生答案B

转换后:
正确答案A. 阿斯蒂芬都是阿凡达
学生答案B. 撒旦法的发

测试2多选题

题目:"汉"这个字的读音是?
选项:["han", "han2", "han3"]
正确答案A,B
学生答案A,C

转换后:
正确答案A. han, B. han2
学生答案A. han, C. han3

测试3判断题

正确答案:正确
学生答案:错误

转换后:
正确答案:正确
学生答案:错误

测试4填空题

正确答案zi
学生答案zi

转换后:
正确答案zi
学生答案zi

⚠️ 注意事项

1. 学生答案格式兼容

  • 如果学生答案已经是完整格式(如"B. 内容"),不再转换
  • 如果学生答案是纯字母(如"B"),进行转换
  • 通过检查是否包含"."来判断

2. 选项索引范围检查

if (index >= 0 && index < optionsList.size())
{
    // 索引有效,进行转换
}
else
{
    // 索引无效,返回原字母
}

3. 大小写处理

  • 答案字母统一转换为大写
  • 正则匹配:[A-Fa-f](支持大小写)

4. 空值处理

if (StringUtils.isBlank(answer))
{
    return "";
}

🎨 前端显示效果

修改前

第 1 题                               0/5分

阿萨德发多少分

我的答案:    B. 撒旦法的发
正确答案:    A                      ❌ 只显示字母

修改后

第 1 题                               0/5分

阿萨德发多少分

我的答案:    B. 撒旦法的发
正确答案:    A. 阿斯蒂芬都是阿凡达    ✅ 显示完整

🚀 部署步骤

1. 重新编译后端

cd C:\Users\Administrator\Desktop\Project\ry_study-v_03\Study-Vue-redis
mvn clean package -DskipTests

2. 重启后端服务

停止当前服务启动新编译的jar包

3. 测试验证

  1. 在App中完成一份试卷
  2. 提交试卷
  3. 查看成绩详情
  4. 检查答案显示格式:
    • 正确答案显示完整格式
    • 学生答案显示完整格式
    • 多选题用逗号分隔

📝 验收标准

  • 单选题正确答案显示:"A. 选项内容"
  • 单选题学生答案显示:"B. 选项内容"
  • 多选题正确答案显示:"A. 内容1, B. 内容2"
  • 多选题学生答案显示:"A. 内容1, C. 内容3"
  • 判断题正确显示:"正确"或"错误"
  • 填空题正确显示答案内容
  • 简答题正确显示答案内容
  • 没有出现格式错误或显示异常

🐛 可能的问题

问题1选项内容显示为空

原因: 选项JSON解析失败或索引超出范围
解决: 检查数据库中的options字段格式是否正确

问题2答案显示乱码

原因: 字符编码问题
解决: 确保数据库和Java代码使用UTF-8编码

问题3多选题逗号显示异常

原因: 分隔符问题
解决: 检查String.join(", ", formattedParts)的分隔符


总结

核心改进

  1. 答案显示更直观(字母+内容)
  2. 学生更容易理解错误原因
  3. 支持所有题型
  4. 兼容已有数据格式

技术要点

  • 后端动态格式化答案
  • 根据题型选择不同处理逻辑
  • 兼容已存在的完整格式答案
  • 统一学生答案和正确答案的显示格式