ソースを参照

修改专项诊断报告接口,现已支持生成数学中考的认识理解和应用

4228306 5 年 前
コミット
ab39e488b9

BIN
doc/数学中考专项诊断.docx


BIN
doc/数学中考专项诊断知识点列表.xlsx


+ 14 - 1
src/main/java/com/yaoxiang/diagnosis/config/Constants.java

@@ -3,7 +3,9 @@ package com.yaoxiang.diagnosis.config;
 
 import org.springframework.security.core.authority.SimpleGrantedAuthority;
 
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 public class Constants {
@@ -114,5 +116,16 @@ public class Constants {
     public static final int PAPER_STATUS_INVALIDATE = 2;
 
     public static final String SPECIAL_KNOWLEDGE_MASTER = "掌握";
-    public static final String SPECIAL_KNOWLEDGE_UNMASTER  = "未掌握";
+    public static final String SPECIAL_KNOWLEDGE_UNMASTER = "未掌握";
+
+    public static final String SPECIAL_MASTER_STATUS_KNOW = "认识";
+    public static final String SPECIAL_MASTER_STATUS_UNDERSTAND = "理解";
+    public static final String SPECIAL_MASTER_STATUS_USAGE = "应用";
+
+    public static final List<String> SPECIAL_MASTER_STATUS = new ArrayList<String>() {{
+        add(SPECIAL_MASTER_STATUS_KNOW);
+        add(SPECIAL_MASTER_STATUS_UNDERSTAND);
+        add(SPECIAL_MASTER_STATUS_USAGE);
+    }};
+
 }

+ 12 - 6
src/main/java/com/yaoxiang/diagnosis/controller/SpecialReportController.java

@@ -1,5 +1,6 @@
 package com.yaoxiang.diagnosis.controller;
 
+import com.yaoxiang.diagnosis.entity.SpecialMind;
 import com.yaoxiang.diagnosis.entity.SpecialResult;
 import com.yaoxiang.diagnosis.service.SpecialReportService;
 import io.swagger.annotations.Api;
@@ -9,7 +10,7 @@ import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
 
-@Api(tags="专项诊断报告")
+@Api(tags = "专项诊断报告")
 @RestController
 @RequestMapping("/specialReport")
 public class SpecialReportController {
@@ -18,12 +19,17 @@ public class SpecialReportController {
     private SpecialReportService specialReportService;
 
     @GetMapping("/generate")
-    public SpecialResult generate(Long pid,Long uid){
-        return specialReportService.generate2(pid,uid);
+    public SpecialResult generate(Long pid, Long uid) {
+        return specialReportService.generate2(pid, uid);
     }
 
-    @GetMapping("/generate2")
-    public SpecialResult generate2(Long pid,Long uid){
-        return specialReportService.generate2(pid,uid);
+    @GetMapping("/generateMind")
+    public SpecialMind generateMind(Long pid, Long uid) {
+        return new SpecialMind();
     }
+
+//    @GetMapping("/generate2")
+//    public SpecialResult generate2(Long pid,Long uid){
+//        return specialReportService.generate2(pid,uid);
+//    }
 }

+ 7 - 5
src/main/java/com/yaoxiang/diagnosis/entity/SpecialKnowledge.java

@@ -35,7 +35,7 @@ public class SpecialKnowledge {
     @ApiModelProperty("知识点内容")
     private String content;
 
-    @ApiModelProperty("掌握等级 掌握 理解 应用")
+    @ApiModelProperty("认识等级 red yellow green")
     private String masterLevel;
 
     @ApiModelProperty("父Id")
@@ -57,7 +57,7 @@ public class SpecialKnowledge {
     @ApiModelProperty("掌握率")
     private Double master = 100.0;
     @Transient
-    @ApiModelProperty("掌握情况")
+    @ApiModelProperty("掌握情况 掌握 未掌握 ")
     private String masterStatus = Constants.SPECIAL_KNOWLEDGE_MASTER;
 
     @Transient
@@ -220,10 +220,12 @@ public class SpecialKnowledge {
     @Override
     public String toString() {
         return "SpecialKnowledge{" +
-                "level=" + level +
-                ", code='" + code + '\'' +
+                "id=" + id +
+                ", level=" + level +
                 ", content='" + content + '\'' +
-                ", parentId=" + parentId +
+                ", questionNum=" + questionNum +
+                ", collectNum=" + collectNum +
+                ", qids='" + qids + '\'' +
                 '}';
     }
 }

+ 20 - 4
src/main/java/com/yaoxiang/diagnosis/entity/SpecialMind.java

@@ -1,9 +1,6 @@
 package com.yaoxiang.diagnosis.entity;
 
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
+import javax.persistence.*;
 
 @Entity
 public class SpecialMind {
@@ -12,12 +9,15 @@ public class SpecialMind {
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private Long id;
 
+    private Integer level;
     private String step;
     private String content;
     private Long pid;
     private Long subjectId;
     private String grade;
     private String qids;
+    @Transient
+    private Boolean mistake;
 
     public Long getId() {
         return id;
@@ -27,6 +27,14 @@ public class SpecialMind {
         this.id = id;
     }
 
+    public Integer getLevel() {
+        return level;
+    }
+
+    public void setLevel(Integer level) {
+        this.level = level;
+    }
+
     public String getStep() {
         return step;
     }
@@ -74,4 +82,12 @@ public class SpecialMind {
     public void setQids(String qids) {
         this.qids = qids;
     }
+
+    public Boolean getMistake() {
+        return mistake;
+    }
+
+    public void setMistake(Boolean mistake) {
+        this.mistake = mistake;
+    }
 }

+ 35 - 0
src/main/java/com/yaoxiang/diagnosis/model/SpecialMindVo.java

@@ -0,0 +1,35 @@
+package com.yaoxiang.diagnosis.model;
+
+import com.yaoxiang.diagnosis.entity.SpecialMind;
+
+import java.util.List;
+
+public class SpecialMindVo {
+    private Double master;
+    private String step;
+    private List<SpecialMind> minds;
+
+    public Double getMaster() {
+        return master;
+    }
+
+    public void setMaster(Double master) {
+        this.master = master;
+    }
+
+    public String getStep() {
+        return step;
+    }
+
+    public void setStep(String step) {
+        this.step = step;
+    }
+
+    public List<SpecialMind> getMinds() {
+        return minds;
+    }
+
+    public void setMinds(List<SpecialMind> minds) {
+        this.minds = minds;
+    }
+}

+ 121 - 0
src/main/java/com/yaoxiang/diagnosis/service/SpecialKnowledgeService.java

@@ -148,4 +148,125 @@ public class SpecialKnowledgeService {
         }
         return true;
     }
+
+    public void calcComplex(List<SpecialKnowledge> list) {
+        int max = list.stream().map(SpecialKnowledge::getLevel).max(Comparator.naturalOrder()).orElse(0);
+        if (max == 0) {
+            logger.error("最大层级为0,请检查数据");
+            return;
+        }
+        Map<Long, SpecialKnowledge> mapper = list.stream().collect(Collectors.toMap(SpecialKnowledge::getId, Function.identity()));
+        List<SpecialKnowledge> ks = list.stream().filter(s -> s.getLevel() == max).collect(Collectors.toList());
+        Map<Long, List<SpecialKnowledge>> parentMap = ks.stream().collect(Collectors.groupingBy(SpecialKnowledge::getParentId));
+        for (Map.Entry<Long, List<SpecialKnowledge>> entry : parentMap.entrySet()) {
+            List<SpecialKnowledge> s = entry.getValue();
+            SpecialKnowledge parent = mapper.get(entry.getKey());
+            //TODO 后续优化这个排序
+            SpecialKnowledge know = null, under = null, usage = null;
+            for (SpecialKnowledge k : s) {
+                switch (k.getContent()) {
+                    case Constants.SPECIAL_MASTER_STATUS_KNOW:
+                        know = k;
+                        break;
+                    case Constants.SPECIAL_MASTER_STATUS_UNDERSTAND:
+                        under = k;
+                        break;
+                    case Constants.SPECIAL_MASTER_STATUS_USAGE:
+                        usage = k;
+                        break;
+                }
+            }
+            int weight = calcWeight(know, under, usage,parent);
+            logger.info("当前知识点为parent={}", parent);
+            switch (weight) {
+                case 0:
+                    logger.error("unexpected error,当前知识点没有考试题");
+                    break;
+                case 1:
+                    logger.info("当前知识点只考了认识");
+                    break;
+                case 6:
+                    logger.info("当前知识点考了理解和应用");
+                    if (usage.getMaster() >= 50) {
+                        parent.setMasterLevel("应用");
+                        if (parent.getMaster() >= 75) {
+                            parent.setMasterStatus("green");
+                        } else {
+                            parent.setMasterStatus("yellow");
+                        }
+                        break;
+                    }
+                    //应用小于50
+                    if (under.getMaster() >= 50) {
+                        parent.setMasterLevel("理解");
+                        int collect = under.getCollectNum() + know.getCollectNum();
+                        int questionNum = under.getQuestionNum() + know.getQuestionNum();
+                        if (questionNum == 0) {
+                            logger.error("unexpected error,题目数量为0,认识和理解未考题目");
+                        }
+                        double master = collect * 100.0 / questionNum;
+                        if (master >= 75) {
+                            parent.setMasterStatus("yellow");
+                        } else {
+                            parent.setMasterStatus("red");
+                        }
+                    } else {
+                        //最低评价 理解红色
+                        parent.setMasterLevel("理解");
+                        parent.setMasterStatus("red");
+                    }
+                    break;
+                case 7:
+                    logger.info("当前知识点考了所有题目");
+                    if (usage.getMaster() >= 50) {
+                        parent.setMasterLevel("应用");
+                        if (parent.getMaster() >= 75) {
+                            parent.setMasterStatus("green");
+                        } else {
+                            parent.setMasterStatus("yellow");
+                        }
+                        break;
+                    }
+                    //应用小于50
+                    if (under.getMaster() >= 50) {
+                        parent.setMasterLevel("理解");
+                        int collect = under.getCollectNum() + know.getCollectNum();
+                        int questionNum = under.getQuestionNum() + know.getQuestionNum();
+                        if (questionNum == 0) {
+                            logger.error("unexpected error,题目数量为0,认识和理解未考题目");
+                        }
+                        double master = collect * 100.0 / questionNum;
+                        if (master >= 75) {
+                            parent.setMasterStatus("yellow");
+                        } else {
+                            parent.setMasterStatus("red");
+                        }
+                        break;
+                    }
+                    parent.setMasterLevel("认识");
+                    if (know.getMaster() >= 75) {
+                        parent.setMasterStatus("yellow");
+                    } else {
+                        parent.setMasterStatus("red");
+                    }
+            }
+        }
+    }
+
+    private int calcWeight(SpecialKnowledge know, SpecialKnowledge under, SpecialKnowledge usage,SpecialKnowledge parent) {
+        int a = 1, b = 2, c = 4;
+        if (know == null || StringUtils.isBlank(know.getQids())) {
+            a = 0;
+            logger.warn("未找到认识层级,parent={}", parent.getContent());
+        }
+        if (under == null || StringUtils.isBlank(under.getQids())) {
+            b = 0;
+            logger.warn("未找到理解层级,parent={}", parent.getContent());
+        }
+        if (usage == null || StringUtils.isBlank(usage.getQids())) {
+            c = 0;
+            logger.warn("未找到应用层级,parent={}", parent.getContent());
+        }
+        return a + b + c;
+    }
 }

+ 22 - 15
src/main/java/com/yaoxiang/diagnosis/service/SpecialReportService.java

@@ -33,21 +33,22 @@ public class SpecialReportService {
 
     private static final Logger logger = LoggerFactory.getLogger(SpecialReportService.class);
 
-    public SpecialResult generate(Long pid, Long uid) {
-        Paper paper = paperService.getOnePaper(pid);
-        if (paper == null) {
-            logger.error("未找到试卷 pid={}", pid);
-            return null;
-        }
-        PaperCommit commit = commitService.getPaperCommit(pid, uid);
-        if (commit == null) {
-            logger.error("用户未提交 pid={},uid={}", pid, uid);
-            return null;
-        }
-        return generate(commit, paper);
-    }
+//    public SpecialResult generate(Long pid, Long uid) {
+//        Paper paper = paperService.getOnePaper(pid);
+//        if (paper == null) {
+//            logger.error("未找到试卷 pid={}", pid);
+//            return null;
+//        }
+//        PaperCommit commit = commitService.getPaperCommit(pid, uid);
+//        if (commit == null) {
+//            logger.error("用户未提交 pid={},uid={}", pid, uid);
+//            return null;
+//        }
+//        return generate(commit, paper);
+//    }
 
     public SpecialResult generate2(Long pid, Long uid) {
+        logger.info("正在生成专项诊断报告");
         Paper paper = paperService.getOnePaper(pid);
         if (paper == null) {
             logger.error("未找到试卷 pid={}", pid);
@@ -129,8 +130,10 @@ public class SpecialReportService {
         List<Long> collects = Arrays.stream(collect.split(","))
                 .map(Long::parseLong).collect(Collectors.toList());
 
+        boolean complexMaster = list.stream().anyMatch(s -> Constants.SPECIAL_MASTER_STATUS.contains(s.getContent()));
+
         for (SpecialKnowledge knowledge : list) {
-            //过滤掉非叶子节点
+            //过滤掉非叶子节点,或者叶子节点为null的知识点
             if (StringUtils.isBlank(knowledge.getQids())) {
                 continue;
             }
@@ -141,7 +144,7 @@ public class SpecialReportService {
             knowledge.setQuestionNum(number.size());
             number.retainAll(collects);
             knowledge.setCollectNum(number.size());
-            if(knowledge.getQuestionNum() > 0) {
+            if (knowledge.getQuestionNum() > 0) {
                 double master = knowledge.getCollectNum() * 100.0 / knowledge.getQuestionNum();
                 knowledge.setMaster(NumberUtil.format(master));
                 if (master < 80) {
@@ -150,6 +153,10 @@ public class SpecialReportService {
             }
         }
         specialKnowledgeService.calcCount(list);
+        if (complexMaster) {
+            logger.info("计算认识理解应用情况,pid={},grade={},subjectId={}", paper.getId(), paper.getGrade(), paper.getSubjectId());
+            specialKnowledgeService.calcComplex(list);
+        }
         //统计结果并且剪枝,剪掉>3的层级
         List<SpecialKnowledge> tree = specialKnowledgeService.toTree(list);
 

+ 33 - 3
src/main/java/com/yaoxiang/diagnosis/word/KnowledgeUtil.java

@@ -14,6 +14,8 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import static com.yaoxiang.diagnosis.config.Constants.SPECIAL_MASTER_STATUS;
+
 public class KnowledgeUtil {
 
     public static final int START_ROW = 2;
@@ -219,6 +221,11 @@ public class KnowledgeUtil {
             XSSFRow row = sheet.getRow(i);
             for (int j = 0; j < row.getLastCellNum() - 1; j++) {
                 String content = row.getCell(j).getStringCellValue();
+                String rawContent = content;
+                //对有认识、理解和应用的特色处理
+                if (SPECIAL_MASTER_STATUS.contains(content)) {
+                    content = row.getCell(j - 1).getStringCellValue() + content;
+                }
                 if (map.containsKey(content)) {
                     continue;
                 }
@@ -229,7 +236,9 @@ public class KnowledgeUtil {
                 }
                 if (j == row.getLastCellNum() - 2) {
                     XSSFCell cell = row.getCell(j + 1);
-                    if (CellType.NUMERIC == cell.getCellTypeEnum()) {
+                    if (CellType.BLANK == cell.getCellTypeEnum()) {
+                        k.setQids("");
+                    } else if (CellType.NUMERIC == cell.getCellTypeEnum()) {
                         k.setQids(String.valueOf((int) cell.getNumericCellValue()));
                     } else {
                         k.setQids(cell.getStringCellValue());
@@ -239,7 +248,7 @@ public class KnowledgeUtil {
                 k.setGrade(grade);
                 k.setPid(pid);
                 k.setSubjectId(subjectId);
-                k.setContent(content);
+                k.setContent(rawContent);
                 map.put(content, k);
                 result.add(k);
             }
@@ -263,7 +272,9 @@ public class KnowledgeUtil {
         for (int i = 1; i <= sheet.getLastRowNum(); i++) {
             XSSFRow row = sheet.getRow(i);
             SpecialMind mind = new SpecialMind();
-            mind.setStep(row.getCell(0).getStringCellValue());
+            String step = row.getCell(0).getStringCellValue();
+            mind.setLevel(toLevel(step));
+            mind.setStep(step);
             mind.setContent(row.getCell(1).getStringCellValue());
             XSSFCell cell = row.getCell(2);
             String qids = "";
@@ -280,4 +291,23 @@ public class KnowledgeUtil {
         }
         return result;
     }
+
+    private static Integer toLevel(String step) {
+        //有点蠢
+        switch (step) {
+            case "第一步":
+                return 1;
+            case "第二步":
+                return 2;
+            case "第三步":
+                return 3;
+            case "第四步":
+                return 4;
+            case "第五步":
+                return 5;
+            case "第六步":
+                return 6;
+        }
+        return 0;
+    }
 }