word导入试题,未完

beetlsql3-dev
Mlxa0324 2 years ago
parent 129a95caf1
commit c30b7fdc34

@ -314,9 +314,7 @@ public class ResourcesQuestion extends BaseEntity{
List<String> result = new ArrayList<>();
Field[] fields = ReflectUtil.getFields(this.getClass(), f -> f.getName().startsWith("questionOption"));
for (Field field : fields) {
for (Field field : optionFields) {
Object fieldValue = ReflectUtil.getFieldValue(this, field);
if (fieldValue != null) {
result.add(fieldValue.toString());
@ -325,14 +323,17 @@ public class ResourcesQuestion extends BaseEntity{
return result;
}
/**
*
*/
private final static Field[] optionFields = ReflectUtil.getFields(ResourcesQuestion.class, f -> f.getName().startsWith("questionOption"));
/**
* Null
* @return
*/
private Field findNullQuestionOptionField() {
Field[] fields = ReflectUtil.getFields(this.getClass(), f -> f.getName().startsWith("questionOption"));
for (Field field : fields) {
for (Field field : optionFields) {
Object fieldValue = ReflectUtil.getFieldValue(this, field);
if (fieldValue == null) {
return field;
@ -346,16 +347,16 @@ public class ResourcesQuestion extends BaseEntity{
*/
@UpdateIgnore
@InsertIgnore
private List<String> questionOptionList;
private List<String> resourcesQuestionOptionList;
public List<String> getQuestionOptionList() {
public List<String> getResourcesQuestionOptionList() {
List<String> result = takeQuestionOptionConcatList();
result.addAll(defaultIfNull(questionOptionList, Collections.emptyList()));
result.addAll(defaultIfNull(resourcesQuestionOptionList, Collections.emptyList()));
return result;
}
public void setQuestionOptionList(List<String> questionOptionList) {
this.questionOptionList = questionOptionList;
public void setResourcesQuestionOptionList(List<String> questionOptionList) {
this.resourcesQuestionOptionList = questionOptionList;
}
/**

@ -0,0 +1,39 @@
package com.ibeetl.jlw.entity.vo;
import com.ibeetl.jlw.entity.ResourcesQuestion;
import lombok.Data;
import java.util.List;
/**
* : <br>
* word
* ResourcesQuestion
*
* @author: mlx
* @description:
* @date: 2023/1/9 22:07
* @version: 1.0
*/
@Data
public class ImportQuestionByWordTemplateResultVO {
/**
*
*/
private String title;
/**
*
*/
private List<String> otherMsg;
/**
*
*/
private Integer questionCount;
/**
*
*/
private List<ResourcesQuestion> questionList;
}

@ -15,6 +15,7 @@ import com.ibeetl.jlw.dao.CourseInfoDao;
import com.ibeetl.jlw.dao.ResourcesQuestionDao;
import com.ibeetl.jlw.entity.*;
import com.ibeetl.jlw.entity.dto.QuestionSettingDTO;
import com.ibeetl.jlw.entity.vo.ImportQuestionByWordTemplateResultVO;
import com.ibeetl.jlw.entity.vo.QuestionTypeCountVO;
import com.ibeetl.jlw.enums.AddTypeEnum;
import com.ibeetl.jlw.enums.ResourcesQuestionTypeEnum;
@ -22,6 +23,7 @@ import com.ibeetl.jlw.service.strategy.StrategyContext;
import com.ibeetl.jlw.validator.QuestionValidator;
import com.ibeetl.jlw.web.query.CourseInfoQuery;
import com.ibeetl.jlw.web.query.ResourcesQuestionQuery;
import lombok.Cleanup;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
@ -53,6 +55,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -798,20 +801,18 @@ public class ResourcesQuestionService extends CoreBaseService<ResourcesQuestion>
* @Author: lx
* @Date: 2023/1/8 22:49
*/
public JsonResult importQuestionByWordTemplate(@NotEmpty List<FileEntity> fileEntityList, CoreUser coreUser) {
public ImportQuestionByWordTemplateResultVO importQuestionByWordTemplate(@NotEmpty List<FileEntity> fileEntityList, CoreUser coreUser) {
/** 找出段落, 逐段落处理 */
AtomicReference<FileInputStream> inputStream = new AtomicReference<>();
AtomicReference<XWPFDocument> xDocument = new AtomicReference<>();
//装结果 key卷子访问地址 value{标题题目List}
Map<String,Object[]> resultMap = new HashMap<>();
ImportQuestionByWordTemplateResultVO resultVO = new ImportQuestionByWordTemplateResultVO();
/** 仅用于存放标题 */
final String[] title = { Strings.EMPTY };
/** 标题暂存,可能是多个 */
final StringBuilder titleStb = new StringBuilder();
/** 循环文件集合 */
fileEntityList.forEach(fileEntity -> {
for (FileEntity fileEntity: fileEntityList) {
/** 上传文件的临时路径 */
String importPath = fileEntity.getAbsoluteUrl();
/** 新建文件夹绝对路径 */
@ -820,8 +821,8 @@ public class ResourcesQuestionService extends CoreBaseService<ResourcesQuestion>
String absolutePath = absoluteDirPath + fileEntity.getTempName();
//各种流
try {
inputStream.set(new FileInputStream(importPath));
xDocument.set(new XWPFDocument(inputStream.get()));
@Cleanup FileInputStream fileInputStream = new FileInputStream(importPath);
xDocument.set(new XWPFDocument(fileInputStream));
/** 集合拷贝 */
List<MyXWPFParagraph> myParagraphs = BeanCopyUtil.copyListProperties(xDocument.get().getParagraphs() , MyXWPFParagraph::new, (t, d) -> {
d.setXwpfParagraph(t);
@ -844,35 +845,39 @@ public class ResourcesQuestionService extends CoreBaseService<ResourcesQuestion>
/** 题干计数 */
AtomicInteger recordsCount = new AtomicInteger();
/** 遍历所有段落 */
myParagraphs.forEach(e -> {
for (MyXWPFParagraph myParagraph : myParagraphs) {
/** 策略中的参数设置 */
strategyContext.setText(e.getText(absoluteDirPath, fileEntity.getTempName())).start(c -> {
Consumer<Map<StrategyContext.QuestionParagraphTypeEnum, String>> mapConsumer = item -> {
/** 第一行 */
if (recordsCount.get() == 1 && StringUtils.isBlank(title[0])) {
if (recordsCount.get() == 1 && StringUtils.isBlank(title[0])) {
/** 暴力取值 */
titleStb.append(title[0] = myParagraphs.get(0).getText(absoluteDirPath, fileEntity.getTempName()));
}
/** k 策略枚举v 处理后的段落文字 */
c.forEach((k, v) -> {
item.forEach((k, v) -> {
/** 记录段落类型, 未查询类型之外的类型 */
if (!k.equals(OTHER)) {paragraphTypeEnum.set(k);}
switch(k) {
if (!k.equals(OTHER)) {
paragraphTypeEnum.set(k);
}
switch (k) {
/** 未匹配到的段落 */
case OTHER: {
/** 如果非标题字符,可能是前一个段落的副行。需要追加到相应的段落中 */
insertCorrespondingParagraph(typeConcatEnum, paragraphTypeEnum.get() ,v, question, questionStem, questionAnswer);
} break;
insertCorrespondingParagraph(typeConcatEnum, paragraphTypeEnum.get(), v, question, questionStem, questionAnswer);
}
break;
/** 题目类型,分值,该类型的总分 */
case TYPE: {
/** 题目类型作用域 */
String[] sp = v.split(",");
typeConcatEnum.set(StrategyContext.QuestionTypeConcatEnum.matchText(sp[2]));
questionScore.set(NumberUtil.toBigDecimal(sp[0]).setScale(1, RoundingMode.HALF_UP));
} break;
questionScore.set(NumberUtil.toBigDecimal(sp[0]).setScale(1, RoundingMode.HALF_UP));
}
break;
/** 题干 */
case STEM: {
final String numStartRegex = "^\\d+[\\.\\、\\]";
if(ReUtil.contains(numStartRegex, v)) {
if (ReUtil.contains(numStartRegex, v)) {
/** 题干的编号需要移除掉 */
questionStem.set(v.replaceFirst(numStartRegex, Strings.EMPTY).trim());
/** 题数++ */
@ -890,37 +895,36 @@ public class ResourcesQuestionService extends CoreBaseService<ResourcesQuestion>
resourcesQuestion.setUserId(coreUser.getId());
resourcesQuestion.setOrgId(coreUser.getOrgId());
if (StringUtils.isNotBlank(questionStem.get())){
resourcesQuestion.setQuestionStem(questionStem.get().replace("<","&lt;").replace(">","&gt;"));
}else {
if (StringUtils.isNotBlank(questionStem.get())) {
resourcesQuestion.setQuestionStem(questionStem.get().replace("<", "&lt;").replace(">", "&gt;"));
} else {
resourcesQuestion.setQuestionStem(questionStem.get());
}
question.set(resourcesQuestion);
questionList.add(question.get());
}
} break;
}
break;
/** 选项 */
case OPTION: {
putQuestionOption(v, question.get());
} break;
}
break;
/** 答案 questionAnswer不包含答案 字样 */
case ANSWER: {
questionAnswer.set(questionAnswer.get().concat(v));
// questionAnswer.get() 默认不包含 【答案】 字样
questionAnswer.set(secondFormat(questionAnswer.get(), typeConcatEnum.get()));
question.get().setQuestionAnswer(questionAnswer.get());
} break;
}
break;
}
});
});
});
};
titleStb.append("</br><font size=\"0.5\" color=\"blue\">解析结果:");
titleStb.append(recordsCount.get());
titleStb.append(" 道题目</font>");
String finalTitle = titleStb.toString();
strategyContext.setText(myParagraph.getText(absoluteDirPath, fileEntity.getTempName())).start(mapConsumer);
}
/** 最后检测属性, 并行处理,没有向外部非线程安全的变量写入东西,无需担心丢数据 */
questionList.parallelStream().forEach(item -> {
@ -932,15 +936,18 @@ public class ResourcesQuestionService extends CoreBaseService<ResourcesQuestion>
checkLocalQuestionsUnique(questionList);
/** 拼成前端需要的数据 */
resultMap.put(fileEntity.getUrl(), new Object[]{ finalTitle, questionList });
resultVO.setTitle(titleStb.toString());
resultVO.setOtherMsg(Collections.emptyList());
resultVO.setQuestionCount(recordsCount.get());
resultVO.setQuestionList(questionList);
} catch (Exception ex) { ex.printStackTrace(); }
finally {
try {inputStream.get().close(); xDocument.get().close(); }
try {xDocument.get().close(); }
catch (Exception ioe) { ioe.printStackTrace(); }
}
});
return JsonResult.success(resultMap);
}
return resultVO;
}
/** 取选项的正则 */
@ -960,10 +967,10 @@ public class ResourcesQuestionService extends CoreBaseService<ResourcesQuestion>
if(matcher.find()){
String questionOption = text.substring(2);
// 在现有的列表中添加
if(null != question.getQuestionOptionList()){
List<String> questionOptionList = question.getQuestionOptionList();
questionOptionList.add(questionOption);
question.putQuestionOptionList(questionOptionList);
List<String> optionList = question.getResourcesQuestionOptionList();
if(null != optionList){
optionList.add(questionOption);
question.putQuestionOptionList(optionList);
}
// 新建
else {

@ -10,6 +10,7 @@ import org.apache.logging.log4j.util.Strings;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static com.ibeetl.jlw.service.strategy.StrategyContext.QuestionTypeConcatEnum.*;
@ -95,7 +96,10 @@ public class QuestionValidator {
* @return
*/
private String optionIncludeAnswer(ResourcesQuestion question, List<String> questionOptionConcatList, String questionAnswer) {
if(ObjectUtil.isEmpty(questionOptionConcatList)) {
Integer questionType = question.getQuestionType();
// 单选和多选的选项不能为空
if(Arrays.asList(SINGLE.getTypeConcat(), MULTIPLE.getTypeConcat()).contains(questionType) && ObjectUtil.isEmpty(questionOptionConcatList)) {
return "选项为空";
}
if(StringUtils.isBlank(questionAnswer)){
@ -103,13 +107,13 @@ public class QuestionValidator {
}
// 是判断题
if (DECIDE.getTypeConcat().equals(question.getQuestionType())) {
if (DECIDE.getTypeConcat().equals(questionType)) {
// 答案只能是对或错,前后不能有空格
return !questionAnswer.matches("^[对错]$") ? "判断题答案有误": "";
}
// 是单选题
if (SINGLE.getTypeConcat().equals(question.getQuestionType())) {
if (SINGLE.getTypeConcat().equals(questionType)) {
// 单选题只能有一个答案
return questionAnswer.length() != 1 ? "单选题只能有一个答案": "";
}

@ -13,6 +13,7 @@ import com.ibeetl.admin.core.web.JsonResult;
import com.ibeetl.jlw.entity.CourseInfo;
import com.ibeetl.jlw.entity.FileEntity;
import com.ibeetl.jlw.entity.ResourcesQuestion;
import com.ibeetl.jlw.entity.vo.ImportQuestionByWordTemplateResultVO;
import com.ibeetl.jlw.entity.vo.QuestionTypeCountVO;
import com.ibeetl.jlw.enums.AddTypeEnum;
import com.ibeetl.jlw.service.CourseInfoService;
@ -636,7 +637,7 @@ public class ResourcesQuestionController{
* : <br>
* word
*
* @param fileEntityList
* @param fileEntityList namefile
* @param coreUser 使IDID
* @return {@link JsonResult}
* @Author: lx
@ -644,8 +645,7 @@ public class ResourcesQuestionController{
*/
@PostMapping(MODEL + "/importQuestionByWordTemplate.json")
@ResponseBody
public JsonResult importQuestionByWordTemplate(@RFile List<FileEntity> fileEntityList, @SCoreUser CoreUser coreUser) {
JsonResult jsonResult = resourcesQuestionService.importQuestionByWordTemplate(fileEntityList, coreUser);
return jsonResult;
public JsonResult<ImportQuestionByWordTemplateResultVO> importQuestionByWordTemplate(@RFile List<FileEntity> fileEntityList, @SCoreUser CoreUser coreUser) {
return JsonResult.success(resourcesQuestionService.importQuestionByWordTemplate(fileEntityList, coreUser));
}
}

Loading…
Cancel
Save