|
@@ -2,6 +2,7 @@ package com.xhkjedu.smarking.service.report.generate;
|
2
|
2
|
|
3
|
3
|
import com.alibaba.fastjson.JSON;
|
4
|
4
|
import com.xhkjedu.smarking.mapper.paper.MsPaperAnalyzeMapper;
|
|
5
|
+import com.xhkjedu.smarking.mapper.report.reportsubject.MsrSubjectPointMapper;
|
5
|
6
|
import com.xhkjedu.smarking.model.exam.MsClassStudent;
|
6
|
7
|
import com.xhkjedu.smarking.model.paper.MsPaperAnalyze;
|
7
|
8
|
import com.xhkjedu.smarking.model.paper.MsPaperQtypeQuestion;
|
|
@@ -16,14 +17,14 @@ import com.xhkjedu.smarking.vo.paper.QuestionPointVo;
|
16
|
17
|
import com.xhkjedu.smarking.vo.report.reportother.RankGroupVo;
|
17
|
18
|
import com.xhkjedu.smarking.vo.report.reportstu.PointQuestionVo;
|
18
|
19
|
import com.xhkjedu.smarking.vo.report.reportstu.PointStudentVo;
|
|
20
|
+import com.xhkjedu.smarking.vo.report.reportsubject.PointLevelVo;
|
|
21
|
+import com.xhkjedu.smarking.vo.report.reportsubject.PointVo;
|
19
|
22
|
import com.xhkjedu.utils.N_Utils;
|
20
|
23
|
import org.springframework.stereotype.Service;
|
21
|
24
|
|
22
|
25
|
import javax.annotation.Resource;
|
23
|
|
-import java.util.ArrayList;
|
24
|
|
-import java.util.Arrays;
|
25
|
|
-import java.util.List;
|
26
|
|
-import java.util.Map;
|
|
26
|
+import java.util.*;
|
|
27
|
+import java.util.function.Function;
|
27
|
28
|
import java.util.stream.Collectors;
|
28
|
29
|
|
29
|
30
|
/**
|
|
@@ -35,6 +36,8 @@ import java.util.stream.Collectors;
|
35
|
36
|
public class ReportGeneratePointService {
|
36
|
37
|
@Resource
|
37
|
38
|
private MsPaperAnalyzeMapper msPaperAnalyzeMapper;
|
|
39
|
+ @Resource
|
|
40
|
+ private MsrSubjectPointMapper msrSubjectPointMapper;
|
38
|
41
|
|
39
|
42
|
//知识点分析,题库知识点按母题分析
|
40
|
43
|
public void generatePoint(List<MsPaperStudentQuestion> stuSubjectQuestions, List<MsPaperQtypeQuestion> qtypeQuestions,List<MsClassStudent> classStus,
|
|
@@ -153,7 +156,9 @@ public class ReportGeneratePointService {
|
153
|
156
|
List<MsrSubjectPointSection> pointSecs = pointSection(pointStuScores, pointSections, pqvo, 3);
|
154
|
157
|
savePointSections.addAll(pointSecs);
|
155
|
158
|
|
156
|
|
- //知识点机构考生分组分析
|
|
159
|
+ //知识点考生分组分析
|
|
160
|
+ List<MsrSubjectPointRankgroup> pointRankg = pointRankGroup(pointStuScores,sturanks, pqvo, examid, subjectid, 3);
|
|
161
|
+ savePointRankgroups.addAll(pointRankg);
|
157
|
162
|
|
158
|
163
|
double schoolSumScore = pointStuScores.stream().mapToDouble(PointStudentVo::getStuscore).sum();
|
159
|
164
|
int stunum = pointStuScores.size();
|
|
@@ -178,7 +183,6 @@ public class ReportGeneratePointService {
|
178
|
183
|
saveStuPoints.add(stuPoint);
|
179
|
184
|
}
|
180
|
185
|
}
|
181
|
|
-
|
182
|
186
|
}
|
183
|
187
|
|
184
|
188
|
// 知识点:设置每个学生每个试题知识点得分
|
|
@@ -289,7 +293,7 @@ public class ReportGeneratePointService {
|
289
|
293
|
}
|
290
|
294
|
|
291
|
295
|
//知识点-考试排名分组分析
|
292
|
|
- private List<MsrSubjectPointRankgroup> questionScoreRankGroup(List<PointStudentVo> pointStuScores, List<MsrStudent> stuPapers, PointQuestionVo pqvo,Integer examid,String subjectid, Integer pointlevel){
|
|
296
|
+ private List<MsrSubjectPointRankgroup> pointRankGroup(List<PointStudentVo> pointStuScores, List<MsrStudent> stuPapers, PointQuestionVo pqvo,Integer examid,String subjectid, Integer pointlevel){
|
293
|
297
|
//获取学生排名最大名次的树
|
294
|
298
|
Integer totalRank = stuPapers.stream().mapToInt(MsrStudent::getSchoolrank).max().orElse(0);
|
295
|
299
|
//获取排名分组,默认分为7组
|
|
@@ -343,8 +347,6 @@ public class ReportGeneratePointService {
|
343
|
347
|
}else{
|
344
|
348
|
sectionStuQuestions = groupStuPoints.stream().filter(q -> q.getStuscore() >= sectionScore.getMinvalue() && q.getStuscore() < sectionScore.getMaxvalue()).collect(Collectors.toList());
|
345
|
349
|
}
|
346
|
|
- // double sectionStuSumScore = sectionStuQuestions.stream().mapToDouble(PointStudentVo::getStuscore).sum();
|
347
|
|
- // double sectionStuAvgScore = MarkingUtil.div(sectionStuSumScore, sectionStuQuestions.size());
|
348
|
350
|
sqrg.setStunum(sectionStuQuestions.size());
|
349
|
351
|
sqrg.setStuids(sectionStuQuestions.stream().map(q -> q.getStudentid().toString()).collect(Collectors.joining(",")));
|
350
|
352
|
}else{
|
|
@@ -358,4 +360,194 @@ public class ReportGeneratePointService {
|
358
|
360
|
}
|
359
|
361
|
return rtnList;
|
360
|
362
|
}
|
|
363
|
+
|
|
364
|
+ //获取处理知识点对应的顶层、上层知识点
|
|
365
|
+ private Map<String,Map<String,List<PointLevelVo>>> listSubjectPoints(String subjectid,Integer examid,List<PointQuestionVo> pointques){
|
|
366
|
+ //获取所有知识点
|
|
367
|
+ List<PointVo> points = msrSubjectPointMapper.listSubjectPoints(subjectid,examid);
|
|
368
|
+ Map<String,PointVo> pointMap = points.stream().collect(Collectors.toMap(PointVo::getPointid, Function.identity()));
|
|
369
|
+
|
|
370
|
+ List<PointLevelVo> upPoints = new ArrayList<>();//知识点的上层(二级)知识点
|
|
371
|
+ List<PointLevelVo> topPoints = new ArrayList<>();//知识点的顶层层(一级)知识点
|
|
372
|
+ for(PointQuestionVo point : pointques){
|
|
373
|
+ PointLevelVo upPoint = new PointLevelVo();
|
|
374
|
+ upPoint.setPointid(point.getPointid());
|
|
375
|
+ upPoint.setPointname(point.getPointname());
|
|
376
|
+
|
|
377
|
+ PointLevelVo topPoint = new PointLevelVo();
|
|
378
|
+ topPoint.setPointid(point.getPointid());
|
|
379
|
+ topPoint.setPointname(point.getPointname());
|
|
380
|
+
|
|
381
|
+ //获取知识点的详细信息
|
|
382
|
+ if(pointMap.containsKey(point.getPointid())){
|
|
383
|
+ PointVo pointVo = pointMap.get(point.getPointid());
|
|
384
|
+ PointVo parentNode =pointVo.getParent(points);//上层知识点
|
|
385
|
+ upPoint.setTopPointid(parentNode.getPointid());
|
|
386
|
+ upPoint.setTopPointname(parentNode.getPointname());
|
|
387
|
+
|
|
388
|
+ //找到顶层知识点
|
|
389
|
+ PointVo rootNode = getRootNode(parentNode, points);
|
|
390
|
+ if(rootNode!= null){
|
|
391
|
+ topPoint.setTopPointid(rootNode.getPointid());
|
|
392
|
+ topPoint.setTopPointname(rootNode.getPointname());
|
|
393
|
+ }else{
|
|
394
|
+ topPoint.setTopPointid(point.getPointid());
|
|
395
|
+ topPoint.setTopPointname(point.getPointname());
|
|
396
|
+ }
|
|
397
|
+ }else{
|
|
398
|
+ upPoint.setTopPointid(point.getPointid());
|
|
399
|
+ upPoint.setTopPointname(point.getPointname());
|
|
400
|
+
|
|
401
|
+ topPoint.setTopPointid(point.getPointid());
|
|
402
|
+ topPoint.setTopPointname(point.getPointname());
|
|
403
|
+ }
|
|
404
|
+
|
|
405
|
+ upPoints.add(upPoint);
|
|
406
|
+ topPoints.add(topPoint);
|
|
407
|
+ }
|
|
408
|
+
|
|
409
|
+ Map<String,List<PointLevelVo>> upMap = upPoints.stream().collect(Collectors.groupingBy(PointLevelVo::getTopPointid));
|
|
410
|
+ Map<String,List<PointLevelVo>> topMap = topPoints.stream().collect(Collectors.groupingBy(PointLevelVo::getTopPointid));
|
|
411
|
+ Map<String,Map<String,List<PointLevelVo>>> rtnMap = new HashMap<>();
|
|
412
|
+ rtnMap.put("up",upMap);
|
|
413
|
+ rtnMap.put("top",topMap);
|
|
414
|
+ return rtnMap;
|
|
415
|
+ }
|
|
416
|
+ //获取顶层节点
|
|
417
|
+ private PointVo getRootNode(PointVo targetNode, List<PointVo> allNodes) {
|
|
418
|
+ PointVo current = targetNode;
|
|
419
|
+ while (N_Utils.isNotEmpty(current.getPointpid())) {
|
|
420
|
+ current = current.getParent(allNodes);
|
|
421
|
+ }
|
|
422
|
+ return current;
|
|
423
|
+ }
|
|
424
|
+
|
|
425
|
+ //处理顶级、上级知识点
|
|
426
|
+ private void handlePointLevel(Map<String,List<PointLevelVo>> pointMap,List<PointQuestionVo> pointques,List<PointStudentVo> schoolStuPoints,Integer pointlevel,List<MsrSubjectPointSection> pointSections,
|
|
427
|
+ List<MsPaperQtypeQuestion> qtypeQuestions,List<MsClassStudent> classStus,Integer examid,String subjectid,List<MsrStudent> sturanks,
|
|
428
|
+ List<MsrSubjectPoint> saveSubjectPoints,List<MsrSubjectPointSection> savePointSections,List<MsrSubjectPointRankgroup> savePointRankgroups){
|
|
429
|
+
|
|
430
|
+ //科目班级知识点情况
|
|
431
|
+ Map<String, List<MsrSubjectPoint>> subjectPointMap = saveSubjectPoints.stream().filter(p -> p.getPointlevel()==3).collect(Collectors.groupingBy(MsrSubjectPoint::getPointid));
|
|
432
|
+ //知识点学科总分区间
|
|
433
|
+ Map<String, List<MsrSubjectPointSection>> pointSectionMap = savePointSections.stream().filter(p -> p.getPointlevel()==3).collect(Collectors.groupingBy(MsrSubjectPointSection::getPointid));
|
|
434
|
+ //知识点分组
|
|
435
|
+ Map<String, List<MsrSubjectPointRankgroup>> pointRankgroupMap = savePointRankgroups.stream().filter(p -> p.getPointlevel()==3).collect(Collectors.groupingBy(MsrSubjectPointRankgroup::getPointid));
|
|
436
|
+
|
|
437
|
+ //处理上层知识点
|
|
438
|
+ for(Map.Entry<String,List<PointLevelVo>> entry : pointMap.entrySet()){
|
|
439
|
+ List<PointLevelVo> pointLevels = entry.getValue();
|
|
440
|
+ PointLevelVo firstPoint = pointLevels.get(0);
|
|
441
|
+ if(pointLevels.size() ==1){
|
|
442
|
+ //说明知识的上层知识点是知识点本身或者仅有一个知识点,则上层知识点分析和他本身的分析一致
|
|
443
|
+ //科目知识点
|
|
444
|
+ List<MsrSubjectPoint> subpoints = subjectPointMap.get(firstPoint.getPointid());
|
|
445
|
+ for(MsrSubjectPoint subpoint : subpoints){
|
|
446
|
+ subpoint.setPointid(firstPoint.getTopPointid());
|
|
447
|
+ subpoint.setPointname(firstPoint.getPointname());
|
|
448
|
+ subpoint.setPointlevel(pointlevel);
|
|
449
|
+ saveSubjectPoints.add(subpoint);
|
|
450
|
+ }
|
|
451
|
+
|
|
452
|
+ //分数分段
|
|
453
|
+ List<MsrSubjectPointSection> sepoints = pointSectionMap.get(firstPoint.getPointid());
|
|
454
|
+ for(MsrSubjectPointSection sepoint : sepoints) {
|
|
455
|
+ sepoint.setPointid(firstPoint.getTopPointid());
|
|
456
|
+ sepoint.setPointname(firstPoint.getPointname());
|
|
457
|
+ sepoint.setPointlevel(pointlevel);
|
|
458
|
+ savePointSections.add(sepoint);
|
|
459
|
+ }
|
|
460
|
+
|
|
461
|
+ //分组分析
|
|
462
|
+ List<MsrSubjectPointRankgroup> rgpoints = pointRankgroupMap.get(firstPoint.getPointid());
|
|
463
|
+ for(MsrSubjectPointRankgroup rgpoint : rgpoints) {
|
|
464
|
+ rgpoint.setPointid(firstPoint.getTopPointid());
|
|
465
|
+ rgpoint.setPointname(firstPoint.getPointname());
|
|
466
|
+ rgpoint.setPointlevel(pointlevel);
|
|
467
|
+ savePointRankgroups.add(rgpoint);
|
|
468
|
+ }
|
|
469
|
+ }else{
|
|
470
|
+ //上层知识点所包含的知识点id集合
|
|
471
|
+ List<String> pointids = pointLevels.stream().map(PointLevelVo::getPointid).collect(Collectors.toList());
|
|
472
|
+ //知识点下试题,以及学生得分
|
|
473
|
+ List<PointQuestionVo> levelPointQues = pointques.stream().filter(q -> pointids.contains(q.getPointid())).collect(Collectors.toList());
|
|
474
|
+ List<PointStudentVo> levelStuPoints = schoolStuPoints.stream().filter(q -> pointids.contains(q.getPointid())).collect(Collectors.toList());
|
|
475
|
+ List<QuestionPointVo> ques = new ArrayList<>();//知识点下所有试题
|
|
476
|
+ for(PointQuestionVo point : levelPointQues) {
|
|
477
|
+ ques.addAll(point.getQues());
|
|
478
|
+ }
|
|
479
|
+
|
|
480
|
+ List<Integer> mptqids = ques.stream().map(QuestionPointVo::getMptqid).distinct().collect(Collectors.toList());
|
|
481
|
+ //获取试题对应的qn
|
|
482
|
+ List<MsPaperQtypeQuestion> qtypeQues = qtypeQuestions.stream().filter(q -> mptqids.contains(q.getMptqid())).collect(Collectors.toList());
|
|
483
|
+ String qnStr = qtypeQues.stream().map(q -> q.getMptqn() + "." + q.getQn()).collect(Collectors.joining(","));
|
|
484
|
+ String mptqidStr = mptqids.stream().map(Object::toString).collect(Collectors.joining(","));
|
|
485
|
+ double pointscore = levelPointQues.stream().mapToDouble(PointQuestionVo::getScore).sum();
|
|
486
|
+ pointscore = N_Utils.formatDouble(pointscore, 1);
|
|
487
|
+ //知识点多个试题,处理成单个学生试题总分值
|
|
488
|
+ List<PointStudentVo> pointStuScores = new ArrayList<>();//处理成学生知识点形式,后续计算使用
|
|
489
|
+ Map<Integer, List<PointStudentVo>> pointStuMap = levelStuPoints.stream().collect(Collectors.groupingBy(PointStudentVo::getStudentid));
|
|
490
|
+ for (Map.Entry<Integer, List<PointStudentVo>> psentry : pointStuMap.entrySet()){
|
|
491
|
+ List<PointStudentVo> pstuScores = psentry.getValue();
|
|
492
|
+ double stuScore = pstuScores.stream().mapToDouble(PointStudentVo::getStuscore).sum();
|
|
493
|
+ stuScore = N_Utils.formatDouble(stuScore, 1);
|
|
494
|
+ PointStudentVo pstuvo = new PointStudentVo();
|
|
495
|
+ pstuvo.setStudentid(psentry.getKey());
|
|
496
|
+ pstuvo.setPointid(entry.getKey());
|
|
497
|
+ pstuvo.setStuscore(stuScore);
|
|
498
|
+ pstuvo.setScore(pointscore);
|
|
499
|
+ pointStuScores.add(pstuvo);
|
|
500
|
+ }
|
|
501
|
+
|
|
502
|
+ MsrSubjectPoint subjectPoint = new MsrSubjectPoint();
|
|
503
|
+ subjectPoint.setExamid(examid);
|
|
504
|
+ subjectPoint.setSubjectid(subjectid);
|
|
505
|
+ subjectPoint.setPointid(firstPoint.getTopPointid());
|
|
506
|
+ subjectPoint.setClassid(0);
|
|
507
|
+ subjectPoint.setPointname(firstPoint.getTopPointid());
|
|
508
|
+ subjectPoint.setFullscore(pointscore);
|
|
509
|
+ subjectPoint.setPointlevel(pointlevel);
|
|
510
|
+ subjectPoint.setMptqids(mptqidStr);
|
|
511
|
+ subjectPoint.setQns(qnStr);
|
|
512
|
+
|
|
513
|
+ //校知识点分析
|
|
514
|
+ MsrSubjectPoint schoolPoint = pointLevelClass(pointStuScores, subjectPoint);
|
|
515
|
+ saveSubjectPoints.add(schoolPoint);
|
|
516
|
+
|
|
517
|
+ //班级知识点分析
|
|
518
|
+ List<Integer> classIds = classStus.stream().map(MsClassStudent::getClassid).distinct().collect(Collectors.toList());
|
|
519
|
+ List<MsrSubjectPoint> classPoints = new ArrayList<>();
|
|
520
|
+ for (Integer classid : classIds) {
|
|
521
|
+ // 获取班级下学生id
|
|
522
|
+ List<Integer> classStuIds = classStus.stream().filter(c -> c.getClassid().equals(classid)).map(MsClassStudent::getStudentid).collect(Collectors.toList());
|
|
523
|
+ // 获取班级下学生试题
|
|
524
|
+ List<PointStudentVo> classStuPoints = pointStuScores.stream().filter(q -> classStuIds.contains(q.getStudentid())).collect(Collectors.toList());
|
|
525
|
+ subjectPoint.setClassid(classid);
|
|
526
|
+ MsrSubjectPoint classPoint = pointLevelClass(classStuPoints, subjectPoint);
|
|
527
|
+ classPoints.add(classPoint);
|
|
528
|
+ }
|
|
529
|
+
|
|
530
|
+ // 班级知识点保存后,要对平均分排序
|
|
531
|
+ List<Double> avgScores = classPoints.stream().map(MsrSubjectPoint::getAvgscore).collect(Collectors.toList());
|
|
532
|
+ Map<Double,Integer> avgScoreRankMap = MarkingUtil.fspm(avgScores);
|
|
533
|
+ for(MsrSubjectPoint sp : classPoints){
|
|
534
|
+ sp.setAvgrank(avgScoreRankMap.get(sp.getAvgscore()));
|
|
535
|
+ }
|
|
536
|
+ saveSubjectPoints.addAll(classPoints);
|
|
537
|
+
|
|
538
|
+ PointQuestionVo pqvo = new PointQuestionVo();
|
|
539
|
+ pqvo.setPointid(firstPoint.getTopPointid());
|
|
540
|
+ pqvo.setPointname(firstPoint.getPointname());
|
|
541
|
+ pqvo.setScore(pointscore);
|
|
542
|
+
|
|
543
|
+ //知识点结构与总分的相关性(三级知识点)
|
|
544
|
+ List<MsrSubjectPointSection> pointSecs = pointSection(pointStuScores, pointSections, pqvo, pointlevel);
|
|
545
|
+ savePointSections.addAll(pointSecs);
|
|
546
|
+
|
|
547
|
+ //知识点考生分组分析
|
|
548
|
+ List<MsrSubjectPointRankgroup> pointRankg = pointRankGroup(pointStuScores,sturanks, pqvo, examid, subjectid, pointlevel);
|
|
549
|
+ savePointRankgroups.addAll(pointRankg);
|
|
550
|
+ }
|
|
551
|
+ }
|
|
552
|
+ }
|
361
|
553
|
}
|