Explorar el Código

知识点考卷接口调整

mingfu hace 1 mes
padre
commit
f894323da0

+ 9 - 91
ie-admin/src/main/java/com/ruoyi/web/controller/front/FrontExamController.java

@@ -10,11 +10,13 @@ import com.ruoyi.enums.ExamineeStatus;
 import com.ruoyi.enums.PaperType;
 import com.ruoyi.ie.domain.AMarjorPlan;
 import com.ruoyi.ie.service.IAMarjorPlanService;
+import com.ruoyi.learn.domain.AnswerSheet;
 import com.ruoyi.learn.domain.LearnExaminee;
 import com.ruoyi.learn.domain.LearnPaper;
 import com.ruoyi.learn.service.ILearnExamineeService;
 import com.ruoyi.learn.service.ILearnPaperService;
 import com.ruoyi.system.service.ISysUserService;
+import com.ruoyi.web.service.ExamService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
@@ -30,108 +32,24 @@ import java.util.Set;
 @RequestMapping("/front/exam")
 @Api(tags = "前台-学习-考试练习")
 public class FrontExamController {
-    private Set<PaperType> paperTypeSet = Sets.newHashSet(PaperType.Real, PaperType.Custom, PaperType.Test);
     private final IDzControlService controlService;
     private final ISysUserService sysUserService;
-    private final ILearnPaperService paperService;
-    private final ILearnExamineeService examineeService;
-    private final IAMarjorPlanService marjorPlanService;
+    private final ExamService examService;
 
-    public FrontExamController(IDzControlService controlService, ISysUserService sysUserService, ILearnPaperService paperService, ILearnExamineeService examineeService, IAMarjorPlanService marjorPlanService) {
+    public FrontExamController(IDzControlService controlService, ISysUserService sysUserService, ExamService examService) {
         this.controlService = controlService;
         this.sysUserService = sysUserService;
-        this.paperService = paperService;
-        this.examineeService = examineeService;
-        this.marjorPlanService = marjorPlanService;
+        this.examService = examService;
     }
 
     // 试卷: 真题卷,批次测试卷,自组卷, 生成考试记录
     // 定向模拟卷: 根据用户选择生成记录
     // 组卷: 知识点 错题 必刷题 实时组卷后才生成记录
     @ApiOperation("01 开卷")
-    @GetMapping(value = "openExaminee")
-    public AjaxResult openExamineePaper(@ApiParam("考卷类型PaperType") PaperType paperType,
-                                        @ApiParam("考卷类型关联ID") Long relateId,
-                                        @RequestBody JSONObject param) {
-        LearnPaper paper = paperService.selectLearnPaperById(relateId);
-        LearnExaminee examinee = new LearnExaminee();
-        examinee.setStudentId(SecurityUtils.getLoginUser().getUser().getUserId());
-        examinee.setPaperType(paperType.getVal());
-        if(!paperTypeSet.contains(paperType)) {
-            if(PaperType.Simulated.equals(paperType)) { // 检查是否超过最大值从顺序选择未做过的考卷来
-                return AjaxResult.success(openSimulatedPaper(examinee, param));
-            } else { // 根据几种场景实时组卷,然后返回PaperId
-                return AjaxResult.success(openCustomPaper(paperType, examinee, param));
-            }
-        }
-        examinee.setPaperKey(paperType.name() + "_" + paper.getId());
-        return AjaxResult.success(newExamineePcondaper(examinee, paper, param));
-    }
-
-    private LearnExaminee newExamineePcondaper(LearnExaminee examinee, LearnPaper paper, JSONObject param) {
-        examinee.setPaperId(paper.getId());
-        examinee.setParams(param);
-        examinee.setState(ExamineeStatus.Exam.getVal());
-        examinee.setBeginTime(DateUtils.getNowDate());
-        examineeService.insertLearnExaminee(examinee);
-        return examinee;
-    }
-
-    private LearnExaminee openCustomPaper(PaperType paperType, LearnExaminee examinee, JSONObject param) {
-        Long knowledgeId = param.getLong("knowledgeId");
-        examinee.setPaperKey(paperType.name() + knowledgeId);
-        examinee.setState(ExamineeStatus.Exam.getVal());
-        List<LearnExaminee> examineeList = examineeService.selectLearnExamineeList(examinee);
-        if(CollectionUtils.isNotEmpty(examineeList)) {
-            return examineeList.get(0);
-        }
-        // 全局配置模板参数或知识点级的参数
-        LearnPaper paper = paperService.selectLearnPaperById(0L);
-        if(null == paper) {
-            throw new ValidationException("未组卷");
-        }
-        return newExamineePcondaper(examinee, paper, param);
-    }
-
-    private LearnExaminee openSimulatedPaper(LearnExaminee examinee, JSONObject param) {
-        List<LearnExaminee> examineeList = examineeService.selectLearnExamineeList(examinee);
-        Set<Long> existPaperIdSet = Sets.newHashSet();
-        for(LearnExaminee e : examineeList) {
-            if(ExamineeStatus.Exam.getVal().equals(e.getState())) {
-                return e;
-            }
-            existPaperIdSet.add(e.getPaperId());
-        }
-        Long id = param.getLong("id");
-        AMarjorPlan plan = marjorPlanService.selectAMarjorPlanById(id);
-        if(null == plan) {
-            throw new ValidationException("专业id无效");
-        }
-        LearnPaper paper = getBestPaper(plan, existPaperIdSet);
-        examinee.setPaperKey(PaperType.Simulated.name() + "_" + paper.getId());
-        return newExamineePcondaper(examinee, paper, param);
-    }
-
-    private LearnPaper getBestPaper(AMarjorPlan plan, Set<Long> existPaperIdSet) {
-        String groupName = StringUtils.trimToEmpty(plan.getMajorGroup());
-        LearnPaper paperCond = new LearnPaper();
-        paperCond.setPaperType(PaperType.Simulated.name());
-        for(int i = 3; i>0; i--) {
-            if(i == 3) {
-                paperCond.setDirectKey(plan.getUniversityId() + "_" + groupName + "_" + plan.getMajorName());
-            } else if(i == 2) {
-                paperCond.setDirectKey(plan.getUniversityId() + "_" + groupName);
-            } else if(StringUtils.isBlank(groupName)) {
-                break;
-            }
-            List<LearnPaper> paperList = paperService.selectLearnPaperList(paperCond);
-            for(LearnPaper paper : paperList) {
-                if(existPaperIdSet.add(paper.getId())) {
-                    return paper;
-                }
-            }
-        }
-        throw new ValidationException("未初始化院校定向模拟题库: " + plan.getId());
+    @PostMapping(value = "openExaminee")
+    public AjaxResult openExamineePaper(@ApiParam("考卷类型PaperType") @RequestParam PaperType paperType,
+                                        @ApiParam("考卷类型关联ID") @RequestParam Long relateId) {
+        return AjaxResult.success(examService.openExaminee(paperType, relateId));
     }
 
     @ApiOperation("04 取答案")

+ 11 - 12
ie-admin/src/main/java/com/ruoyi/web/controller/front/FrontPaperController.java

@@ -1,6 +1,7 @@
 package com.ruoyi.web.controller.front;
 
 import com.alibaba.fastjson2.JSONObject;
+import com.google.common.collect.Maps;
 import com.ruoyi.common.core.content.VistorContextHolder;
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.core.domain.AjaxResult2;
@@ -14,7 +15,9 @@ import com.ruoyi.learn.domain.LearnTest;
 import com.ruoyi.learn.service.ILearnPaperQuestionService;
 import com.ruoyi.learn.service.ILearnPaperService;
 import com.ruoyi.learn.service.ILearnTestService;
+import com.ruoyi.web.service.ExamService;
 import com.ruoyi.web.service.LearnTeacherService;
+import com.ruoyi.web.service.PaperService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
@@ -23,6 +26,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
 import java.util.List;
+import java.util.Map;
 
 @RestController
 @RequestMapping("/front/paper")
@@ -30,18 +34,16 @@ import java.util.List;
 public class FrontPaperController {
     private final IDzControlService dzControlService;
     private final IDzSubjectService dzSubjectService;
+    private final PaperService paperService;
     private final ILearnTestService testService;
-    private final ILearnPaperService paperService;
     private final LearnTeacherService learnTeacherService;
-    private final ILearnPaperQuestionService paperQuestionService;
 
-    public FrontPaperController(IDzControlService dzControlService, IDzSubjectService dzSubjectService, ILearnTestService testService, ILearnPaperService paperService, LearnTeacherService learnTeacherService, ILearnPaperQuestionService paperQuestionService) {
+    public FrontPaperController(IDzControlService dzControlService, IDzSubjectService dzSubjectService, PaperService paperService, ILearnTestService testService, LearnTeacherService learnTeacherService) {
         this.dzControlService = dzControlService;
         this.dzSubjectService = dzSubjectService;
-        this.testService = testService;
         this.paperService = paperService;
+        this.testService = testService;
         this.learnTeacherService = learnTeacherService;
-        this.paperQuestionService = paperQuestionService;
     }
 
     @ApiOperation("01 考试批次")
@@ -62,17 +64,14 @@ public class FrontPaperController {
     }
 
     @ApiOperation("03 知识点树")
-    @GetMapping(value = "knownledge")
-    public AjaxResult getKnownledge(@ApiParam("科目ID") Long subjectId) {
-        return AjaxResult.success(learnTeacherService.getKnowledgeTree(subjectId, null));
+    @GetMapping(value = "knowledge")
+    public AjaxResult getKnowledge(@ApiParam("科目ID") Long subjectId) {
+        return AjaxResult.success(learnTeacherService.getKnowledgeTree(subjectId, null, true));
     }
 
     @ApiOperation("04 取试卷")
     @GetMapping(value = "paper")
     public AjaxResult loadPaper(@ApiParam("考卷类型PaperType") PaperType type, @ApiParam("考卷标识") Long id) {
-        LearnPaper paper = paperService.selectLearnPaperById(id);
-        JSONObject root = JSONObject.from(paper);
-        root.put("questions", paperQuestionService.selectLearnPaperQuestionById(id));
-        return AjaxResult.success(root);
+        return AjaxResult.success(paperService.loadPaper(id));
     }
 }

+ 3 - 5
ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnTeacherController.java

@@ -144,7 +144,7 @@ public class LearnTeacherController extends BaseController {
     @ApiOperation("知识点列表")
     public AjaxResult knowledges(@ApiParam("科目ID") Long subjectId, @RequestParam(required = false) @ApiParam("专业计划ID") Long[] majorPlanIds)
     {
-        return AjaxResult.success(learnTeacherService.getKnowledgeTree(subjectId, majorPlanIds));
+        return AjaxResult.success(learnTeacherService.getKnowledgeTree(subjectId, majorPlanIds, false));
     }
 
     @GetMapping("/questionTypes")
@@ -202,7 +202,6 @@ public class LearnTeacherController extends BaseController {
     }
 
 
-    @PreAuthorize("@ss.hasPermi('learn:test_paper:add')")
     @ApiOperation("04 取试卷列表")
     @GetMapping(value = "papers")
     public AjaxResult papers(@ApiParam("批次") @RequestParam(required = false) Integer batchId) {
@@ -210,11 +209,10 @@ public class LearnTeacherController extends BaseController {
         tpCond.setCreatorId(SecurityUtils.getUserId());
         tpCond.setBatchId(batchId);
         List<LearnTestPaper> testPaperList = testPaperService.selectLearnTestPaperList(tpCond);
-        List<JSONObject> paperList = Lists.newArrayList();
+        List<LearnPaper> paperList = Lists.newArrayList();
         for(LearnTestPaper tp : testPaperList) {
             JSONObject root = JSONObject.from(tp);
-            root.put("paper", paperService.selectLearnPaperById(tp.getPaperId()));
-            paperList.add(root);
+            paperList.add(paperService.selectLearnPaperById(tp.getPaperId()));
         }
         return AjaxResult.success(paperList);
     }

+ 90 - 15
ie-admin/src/main/java/com/ruoyi/web/service/ExamService.java

@@ -2,49 +2,66 @@ package com.ruoyi.web.service;
 
 import com.alibaba.fastjson2.util.DateUtils;
 import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
 import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.enums.ExamineeStatus;
 import com.ruoyi.enums.PaperStatus;
 import com.ruoyi.enums.PaperType;
+import com.ruoyi.ie.domain.AMarjorPlan;
+import com.ruoyi.ie.service.IAMarjorPlanService;
 import com.ruoyi.learn.domain.*;
 import com.ruoyi.learn.mapper.LearnExamineeMapper;
 import com.ruoyi.learn.mapper.LearnKnowledgeTreeMapper;
 import com.ruoyi.learn.mapper.LearnPaperMapper;
+import com.ruoyi.learn.service.ILearnPaperService;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import javax.validation.ValidationException;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.List;
+import java.util.Set;
 
 /**
  * 考试服务
  */
 @Service
 public class ExamService {
+    private Set<PaperType> paperTypeSet = Sets.newHashSet(PaperType.Real, PaperType.Custom, PaperType.Test);
     private final LearnPaperMapper paperMapper;
     private final LearnKnowledgeTreeMapper knowledgeTreeMapper;
     private final LearnExamineeMapper examineeMapper;
+    private final ILearnPaperService learnPaperService;
     private final PaperService paperService;
+    private final IAMarjorPlanService marjorPlanService;
 
-    public ExamService(LearnPaperMapper paperMapper, LearnKnowledgeTreeMapper knowledgeTreeMapper, LearnExamineeMapper examineeMapper, PaperService paperService) {
+    public ExamService(LearnPaperMapper paperMapper, LearnKnowledgeTreeMapper knowledgeTreeMapper, LearnExamineeMapper examineeMapper, ILearnPaperService learnPaperService, PaperService paperService, IAMarjorPlanService marjorPlanService) {
         this.paperMapper = paperMapper;
         this.knowledgeTreeMapper = knowledgeTreeMapper;
         this.examineeMapper = examineeMapper;
+        this.learnPaperService = learnPaperService;
         this.paperService = paperService;
+        this.marjorPlanService = marjorPlanService;
     }
 
     /**
      * 开卷 (卷, 实时组卷)
      * @return
      */
+    @Transactional(rollbackFor = Exception.class)
     public AnswerSheet openExaminee(PaperType paperType, Long relatedId) {
-        if(PaperType.Practice.equals(paperType)) { // TODO 先连接学生的定向信息
+        if(paperTypeSet.contains(paperType)) {
+            return openExaminee(paperType, relatedId, SecurityUtils.getUserId());
+        } else if(PaperType.Practice.equals(paperType)) { // TODO 先连接学生的定向信息
             return openExaminee(relatedId, SecurityUtils.getUserId(), "");
+        } else if(PaperType.Simulated.equals(paperType)) {
+            Integer cnt = 3;
+            return openExaminee(SecurityUtils.getUserId(), cnt);
         }
-        return openExaminee(paperType, relatedId, SecurityUtils.getUserId(), "");
+        throw new RuntimeException("错误类型: " + paperType);
     }
 
     /**
@@ -62,9 +79,7 @@ public class ExamService {
 
     }
 
-    public AnswerSheet openExaminee(PaperType paperType, Long paperId, Long studentId, String directKey) {
-        AnswerSheet answerSheet = new AnswerSheet();
-
+    private AnswerSheet openExaminee(PaperType paperType, Long paperId, Long studentId) {
         LearnPaper paper = paperMapper.selectLearnPaperById(paperId);
 
         LearnExaminee learnExaminee = new LearnExaminee();
@@ -80,17 +95,41 @@ public class ExamService {
             learnExaminee.setBeginTime(new Date());
             examineeMapper.insertLearnExaminee(learnExaminee);
         }
-        return answerSheet;
+        return buildAnswerSheet(paper, learnExaminee);
+    }
+
+    private AnswerSheet openExaminee(Long planId, Integer maxCount) {
+        LearnExaminee examinee = new LearnExaminee();
+        examinee.setStudentId(SecurityUtils.getLoginUser().getUser().getUserId());
+        examinee.setPaperType(PaperType.Simulated.getVal());
+        List<LearnExaminee> examineeList = examineeMapper.selectLearnExamineeList(examinee);
+        Set<Long> existPaperIdSet = Sets.newHashSet();
+        for(LearnExaminee e : examineeList) {
+            if(ExamineeStatus.Exam.getVal().equals(e.getState())) {
+                return buildAnswerSheet(learnPaperService.selectLearnPaperById(e.getPaperId()), e);
+            }
+            existPaperIdSet.add(e.getPaperId());
+        }
+        if(existPaperIdSet.size() >= maxCount) {
+            throw new ValidationException("超过最大次数限制" + maxCount );
+        }
+        AMarjorPlan plan = marjorPlanService.selectAMarjorPlanById(planId);
+        if(null == plan) {
+            throw new ValidationException("专业id无效");
+        }
+        LearnPaper paper = getBestPaper(plan, existPaperIdSet);
+        examinee.setPaperKey(PaperType.Simulated.name() + "_" + paper.getId());
+        examinee.setState(ExamineeStatus.Exam.getVal());
+        examinee.setBeginTime(new Date());
+        examineeMapper.insertLearnExaminee(examinee);
+        return buildAnswerSheet(paper, examinee);
     }
 
     /**
      * 根据知识点生成一次性练习卷并开始做题
      * @return
      */
-    @Transactional(rollbackFor = Exception.class)
-    public AnswerSheet openExaminee(Long knowledgeId, Long studentId, String directKey) {
-        AnswerSheet answerSheet = new AnswerSheet();
-
+    private AnswerSheet openExaminee(Long knowledgeId, Long studentId, String directKey) {
         LearnKnowledgeTree knowledgeTree = knowledgeTreeMapper.selectLearnKnowledgeTreeById(knowledgeId);
         LearnPaper paper = new LearnPaper();
         paper.setPaperType(PaperType.Practice.name());
@@ -100,14 +139,15 @@ public class ExamService {
         paper.setDirectKey(StringUtils.trimToEmpty(directKey));
         List<LearnPaper> paperList = paperMapper.selectLearnPaperList(paper);
         if (CollectionUtils.isNotEmpty(paperList)) { // 有未做完的
+            LearnPaper existPaper = paperList.get(0);
             LearnExaminee learnExaminee = new LearnExaminee();
             learnExaminee.setStudentId(studentId);
-            learnExaminee.setPaperId(paperList.get(0).getId());
+            learnExaminee.setPaperId(existPaper.getId());
             learnExaminee.setPaperType(PaperType.Practice.getVal());
             List<LearnExaminee> examineeList = examineeMapper.selectLearnExamineeList(learnExaminee);
             if (CollectionUtils.isNotEmpty(examineeList)) {
-                examineeList.get(0);
-                return answerSheet;
+                LearnExaminee examinee = examineeList.get(0);
+                return buildAnswerSheet(existPaper, examinee);
             }
             // 关闭试卷
             LearnPaper up = new LearnPaper();
@@ -125,7 +165,6 @@ public class ExamService {
         typeDefList.add(new TestPaperVO.TypeDef("判断题", "判断题", 10, 2));
         paperDef.setTypes(typeDefList);
         List<LearnPaperQuestion> pqList = paperService.getQuestions(studentId,  paperDef);
-
         paper.setPaperSource(0);
         paper.setSubjectId(knowledgeTree.getSubjectId());
         paper.setPaperName(studentId + "-" + knowledgeTree.getName() + "-" + DateUtils.format(new Date(), "yyyyMMddHHmmss"));
@@ -138,6 +177,42 @@ public class ExamService {
         learnExaminee.setState(ExamineeStatus.Exam.getVal());
         learnExaminee.setBeginTime(new Date());
         examineeMapper.insertLearnExaminee(learnExaminee);
+        return buildAnswerSheet(paper, learnExaminee);
+    }
+
+    private LearnPaper getBestPaper(AMarjorPlan plan, Set<Long> existPaperIdSet) {
+        String groupName = StringUtils.trimToEmpty(plan.getMajorGroup());
+        LearnPaper paperCond = new LearnPaper();
+        paperCond.setPaperType(PaperType.Simulated.name());
+        for(int i = 3; i>0; i--) {
+            if(i == 3) {
+                paperCond.setDirectKey(plan.getUniversityId() + "_" + groupName + "_" + plan.getMajorName());
+            } else if(i == 2) {
+                paperCond.setDirectKey(plan.getUniversityId() + "_" + groupName);
+            } else if(StringUtils.isBlank(groupName)) {
+                break;
+            }
+            List<LearnPaper> paperList = learnPaperService.selectLearnPaperList(paperCond);
+            for(LearnPaper paper : paperList) {
+                if(existPaperIdSet.add(paper.getId())) {
+                    return paper;
+                }
+            }
+        }
+        throw new ValidationException("未初始化院校定向模拟题库: " + plan.getId());
+    }
+
+    private AnswerSheet buildAnswerSheet(LearnPaper paper, LearnExaminee examinee) {
+        AnswerSheet answerSheet = new AnswerSheet();
+        answerSheet.setExamineeId(examinee.getExamineeId());
+        answerSheet.setPaperId(examinee.getPaperId());
+        answerSheet.setName(paper.getPaperName());
+        answerSheet.setBeginTime(examinee.getBeginTime());
+        answerSheet.setScoringType("1");
+        answerSheet.setMode(0L);
+        answerSheet.setState(examinee.getState());
+        answerSheet.setAllowAnswer(true);
+        answerSheet.setAllowScore(false);
         return answerSheet;
     }
 }

+ 45 - 15
ie-admin/src/main/java/com/ruoyi/web/service/LearnTeacherService.java

@@ -1,10 +1,10 @@
 package com.ruoyi.web.service;
 
 import cn.hutool.core.lang.Dict;
+import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
-import com.ruoyi.common.annotation.Excel;
-import com.ruoyi.common.core.domain.TreeEntity;
+import com.ruoyi.common.utils.NumberUtils;
 import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.dz.domain.DzClasses;
 import com.ruoyi.dz.mapper.DzClassesMapper;
@@ -12,14 +12,10 @@ import com.ruoyi.enums.PaperType;
 import com.ruoyi.ie.domain.AMarjorPlan;
 import com.ruoyi.ie.mapper.AMarjorPlanMapper;
 import com.ruoyi.learn.domain.*;
-import com.ruoyi.learn.mapper.LearnDirectedKnowledgeMapper;
-import com.ruoyi.learn.mapper.LearnKnowledgeTreeMapper;
-import com.ruoyi.learn.mapper.LearnStudentMapper;
-import com.ruoyi.learn.mapper.LearnTestPaperMapper;
+import com.ruoyi.learn.mapper.*;
 import com.ruoyi.syzy.domain.BBusiWishUniversities;
 import com.ruoyi.syzy.mapper.BBusiWishUniversitiesMapper;
 import lombok.Data;
-import org.apache.commons.compress.utils.Lists;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
@@ -45,8 +41,9 @@ public class LearnTeacherService {
     private final LearnDirectedKnowledgeMapper learnDirectedKnowledgeMapper;
     private final PaperService paperService;
     private final LearnTestPaperMapper learnTestPaperMapper;
+    private final LearnQuestionsMapper learnQuestionsMapper;
 
-    public LearnTeacherService(DzClassesMapper dzClassesMapper, LearnKnowledgeTreeMapper learnKnowledgeTreeMapper, LearnStudentMapper learnStudentMapper, AMarjorPlanMapper marjorPlanMapper, BBusiWishUniversitiesMapper busiWishUniversitiesMapper, LearnDirectedKnowledgeMapper learnDirectedKnowledgeMapper, PaperService paperService, LearnTestPaperMapper learnTestPaperMapper) {
+    public LearnTeacherService(DzClassesMapper dzClassesMapper, LearnKnowledgeTreeMapper learnKnowledgeTreeMapper, LearnStudentMapper learnStudentMapper, AMarjorPlanMapper marjorPlanMapper, BBusiWishUniversitiesMapper busiWishUniversitiesMapper, LearnDirectedKnowledgeMapper learnDirectedKnowledgeMapper, PaperService paperService, LearnTestPaperMapper learnTestPaperMapper, LearnQuestionsMapper learnQuestionsMapper) {
         this.dzClassesMapper = dzClassesMapper;
         this.learnKnowledgeTreeMapper = learnKnowledgeTreeMapper;
         this.learnStudentMapper = learnStudentMapper;
@@ -55,6 +52,7 @@ public class LearnTeacherService {
         this.learnDirectedKnowledgeMapper = learnDirectedKnowledgeMapper;
         this.paperService = paperService;
         this.learnTestPaperMapper = learnTestPaperMapper;
+        this.learnQuestionsMapper = learnQuestionsMapper;
     }
 
     public List<DzClasses> getClasses(Long teacherId)
@@ -270,7 +268,26 @@ public class LearnTeacherService {
         return "";
     }
 
-    public List<TreeNode> getKnowledgeTree(Long subjectId, Long[] planIds) {
+    public List<TreeNode> getKnowledgeTree(Long subjectId, Long[] planIds, boolean count) {
+        Set<Long> knowledgeIdSet = getKnowledgeIdSet(planIds);
+        LearnKnowledgeTree ktCond = new LearnKnowledgeTree();
+        ktCond.setSubjectId(subjectId);
+        List<LearnKnowledgeTree> ktList = learnKnowledgeTreeMapper.selectLearnKnowledgeTreeList(ktCond);
+        Map<Long, Integer> knowCountMap = null;
+        if(count) {
+            Map cond = Maps.newHashMap();
+            cond.put("studentId", SecurityUtils.getUserId());
+            cond.put("knowIds", ktList.stream().map(LearnKnowledgeTree::getId).collect(Collectors.toList()));
+            cond.put("types", Lists.newArrayList("单选题", "判断题"));
+            knowCountMap = Maps.newHashMap();
+            for(LearnQuestions qs : learnQuestionsMapper.statByKnowledge(cond)) {
+                knowCountMap.put(qs.getKnowledgeId(), qs.getNumber().intValue());
+            }
+        }
+        return buildTree(ktList, knowledgeIdSet, knowCountMap);
+    }
+
+    public Set<Long> getKnowledgeIdSet(Long[] planIds) {
         Set<Long> knowledgeIdSet = Sets.newHashSet();
         if(ArrayUtils.isNotEmpty(planIds)) {
             List<AMarjorPlan> planList = marjorPlanMapper.selectAMarjorPlanByIds(planIds);
@@ -289,17 +306,27 @@ public class LearnTeacherService {
                 }
             }
         }
-        LearnKnowledgeTree ktCond = new LearnKnowledgeTree();
-        ktCond.setSubjectId(subjectId);
-        List<LearnKnowledgeTree> ktList = learnKnowledgeTreeMapper.selectLearnKnowledgeTreeList(ktCond);
+        return knowledgeIdSet;
+    }
+
+    public List<TreeNode> buildTree(List<LearnKnowledgeTree> ktList, Set<Long> knowledgeIdSet, Map<Long, Integer> knowCountMap) {
         List<TreeNode> treeNodeList = Lists.newArrayList();
-        Map<Long, TreeNode> teMap = ktList.stream().collect(Collectors.toMap(LearnKnowledgeTree::getId, t -> new TreeNode(t.getId(), t.getName())));
+        Map<Long, TreeNode> teMap = Maps.newHashMap();
+        for(LearnKnowledgeTree kt : ktList) {
+            TreeNode tn = new TreeNode(kt.getId(), kt.getName(), knowCountMap.get(kt.getId()));
+            teMap.put(kt.getId(), tn);
+        }
         for(LearnKnowledgeTree kt : ktList) {
             if(null == kt.getPid()) {
                 treeNodeList.add(teMap.get(kt.getId()));
                 continue;
             }
-            teMap.get(kt.getPid()).getChildren().add(teMap.get(kt.getId()));
+            TreeNode parent = teMap.get(kt.getPid());
+            TreeNode node = teMap.get(kt.getId());
+            if(null != node.getQuestionCount()) {
+                parent.setQuestionCount(parent.getQuestionCount() + node.getQuestionCount());
+            }
+            parent.getChildren().add(node);
         }
         for(TreeNode tn : treeNodeList) {
             tn.setChecked(knowledgeIdSet);
@@ -312,11 +339,14 @@ public class LearnTeacherService {
         private Long id;
         private String name;
         private Integer status;
+        private Integer questionCount;
+
         List<TreeNode> children = Lists.newArrayList();
-        public TreeNode(Long id, String name) {
+        public TreeNode(Long id, String name, Integer questionCount) {
             this.id = id;
             this.name = name;
             this.status = 0;
+            this.questionCount = null != questionCount ? questionCount : 0;
         }
 
         public boolean setChecked(Set<Long> idSet) {

+ 29 - 6
ie-admin/src/main/java/com/ruoyi/web/service/PaperService.java

@@ -11,6 +11,8 @@ import com.ruoyi.enums.PaperType;
 import com.ruoyi.learn.domain.*;
 import com.ruoyi.learn.mapper.*;
 import lombok.Data;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.springframework.stereotype.Service;
 
@@ -56,11 +58,26 @@ public class PaperService {
         LearnPaper learnPaper = paperMapper.selectLearnPaperById(paperId);
         BeanUtils.copyProperties(learnPaper, result);
         List<LearnQuestions> questions = questionsMapper.selectQuestionByPaperId(paperId);
-        result.setQuestions(questions.stream().map(t -> {
+        Map<String, PaperVO.QuestionSeq> gropuMap = Maps.newHashMap();
+        List<PaperVO.QuestionSeq> paperQuestionList = Lists.newArrayList();
+        for(LearnQuestions lqs : questions) {
             PaperVO.QuestionSeq qs = new PaperVO.QuestionSeq();
-            BeanUtils.copyProperties(t, qs);
-            return qs;
-        }).collect(Collectors.toList()));
+            BeanUtils.copyProperties(lqs, qs);
+            if(StringUtils.isNotBlank(lqs.getTitle0())) { // 大题
+                PaperVO.QuestionSeq qg = gropuMap.get(lqs.getTitle0());
+                if(qg == null) {
+                    qg = new PaperVO.QuestionSeq();
+                    qg.setTitle(lqs.getTitle0());
+                    gropuMap.put(lqs.getTitle0(), qg);
+                    paperQuestionList.add(qg);
+                }
+                qs.setTitle0(null); // 清除
+                qg.getSubQuestions().add(qs);
+            } else {
+                paperQuestionList.add(qs);
+            }
+        }
+        result.setQuestions(paperQuestionList);
         return result;
     }
 
@@ -184,6 +201,9 @@ public class PaperService {
             for (Long knowId : paperDef.getKnowIds()) {
                 String key = knowId + "_" + typeDef.getType();
                 KnowTypeAssign ktc = knowTypeAssignMap.get(key);
+                if(null == ktc) {
+                    continue;
+                }
                 qCond.setKnowledgeId(ktc.getKnowId());
                 qCond.setQtpye(ktc.getType());
                 if(ktc.exclAssign > 0){
@@ -201,6 +221,9 @@ public class PaperService {
 
             }
         }
+        if(CollectionUtils.isEmpty(pqList)) {
+            throw new RuntimeException("题数不足");
+        }
         return pqList;
     }
 
@@ -235,7 +258,7 @@ public class PaperService {
         String key = knowId + "_" + qtype;
         KnowTypeAssign knowTypeAssign = knowTypeAssignMap.get(key);
         long lackCount;
-        if (knowTypeAssign.exclCount > 0) {
+        if (null != knowTypeAssign && knowTypeAssign.exclCount > 0) {
             lackCount = knowTypeCount - knowTypeAssign.exclCount;
             if (lackCount <= 0) { // 足量
                 assignCount.getAndAdd(knowTypeCount);
@@ -251,7 +274,7 @@ public class PaperService {
         }
         long lack = 0;
         if (lackCount > 0) { // 差额优先补充已做过的
-            if(fillExclude && knowTypeAssign.total > 0) {
+            if(fillExclude && null != knowTypeAssign && knowTypeAssign.total > 0) {
                 lack = lackCount - knowTypeAssign.total;
                 if (lack <= 0) { // 足量
                     assignCount.getAndAdd(lackCount);

+ 36 - 0
ie-system/src/main/java/com/ruoyi/enums/QuestionType.java

@@ -0,0 +1,36 @@
+package com.ruoyi.enums;
+
+import com.google.common.collect.Maps;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+import java.util.Map;
+
+@AllArgsConstructor
+@Getter
+public enum QuestionType {
+    Single(1, "单选题"), Multiple(2, "多选题"), Judgment(3, "判断题"), Fill(4, "填空题"),
+    Subjective(5, "主观题");
+
+    private final Integer val;
+    private final String name;
+
+    private static final Map<String, QuestionType> valMap = Maps.newHashMap();
+
+    public static QuestionType of(Integer vol) {
+        return valMap.get(vol.toString());
+    }
+
+    public static QuestionType of(String vol) {
+        QuestionType type = valMap.get(vol);
+        return null == type ? QuestionType.Subjective : type;
+    }
+
+    static {
+        Arrays.stream(QuestionType.values()).forEach(t -> {
+            valMap.put(t.val.toString(), t);
+            valMap.put(t.name(), t);
+        });
+    }
+}

+ 3 - 1
ie-system/src/main/java/com/ruoyi/learn/domain/AnswerSheet.java

@@ -4,10 +4,12 @@ import com.fasterxml.jackson.annotation.JsonFormat;
 import com.ruoyi.common.annotation.Excel;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
 
 import java.util.Date;
 
 @ApiModel("答题卷")
+@Data
 public class AnswerSheet {
     @ApiModelProperty("考生答题卡")
     Long examineeId;
@@ -28,7 +30,7 @@ public class AnswerSheet {
     @ApiModelProperty("考场分钟 90, 120, xxx")
     private Long mode;
     @ApiModelProperty("答卷状态 examinee_status")
-    Long state;
+    Integer state;
     @ApiModelProperty("答卷状态名称")
     String stateStr;
     @ApiModelProperty("是否可答题")

+ 2 - 0
ie-system/src/main/java/com/ruoyi/learn/domain/PaperVO.java

@@ -26,5 +26,7 @@ public class PaperVO {
     public static class QuestionSeq extends LearnQuestions {
         @ApiModelProperty("序号")
         Integer seq;
+
+        List<QuestionSeq> subQuestions;
     }
 }

+ 0 - 8
ie-system/src/main/java/com/ruoyi/learn/mapper/LearnPaperQuestionMapper.java

@@ -2,7 +2,6 @@ package com.ruoyi.learn.mapper;
 
 import java.util.List;
 import com.ruoyi.learn.domain.LearnPaperQuestion;
-import com.ruoyi.learn.domain.LearnQuestions;
 
 /**
  * 试卷题关系Mapper接口
@@ -59,11 +58,4 @@ public interface LearnPaperQuestionMapper
      * @return 结果
      */
     public int deleteLearnPaperQuestionByIds(Long[] ids);
-
-    /**
-     * 查询卷的题
-     * @param paperId
-     * @return
-     */
-    public List<LearnQuestions> selectQuestionByPaperId(Long paperId);
 }

+ 1 - 0
ie-system/src/main/java/com/ruoyi/learn/mapper/LearnQuestionsMapper.java

@@ -64,6 +64,7 @@ public interface LearnQuestionsMapper
     public List<LearnQuestions> selectQuestionByPaperId(Long paperId);
 
     public List<LearnQuestions> statByKnowledgeType(Map cond);
+    public List<LearnQuestions> statByKnowledge(Map cond);
 
     public List<LearnQuestions> selectQuestionsForPaper(LearnQuestions cond);
 }

+ 0 - 3
ie-system/src/main/java/com/ruoyi/learn/service/ILearnPaperQuestionService.java

@@ -2,7 +2,6 @@ package com.ruoyi.learn.service;
 
 import java.util.List;
 import com.ruoyi.learn.domain.LearnPaperQuestion;
-import com.ruoyi.learn.domain.LearnQuestions;
 
 /**
  * 试卷题关系Service接口
@@ -59,6 +58,4 @@ public interface ILearnPaperQuestionService
      * @return 结果
      */
     public int deleteLearnPaperQuestionById(Long id);
-
-    public List<LearnQuestions> selectQuestionByPaperId(Long paperId);
 }

+ 0 - 6
ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnPaperQuestionServiceImpl.java

@@ -2,7 +2,6 @@ package com.ruoyi.learn.service.impl;
 
 import java.util.List;
 import com.ruoyi.common.utils.DateUtils;
-import com.ruoyi.learn.domain.LearnQuestions;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.ruoyi.learn.mapper.LearnPaperQuestionMapper;
@@ -93,9 +92,4 @@ public class LearnPaperQuestionServiceImpl implements ILearnPaperQuestionService
     {
         return learnPaperQuestionMapper.deleteLearnPaperQuestionById(id);
     }
-
-    @Override
-    public List<LearnQuestions> selectQuestionByPaperId(Long paperId) {
-        return learnPaperQuestionMapper.selectQuestionByPaperId(paperId);
-    }
 }

+ 16 - 4
ie-system/src/main/resources/mapper/learn/LearnQuestionsMapper.xml

@@ -275,8 +275,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
           order by pq.`seq`, q.`id`
     </select>
 
+    <select id="statByKnowledge" parameterType="map" resultMap="LearnQuestionsResult">
+        SELECT kq.knowledge_id `knowledgeId`, COUNT(DISTINCT kq.`question_id`) number, COUNT(DISTINCT IF(a.`student_id` IS NOT NULL, kq.`question_id`, NULL)) id
+        FROM `learn_knowledge_question` kq
+        LEFT JOIN `learn_answer` a ON kq.`question_id` = a.`question_id` AND a.`student_id` = #{studentId}
+        JOIN `learn_questions` q ON q.`id` = kq.`question_id`
+        <where>
+            <if test="knowIds != null"> and kq.`knowledge_id` in <foreach item="id" collection="knowIds" open="(" separator="," close=")">#{id}</foreach></if>
+            <if test="types != null"> and q.`qtpye` in <foreach item="id" collection="types" open="(" separator="," close=")">#{id}</foreach></if>
+        </where>
+        GROUP BY kq.`knowledge_id`
+    </select>
+
     <select id="statByKnowledgeType" parameterType="map" resultMap="LearnQuestionsResult">
-       SELECT q.`knowledgeId`, q.`qtpye`, COUNT(*) number
+       SELECT kq.knowledge_id `knowledgeId`, q.`qtpye`, COUNT(*) number
          FROM `learn_knowledge_question` kq
          <if test="studentId != null">
              LEFT JOIN `learn_answer` a ON kq.`question_id` = a.`question_id` AND a.`student_id` = #{studentId}
@@ -287,11 +299,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="types != null"> and q.`qtpye` in <foreach item="id" collection="types" open="(" separator="," close=")">#{id}</foreach></if>
             <if test="studentId != null"> AND a.`student_id` IS NULL</if>
         </where>
-        GROUP BY q.`knowledgeId`, q.`qtpye`
+        GROUP BY kq.knowledge_id, q.`qtpye`
     </select>
 
     <select id="selectQuestionsForPaper" parameterType="LearnQuestions" resultMap="LearnQuestionsResult">
-        SELECT q.`id`, q.`knowledgeId`
+        SELECT q.`id`, kq.knowledge_id `knowledgeId`
         FROM `learn_knowledge_question` kq
         <if test="id != null">
             LEFT JOIN `learn_answer` a ON kq.`question_id` = a.`question_id` AND a.`student_id` = #{id}
@@ -300,7 +312,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <where>
             <if test="qtpye != null  and qtpye != ''"> and qtpye = #{qtpye}</if>
             <if test="id != null ">  AND a.`student_id` IS NULL</if>
-            <if test="knowledgeId != null "> and knowledgeId = #{knowledgeId}</if>
+            <if test="knowledgeId != null "> and kq.knowledge_id  = #{knowledgeId}</if>
         </where>
         limit #{number}, 500
     </select>