Browse Source

修改章节试题上传问题,现在支持多行选项内容

Feick 3 years ago
parent
commit
35435de3c0

+ 2 - 0
src/main/java/com/yaoxiang/diagnosis/controller/IssueChapterController.java

@@ -2,6 +2,7 @@ package com.yaoxiang.diagnosis.controller;
 
 import com.yaoxiang.diagnosis.entity.IssueChapter;
 import com.yaoxiang.diagnosis.service.IssueChapterService;
+import io.swagger.annotations.Api;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
@@ -10,6 +11,7 @@ import org.springframework.web.bind.annotation.RestController;
 import javax.annotation.Resource;
 import java.util.List;
 
+@Api("issueChapter")
 @RestController
 @RequestMapping("issueChapter")
 public class IssueChapterController {

+ 28 - 0
src/main/java/com/yaoxiang/diagnosis/controller/IssueController.java

@@ -0,0 +1,28 @@
+package com.yaoxiang.diagnosis.controller;
+
+import com.yaoxiang.diagnosis.service.IssueService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+@Api(tags = "issue")
+@RestController
+@RequestMapping("issue")
+public class IssueController {
+
+    @Resource
+    private IssueService issueService;
+
+    @ApiOperation("删除题库,模块一需要提供章节Id或年级,年级不为空时表示删除整个年级;模块二三需要提供年级")
+    @PostMapping("delete")
+    public boolean delete(@RequestParam(defaultValue = "2") Long subjectId,
+                          String grade, Long chapterId, int section) {
+        return issueService.delete(subjectId, grade, chapterId, section);
+    }
+
+}

+ 5 - 1
src/main/java/com/yaoxiang/diagnosis/controller/IssuePaperController.java

@@ -1,11 +1,15 @@
 package com.yaoxiang.diagnosis.controller;
 
 import com.yaoxiang.diagnosis.service.IssueParseService;
+import io.swagger.annotations.Api;
+import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
 
-@RestController("issuePaper")
+@Api(tags = "issuePaper")
+@RequestMapping("issuePaper")
+@RestController
 public class IssuePaperController {
 
     @Resource

+ 7 - 6
src/main/java/com/yaoxiang/diagnosis/controller/IssueParseController.java

@@ -4,6 +4,7 @@ import com.yaoxiang.diagnosis.file.FileService;
 import com.yaoxiang.diagnosis.model.Result;
 import com.yaoxiang.diagnosis.service.IssueParseService;
 import com.yaoxiang.diagnosis.util.CommonUtil;
+import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -16,21 +17,21 @@ import org.springframework.web.multipart.MultipartFile;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 
+@Api(tags = "issueParse")
 @RestController
-@RequestMapping("issuePaper")
+@RequestMapping("issueParse")
 public class IssueParseController {
 
+    private static final Logger logger = LoggerFactory.getLogger(IssueParseController.class);
     @Autowired
     private FileService fileService;
     @Autowired
     private IssueParseService issueParseService;
 
-    private static final Logger logger = LoggerFactory.getLogger(IssueParseController.class);
-
     @ApiOperation(value = "上传试卷")
     @PostMapping("uploadPaper")
     public Result uploadPaper(@RequestParam(defaultValue = "2") Long subjectId,
-                              Long chapterId, int section,
+                              String grade, Long chapterId, int section,
                               @RequestBody MultipartFile file) throws IOException {
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         FileCopyUtils.copy(file.getInputStream(), baos);
@@ -38,11 +39,11 @@ public class IssueParseController {
         String suffix = file.getOriginalFilename().substring(suffixIndex);
         String saveName = CommonUtil.randomUUID() + suffix;
         byte[] data = baos.toByteArray();
-        logger.info("正在上传试卷,subjectId={},chapterId={}", subjectId, chapterId);
+        logger.info("正在上传试卷,subjectId={},chapterId={},grade={}", subjectId, grade, chapterId);
         String url = fileService.upload(data, saveName);
         if (StringUtils.isEmpty(url)) {
             return Result.fail("文件上传失败,请重试");
         }
-        return issueParseService.uploadPaper(subjectId, chapterId, section, data);
+        return issueParseService.uploadPaper(subjectId, grade, chapterId, section, data);
     }
 }

+ 0 - 1
src/main/java/com/yaoxiang/diagnosis/controller/RoleController.java

@@ -1,6 +1,5 @@
 package com.yaoxiang.diagnosis.controller;
 
-import com.yaoxiang.diagnosis.authority.AuthCheck;
 import com.yaoxiang.diagnosis.model.Result;
 import com.yaoxiang.diagnosis.service.RoleService;
 import com.yaoxiang.diagnosis.service.UserService;

+ 6 - 0
src/main/java/com/yaoxiang/diagnosis/dao/IssueDao.java

@@ -3,5 +3,11 @@ package com.yaoxiang.diagnosis.dao;
 import com.yaoxiang.diagnosis.entity.Issue;
 import org.springframework.data.jpa.repository.JpaRepository;
 
+import java.util.List;
+
 public interface IssueDao extends JpaRepository<Issue,Long> {
+
+    List<Issue> findBySubjectIdAndChapterId(Long subjectId,Long chapterId);
+
+    List<Issue> findBySubjectIdAndGrade(Long subjectId,String grade);
 }

+ 4 - 0
src/main/java/com/yaoxiang/diagnosis/dao/IssueOptionDao.java

@@ -3,5 +3,9 @@ package com.yaoxiang.diagnosis.dao;
 import com.yaoxiang.diagnosis.entity.IssueOption;
 import org.springframework.data.jpa.repository.JpaRepository;
 
+import java.util.List;
+
 public interface IssueOptionDao extends JpaRepository<IssueOption,Long> {
+
+    List<IssueOption> findByIssueIdIn(List<Long> issueIds);
 }

+ 19 - 2
src/main/java/com/yaoxiang/diagnosis/service/IssueMindService.java

@@ -1,13 +1,14 @@
 package com.yaoxiang.diagnosis.service;
 
 import com.yaoxiang.diagnosis.dao.IssueMindDao;
-import com.yaoxiang.diagnosis.dao.IssueOptionDao;
 import com.yaoxiang.diagnosis.entity.IssueMind;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
+import java.util.ArrayList;
 import java.util.List;
+import java.util.stream.Collectors;
 
 @Service
 public class IssueMindService {
@@ -19,7 +20,23 @@ public class IssueMindService {
     private IssueOptionService issueOptionService;
 
     @Transactional
-    public boolean adds(List<IssueMind> list){
+    public boolean adds(List<IssueMind> list) {
+        return true;
+    }
+
+    @Transactional
+    public List<IssueMind> list(Long subjectId, String grade) {
+        return new ArrayList<>();
+    }
+
+    @Transactional
+    public boolean delete(Long subjectId, String grade) {
+        List<IssueMind> mindList = list(subjectId, grade);
+
+        //TODO MindOption是否直接关联issue
+        //刪除小題
+        issueOptionService.deleteByIssueIds(mindList.stream().map(IssueMind::getId).collect(Collectors.toList()));
+        issueMindDao.deleteAll(mindList);
         return true;
     }
 }

+ 10 - 0
src/main/java/com/yaoxiang/diagnosis/service/IssueOptionService.java

@@ -20,4 +20,14 @@ public class IssueOptionService {
         issueOptionDao.saveAll(options);
         return true;
     }
+
+    public List<IssueOption> findByIssueIds(List<Long> issueIds) {
+        return issueOptionDao.findByIssueIdIn(issueIds);
+    }
+
+    public boolean deleteByIssueIds(List<Long> issueIds) {
+        List<IssueOption> list = findByIssueIds(issueIds);
+        issueOptionDao.deleteAll(list);
+        return true;
+    }
 }

+ 12 - 6
src/main/java/com/yaoxiang/diagnosis/service/IssueParseAdapter.java

@@ -20,6 +20,7 @@ public abstract class IssueParseAdapter implements IssueParseHandler {
     public static final String QUESTION_PATTERN = "#Q(\\d+)#";
     public static final String ANSWER_PATTERN = "#Ans#";
     public static final String OPTION_PATTERN = "^#[A-Z]#(.*)";
+    public static final String OPTION_REPLACE_PATTERN = "#[A-Z]#";
     public static final String MIND_OPTION = "#M(\\d+)#";
     public static final String SECTION_PATTERN = "#Section (\\d+)#";
     public static final String TAG_PATTERN = "#Tag#";
@@ -28,7 +29,7 @@ public abstract class IssueParseAdapter implements IssueParseHandler {
     public static final String PREFIX_PATTERN = "#";
     public static final String SUFFIX_PATTERN = "#";
 
-    public static final List<String> TOPIC1 = Arrays.asList(QUESTION_PATTERN, ANSWER_PATTERN, OPTION_PATTERN);
+    public static final List<String> TOPIC1 = Arrays.asList(QUESTION_PATTERN, ANSWER_PATTERN, TAG_PATTERN);
 
     protected final Pattern issuePattern = Pattern.compile("\\d+");
 
@@ -81,6 +82,10 @@ public abstract class IssueParseAdapter implements IssueParseHandler {
             if (text.matches(QUESTION_PATTERN)) {
                 tag = text;
             }
+            //过滤掉试题标题
+            if (tag.isEmpty()) {
+                continue;
+            }
             logger.info("initQuestions,current tag is {},current text is {}", tag, text);
             List<XWPFParagraph> list = result.getOrDefault(tag, new ArrayList<>());
             list.add(paragraph);
@@ -127,21 +132,22 @@ public abstract class IssueParseAdapter implements IssueParseHandler {
         return map;
     }
 
-    protected Issue init(Long subjectId, Long chapterId, int section) {
+    protected Issue init(Long subjectId, String grade, Long chapterId, int section) {
         Issue issue = new Issue();
         issue.setChapterId(chapterId);
+        issue.setGrade(grade);
         issue.setSubjectId(subjectId);
         issue.setSection(section);
         issue.setCreatetime(new Date());
         return issue;
     }
 
-    protected IssueOption initOption(int index,int section, String content) {
+    protected IssueOption initOption(int index, int section, String content) {
         IssueOption option = new IssueOption();
         option.setOindex(index);
         option.setSection(section);
         //去掉选项中的#A#
-        option.setContent("<p>" + content.substring(3) + "</p>");
+        option.setContent(content.replaceFirst(OPTION_REPLACE_PATTERN, ""));
         option.setCreatetime(new Date());
         option.setCorrect(false);
         return option;
@@ -158,12 +164,12 @@ public abstract class IssueParseAdapter implements IssueParseHandler {
     }
 
     @Override
-    public List<Issue> parse(List<XWPFParagraph> list, Long subjectId, Long chapterId) {
+    public List<Issue> parse(List<XWPFParagraph> list, Long subjectId, String grade, Long chapterId) {
         Map<String, List<XWPFParagraph>> map = split(list);
         List<Issue> result = new ArrayList<>();
         for (Map.Entry<String, List<XWPFParagraph>> entry : map.entrySet()) {
             List<XWPFParagraph> data = entry.getValue();
-            Issue issue = parse(entry.getKey(), data, subjectId, chapterId);
+            Issue issue = parse(entry.getKey(), data, subjectId, grade, chapterId);
             result.add(issue);
         }
         return result;

+ 2 - 2
src/main/java/com/yaoxiang/diagnosis/service/IssueParseHandler.java

@@ -9,7 +9,7 @@ public interface IssueParseHandler {
 
     int getSection();
 
-    List<Issue> parse(List<XWPFParagraph> list, Long subjectId, Long chapterId);
+    List<Issue> parse(List<XWPFParagraph> list, Long subjectId, String grade, Long chapterId);
 
-    Issue parse(String issueIndex, List<XWPFParagraph> list, Long subjectId, Long chapterId);
+    Issue parse(String issueIndex, List<XWPFParagraph> list, Long subjectId, String grade, Long chapterId);
 }

+ 4 - 8
src/main/java/com/yaoxiang/diagnosis/service/IssueParseService.java

@@ -1,14 +1,11 @@
 package com.yaoxiang.diagnosis.service;
 
-import com.yaoxiang.diagnosis.dao.IssueDao;
 import com.yaoxiang.diagnosis.entity.Issue;
 import com.yaoxiang.diagnosis.model.Result;
 import com.yaoxiang.diagnosis.word.WordUtil;
 import org.apache.poi.xwpf.usermodel.XWPFDocument;
 import org.apache.poi.xwpf.usermodel.XWPFParagraph;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
-import org.springframework.stereotype.Service;
 import org.springframework.util.Assert;
 
 import javax.annotation.PostConstruct;
@@ -34,19 +31,18 @@ public class IssueParseService {
         handlerMap = handlers.stream().collect(Collectors.toMap(IssueParseHandler::getSection, Function.identity()));
     }
 
-    public Result uploadPaper(Long subjectId, Long chapterId, int section, byte[] data) {
+    public Result uploadPaper(Long subjectId, String grade, Long chapterId, int section, byte[] data) {
         XWPFDocument document = WordUtil.open(data);
-        List<Issue> issues = parseIssues(document, subjectId, chapterId, section);
+        List<Issue> issues = parseIssues(document, subjectId,grade, chapterId, section);
         WordUtil.close(document);
-
         issueService.adds(issues);
         return Result.ok(issues);
     }
 
-    private List<Issue> parseIssues(XWPFDocument document, Long subjectId, Long chapterId, int section) {
+    private List<Issue> parseIssues(XWPFDocument document, Long subjectId,String grade, Long chapterId, int section) {
         List<XWPFParagraph> paragraphs = document.getParagraphs();
         Assert.notEmpty(paragraphs, "未检测到段落,请检查上传的文档");
-        List<Issue> result = handlerMap.get(section).parse(paragraphs, subjectId, chapterId);
+        List<Issue> result = handlerMap.get(section).parse(paragraphs, subjectId,grade, chapterId);
         return result;
     }
 

+ 33 - 9
src/main/java/com/yaoxiang/diagnosis/service/IssueParseWordHandler.java

@@ -3,7 +3,7 @@ package com.yaoxiang.diagnosis.service;
 import com.yaoxiang.diagnosis.config.Constants;
 import com.yaoxiang.diagnosis.entity.Issue;
 import com.yaoxiang.diagnosis.entity.IssueOption;
-import lombok.extern.slf4j.Slf4j;
+import com.yaoxiang.diagnosis.word.WordUtil;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.poi.xwpf.usermodel.XWPFParagraph;
 import org.slf4j.Logger;
@@ -12,6 +12,7 @@ import org.springframework.stereotype.Component;
 import org.springframework.util.Assert;
 
 import java.util.ArrayList;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.regex.Matcher;
@@ -27,8 +28,8 @@ public class IssueParseWordHandler extends IssueParseAdapter implements IssuePar
     }
 
     @Override
-    public Issue parse(String issueIndex, List<XWPFParagraph> list, Long subjectId, Long chapterId) {
-        Issue issue = init(subjectId, chapterId, getSection());
+    public Issue parse(String issueIndex, List<XWPFParagraph> list, Long subjectId, String grade, Long chapterId) {
+        Issue issue = init(subjectId, grade,chapterId, getSection());
         Map<String, List<XWPFParagraph>> group = initGroup(list, TOPIC1);
 
         Matcher matcher = issuePattern.matcher(issueIndex);
@@ -51,21 +52,44 @@ public class IssueParseWordHandler extends IssueParseAdapter implements IssuePar
         int i = 0;
         StringBuilder content = new StringBuilder();
         boolean hasFormula = false;
+        String index = "";
+        Map<String, List<XWPFParagraph>> indexMap = new LinkedHashMap<>();
+        boolean isQuestion = true;
         for (XWPFParagraph p : ps) {
 
             String text = p.getText();
+            if (WordUtil.notContent(p, text)) {
+                continue;
+            }
             //清除掉#Small#
             text = text.replaceAll(PICTURE_PATTERN, "");
             if (text.matches(OPTION_PATTERN)) {
-                //匹配到选项,至少有2个字符
-                IssueOption option = initOption(i++,issue.getSection(), text);
-                String optionNoContent = String.format("parseQuestion,题号为%s的题目选项 %s 未检测到内容,题目内容为“%s”,请检查选项结构", code, text, content);
-                Assert.hasText(option.getContent(), optionNoContent);
-                options.add(option);
-            } else {
+                isQuestion = false;
+                index = text;
+            }
+
+            if (isQuestion) {
                 content.append("<p>").append(text).append("</p>");
+                continue;
+            }
+            List<XWPFParagraph> list = indexMap.getOrDefault(index, new ArrayList<>());
+            list.add(p);
+            indexMap.put(index, list);
+
+        }
+
+        for (Map.Entry<String, List<XWPFParagraph>> entry : indexMap.entrySet()) {
+            StringBuilder builder = new StringBuilder();
+            for (XWPFParagraph p : entry.getValue()) {
+                builder.append("<p>").append(p.getText()).append("</p>");
             }
+            String text = builder.toString();
+            IssueOption option = initOption(i++, issue.getSection(), text);
+            String optionNoContent = String.format("parseQuestion,题号为%s的题目选项 %s 未检测到内容,题目内容为“%s”,请检查选项结构", code, text, content);
+            Assert.hasText(option.getContent(), optionNoContent);
+            options.add(option);
         }
+
         String noContent = String.format("parseQuestion,题号为 %s 的题目未检测到题干,题目内容为 “%s” ,请检查", code, content);
         String noOptions = String.format("parseQuestion,题号为 %s 的题目未检测到选项,题目内容为 “%s” ,请检查", code, content);
         String lostOptions = String.format("parseQuestion,题号为 %s 的题目检测到选项数量为 %s ,题目内容为 “%s” ,请检查选项换行情况", code, options.size(), content);

+ 49 - 0
src/main/java/com/yaoxiang/diagnosis/service/IssueService.java

@@ -2,11 +2,13 @@ package com.yaoxiang.diagnosis.service;
 
 import com.yaoxiang.diagnosis.dao.IssueDao;
 import com.yaoxiang.diagnosis.entity.Issue;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
 import java.util.List;
+import java.util.stream.Collectors;
 
 @Service
 public class IssueService {
@@ -32,5 +34,52 @@ public class IssueService {
         return true;
     }
 
+    @Transactional
+    public boolean delete(Long subjectId, String grade, Long chapterId, int section) {
+        if (section == 1 && StringUtils.isBlank(grade)) {
+            return delete(subjectId, chapterId);
+        }
+        return delete(subjectId, grade, section);
+    }
+
+    /**
+     * 删除模块一
+     *
+     * @param subjectId 科目Id
+     * @param chapterId 章节Id
+     * @return 是否删除
+     */
+    private boolean delete(Long subjectId, Long chapterId) {
+        List<Issue> list = issueDao.findBySubjectIdAndChapterId(subjectId, chapterId);
+        issueOptionService.deleteByIssueIds(list.stream().map(Issue::getId).collect(Collectors.toList()));
+        issueDao.deleteAll(list);
+        return true;
+    }
+
+    /**
+     * 删除模块二三
+     *
+     * @param subjectId 科目Id
+     * @param grade     年级
+     * @param section   模块
+     * @return 是否成功
+     */
+    private boolean delete(Long subjectId, String grade, int section) {
+
+        List<Issue> list = issueDao.findBySubjectIdAndGrade(subjectId, grade);
+
+        if (section != 1) {
+            issueMindService.delete(subjectId, grade);
+        }else {
+            issueOptionService.deleteByIssueIds(list.stream().map(Issue::getId).collect(Collectors.toList()));
+            issueDao.deleteAll(list);
+        }
+
+        issueDao.deleteAll(list);
+
+        return true;
+    }
+
+
 //    public boolean add(Issue issue){}
 }