mingfu 3 недель назад
Родитель
Сommit
28bf9adf2d

+ 2 - 1
ie-admin/src/main/java/com/ruoyi/web/controller/front/FrontExamController.java

@@ -4,6 +4,7 @@ import com.alibaba.fastjson2.JSONObject;
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.core.domain.AjaxResult2;
 import com.ruoyi.common.core.domain.entity.SysUser;
+import com.ruoyi.common.enums.ExamType;
 import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.dz.domain.DzSubject;
 import com.ruoyi.dz.service.IDzControlService;
@@ -48,7 +49,7 @@ public class FrontExamController {
     public AjaxResult subjects()
     {
         SysUser sysUser = SecurityUtils.getLoginUser().getUser();
-        List<DzSubject> list = dzSubjectService.selectDzSubjectBySubjectIds(new Long[] {1L, 2L, 3L, 11L});
+        List<DzSubject> list = dzSubjectService.selectDzSubjectBySubjectIds(ExamType.OHS.equals(sysUser.getExamType()) ? new Long[] {1L, 2L, 3L, 11L} : new Long[] {11L});
         JSONObject evalCounts = JSONObject.parseObject(sysUserService.selectUserById(sysUser.getUserId()).getEvalCounts());
         return AjaxResult.success(list.stream().map(t -> {
             JSONObject o = new JSONObject();

+ 57 - 11
ie-admin/src/main/java/com/ruoyi/web/service/ExamService.java

@@ -6,8 +6,11 @@ import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 import com.ruoyi.common.core.domain.entity.SysUser;
+import com.ruoyi.common.enums.ExamType;
 import com.ruoyi.common.enums.UserRegStatus;
 import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.dz.service.IDzSubjectService;
+import com.ruoyi.dz.service.impl.DzSubjectServiceImpl;
 import com.ruoyi.enums.ExamineeStatus;
 import com.ruoyi.enums.PaperStatus;
 import com.ruoyi.enums.PaperType;
@@ -20,6 +23,7 @@ import com.ruoyi.learn.service.ILearnPaperService;
 import com.ruoyi.learn.service.ILearnPlanService;
 import com.ruoyi.mxjb.domain.MxjbContants;
 import com.ruoyi.system.service.ISysUserService;
+import io.swagger.annotations.ApiModelProperty;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
@@ -39,6 +43,7 @@ public class ExamService {
     private final LearnStudentMapper learnStudentMapper;
     private final ILearnPlanService learnPlanService;
     private final LearnQuestionsMapper learnQuestionsMapper;
+    private final IDzSubjectService dzSubjectService;
     private Set<PaperType> paperTypeSet = Sets.newHashSet(PaperType.Real, PaperType.Custom, PaperType.Test);
     private final LearnPaperMapper paperMapper;
     private final LearnKnowledgeTreeMapper knowledgeTreeMapper;
@@ -50,7 +55,7 @@ public class ExamService {
     private final IAMarjorPlanService marjorPlanService;
     private final ISysUserService sysUserService;
 
-    public ExamService(LearnPaperMapper paperMapper, LearnKnowledgeTreeMapper knowledgeTreeMapper, LearnExamineeMapper examineeMapper, ILearnPaperService learnPaperService, PaperService paperService, IAMarjorPlanService marjorPlanService, LearnAnswerMapper learnAnswerMapper, LearnExamineeMapper learnExamineeMapper, ISysUserService sysUserService, LearnStudentMapper learnStudentMapper, ILearnPlanService learnPlanService, LearnQuestionsMapper learnQuestionsMapper, LearnWrongBookMapper wrongBookMapper, LearnWrongDetailMapper wrongDetailMapper) {
+    public ExamService(LearnPaperMapper paperMapper, LearnKnowledgeTreeMapper knowledgeTreeMapper, LearnExamineeMapper examineeMapper, ILearnPaperService learnPaperService, PaperService paperService, IAMarjorPlanService marjorPlanService, LearnAnswerMapper learnAnswerMapper, LearnExamineeMapper learnExamineeMapper, ISysUserService sysUserService, LearnStudentMapper learnStudentMapper, ILearnPlanService learnPlanService, LearnQuestionsMapper learnQuestionsMapper, IDzSubjectService dzSubjectService, LearnWrongBookMapper wrongBookMapper, LearnWrongDetailMapper wrongDetailMapper) {
         this.paperMapper = paperMapper;
         this.knowledgeTreeMapper = knowledgeTreeMapper;
         this.examineeMapper = examineeMapper;
@@ -63,6 +68,7 @@ public class ExamService {
         this.learnStudentMapper = learnStudentMapper;
         this.learnPlanService = learnPlanService;
         this.learnQuestionsMapper = learnQuestionsMapper;
+        this.dzSubjectService = dzSubjectService;
         this.wrongBookMapper = wrongBookMapper;
         this.wrongDetailMapper = wrongDetailMapper;
     }
@@ -90,7 +96,7 @@ public class ExamService {
             if(null == ls) {
                 throw new RuntimeException("请先定设置定向学习" + exist.getUserId());
             }
-            return openExaminee(ls.getMajorPlanId(), subjectId, exist);
+            return openExaminee(ls, subjectId, exist);
         }
         throw new RuntimeException("错误类型: " + paperType);
     }
@@ -127,6 +133,16 @@ public class ExamService {
         answerSheet.setTotalCount(questionList.size());
         answerSheet.setWrongCount(examinee.getWrongCount());
         answerSheet.setQuestions(questionList);
+
+        if(null != examinee.getPaperInfo()) {
+            JSONObject info = JSONObject.parseObject(examinee.getPaperInfo());
+            answerSheet.setCollegeId(info.getLong("universityId"));
+            answerSheet.setCollegeName(info.getString("universityName"));
+            answerSheet.setMajorId(info.getLong("planId"));
+            answerSheet.setMajorName(info.getString("majorName"));
+            answerSheet.setSubjectId(learnPaper.getSubjectId());
+            answerSheet.setSubjectName(dzSubjectService.selectDzSubjectBySubjectId(learnPaper.getSubjectId()).getSubjectName());
+        }
         return answerSheet;
     }
 
@@ -188,6 +204,15 @@ public class ExamService {
             upExaminee.setEndTime(new Date());
             upExaminee.setState(ExamineeStatus.Commit.getVal());
             upExaminee.setWrongCount(wrongCount);
+            if(PaperType.Simulated.getVal().equals(exitExaminee.getPaperType())) {
+                JSONObject stats = new JSONObject();
+                stats.put("score", 100);
+                stats.put("rate", 50);
+                stats.put("maxScore", 300);
+                stats.put("averageScore", 100);
+                stats.put("hitRate", 50);
+                upExaminee.setStats(JSONObject.toJSONString(stats));
+            }
         }
         learnExamineeMapper.updateLearnExaminee(upExaminee);
         if(answerSheet.getIsDone()) {
@@ -305,8 +330,8 @@ public class ExamService {
         return buildAnswerSheet(paper, learnExaminee);
     }
 
-    private AnswerSheet openExaminee(Long planId, Long subjectId, SysUser sysUser) {
-        AMarjorPlan plan = marjorPlanService.selectAMarjorPlanById(planId);
+    private AnswerSheet openExaminee(LearnStudent ls, Long subjectId, SysUser sysUser) {
+        AMarjorPlan plan = marjorPlanService.selectAMarjorPlanById(ls.getMajorPlanId());
         if(null == plan) {
             throw new ValidationException("专业id无效");
         }
@@ -330,11 +355,28 @@ public class ExamService {
         upUser.setEvalCounts(evalCountObj.toJSONString());
         sysUserService.updateUserProfile(upUser);
 
-        LearnPaper paper = getBestPaper(plan, subjectId, existPaperIdSet);
+        LearnPaper paper = getBestPaper(sysUser.getExamType(), plan, subjectId, existPaperIdSet);
+        examinee.setPaperId(paper.getId());
         examinee.setState(ExamineeStatus.Sign.getVal());
         examinee.setDuration(0L);
+
+        JSONObject info = new JSONObject();
+        info.put("universityId", ls.getUniversityId());
+        info.put("universityName", plan.getUniversityName());
+        info.put("planId", ls.getMajorPlanId());
+        info.put("majorName", plan.getMajorName());
+        examinee.setPaperInfo(info.toJSONString());
         examineeMapper.insertLearnExaminee(examinee);
-        return buildAnswerSheet(paper, examinee);
+        AnswerSheet answerSheet = buildAnswerSheet(paper, examinee);
+
+        answerSheet.setCollegeId(ls.getUniversityId());
+        answerSheet.setCollegeName(plan.getUniversityName());
+        answerSheet.setMajorId(ls.getMajorPlanId());
+        answerSheet.setMajorName(plan.getMajorName());
+        answerSheet.setSubjectId(paper.getSubjectId());
+        answerSheet.setSubjectName(dzSubjectService.selectDzSubjectBySubjectId(paper.getSubjectId()).getSubjectName());
+        return answerSheet;
+
     }
 
     /**
@@ -386,6 +428,7 @@ public class ExamService {
         paperDef.setTypes(typeDefList);
         List<LearnPaperQuestion> pqList = paperService.getQuestions(studentId,  paperDef);
         paper.setPaperSource(0);
+        paper.setFenshu(0);
         paper.setSubjectId(knowledgeTree.getSubjectId());
         paper.setPaperName(studentId + "-" + knowledgeTree.getName() + "-" + DateUtils.format(new Date(), "yyyyMMddHHmmss"));
         paper.setRelateId(knowledgeId);
@@ -406,18 +449,21 @@ public class ExamService {
         return answerSheet;
     }
 
-    private LearnPaper getBestPaper(AMarjorPlan plan, Long subjectId, Set<Long> existPaperIdSet) {
+    private LearnPaper getBestPaper(ExamType examType, AMarjorPlan plan, Long subjectId, Set<Long> existPaperIdSet) {
         String groupName = StringUtils.trimToEmpty(plan.getMajorGroup());
         LearnPaper paperCond = new LearnPaper();
         paperCond.setSubjectId(subjectId);
         paperCond.setPaperType(PaperType.Simulated.name());
+        String baseKey = plan.getUniversityId() + "_" + examType.name();
         for(int i = 3; i>0; i--) {
             if(i == 3) {
-                paperCond.setDirectKey(plan.getUniversityId() + "_" + groupName + "_" + plan.getMajorName());
+                paperCond.setDirectKey(baseKey + "_" + groupName + "_" + plan.getMajorName());
             } else if(i == 2) {
-                paperCond.setDirectKey(plan.getUniversityId() + "_" + groupName);
+                paperCond.setDirectKey(baseKey + "_" + groupName);
             } else if(StringUtils.isBlank(groupName)) {
                 break;
+            } else {
+                paperCond.setDirectKey(baseKey);
             }
             List<LearnPaper> paperList = learnPaperService.selectLearnPaperList(paperCond);
             for(LearnPaper paper : paperList) {
@@ -436,8 +482,8 @@ public class ExamService {
         answerSheet.setName(paper.getPaperName());
         answerSheet.setBeginTime(examinee.getBeginTime());
         answerSheet.setDuration(examinee.getDuration());
-        if(StringUtils.isNotBlank(paper.getConditions())) {
-            answerSheet.setConditions(JSONObject.parseObject(paper.getConditions(), AnswerSheet.PaperCond.class));
+        if(StringUtils.isNotBlank(paper.getPaperInfo())) {
+            answerSheet.setConditions(JSONObject.parseObject(paper.getPaperInfo(), AnswerSheet.PaperCond.class));
         }
         answerSheet.setScoringType("1");
         answerSheet.setMode(0L);

+ 3 - 0
ie-admin/src/main/java/com/ruoyi/web/service/LearnTeacherService.java

@@ -98,6 +98,7 @@ public class LearnTeacherService {
             paper.setPaperType(PaperType.Test.name());
             paper.setSubjectId(req.getSubjectId());
             paper.setDirectKey("");
+            paper.setFenshu(0);
             for(Long universityId : universityMap.keySet()) {
                 Map<String, LearnTestPaper> directPaperMap = universityDirectPaperMap.get(universityId);
                 if(null != directPaperMap && directPaperMap.containsKey("")) {
@@ -161,6 +162,7 @@ public class LearnTeacherService {
                 paper.setYear(plan.getYear());
                 paper.setPaperType(PaperType.Test.name());
                 paper.setDirectKey(directedKey);
+                paper.setFenshu(0);
                 Pair<LearnPaper, List<LearnPaperQuestion>> paperResult = paperService.buildPaper(null, paper, paperDef);
                 paperService.savePaper(paperResult.getKey(), paperResult.getValue());
 
@@ -208,6 +210,7 @@ public class LearnTeacherService {
         if(null == req.getDirectType() || !req.getDirectType()) { // 全量
             paper.setSubjectId(req.getSubjectId());
             paper.setDirectKey("");
+            paper.setFenshu(0);
             for(Long universityId : universityMap.keySet()) {
                 Map<String, LearnTestPaper> directPaperMap = universityDirectPaperMap.get(universityId);
                 if(null != directPaperMap && directPaperMap.containsKey("")) {

+ 123 - 32
ie-admin/src/main/java/com/ruoyi/web/service/PaperService.java

@@ -13,6 +13,8 @@ import com.ruoyi.enums.QuestionType;
 import com.ruoyi.learn.domain.*;
 import com.ruoyi.learn.mapper.*;
 import com.ruoyi.learn.service.ILearnQuestionsService;
+import com.ruoyi.syzy.domain.BBusiWishUniversities;
+import com.ruoyi.syzy.service.IBBusiWishUniversitiesService;
 import lombok.Data;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.tuple.Pair;
@@ -32,13 +34,18 @@ public class PaperService {
     private final LearnPaperQuestionMapper paperQuestionMapper;
     private final LearnQuestionsMapper questionsMapper;
     private final ILearnQuestionsService learnQuestionsService;
+    private final LearnDirectedKnowledgeMapper learnDirectedKnowledgeMapper;
+    private final IBBusiWishUniversitiesService wishUniversitiesService;
 
 
-    PaperService(LearnPaperMapper paperMapper, LearnPaperQuestionMapper paperQuestionMapper, LearnQuestionsMapper questionsMapper, ILearnQuestionsService learnQuestionsService) {
+    PaperService(LearnPaperMapper paperMapper, LearnPaperQuestionMapper paperQuestionMapper, LearnQuestionsMapper questionsMapper, ILearnQuestionsService learnQuestionsService, LearnDirectedKnowledgeMapper learnDirectedKnowledgeMapper, IBBusiWishUniversitiesService wishUniversitiesService) {
         this.paperMapper = paperMapper;
         this.paperQuestionMapper = paperQuestionMapper;
         this.questionsMapper = questionsMapper;
         this.learnQuestionsService = learnQuestionsService;
+        this.learnDirectedKnowledgeMapper = learnDirectedKnowledgeMapper;
+        // buildSimulatedPaper(20154L, 11L);
+        this.wishUniversitiesService = wishUniversitiesService;
     }
 
     public void test() {
@@ -139,6 +146,43 @@ public class PaperService {
      * 根据院校专业要求生成模拟试卷
      * @return
      */
+
+    public int buildSimulatedPaper(Long universityId, Long subjectId) {
+        LearnDirectedKnowledge dkCond = new LearnDirectedKnowledge();
+        dkCond.setUniversityId(universityId);
+        List<LearnDirectedKnowledge> directedKnowledgeList = learnDirectedKnowledgeMapper.selectLearnDirectedKnowledgeList(dkCond);
+        BBusiWishUniversities universities = wishUniversitiesService.selectBBusiWishUniversitiesById(universityId);
+        for(LearnDirectedKnowledge dk : directedKnowledgeList) {
+            TestPaperVO.PaperDef paperDef = new TestPaperVO.PaperDef();
+            paperDef.setTotal(120L);  // 120题
+            paperDef.setFillExclude(false);
+            paperDef.setKnowIds(Stream.of(dk.getKnowledges().split(",")).map(Long::parseLong).collect(Collectors.toList()));
+            List<TestPaperVO.TypeDef> typeDefList= Lists.newArrayList();
+            typeDefList.add(new TestPaperVO.TypeDef("单选题", "单选题", 40, 3));
+            typeDefList.add(new TestPaperVO.TypeDef("多选题", "多选题", 40, 3));
+            typeDefList.add(new TestPaperVO.TypeDef("判断题", "判断题", 40, 3));
+            paperDef.setTypes(typeDefList);
+
+            LearnPaper paper = new LearnPaper();
+            paper.setSubjectId(subjectId);
+            paper.setPaperName(StringUtils.isNotBlank(dk.getDirectKey()) ? universities.getName() + "(" + dk.getDirectKey() + ")" : universities.getName());
+            paper.setPaperType(PaperType.Simulated.name());
+            paper.setRelateId(dk.getId()); // 定向ID
+            paper.setYear(dk.getYear());
+            paper.setStatus(PaperStatus.Valid.getVal());
+            paper.setDirectKey(universityId + "_" + dk.getExamineeTypes() + "_" + dk.getDirectKey());
+            paper.setNumber(120);
+            paper.setFenshu(360);
+            AnswerSheet.PaperCond info = new AnswerSheet.PaperCond();
+            info.setScore(360);
+            info.setTime(90 * 60);
+            info.setTypes(typeDefList.stream().map(t -> new AnswerSheet.PaperCondType(t.getType(), t.getCount(), t.getScore())).collect(Collectors.toList()));
+            paper.setPaperInfo(JSONObject.toJSONString(info));
+            Pair<LearnPaper, List<LearnPaperQuestion>> paperResult = buildPaper(null, paper, paperDef);
+            savePaper(paperResult.getKey(), paperResult.getValue());
+        }
+        return 0;
+    }
     public Pair<LearnPaper, List<LearnPaperQuestion>> buildSimulatedPaper(LearnDirectedKnowledge directedKnowledge) {
         LearnPaper paper = new LearnPaper();
         paper.setPaperType(PaperType.Simulated.name());
@@ -176,7 +220,6 @@ public class PaperService {
      */
     public LearnPaper savePaper(LearnPaper paper, List<LearnPaperQuestion> pqList) {
         paper.setNumber(pqList.size());
-        paper.setFenshu(0);
         paperMapper.insertLearnPaper(paper);
         Long paperId = paper.getId();
         pqList.stream().forEach(t -> {
@@ -187,7 +230,7 @@ public class PaperService {
     }
 
     /**
-     * 动态组卷查题
+     * 按知识点,题型平均分配组卷
      * @param studentId
      * @param paperDef
      * @return
@@ -195,27 +238,21 @@ public class PaperService {
     public List<LearnPaperQuestion> getQuestions(Long studentId, TestPaperVO.PaperDef paperDef) {
         // 题型分布定义, 知识点列表, 分值定义
         // 统计知识点+类型的有效数量 TODO 总量可以缓存
-        Map<String, KnowTypeAssign> knowTypeAssignMap = Maps.newHashMap();
-        List<String> typeSet = paperDef.getTypes().stream().map(TestPaperVO.TypeDef::getType).collect(Collectors.toList());
-        Map cond = Maps.newHashMap();
-        cond.put("studentId", studentId);
-        cond.put("knowIds", paperDef.getKnowIds());
-        cond.put("types", typeSet);
-        setValue(knowTypeAssignMap, cond, 1); // 填充排除总量
-        if (paperDef.getFillExclude()) {
-            cond.remove("studentId");
-            setValue(knowTypeAssignMap, cond, 2); // 按需填充总量
-        }
+        Map<String, KnowTypeAssign> knowTypeAssignMap = buildKnowTypeAssignMap(studentId, paperDef);
+        assignKnowFirst(paperDef, knowTypeAssignMap); // 知识优先,类型可变
+        return getQuestions(studentId, paperDef, knowTypeAssignMap);
+    }
 
+    private void assignKnowFirst(TestPaperVO.PaperDef paperDef, Map<String, KnowTypeAssign> knowTypeAssignMap) {
         // 循环补充未做+已做,如果知识点总数不够时才填充其他知识点的
         Long lackTotal = paperDef.getTotal();
         AtomicLong assignCount = new AtomicLong(0);
         Map<Long, Integer> knowTypesMap = Maps.newHashMap();
         int typeCount = paperDef.getTypes().size();
+        Set<Long> knowSet = knowTypeAssignMap.values().stream().map(KnowTypeAssign::getKnowId).collect(Collectors.toSet());
         for (Long knowId : paperDef.getKnowIds()) {
-            knowTypesMap.put(knowId, typeCount);
+            knowTypesMap.put(knowId, knowSet.contains(knowId) ? typeCount : 0);
         }
-        Set<Long> knowSet = Sets.newHashSet(paperDef.getKnowIds());
         Long minKnowTypeCount = Long.MAX_VALUE;
         do {
             Integer knowCount = knowSet.size();
@@ -245,12 +282,22 @@ public class PaperService {
                 break;
             }
         } while (true);
+    }
 
+    /**
+     * 根据计划的分配数生成题关系
+     * @param studentId
+     * @param paperDef
+     * @param knowTypeAssignMap
+     * @return
+     */
+    public List<LearnPaperQuestion> getQuestions(Long studentId, TestPaperVO.PaperDef paperDef, Map<String, KnowTypeAssign> knowTypeAssignMap) {
         // 知识点已经分配,准备题型分配
         LearnQuestions qCond = new LearnQuestions();
         Random random = new Random();
         List<LearnPaperQuestion> pqList = Lists.newArrayList();
         Set<Long> existQuestionIdSet = Sets.newHashSet();
+        int total = paperDef.getTotal().intValue();
         for (TestPaperVO.TypeDef typeDef : paperDef.getTypes()) {
             for (Long knowId : paperDef.getKnowIds()) {
                 String key = knowId + "_" + typeDef.getType();
@@ -262,17 +309,25 @@ public class PaperService {
                 qCond.setQtpye(ktc.getType());
                 if(ktc.exclAssign > 0){
                     qCond.setId(studentId);
-                    qCond.setNumber(ktc.assign > 500 ? (long) random.nextInt(ktc.exclAssign.intValue() - 500) :  0L);
+                    qCond.setNumber(ktc.exclAssign > 500 ? (long) random.nextInt(ktc.exclAssign.intValue() - 500) :  0L);
                     List<LearnQuestions> questions = questionsMapper.selectQuestionsForPaper(qCond);
-                    addRandomList(knowId, questions, random, paperDef.getTotal(), ktc.exclAssign, typeDef.getScore(), existQuestionIdSet, pqList);
+                    ktc.exclAssign = addRandomList(knowId, ktc.getType(), questions, random, paperDef.getTotal(), ktc.exclAssign, typeDef.getScore(), existQuestionIdSet, pqList);
+                    if(pqList.size() == total) {
+                        break;
+                    }
                 }
                 if(ktc.assign > 0L) {
                     qCond.setId(null);
                     qCond.setNumber(ktc.assign > 500 ? (long) random.nextInt(ktc.assign.intValue() - 500) :  0L);
                     List<LearnQuestions> questions = questionsMapper.selectQuestionsForPaper(qCond);
-                    addRandomList(knowId, questions, random, paperDef.getTotal(), ktc.exclAssign, typeDef.getScore(), existQuestionIdSet, pqList);
+                    ktc.assign = addRandomList(knowId, ktc.getType(), questions, random, paperDef.getTotal(), ktc.assign, typeDef.getScore(), existQuestionIdSet, pqList);
+                    if(pqList.size() == total) {
+                        break;
+                    }
                 }
-
+            }
+            if(pqList.size() == total) {
+                break;
             }
         }
         if(CollectionUtils.isEmpty(pqList)) {
@@ -281,15 +336,50 @@ public class PaperService {
         return pqList;
     }
 
-    private void addRandomList(Long knowId, List<LearnQuestions> questions, Random random, Long totalCount, Long count, Integer score, Set<Long> existQuestionIdSet, List<LearnPaperQuestion> pqList) {
-        while(count > 0 && questions.size() > 0) {
+
+    /**
+     * 初始化当前用户卷情况
+     * @param studentId
+     * @param paperDef
+     * @return
+     */
+    private Map<String, KnowTypeAssign> buildKnowTypeAssignMap(Long studentId, TestPaperVO.PaperDef paperDef) {
+        Map<String, KnowTypeAssign> knowTypeAssignMap = Maps.newHashMap();
+        List<String> typeSet = paperDef.getTypes().stream().map(TestPaperVO.TypeDef::getType).collect(Collectors.toList());
+        Map cond = Maps.newHashMap();
+        cond.put("studentId", studentId);
+        cond.put("knowIds", paperDef.getKnowIds());
+        cond.put("types", typeSet);
+        setValue(knowTypeAssignMap, cond, 1); // 填充排除后总量
+        if (null != studentId && paperDef.getFillExclude()) {
+            cond.remove("studentId");
+            setValue(knowTypeAssignMap, cond, 2); // 按需填充已做总量
+        }
+        return knowTypeAssignMap;
+    }
+
+    /**
+     * 随机从 knowId 题池中提取需要个数的题
+     * @param knowId 知识点
+     * @param type 类型
+     * @param questions 题池
+     * @param random 随机数
+     * @param totalCount 总题数
+     * @param count  本池分配数
+     * @param score 题分
+     * @param existQuestionIdSet 不能使用的题
+     * @param pqList 卷题关系
+     */
+    private Long addRandomList(Long knowId, String type, List<LearnQuestions> questions, Random random, Long totalCount, Long count, Integer score, Set<Long> existQuestionIdSet, List<LearnPaperQuestion> pqList) {
+        while(count > 0L && !questions.isEmpty()) {
             LearnQuestions q = questions.size() > 1 ? questions.remove(random.nextInt(questions.size() - 1)) : questions.remove(0);
             if(existQuestionIdSet.add(q.getId())) {
                 LearnPaperQuestion pq = new LearnPaperQuestion();
                 pq.setSeq(pqList.size() + 1);
-                pq.setKnowledgeId(q.getKnowledgeId());
+                pq.setKnowledgeId(knowId);
                 pq.setScore(score);
                 pq.setQuestionId(q.getId());
+                pq.setType(type);
                 pqList.add(pq);
                 count--;
                 if(pqList.size() == totalCount) {
@@ -297,6 +387,7 @@ public class PaperService {
                 }
             }
         }
+        return count;
     }
 
     /**
@@ -353,10 +444,10 @@ public class PaperService {
     }
 
     /**
-     * 合并 排除总量和总量
-     * @param knowTypeAssignMap
+     * 合并 未用总量和已有总量, 分配数置0
+     * @param knowTypeAssignMap key=knowId +"_" + qtype
      * @param cond
-     * @param index 1 free 2 total
+     * @param index 1 free 2 used
      */
     private void setValue(Map<String, KnowTypeAssign> knowTypeAssignMap, Map cond, Integer index) {
         for (LearnQuestions q : questionsMapper.statByKnowledgeType(cond)) {
@@ -382,11 +473,11 @@ public class PaperService {
 
     @Data
     public static class KnowTypeAssign {
-        Long knowId;
-        String type;
-        Long exclAssign; // 分配
-        Long assign; // 全量分配个
-        Long exclCount; // 排除总数
-        Long total; // 全量总数
+        Long knowId; // 知识点
+        String type; // 题类型
+        Long exclAssign; // 未用分配数
+        Long assign; // 已用分配
+        Long exclCount; // 未用总量
+        Long total; // 已用总量
     }
 }

+ 17 - 0
ie-system/src/main/java/com/ruoyi/learn/domain/AnswerSheet.java

@@ -4,7 +4,9 @@ import com.fasterxml.jackson.annotation.JsonFormat;
 import com.ruoyi.common.annotation.Excel;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 
 import java.util.Date;
 import java.util.List;
@@ -51,6 +53,19 @@ public class AnswerSheet {
     @ApiModelProperty("错误题数")
     private Integer wrongCount;
 
+    @ApiModelProperty("院校id")
+    private Long collegeId;
+    @ApiModelProperty("院校名称")
+    private String collegeName;
+    @ApiModelProperty("专业id")
+    private Long majorId;
+    @ApiModelProperty("专业名称")
+    private String majorName;
+    @ApiModelProperty("科目ID")
+    private Long subjectId;
+    @ApiModelProperty("科目名称")
+    private String subjectName;
+
     List<PaperVO.QuestionAnswer> questions;
 
     @Data
@@ -60,6 +75,8 @@ public class AnswerSheet {
         List<PaperCondType> types;
     }
     @Data
+    @AllArgsConstructor
+    @NoArgsConstructor
     public static class PaperCondType {
         String type;
         Integer count;

+ 11 - 0
ie-system/src/main/java/com/ruoyi/learn/domain/LearnExaminee.java

@@ -35,6 +35,9 @@ public class LearnExaminee extends BaseEntity
     @Excel(name = "试卷标识")
     private String paperKey;
 
+    @Excel(name = "试卷信息")
+    private String paperInfo;
+
     @Excel(name = "做题时长")
     private Long duration;
     
@@ -141,6 +144,14 @@ public class LearnExaminee extends BaseEntity
         this.paperKey = paperKey;
     }
 
+    public String getPaperInfo() {
+        return paperInfo;
+    }
+
+    public void setPaperInfo(String paperInfo) {
+        this.paperInfo = paperInfo;
+    }
+
     public Long getDuration() {
         return duration;
     }

+ 8 - 6
ie-system/src/main/java/com/ruoyi/learn/domain/LearnPaper.java

@@ -54,6 +54,10 @@ public class LearnPaper extends BaseEntity
     @Excel(name = "定向key")
     private String directKey;
 
+    /** 试卷信息 */
+    @Excel(name = "试卷信息")
+    private String paperInfo;
+
     /** 标识 */
     @Excel(name = "标识")
     private String tiid;
@@ -78,8 +82,6 @@ public class LearnPaper extends BaseEntity
     @Excel(name = "适用考生")
     private String examineeTypes;
 
-    private String conditions;
-
     private Long examineeId;
 
     private boolean collect;
@@ -258,12 +260,12 @@ public class LearnPaper extends BaseEntity
         return examineeTypes;
     }
 
-    public String getConditions() {
-        return conditions;
+    public String getPaperInfo() {
+        return paperInfo;
     }
 
-    public void setConditions(String conditions) {
-        this.conditions = conditions;
+    public void setPaperInfo(String paperInfo) {
+        this.paperInfo = paperInfo;
     }
 
     @Override

+ 8 - 3
ie-system/src/main/resources/mapper/learn/LearnExamineeMapper.xml

@@ -9,6 +9,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="studentId"    column="student_id"    />
         <result property="paperType"    column="paper_type"    />
         <result property="paperId"    column="paper_id"    />
+        <result property="paperKey"    column="paper_key"    />
+        <result property="paperInfo"    column="paper_info"    />
         <result property="beginTime"    column="begin_time"    />
         <result property="endTime"    column="end_time"    />
         <result property="duration"    column="duration"    />
@@ -28,7 +30,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </resultMap>
 
     <sql id="selectLearnExamineeVo">
-        select examinee_id, student_id, paper_type, paper_id, begin_time, end_time, duration, stats, state, score_level, score, score_rate, ranking, grade_ranking, wrong_count, choose_count, choose_total, subjective_count, subjective_total, create_time, update_time from learn_examinee
+        select examinee_id, student_id, paper_type, paper_id, paper_key, paper_info, begin_time, end_time, duration, stats, state, score_level, score, score_rate, ranking, grade_ranking, wrong_count, choose_count, choose_total, subjective_count, subjective_total, create_time, update_time from learn_examinee
     </sql>
 
     <select id="selectLearnExamineeList" parameterType="LearnExaminee" resultMap="LearnExamineeResult">
@@ -37,6 +39,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="studentId != null "> and student_id = #{studentId}</if>
             <if test="paperType != null "> and paper_type = #{paperType}</if>
             <if test="paperId != null "> and paper_id = #{paperId}</if>
+            <if test="paperKey != null "> and paper_key = #{paperKey}</if>
             <if test="beginTime != null "> and begin_time = #{beginTime}</if>
             <if test="endTime != null "> and end_time = #{endTime}</if>
             <if test="duration != null "> and duration = #{duration}</if>
@@ -65,6 +68,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="studentId != null">student_id,</if>
             <if test="paperType != null">paper_type,</if>
             <if test="paperId != null">paper_id,</if>
+            <if test="paperKey != null ">paper_key,</if>
+            <if test="paperInfo != null ">paper_info,</if>
             <if test="beginTime != null">begin_time,</if>
             <if test="endTime != null">end_time,</if>
             <if test="duration != null">duration,</if>
@@ -87,6 +92,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="studentId != null">#{studentId},</if>
             <if test="paperType != null">#{paperType},</if>
             <if test="paperId != null">#{paperId},</if>
+            <if test="paperKey != null">#{paperKey},</if>
+            <if test="paperInfo != null">#{paperInfo},</if>
             <if test="beginTime != null">#{beginTime},</if>
             <if test="endTime != null">#{endTime},</if>
             <if test="duration != null">#{duration},</if>
@@ -111,8 +118,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         update learn_examinee
         <trim prefix="SET" suffixOverrides=",">
             <if test="studentId != null">student_id = #{studentId},</if>
-            <if test="paperType != null">paper_type = #{paperType},</if>
-            <if test="paperId != null">paper_id = #{paperId},</if>
             <if test="beginTime != null">begin_time = #{beginTime},</if>
             <if test="endTime != null">end_time = #{endTime},</if>
             <if test="duration != null">duration = #{duration},</if>