|
@@ -5,11 +5,13 @@ import com.yaoxiang.diagnosis.dao.PaperRepo;
|
|
|
import com.yaoxiang.diagnosis.dao.QuestionRepo;
|
|
|
import com.yaoxiang.diagnosis.dao.RemarkTemplateRepo;
|
|
|
import com.yaoxiang.diagnosis.entity.*;
|
|
|
+import com.yaoxiang.diagnosis.model.AuthUser;
|
|
|
import com.yaoxiang.diagnosis.util.CommonUtil;
|
|
|
import com.yaoxiang.diagnosis.util.ObjectUtil;
|
|
|
import com.yaoxiang.diagnosis.config.Constants;
|
|
|
import com.yaoxiang.diagnosis.model.PaperVo;
|
|
|
import com.yaoxiang.diagnosis.model.Result;
|
|
|
+import com.yaoxiang.diagnosis.util.SecurityUtil;
|
|
|
import com.yaoxiang.diagnosis.word.WordService;
|
|
|
import com.yaoxiang.diagnosis.word.WordUtil;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
@@ -66,8 +68,13 @@ public class PaperService {
|
|
|
private static final Logger logger = LoggerFactory.getLogger(PaperService.class);
|
|
|
|
|
|
public List<Paper> listPapers(Long subjectId, Integer status) {
|
|
|
+ AuthUser user = SecurityUtil.getCurrentUser();
|
|
|
Sort sort = new Sort(Sort.Direction.DESC, "updatetime");
|
|
|
List<Paper> papers = paperRepo.findAll(sort);
|
|
|
+ if (Constants.USER_TYPE_STUDENT.equals(user.getUser().getUserType())
|
|
|
+ && !user.getUser().getAuthorities().contains("重复提交")) {
|
|
|
+ papers = papers.stream().filter(p -> p.getGrade().contains(user.getUser().getGrade())).collect(Collectors.toList());
|
|
|
+ }
|
|
|
if (subjectId != null) {
|
|
|
papers = papers.stream().filter(p -> p.getSubjectId() == subjectId.longValue())
|
|
|
.collect(Collectors.toList());
|
|
@@ -89,43 +96,57 @@ public class PaperService {
|
|
|
return papers;
|
|
|
}
|
|
|
|
|
|
- public Paper getOnePaper(Long id) {
|
|
|
- Paper paper = paperRepo.getOne(id);
|
|
|
+ public Paper getOneWithAuth(Long id) {
|
|
|
+ AuthUser user = SecurityUtil.getCurrentUser();
|
|
|
+ boolean student = Constants.USER_TYPE_STUDENT.equals(user.getUser().getUserType());
|
|
|
+ Paper paper = paperRepo.findById(id).orElse(null);
|
|
|
if (paper == null || paper.getStatus() == Constants.NOTREADY) {
|
|
|
return null;
|
|
|
}
|
|
|
List<Question> questions = questionRepo.findByPidOrderBySectionAscNumberAsc(id);
|
|
|
List<Section> sections = sectionService.findByPid(id);
|
|
|
paper.setSections(sections);
|
|
|
-// questions.sort((q1, q2) -> {
|
|
|
-// if (q1.getSection() < q2.getSection()) {
|
|
|
-// return -1;
|
|
|
-// } else if (q1.getSection() > q2.getSection()) {
|
|
|
-// return 1;
|
|
|
-// }
|
|
|
-// if (q1.getNumber() < q2.getNumber()) {
|
|
|
-// return -1;
|
|
|
-// } else if (q1.getNumber() > q2.getNumber()) {
|
|
|
-// return 1;
|
|
|
-// }
|
|
|
-// return 0;
|
|
|
-// });
|
|
|
- paper.setQuestions(questions);
|
|
|
+// paper.setQuestions(questions);
|
|
|
List<Long> qids = questions.stream().map(Question::getId).collect(Collectors.toList());
|
|
|
//一次查出该试卷所有的选项
|
|
|
List<QuestionOption> options = optionRepo.findByQidIn(qids);
|
|
|
//然后根据Id进行分组
|
|
|
+ List<Question> qs = new ArrayList<>();
|
|
|
Map<Long, List<QuestionOption>> group = options.stream().collect(Collectors.groupingBy(QuestionOption::getQid));
|
|
|
for (Question question : questions) {
|
|
|
-// List<QuestionOption> options = optionRepo.findByQid(question.getId());
|
|
|
-// for (QuestionOption option : options) {
|
|
|
- //todo 判断是否考生,如是 将答案设为null
|
|
|
-// option.setCorrect(null);
|
|
|
-// option.setUpdatetime(null);
|
|
|
-// option.setCreatetime(null);
|
|
|
-// }
|
|
|
- question.setOptions(group.get(question.getId()));
|
|
|
+ Question q = ObjectUtil.convert(question, Question.class);
|
|
|
+ List<QuestionOption> optionList = group.get(question.getId());
|
|
|
+ List<QuestionOption> os = new ArrayList<>();
|
|
|
+ //学生要去掉答案
|
|
|
+ if (student) {
|
|
|
+ q.setCorrectNum(0);
|
|
|
+ q.setAnswer(null);
|
|
|
+ //避免自动持久化
|
|
|
+ for (QuestionOption o : optionList) {
|
|
|
+ QuestionOption option = new QuestionOption();
|
|
|
+ option.setId(o.getId());
|
|
|
+ option.setContent(o.getContent());
|
|
|
+ option.setOindex(o.getOindex());
|
|
|
+ option.setQid(o.getQid());
|
|
|
+ os.add(option);
|
|
|
+ }
|
|
|
+ q.setOptions(os);
|
|
|
+ } else {
|
|
|
+ q.setOptions(optionList);
|
|
|
+ }
|
|
|
+ qs.add(q);
|
|
|
+ }
|
|
|
+ paper.setQuestions(qs);
|
|
|
+ return paper;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Paper getOnePaper(Long id) {
|
|
|
+ Paper paper = paperRepo.findById(id).orElse(null);
|
|
|
+ if (paper == null || paper.getStatus() == Constants.NOTREADY) {
|
|
|
+ return null;
|
|
|
}
|
|
|
+ List<Question> questions = questionRepo.findByPidOrderBySectionAscNumberAsc(id);
|
|
|
+ paper.setQuestions(questions);
|
|
|
return paper;
|
|
|
}
|
|
|
|
|
@@ -155,10 +176,6 @@ public class PaperService {
|
|
|
}
|
|
|
//init json score
|
|
|
Map<String, Double> data = new HashMap<>();
|
|
|
- List<SubjectAbility> abilities = subjectAbilityService.list(paper.getSubjectId());
|
|
|
- //初始化数据
|
|
|
- abilities.forEach(a -> data.put(a.getCode(), 0d));
|
|
|
- data.put("A0", 0d);
|
|
|
double totalScore = 0;
|
|
|
for (Question question : save.getQuestions()) {
|
|
|
question.setPid(save.getId());
|
|
@@ -176,18 +193,21 @@ public class PaperService {
|
|
|
abilityScoreService.add(score);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
for (Section section : save.getSections()) {
|
|
|
section.setPid(save.getId());
|
|
|
//保存段落
|
|
|
sectionService.add(section);
|
|
|
}
|
|
|
//不使用能力计分,并且能力数量大于0
|
|
|
- if (!paper.getUseAbility() && abilities.size() > 0) {
|
|
|
- //put第一个能力进去
|
|
|
- data.put(abilities.get(0).getCode(), (double) paper.getQuestions().size());
|
|
|
+ if (!paper.getUseAbility()) {
|
|
|
+ //put一个A0能力进去
|
|
|
+ data.put("A0", (double) paper.getQuestions().size());
|
|
|
+ paper.setTotalScore(paper.getQuestionNum());
|
|
|
+ } else {
|
|
|
+ paper.setTotalScore((int) totalScore);
|
|
|
}
|
|
|
String jsonScore = ObjectUtil.object2Json(data);
|
|
|
- paper.setTotalScore((int) totalScore);
|
|
|
paper.setJsonScore(jsonScore);
|
|
|
paperRepo.saveAndFlush(paper);
|
|
|
logger.info("试卷增加成功");
|
|
@@ -206,7 +226,8 @@ public class PaperService {
|
|
|
|
|
|
public Result update(Paper paper) {
|
|
|
paper.setUpdatetime(new Date());
|
|
|
- return new Result(paperRepo.saveAndFlush(paper) != null);
|
|
|
+ paperRepo.saveAndFlush(paper);
|
|
|
+ return Result.ok();
|
|
|
}
|
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
@@ -254,72 +275,43 @@ public class PaperService {
|
|
|
// return Result.ok(paper);
|
|
|
}
|
|
|
|
|
|
- private Map<String, List<XWPFParagraph>> initSections(Paper paper, String sectionPattern, String questionPattern, String picturePattern, List<XWPFParagraph> paragraphs) {
|
|
|
- //保证顺序
|
|
|
- Map<String, List<XWPFParagraph>> sections = new LinkedHashMap<>();
|
|
|
- String tag = "";
|
|
|
- boolean betweenSectionAndQuestion = false;
|
|
|
- StringBuilder material = new StringBuilder();
|
|
|
- int section = 0;
|
|
|
- List<Section> sectionList = new ArrayList<>();
|
|
|
- logger.info("initSections start");
|
|
|
- boolean hasFormula = false;
|
|
|
- for (XWPFParagraph paragraph : paragraphs) {
|
|
|
- String text = paragraph.getText();
|
|
|
- //此处应判断下是否有照片跟图片
|
|
|
- if (WordUtil.notContent(paragraph, text)) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- //下一个section
|
|
|
- if (text.matches(sectionPattern)) {
|
|
|
- logger.info("match section: text is {} sectionPattern is {}", text, sectionPattern);
|
|
|
- Matcher matcher = Pattern.compile("\\d+").matcher(text);
|
|
|
- //获取到section编号
|
|
|
- if (matcher.find()) {
|
|
|
- section = Integer.parseInt(matcher.group());
|
|
|
- }
|
|
|
- //1 2 3
|
|
|
- tag = String.valueOf(section);
|
|
|
- betweenSectionAndQuestion = true;
|
|
|
- continue;
|
|
|
- }
|
|
|
- if (betweenSectionAndQuestion && text.matches(questionPattern)) {
|
|
|
- Section s = initSection(section, material.toString());
|
|
|
- sectionList.add(s);
|
|
|
- //清空背景材料
|
|
|
- material = new StringBuilder();
|
|
|
- betweenSectionAndQuestion = false;
|
|
|
- }
|
|
|
- //Session后面可能有背景材料,背景材料里面可能有图片和公式,这个放后面来处理
|
|
|
- if (betweenSectionAndQuestion) {
|
|
|
- //解析背景材料的图片和公式
|
|
|
- wordService.parsePicture(paragraph, picturePattern);
|
|
|
- hasFormula = wordService.parseFormula(paragraph);
|
|
|
- material.append("<p>").append(paragraph.getText()).append("</p>");
|
|
|
- }
|
|
|
- //此处可能是第一段
|
|
|
- if (StringUtils.isNotBlank(tag)) {
|
|
|
- List<XWPFParagraph> list = sections.getOrDefault(tag, new ArrayList<>());
|
|
|
- list.add(paragraph);
|
|
|
- sections.put(tag, list);
|
|
|
- }
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public Result uploadPaperTest(PaperVo paperVo, Long templateId, String url, byte[] data) {
|
|
|
+ Paper paper = init(paperVo, url);
|
|
|
+ paper.setRemark(remarkTemplateRepo.getOne(paperVo.getRemarkId()).getRemark());
|
|
|
+ XWPFDocument document = WordUtil.open(data);
|
|
|
+ PaperTemplate template = paperTemplateService.getOrDefault(templateId);
|
|
|
+ if (template == null) {
|
|
|
+ return Result.fail(String.format("未找到试卷模板Id为 %s 的模板", templateId));
|
|
|
}
|
|
|
- paper.setSections(sectionList);
|
|
|
- logger.info("initSections end,sections num is {}", sectionList.size());
|
|
|
- return sections;
|
|
|
+ logger.info("parsing paper,url is {}", url);
|
|
|
+ parsePaper(paper, template, document);
|
|
|
+ logger.info("parse paper finished,url is {}", url);
|
|
|
+ paper.setStatus(1);
|
|
|
+ paper.setTotalScore(100);
|
|
|
+ paper.setQuestionNum(paper.getQuestions().size());
|
|
|
+ paper.setDuration(paper.getQuestionNum() * 2);
|
|
|
+ //TODO 这里要根据实际情况改
|
|
|
+// paper.setSectionDurations("100,20,20");
|
|
|
+// paper.setSectionRests("2,2,2");
|
|
|
+// paper.setSectionNums("50,10,10");
|
|
|
+ WordUtil.close(document);
|
|
|
+ //TODO due ability score
|
|
|
+ //TODO convert parse exception to reason
|
|
|
+ //TODO use parallel
|
|
|
+// Result<Paper> paperResult = add(paper);
|
|
|
+// return addWithQuestion(paper);
|
|
|
+ paper.getQuestions().sort(Comparator.comparingInt(Question::getNumber));
|
|
|
+ return Result.ok(paper);
|
|
|
}
|
|
|
|
|
|
private void parsePaper(Paper paper, PaperTemplate template, XWPFDocument document) {
|
|
|
- String tagPattern = template.getSection();
|
|
|
- String questionPattern = template.getQuestion();
|
|
|
- String picturePattern = template.getPicturePattern();
|
|
|
List<XWPFParagraph> paragraphs = document.getParagraphs();
|
|
|
Assert.notEmpty(paragraphs, "未检测到段落,请检查上传的文档");
|
|
|
String name = paragraphs.get(0).getText();
|
|
|
- //TODO check name of paper
|
|
|
parsePaperName(paper, name, template);
|
|
|
//获取模块,根据模块,给段落分组
|
|
|
- Map<String, List<XWPFParagraph>> sections = initSections(paper, tagPattern, questionPattern, picturePattern, paragraphs);
|
|
|
+ Map<String, List<XWPFParagraph>> sections = initSections(paper, template, paragraphs);
|
|
|
Assert.notEmpty(sections, "未检测到模块,请检查上传的文档");
|
|
|
// List<String> topics = paperTemplateService.getTopic(template);
|
|
|
Map<String, String> topic = paperTemplateService.getMapTopic(template);
|
|
@@ -338,9 +330,9 @@ public class PaperService {
|
|
|
// Section current = ss.stream().filter(section -> s.contains(section.getNumber().toString())).findFirst().orElse(null);
|
|
|
Section current = sectionMap.get(s);
|
|
|
//根据题目标签,给题目分组
|
|
|
- Map<String, List<XWPFParagraph>> questions = initQuestions(current, questionPattern, ps);
|
|
|
+ Map<String, List<XWPFParagraph>> questions = initQuestions(current, template, ps);
|
|
|
current.setStartNumber(currentNumber);
|
|
|
- List<Question> list = parseQuestions(questions, current, template, topic, abilities);
|
|
|
+ List<Question> list = parseQuestions(questions, current, template, topic, paper.getUseAbility(), abilities);
|
|
|
current.setNums(list.size());
|
|
|
currentNumber = currentNumber + list.size();
|
|
|
qs.put(s, list);
|
|
@@ -369,12 +361,69 @@ public class PaperService {
|
|
|
paper.setGrade(g + (first ? "X" : "Y"));
|
|
|
sb.append(g).append("年级").append(first ? "上学期" : "下学期");
|
|
|
}
|
|
|
- boolean A = name.endsWith("A");
|
|
|
- sb.append(A ? "A卷" : "B卷");
|
|
|
+ //取最后一个字为卷,一般为A、B卷
|
|
|
+ sb.append(name.substring(name.length() - 1)).append("卷");
|
|
|
paper.setName(sb.toString());
|
|
|
}
|
|
|
|
|
|
- private List<Question> parseQuestions(Map<String, List<XWPFParagraph>> questions, Section section, PaperTemplate template, Map<String, String> topic, List<String> abilities) {
|
|
|
+ private Map<String, List<XWPFParagraph>> initSections(Paper paper, PaperTemplate template, List<XWPFParagraph> paragraphs) {
|
|
|
+ //保证顺序
|
|
|
+ Map<String, List<XWPFParagraph>> sections = new LinkedHashMap<>();
|
|
|
+ String tag = "";
|
|
|
+ boolean betweenSectionAndQuestion = false;
|
|
|
+ logger.info("sectionPattern is {},questionPattern is {}", template.getSection(), template.getQuestion());
|
|
|
+ StringBuilder material = new StringBuilder();
|
|
|
+ int section = 0;
|
|
|
+ List<Section> sectionList = new ArrayList<>();
|
|
|
+ logger.info("initSections start");
|
|
|
+ boolean hasFormula = false;
|
|
|
+ for (XWPFParagraph paragraph : paragraphs) {
|
|
|
+ String text = paragraph.getText();
|
|
|
+ //此处应判断下是否有图片、文字或者公式
|
|
|
+ if (WordUtil.notContent(paragraph, text)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ //下一个section
|
|
|
+ if (text.matches(template.getSection())) {
|
|
|
+ logger.info("match section: text is {} sectionPattern is {}", text, template.getSection());
|
|
|
+ Matcher matcher = Pattern.compile("\\d+").matcher(text);
|
|
|
+ //获取到section编号
|
|
|
+ if (matcher.find()) {
|
|
|
+ section = Integer.parseInt(matcher.group());
|
|
|
+ }
|
|
|
+ //1 2 3
|
|
|
+ tag = String.valueOf(section);
|
|
|
+ betweenSectionAndQuestion = true;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (betweenSectionAndQuestion && text.matches(template.getQuestion())) {
|
|
|
+ Section s = initSection(section, material.toString());
|
|
|
+ sectionList.add(s);
|
|
|
+ //清空背景材料
|
|
|
+ material = new StringBuilder();
|
|
|
+ betweenSectionAndQuestion = false;
|
|
|
+ }
|
|
|
+ //Session后面可能有背景材料,背景材料里面可能有图片和公式,这个放后面来处理
|
|
|
+ if (betweenSectionAndQuestion) {
|
|
|
+ //解析背景材料的图片和公式
|
|
|
+ wordService.parseSubScript(paragraph);
|
|
|
+ wordService.parsePicture(paragraph, template.getPicturePattern());
|
|
|
+ hasFormula = wordService.parseFormula(paragraph);
|
|
|
+ material.append("<p>").append(paragraph.getText()).append("</p>");
|
|
|
+ }
|
|
|
+ //此处可能是第一段
|
|
|
+ if (StringUtils.isNotBlank(tag)) {
|
|
|
+ List<XWPFParagraph> list = sections.getOrDefault(tag, new ArrayList<>());
|
|
|
+ list.add(paragraph);
|
|
|
+ sections.put(tag, list);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ paper.setSections(sectionList);
|
|
|
+ logger.info("initSections end,sections num is {}", sectionList.size());
|
|
|
+ return sections;
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<Question> parseQuestions(Map<String, List<XWPFParagraph>> questions, Section section, PaperTemplate template, Map<String, String> topic, Boolean useAbility, List<String> abilities) {
|
|
|
List<Question> list = new ArrayList<>();
|
|
|
//问题合集
|
|
|
Pattern pattern = Pattern.compile("\\d+");
|
|
@@ -382,15 +431,15 @@ public class PaperService {
|
|
|
Matcher matcher = pattern.matcher(k);
|
|
|
if (k.matches(template.getQuestion()) && matcher.find()) {
|
|
|
String code = matcher.group();
|
|
|
- Question question = questionService.initQuestion(section.getNumber(), section.getStartNumber(), Integer.valueOf(code));
|
|
|
- wordService.parseQuestion(question, v, topic, template, abilities);
|
|
|
+ Question question = questionService.initQuestion(section.getNumber(), section.getStartNumber(), Integer.valueOf(code), useAbility);
|
|
|
+ wordService.parseQuestion(question, v, topic, template, useAbility);
|
|
|
list.add(question);
|
|
|
}
|
|
|
});
|
|
|
return list;
|
|
|
}
|
|
|
|
|
|
- private Map<String, List<XWPFParagraph>> initQuestions(Section section, String questionPattern, List<XWPFParagraph> ps) {
|
|
|
+ private Map<String, List<XWPFParagraph>> initQuestions(Section section, PaperTemplate paperTemplate, List<XWPFParagraph> ps) {
|
|
|
Map<String, List<XWPFParagraph>> questions = new ConcurrentHashMap<>();
|
|
|
String tag = "";
|
|
|
for (XWPFParagraph paragraph : ps) {
|
|
@@ -398,9 +447,17 @@ public class PaperService {
|
|
|
if (WordUtil.notContent(paragraph, text)) {
|
|
|
continue;
|
|
|
}
|
|
|
+ //识别上下标
|
|
|
+ wordService.parseSubScript(paragraph);
|
|
|
+ //识别图片
|
|
|
+ wordService.parsePicture(paragraph, paperTemplate.getPicturePattern());
|
|
|
+ //识别公式
|
|
|
+ wordService.parseFormula(paragraph);
|
|
|
+ //重新获取text
|
|
|
+ text = paragraph.getText();
|
|
|
//下一个question
|
|
|
// questionPattern ^#[A-Z]#(.*)
|
|
|
- if (text.matches(questionPattern)) {
|
|
|
+ if (text.matches(paperTemplate.getQuestion())) {
|
|
|
tag = text;
|
|
|
}
|
|
|
logger.info("initQuestions,current tag is {},current text is {}", tag, text);
|