You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tianze-pro/web/src/main/java/com/ibeetl/jlw/entity/ResourcesQuestionOptionEnti...

144 lines
5.3 KiB
Java

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.ibeetl.jlw.entity;
import cn.hutool.core.collection.ConcurrentHashSet;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import java.lang.reflect.Field;
import java.util.*;
import static org.apache.commons.lang3.StringUtils.join;
import static org.apache.commons.lang3.StringUtils.upperCase;
/**
* 选择题选项实体, 部分参数封装
* 题目选项随机工具
*
* @author mlx
*/
public class ResourcesQuestionOptionEntity {
private Map<String, Boolean> optionTextMap = new HashMap(6);
public void put(String optionText, Boolean value) {
optionTextMap.put(optionText, value);
}
public Boolean get(String optionText) {
return optionTextMap.getOrDefault(optionText, false);
}
public boolean remove(String optionText) {
return optionTextMap.remove(optionText);
}
public boolean contains(String optionText) {
return optionTextMap.containsKey(optionText);
}
/**
* 获取是正确答案的列表,无序
*
* @return
*/
public List<String> getOptionTextList() {
List arrayList = new ArrayList(optionTextMap.keySet());
Collections.shuffle(arrayList);
return Collections.unmodifiableList(arrayList);
}
/**
* 获取乱序后的ABCDE答案
*
* @param answerMap <题目ABCD..>
* @return
*/
public Set<String> getAnswerList(Map<String, String> answerMap) {
// 最后的答案
Set<String> answerList = new ConcurrentHashSet<>();
answerMap.forEach((optionText, newAnswer) -> {
optionTextMap.forEach((optionText2, isAnswer) -> {
if (optionText2.equals(optionText) && isAnswer) {
answerList.add(newAnswer);
}
});
});
return answerList;
}
/**
* 随机打乱选项的顺序, 支持所有题型的处理
*
* @param answerFieldName 答案的字段名,只能是逗号分割
* @param prefix 选项的属性前缀 questionOption
* @param lastIsUppercase 最后一个字段是否大写
*/
public static void shuffleOrderOptions(Object obj, final String answerFieldName, final String prefix, Boolean lastIsUppercase) {
String questionAnswer = (String)ReflectUtil.getFieldValue(obj, answerFieldName);
Assert.notBlank(questionAnswer, "答案不能为空!");
Assert.notBlank(prefix, "选项的属性前缀不能为空!");
// Map的简单封装
ResourcesQuestionOptionEntity optionEntity = new ResourcesQuestionOptionEntity();
// 答案字段处理
String[] options = ArrayUtil.removeBlank(questionAnswer.split(","));
// 记录属性名中的最后一位字符记录ABCDEF....
List<String> lastLetterFieldNameList = new ArrayList<>(6);
// 遍历当前对象的所有属性,不包含父类
for (Field field : ReflectUtil.getFieldsDirectly(obj.getClass(), false)) {
// 选项questionOption 开头的属性
if (field.getName().startsWith(prefix)) {
// 反射,来获取当前属性最后一个字母:选项
String lastLetter = field.getName().substring(field.getName().length() - 1);
// 转大写控制
lastLetter = lastIsUppercase.equals(true)? upperCase(lastLetter): lastLetter;
// 选项里的内容
String optionText = (String)ReflectUtil.getFieldValue(obj, field);
if (null == optionText) { continue; }
// 记录ABCDEF....
lastLetterFieldNameList.add(lastLetter);
optionEntity.put(optionText, false);
// 正确答案中,是否包含当前选项
if (ArrayUtil.containsIgnoreCase(options, lastLetter)) {
// 标记为正确答案
optionEntity.put(optionText, true);
}
}
}
// 乱序后
List<String> optionTextList = optionEntity.getOptionTextList();
// 答案和选项ABCDEF..对应
Map<String, String> answerMap = new HashMap<>(6);
// 判断题目是否有重复的值
Assert.isTrue(optionTextList.size() == lastLetterFieldNameList.size(),
"答案中有重复的值,请检查!");
// 乱序集合处理
for (int i = 0; i < lastLetterFieldNameList.size(); i++) {
// 选项的子母
String optionLetter = lastLetterFieldNameList.get(i);
// 选项中的文本
String optionText = optionTextList.get(i);
answerMap.put(optionText, optionLetter);
// 等价于这样赋值this.questionOptionA = "";
ReflectUtil.setFieldValue(obj, prefix.concat(optionLetter), optionText);
}
// 如果没有选项,可能是单选或者其他类型的题目
Set<String> answerList = optionEntity.getAnswerList(answerMap);
Set<String> defaultAnswer = Collections.singleton(questionAnswer);
Set<String> answer = ObjectUtil.isNotEmpty(answerList)? answerList: defaultAnswer;
// 乱序后的正确答案赋值
ReflectUtil.setFieldValue(obj, answerFieldName, join(answer, ","));
}
}