单题选项排序;

beetlsql3-dev
Mlxa0324 3 years ago
parent 09929b9223
commit e86a99d945

@ -5,12 +5,14 @@ import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.json.JSONUtil;
import org.springframework.util.MultiValueMap;
import org.springframework.util.MultiValueMapAdapter;
import java.lang.reflect.Field;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ -34,8 +36,13 @@ public class BeanUtil extends cn.hutool.core.bean.BeanUtil {
public static Map<String, String> beanToMapStr(Object obj) {
Map<String, String> result = new ConcurrentHashMap<>(16);
beanToMap(obj).forEach((s, o) -> {
if (o instanceof Date) {
if (o == null) {
result.put(s, "");
} else if (o instanceof Date) {
result.put(s, DateUtil.date((Date) o).toString());
} else if(o instanceof List) {
List list = (List)o;
result.put(s, ObjectUtil.isEmpty(list)? "": JSONUtil.toJsonStr(o));
} else {
result.put(s, String.valueOf(o));
}

@ -136,7 +136,7 @@ public class RandomUtils {
public static <T, R> String getRandomString(List<T> list, int randomLength, Function<T, R> function, CharSequence delimiter) {
Objects.requireNonNull(list);
// 取随机数长度的集合
List<T> questionList = RandomUtil.randomEleList(list, RandomUtil.randomInt(min(list.size(), randomLength)));
List<T> questionList = RandomUtil.randomEleList(list, RandomUtil.randomInt(min(list.size() == 0 ? 1: list.size(), randomLength)));
return questionList.stream()
.map(e -> String.valueOf(function.apply(e)))

@ -1,17 +1,11 @@
package com.ibeetl.jlw.entity;
import cn.hutool.core.lang.Assert;
import cn.jlw.util.EnumUtil;
import cn.jlw.validate.ValidateConfig;
import com.ibeetl.admin.core.entity.BaseEntity;
import lombok.Getter;
import org.beetl.sql.annotation.entity.AutoID;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/*
* -
@ -85,62 +79,7 @@ public class ResourcesQuestion extends BaseEntity{
public ResourcesQuestion(){
}
public enum AnswerEnum {
// TODO mlx 题目乱序
A("getQuestionOptionA"),
B("getQuestionOptionB"),
C("getQuestionOptionC"),
D("getQuestionOptionD"),
E("getQuestionOptionE");
@Getter
private String methodName;
AnswerEnum(String methodName) {
this.methodName = methodName;
}
/**
*
* @param name
* @return
*/
public static String getMethodNameByEnumName(String name) {
List<Object> methodNameObjList = EnumUtil.getFieldValues(AnswerEnum.class, "methodName");
for (AnswerEnum value : values()) {
if (value.name().equalsIgnoreCase(name)) {
return value.getMethodName();
}
}
throw new RuntimeException("未获取到选项对应的方法名!");
}
/**
*
* @param names ABCD
* @return
*/
public static Map<String, String> getMethodNameByEnumName(String... names) {
Map<String, String> nameAndMethod = new HashMap<>(6);
for (AnswerEnum value : values()) {
for (String name : names) {
if (value.name().equalsIgnoreCase(name)) {
nameAndMethod.put(name, value.getMethodName());
}
}
}
return Assert.notEmpty(nameAndMethod, "未获取到选项对应的方法名!");
}
}
/**
*
*/
public void ShuffleOrderOptions() {
}
/**ID

@ -0,0 +1,139 @@
package com.ibeetl.jlw.entity;
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 java.util.concurrent.CopyOnWriteArrayList;
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 List<String> getAnswerList(Map<String, String> answerMap) {
// 最后的答案
List<String> answerList = new CopyOnWriteArrayList<>();
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);
// 乱序集合处理
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);
}
// 如果没有选项,可能是单选或者其他类型的题目
List<String> answerList = optionEntity.getAnswerList(answerMap);
List<String> defaultAnswer = Collections.singletonList(questionAnswer);
List<String> answer = ObjectUtil.isNotEmpty(answerList)? answerList: defaultAnswer;
// 乱序后的正确答案赋值
ReflectUtil.setFieldValue(obj, answerFieldName, join(answer, ","));
}
}

@ -13,7 +13,7 @@ import java.math.BigDecimal;
* - --
* gen by Spring Boot2 Admin 2022-09-23
*/
public class ResourcesQuestionSnapshot extends BaseEntity{
public class ResourcesQuestionSnapshot extends BaseEntity {
//题目快照ID

@ -1,7 +1,7 @@
package com.ibeetl.jlw.service;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.jlw.util.ToolUtils;
import com.ibeetl.admin.core.service.CoreBaseService;
import com.ibeetl.admin.core.service.CorePlatformService;
@ -38,7 +38,7 @@ import java.text.SimpleDateFormat;
import java.util.*;
import static cn.hutool.core.util.ArrayUtil.join;
import static com.ibeetl.jlw.entity.ResourcesQuestion.AnswerEnum.getMethodNameByEnumName;
import static com.ibeetl.jlw.entity.ResourcesQuestionOptionEntity.shuffleOrderOptions;
import static java.util.stream.Collectors.groupingBy;
@ -58,7 +58,7 @@ public class ResourcesQuestionService extends CoreBaseService<ResourcesQuestion>
@Resource private CorePlatformService platformService;
public PageQuery<ResourcesQuestion>queryByCondition(PageQuery query){
public PageQuery<ResourcesQuestion> queryByCondition(PageQuery query){
PageQuery ret = resourcesQuestionDao.queryByCondition(query);
queryListAfter(ret.getList());
return ret;
@ -638,12 +638,12 @@ public class ResourcesQuestionService extends CoreBaseService<ResourcesQuestion>
*
* @param questionList
*/
public void ShuffleOrderOptions(List<ResourcesQuestion> questionList) {
public void orderOptions(List<ResourcesQuestion> questionList) {
if (ObjectUtil.isEmpty(questionList)) {
return;
}
questionList.forEach(resourcesQuestion -> {
// 答案集合
String[] answers = ArrayUtil.removeBlank(resourcesQuestion.getQuestionAnswer().split(","));
Map<String, String> nameAndMethod = getMethodNameByEnumName(answers);
shuffleOrderOptions(resourcesQuestion, "questionAnswer","questionOption", true);
});
}
}

@ -1,5 +1,7 @@
package com.ibeetl.jlw.service;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.validation.BeanValidationResult;
import cn.hutool.extra.validation.ValidationUtil;
import cn.jlw.util.ToolUtils;
@ -9,10 +11,13 @@ import com.ibeetl.admin.core.service.CoreBaseService;
import com.ibeetl.admin.core.util.PlatformException;
import com.ibeetl.admin.core.web.JsonResult;
import com.ibeetl.admin.core.web.JsonReturnCode;
import com.ibeetl.jlw.dao.ResourcesQuestionSnapshotDao;
import com.ibeetl.jlw.dao.TeacherOpenCourseHomeworkDao;
import com.ibeetl.jlw.entity.ResourcesQuestionSnapshot;
import com.ibeetl.jlw.entity.TeacherOpenCourseHomework;
import com.ibeetl.jlw.entity.TeacherOpenCourseHomeworkSetting;
import com.ibeetl.jlw.enums.FromTypeEnum;
import com.ibeetl.jlw.web.query.ResourcesQuestionSnapshotQuery;
import com.ibeetl.jlw.web.query.TeacherOpenCourseHomeworkQuery;
import com.ibeetl.jlw.web.query.TeacherOpenCourseHomeworkSettingQuery;
import org.apache.commons.lang3.StringUtils;
@ -24,10 +29,14 @@ import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import static cn.hutool.json.JSONUtil.toJsonStr;
import static com.ibeetl.jlw.entity.ResourcesQuestionOptionEntity.shuffleOrderOptions;
import static com.ibeetl.jlw.web.query.TeacherOpenCourseHomeworkQuery.TeacherOpenCourseHomeworkTypeEnum.getClazzByEnum;
import static java.util.stream.Collectors.groupingBy;
/**
* Service
@ -40,6 +49,7 @@ public class TeacherOpenCourseHomeworkService extends CoreBaseService<TeacherOpe
@Resource private TeacherOpenCourseHomeworkDao teacherOpenCourseHomeworkDao;
@Resource private TeacherOpenCourseHomeworkSettingService teacherOpenCourseHomeworkSettingService;
@Resource private ResourcesQuestionSnapshotDao resourcesQuestionSnapshotDao;
public PageQuery<TeacherOpenCourseHomework>queryByCondition(PageQuery query){
PageQuery ret = teacherOpenCourseHomeworkDao.queryByCondition(query);
@ -183,12 +193,12 @@ public class TeacherOpenCourseHomeworkService extends CoreBaseService<TeacherOpe
* @param teacherOpenCourseHomeworkId ID
* @return
*/
public Object getHomeworkDetail(final Long teacherOpenCourseHomeworkId) {
public List<ResourcesQuestionSnapshot> homeworkDetail(final Long teacherOpenCourseHomeworkId) {
// 常量 True的Integer表现
final Integer TRUE_CONST = 1;
TeacherOpenCourseHomework homework = getInfo(teacherOpenCourseHomeworkId);
List<ResourcesQuestionSnapshot> resourcesQuestionSnapshots = new ArrayList<>();
TeacherOpenCourseHomework homework = getInfo(teacherOpenCourseHomeworkId);
cn.hutool.core.lang.Assert.notNull(homework, "未查询到");
TeacherOpenCourseHomeworkSettingQuery settingQuery = new TeacherOpenCourseHomeworkSettingQuery();
@ -197,29 +207,61 @@ public class TeacherOpenCourseHomeworkService extends CoreBaseService<TeacherOpe
// 作答次数
if (TRUE_CONST.equals(hwSetting.getTeacherOpenCourseHomeworkSettingDoCount())) {
// TODO 逻辑不一定要在这里写
}
// 答卷后显示答案解析
if (TRUE_CONST.equals(hwSetting.getTeacherOpenCourseHomeworkSettingEndShowQa())) {
// TODO 逻辑不一定要在这里写
}
// 答卷后显示答案对错
if (TRUE_CONST.equals(hwSetting.getTeacherOpenCourseHomeworkSettingEndShowTrueFalse())) {
// TODO 逻辑不一定要在这里写
}
// 选项乱序(限单选、多选)
if (TRUE_CONST.equals(hwSetting.getTeacherOpenCourseHomeworkSettingOptionNoOrder())) {
ResourcesQuestionSnapshotQuery questionSnapshotQuery = new ResourcesQuestionSnapshotQuery();
questionSnapshotQuery.setFromId(teacherOpenCourseHomeworkId);
resourcesQuestionSnapshots = resourcesQuestionSnapshotDao.getValuesByQuery(questionSnapshotQuery);
// 单题选项排序处理
resourcesQuestionSnapshots.forEach(value ->
shuffleOrderOptions(value, "questionAnswer","questionOption", true));
}
// 题目乱序(同一大题内)
if (TRUE_CONST.equals(hwSetting.getTeacherOpenCourseHomeworkSettingQuestionNoOrder())) {
shuffleOrderQuestions(resourcesQuestionSnapshots);
}
return resourcesQuestionSnapshots;
}
/**
*
* @param resourcesQuestionSnapshots
*/
private void shuffleOrderQuestions(List<ResourcesQuestionSnapshot> resourcesQuestionSnapshots) {
// 安全判空
if (ObjectUtil.isEmpty(resourcesQuestionSnapshots)) {
return;
}
return null;
// 题目根据类型分组
Map<Integer, List<ResourcesQuestionSnapshot>> questionTypeMap = resourcesQuestionSnapshots.stream()
.collect(groupingBy(ResourcesQuestionSnapshot::getQuestionType));
// 同一道大题内,乱序
questionTypeMap.forEach((questionType, questionSnapshots) -> {
Collections.shuffle(questionSnapshots);
});
// 大题数字升序
MapUtil.sort(questionTypeMap);
}
}

@ -219,10 +219,10 @@ public class TeacherOpenCourseHomeworkController {
* @param teacherOpenCourseHomeworkId ID
* @return
*/
@PostMapping(MODEL + "/homework.json")
@PostMapping(MODEL + "/homeworkDetail.json")
@Function("teacherOpenCourseHomework.query")
public JsonResult getHomeworkDetail(Long teacherOpenCourseHomeworkId) {
return JsonResult.success(teacherOpenCourseHomeworkService.getHomeworkDetail(teacherOpenCourseHomeworkId));
public JsonResult homeworkDetail(Long teacherOpenCourseHomeworkId) {
return JsonResult.success(teacherOpenCourseHomeworkService.homeworkDetail(teacherOpenCourseHomeworkId));
}
}

@ -0,0 +1,37 @@
package com.ibeetl.jlw.web;
import base.BaseTest;
import com.ibeetl.admin.core.util.BeanUtil;
import com.ibeetl.jlw.web.query.ResourcesQuestionQuery;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.util.MultiValueMap;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
class ResourcesQuestionControllerTest extends BaseTest {
private static final String MODEL = "/jlw/resourcesQuestion";
private static final String API = "/api/resourcesQuestion";
@Test
void list() throws Exception {
MultiValueMap<String, String> multiValueMap = BeanUtil.beanToStrMultiMap(new ResourcesQuestionQuery());
//构造请求参数
RequestBuilder rb = MockMvcRequestBuilders.post(MODEL + "/list.json")
.contentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
.params(multiValueMap);
//发送请求,验证返回结果
String result = mvc.perform(rb)
.andExpect(status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.code").value("0"))
.andReturn().getResponse().getContentAsString();
System.out.println(result);
}
}

@ -8,12 +8,15 @@ import com.ibeetl.admin.core.util.BeanUtil;
import com.ibeetl.jlw.dao.ResourcesQuestionDao;
import com.ibeetl.jlw.dao.SchoolClassDao;
import com.ibeetl.jlw.dao.TeacherOpenCourseDao;
import com.ibeetl.jlw.dao.TeacherOpenCourseHomeworkDao;
import com.ibeetl.jlw.entity.ResourcesQuestion;
import com.ibeetl.jlw.entity.SchoolClass;
import com.ibeetl.jlw.entity.TeacherOpenCourse;
import com.ibeetl.jlw.entity.TeacherOpenCourseHomework;
import com.ibeetl.jlw.web.query.TeacherOpenCourseHomeworkQuery;
import com.ibeetl.jlw.web.query.TeacherOpenCourseHomeworkSettingQuery;
import org.junit.Assert;
import org.junit.FixMethodOrder;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.RequestBuilder;
@ -28,6 +31,7 @@ import static com.ibeetl.admin.test.util.test.RandomUtils.getRandomString;
import static com.ibeetl.admin.test.util.test.RandomUtils.randomPojo;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@FixMethodOrder()
class TeacherOpenCourseHomeworkControllerTest extends BaseTest {
private static final String MODEL = "/jlw/teacherOpenCourseHomework";
@ -39,6 +43,10 @@ class TeacherOpenCourseHomeworkControllerTest extends BaseTest {
private SchoolClassDao schoolClassDao;
@Resource
private TeacherOpenCourseDao teacherOpenCourseDao;
@Resource
private TeacherOpenCourseHomeworkDao teacherOpenCourseHomeworkDao;
@Test
void getPageList() {
@ -174,4 +182,30 @@ class TeacherOpenCourseHomeworkControllerTest extends BaseTest {
System.out.println(result);
}
@Test
void homeworkDetail() throws Exception {
// 获取一个状态正常的作业ID
TeacherOpenCourseHomework entity = new TeacherOpenCourseHomework();
entity.setTeacherOpenCourseHomeworkStatus(1);
List<TeacherOpenCourseHomework> homeworkList = teacherOpenCourseHomeworkDao.template(entity);
// 断言
Assert.assertTrue(ObjectUtil.isNotEmpty(homeworkList));
Long teacherOpenCourseHomeworkId = RandomUtil.randomEle(homeworkList).getTeacherOpenCourseHomeworkId();
//构造请求参数
RequestBuilder rb = MockMvcRequestBuilders.post(MODEL + "/homeworkDetail.json")
.contentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
.param("teacherOpenCourseHomeworkId", String.valueOf(teacherOpenCourseHomeworkId));
//发送请求,验证返回结果
String result = mvc.perform(rb)
.andExpect(status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.code").value("0"))
.andReturn().getResponse().getContentAsString();
System.out.println(result);
}
}
Loading…
Cancel
Save