Browse Source

完善题块,学生知识点分析

ywx
王宁 1 month ago
parent
commit
0fa2a5fd3b
16 changed files with 423 additions and 38 deletions
  1. 1
    0
      sexam/src/main/java/com/xhkjedu/sexam/service/report/EReportGenerateQuestionService.java
  2. 1
    1
      smarking/src/main/java/com/xhkjedu/smarking/mapper/paper/MsPaperMapper.java
  3. 2
    2
      smarking/src/main/java/com/xhkjedu/smarking/mapper/report/reportsubject/MsrSubjectPointRankgroupMapper.java
  4. 6
    6
      smarking/src/main/java/com/xhkjedu/smarking/model/report/reportstu/MsrStudentPoint.java
  5. 5
    9
      smarking/src/main/java/com/xhkjedu/smarking/model/report/reportsubject/MsrSubjectPoint.java
  6. 8
    6
      smarking/src/main/java/com/xhkjedu/smarking/model/report/reportsubject/MsrSubjectPointRankgroup.java
  7. 11
    1
      smarking/src/main/java/com/xhkjedu/smarking/model/report/reportsubject/MsrSubjectPointSection.java
  8. 1
    1
      smarking/src/main/java/com/xhkjedu/smarking/model/report/reportsubject/MsrSubjectQuestionRankgroup.java
  9. 334
    3
      smarking/src/main/java/com/xhkjedu/smarking/service/report/generate/ReportGeneratePointService.java
  10. 4
    4
      smarking/src/main/java/com/xhkjedu/smarking/service/report/generate/ReportGenerateQuestionService.java
  11. 1
    2
      smarking/src/main/java/com/xhkjedu/smarking/utils/MarkingUtil.java
  12. 25
    0
      smarking/src/main/java/com/xhkjedu/smarking/vo/report/reportstu/PointQuestionVo.java
  13. 21
    0
      smarking/src/main/java/com/xhkjedu/smarking/vo/report/reportstu/PointStudentVo.java
  14. 1
    1
      smarking/src/main/resources/mapper/paper/MsPaperMapper.xml
  15. 1
    1
      smarking/src/main/resources/mapper/paper/MsPaperQtypeQuestionMapper.xml
  16. 1
    1
      smarking/src/main/resources/mapper/report/reportsubject/MsrSubjectPointRankgroupMapper.xml

+ 1
- 0
sexam/src/main/java/com/xhkjedu/sexam/service/report/EReportGenerateQuestionService.java View File

785
                 }
785
                 }
786
             }
786
             }
787
         }
787
         }
788
+
788
         List<Map> classes = examPaperClassVo.getClasses();
789
         List<Map> classes = examPaperClassVo.getClasses();
789
         // 根据试卷知识点分析进行生成学生、班级、年级知识点分析
790
         // 根据试卷知识点分析进行生成学生、班级、年级知识点分析
790
         for (Map map : pointlist) {
791
         for (Map map : pointlist) {

+ 1
- 1
smarking/src/main/java/com/xhkjedu/smarking/mapper/paper/MsPaperMapper.java View File

55
     Integer getMpIdByMsId(@Param("msid") Integer msid);
55
     Integer getMpIdByMsId(@Param("msid") Integer msid);
56
 
56
 
57
     //修改题块设置后试卷中试题数量
57
     //修改题块设置后试卷中试题数量
58
-    Integer updaePaperMeregpnumByMpid(@Param("mpid") Integer mpid, @Param("meregpnum") Integer meregpnum);
58
+    Integer updaePaperMeregpnumByMpid(@Param("mpid") Integer mpid, @Param("mergepnum") Integer mergepnum);
59
 
59
 
60
     //获取试卷对应科目状态
60
     //获取试卷对应科目状态
61
     PExamSubjectVo getSubjectStateByMpid(@Param("mpid") Integer mpid);
61
     PExamSubjectVo getSubjectStateByMpid(@Param("mpid") Integer mpid);

smarking/src/main/java/com/xhkjedu/smarking/mapper/report/reportsubject/MsrSubjectPointGroupMapper.java → smarking/src/main/java/com/xhkjedu/smarking/mapper/report/reportsubject/MsrSubjectPointRankgroupMapper.java View File

1
 package com.xhkjedu.smarking.mapper.report.reportsubject;
1
 package com.xhkjedu.smarking.mapper.report.reportsubject;
2
 
2
 
3
 import com.xhkjedu.base.TkMapper;
3
 import com.xhkjedu.base.TkMapper;
4
-import com.xhkjedu.smarking.model.report.reportsubject.MsrSubjectPointGroup;
4
+import com.xhkjedu.smarking.model.report.reportsubject.MsrSubjectPointRankgroup;
5
 
5
 
6
 /**
6
 /**
7
  * @Description 阅卷报告-学科知识点分段区间表 Mapper 接口
7
  * @Description 阅卷报告-学科知识点分段区间表 Mapper 接口
8
  * @Author auto
8
  * @Author auto
9
  * @Date 2024-12-09
9
  * @Date 2024-12-09
10
  */
10
  */
11
-public interface MsrSubjectPointGroupMapper extends TkMapper<MsrSubjectPointGroup> {
11
+public interface MsrSubjectPointRankgroupMapper extends TkMapper<MsrSubjectPointRankgroup> {
12
 }
12
 }

+ 6
- 6
smarking/src/main/java/com/xhkjedu/smarking/model/report/reportstu/MsrStudentPoint.java View File

25
     private Integer studentid;
25
     private Integer studentid;
26
     //知识点ID
26
     //知识点ID
27
     private String pointid;
27
     private String pointid;
28
+    //知识点名称
29
+    private String pointname;
30
+    //知识点分数
31
+    private Double fullscore;
28
     //学生得分
32
     //学生得分
29
     private Double stuscore;
33
     private Double stuscore;
30
     //学生得分率
34
     //学生得分率
31
     private Double sturate;
35
     private Double sturate;
32
-    //班级平均分
33
-    private Double classavg;
34
-    //班级得分率
35
-    private Double classrate;
36
     //年级平均分
36
     //年级平均分
37
-    private Double gradeavg;
37
+    private Double schoolavg;
38
     //年级得分率
38
     //年级得分率
39
-    private Double graderate;
39
+    private Double schoolrate;
40
     //知识点对应试题题号
40
     //知识点对应试题题号
41
     private String qns;
41
     private String qns;
42
     //知识点对应试题ID
42
     //知识点对应试题ID

+ 5
- 9
smarking/src/main/java/com/xhkjedu/smarking/model/report/reportsubject/MsrSubjectPoint.java View File

25
     private Integer classid;
25
     private Integer classid;
26
     //知识点ID
26
     //知识点ID
27
     private String pointid;
27
     private String pointid;
28
+    //知识点名称
29
+    private String pointname;
28
     //知识点级别1一级2二级3三级
30
     //知识点级别1一级2二级3三级
29
     private Integer pointlevel;
31
     private Integer pointlevel;
30
     //满分
32
     //满分
31
     private Double fullscore;
33
     private Double fullscore;
32
-    //满分人数
33
-    private Integer mfnum;
34
-    //满分人数ids
35
-    private String mfids;
36
-    //零分人数
37
-    private Integer lfnum;
38
-    //零分人数id
39
-    private String lfids;
40
     //最高分
34
     //最高分
41
     private Double maxscore;
35
     private Double maxscore;
42
     //最低分
36
     //最低分
43
     private Double minscore;
37
     private Double minscore;
38
+    //得分率
39
+    private Double scorerate;
44
     //平均分
40
     //平均分
45
     private Double avgscore;
41
     private Double avgscore;
46
     //平均得分率%
42
     //平均得分率%
54
     //区分度
50
     //区分度
55
     private Double qfd;
51
     private Double qfd;
56
     //鉴定指数
52
     //鉴定指数
57
-    private Double jdzs;
53
+    private Double jbzs;
58
     //对应试题ids
54
     //对应试题ids
59
     private String mptqids;
55
     private String mptqids;
60
     //对应题目
56
     //对应题目

smarking/src/main/java/com/xhkjedu/smarking/model/report/reportsubject/MsrSubjectPointGroup.java → smarking/src/main/java/com/xhkjedu/smarking/model/report/reportsubject/MsrSubjectPointRankgroup.java View File

12
  * @Date 2024-12-09
12
  * @Date 2024-12-09
13
  */
13
  */
14
 @Data
14
 @Data
15
-@Table(name = "msr_subject_point_group")
16
-public class MsrSubjectPointGroup extends BaseBean {
15
+@Table(name = "msr_subject_point_rankgroup")
16
+public class MsrSubjectPointRankgroup extends BaseBean {
17
     @Id
17
     @Id
18
     //阅卷报告-学科知识点排名分组
18
     //阅卷报告-学科知识点排名分组
19
     private Integer spgid;
19
     private Integer spgid;
23
     private String subjectid;
23
     private String subjectid;
24
     //知识点ID
24
     //知识点ID
25
     private String pointid;
25
     private String pointid;
26
+    //知识点名称
27
+    private String pointname;
26
     //知识点层级1一级2二级3三级
28
     //知识点层级1一级2二级3三级
27
     private Integer pointlevel;
29
     private Integer pointlevel;
28
-    //排名分组
29
-    private String grouprank;
30
-    //分数段
31
-    private String scoresection;
30
+    //排名分组 第1组(第1~10名)
31
+    private String rgroup;
32
+    //分数段 [0-5)
33
+    private String rsection;
32
     //学生数量
34
     //学生数量
33
     private Integer stunum;
35
     private Integer stunum;
34
     //学生ids
36
     //学生ids

+ 11
- 1
smarking/src/main/java/com/xhkjedu/smarking/model/report/reportsubject/MsrSubjectPointSection.java View File

5
 
5
 
6
 import javax.persistence.Id;
6
 import javax.persistence.Id;
7
 import javax.persistence.Table;
7
 import javax.persistence.Table;
8
+import javax.persistence.Transient;
8
 
9
 
9
 /**
10
 /**
10
  * @Description 阅卷报告-学科知识点分段区间表
11
  * @Description 阅卷报告-学科知识点分段区间表
23
     private String subjectid;
24
     private String subjectid;
24
     //知识点ID
25
     //知识点ID
25
     private String pointid;
26
     private String pointid;
27
+    //知识点名称
28
+    private String pointname;
26
     //知识点层级1一级2二级3三级
29
     //知识点层级1一级2二级3三级
27
     private Integer pointlevel;
30
     private Integer pointlevel;
28
     //分数段范围
31
     //分数段范围
29
-    private String scoresection;
32
+    private String fdfw;
33
+    //平均分
34
+    private Double avgscore;
30
     //平均得分率
35
     //平均得分率
31
     private Double avgrate;
36
     private Double avgrate;
37
+
38
+    @Transient
39
+    private Integer fdnum;//分段人数
40
+    @Transient
41
+    private String fdids;//分段用户id
32
 }
42
 }

+ 1
- 1
smarking/src/main/java/com/xhkjedu/smarking/model/report/reportsubject/MsrSubjectQuestionRankgroup.java View File

32
     //类型1客观题选项 2客/主分值
32
     //类型1客观题选项 2客/主分值
33
     private Integer rgtype;
33
     private Integer rgtype;
34
     //分值范围/选项:为空代表该组情况
34
     //分值范围/选项:为空代表该组情况
35
-    private String rgvalue;
35
+    private String rsection;
36
     //人数
36
     //人数
37
     private Integer stunum;
37
     private Integer stunum;
38
     //人数ids
38
     //人数ids

+ 334
- 3
smarking/src/main/java/com/xhkjedu/smarking/service/report/generate/ReportGeneratePointService.java View File

2
 
2
 
3
 import com.alibaba.fastjson.JSON;
3
 import com.alibaba.fastjson.JSON;
4
 import com.xhkjedu.smarking.mapper.paper.MsPaperAnalyzeMapper;
4
 import com.xhkjedu.smarking.mapper.paper.MsPaperAnalyzeMapper;
5
+import com.xhkjedu.smarking.model.exam.MsClassStudent;
5
 import com.xhkjedu.smarking.model.paper.MsPaperAnalyze;
6
 import com.xhkjedu.smarking.model.paper.MsPaperAnalyze;
7
+import com.xhkjedu.smarking.model.paper.MsPaperQtypeQuestion;
8
+import com.xhkjedu.smarking.model.report.reportstu.MsrStudent;
9
+import com.xhkjedu.smarking.model.report.reportstu.MsrStudentPoint;
10
+import com.xhkjedu.smarking.model.report.reportsubject.MsrSubjectPoint;
11
+import com.xhkjedu.smarking.model.report.reportsubject.MsrSubjectPointRankgroup;
12
+import com.xhkjedu.smarking.model.report.reportsubject.MsrSubjectPointSection;
6
 import com.xhkjedu.smarking.model.stupaper.MsPaperStudentQuestion;
13
 import com.xhkjedu.smarking.model.stupaper.MsPaperStudentQuestion;
14
+import com.xhkjedu.smarking.utils.MarkingUtil;
7
 import com.xhkjedu.smarking.vo.paper.QuestionPointVo;
15
 import com.xhkjedu.smarking.vo.paper.QuestionPointVo;
16
+import com.xhkjedu.smarking.vo.report.reportother.RankGroupVo;
17
+import com.xhkjedu.smarking.vo.report.reportstu.PointQuestionVo;
18
+import com.xhkjedu.smarking.vo.report.reportstu.PointStudentVo;
19
+import com.xhkjedu.utils.N_Utils;
8
 import org.springframework.stereotype.Service;
20
 import org.springframework.stereotype.Service;
9
 
21
 
10
 import javax.annotation.Resource;
22
 import javax.annotation.Resource;
23
+import java.util.ArrayList;
24
+import java.util.Arrays;
11
 import java.util.List;
25
 import java.util.List;
26
+import java.util.Map;
27
+import java.util.stream.Collectors;
12
 
28
 
13
 /**
29
 /**
14
  * @Description:生成知识点相关分析
30
  * @Description:生成知识点相关分析
20
     @Resource
36
     @Resource
21
     private MsPaperAnalyzeMapper msPaperAnalyzeMapper;
37
     private MsPaperAnalyzeMapper msPaperAnalyzeMapper;
22
 
38
 
23
-    public void generatePoint(List<MsPaperStudentQuestion> stuQuestions,Integer mpid) {
39
+    //知识点分析,题库知识点按母题分析
40
+    public void generatePoint(List<MsPaperStudentQuestion> stuSubjectQuestions, List<MsPaperQtypeQuestion> qtypeQuestions,List<MsClassStudent> classStus,
41
+                            List<MsrStudent> sturanks, Integer examid, String subjectid, Integer mpid, Double pscore) {
24
         //获取试卷分析
42
         //获取试卷分析
25
         MsPaperAnalyze paperAnalyze = msPaperAnalyzeMapper.getObjByMpId(mpid);
43
         MsPaperAnalyze paperAnalyze = msPaperAnalyzeMapper.getObjByMpId(mpid);
26
-        if(paperAnalyze == null) return;
44
+        if(paperAnalyze == null || N_Utils.isEmpty(paperAnalyze.getPointjson())) return;
27
 
45
 
28
-        QuestionPointVo qpointvo = JSON.parseObject(paperAnalyze.getPointjson(), QuestionPointVo.class);
46
+        List<MsrStudentPoint> saveStuPoints = new ArrayList<>();//保存学生得分情况
47
+        List<MsrSubjectPoint> saveSubjectPoints = new ArrayList<>();//保存科目班级知识点情况
48
+        List<MsrSubjectPointSection> savePointSections = new ArrayList<>();//知识点学科总分区间
49
+        List<MsrSubjectPointRankgroup>  savePointRankgroups = new ArrayList<>();//知识点分组
50
+
51
+        List<QuestionPointVo> qpoints = JSON.parseArray(paperAnalyze.getQuespointjson(), QuestionPointVo.class);//题号对应知识点
52
+        List<PointQuestionVo> pointques = JSON.parseArray(paperAnalyze.getPointjson(), PointQuestionVo.class);//知识点下题号
53
+
54
+        List<PointStudentVo> schoolStuPoints = new ArrayList<>();//每个知识点每个学生的得分
55
+        for (QuestionPointVo qpoint : qpoints) {
56
+            List<Map<String,Object>> points = qpoint.getPointids();
57
+            if(qpoint.getQlevel() == 1 || !N_Utils.isEmptyInteger(qpoint.getMptqid())){
58
+                //说明本题是单题,获取该题下所有学生的得分情况
59
+                List<MsPaperStudentQuestion> stuQuestions = stuSubjectQuestions.stream().filter(sq -> sq.getMptqid().equals(qpoint.getMptqid())).collect(Collectors.toList());
60
+                for (MsPaperStudentQuestion sq : stuQuestions) {
61
+                    setQuestionPointsForStuQuestion(schoolStuPoints, sq, points, qpoint.getMptqid().toString());
62
+                }
63
+            }else{
64
+                //说明试题为复合题,先获取所有子题
65
+                List<Integer> mptqids = qpoint.getMptqids();
66
+                String mptqidsStr = mptqids.stream().map(Object::toString).collect(Collectors.joining(","));
67
+                List<MsPaperStudentQuestion> stuQuestions = stuSubjectQuestions.stream().filter(sq -> mptqids.contains(sq.getMptqid())).collect(Collectors.toList());
68
+                //根据每个学生id,获取学生对应试题的分值
69
+                Map<Integer,List<MsPaperStudentQuestion>> stuQuestionMap = stuQuestions.stream().collect(Collectors.groupingBy(MsPaperStudentQuestion::getStudentid));
70
+                for (Map.Entry<Integer, List<MsPaperStudentQuestion>> entry : stuQuestionMap.entrySet()){
71
+                    List<MsPaperStudentQuestion> stuQuess = entry.getValue();
72
+                    Double stuScore = stuQuess.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).sum();
73
+                    stuScore = N_Utils.formatDouble(stuScore, 1);
74
+                    MsPaperStudentQuestion sq = new MsPaperStudentQuestion();
75
+                    sq.setStudentid(entry.getKey());
76
+                    sq.setStuscore(stuScore);
77
+                    setQuestionPointsForStuQuestion(schoolStuPoints, sq, points, mptqidsStr);
78
+                }
79
+            }
80
+
81
+        }
82
+
83
+        //学科总分区间学生
84
+        List<MsrSubjectPointSection> pointSections = setPointSection(sturanks,pscore);
85
+
86
+        // 根据试卷知识点分析进行生成学生、年级知识点分析
87
+        for (PointQuestionVo pqvo : pointques){
88
+            List<QuestionPointVo> quePoints = pqvo.getQues();//知识点下试题
89
+            //获取所有试题的mptqids
90
+            List<Integer> mptqids = new ArrayList<>();
91
+            for(QuestionPointVo qpv : quePoints){
92
+                mptqids.addAll(qpv.getMptqids());
93
+            }
94
+            //获取试题对应的qn
95
+            List<MsPaperQtypeQuestion> qtypeQues =  qtypeQuestions.stream().filter(q -> mptqids.contains(q.getMptqid())).collect(Collectors.toList());
96
+            String qnStr = qtypeQues.stream().map(q -> q.getMptqn()  + "." + q.getQn()).collect(Collectors.joining(","));
97
+            String mptqidStr = mptqids.stream().map(Object::toString).collect(Collectors.joining(","));
98
+            // 单个知识点学生得分情况:一个知识对应一个或多个试题,
99
+            List<PointStudentVo> stuPoints = schoolStuPoints.stream().filter(ps -> ps.getPointid().equals(pqvo.getPointid())).collect(Collectors.toList());
100
+            //知识点下多个试题,处理成单个学生总分值情况
101
+            List<PointStudentVo> pointStuScores = new ArrayList<>();//处理成学生知识点形式,后续计算使用
102
+            Map<Integer, List<PointStudentVo>> pointStuMap = stuPoints.stream().collect(Collectors.groupingBy(PointStudentVo::getStudentid));
103
+            for (Map.Entry<Integer, List<PointStudentVo>> entry : pointStuMap.entrySet()){
104
+                List<PointStudentVo> pstuScores = entry.getValue();
105
+                Double stuScore = pstuScores.stream().mapToDouble(PointStudentVo::getStuscore).sum();
106
+                stuScore = N_Utils.formatDouble(stuScore, 1);
107
+                PointStudentVo firstPointStuVo = pstuScores.get(0);
108
+                PointStudentVo pstuvo = new PointStudentVo();
109
+                pstuvo.setStudentid(entry.getKey());
110
+                pstuvo.setPointid(firstPointStuVo.getPointid());
111
+                pstuvo.setStuscore(stuScore);
112
+                pstuvo.setScore(firstPointStuVo.getScore());
113
+                pointStuScores.add(pstuvo);
114
+            }
115
+
116
+            MsrSubjectPoint subjectPoint = new MsrSubjectPoint();
117
+            subjectPoint.setExamid(examid);
118
+            subjectPoint.setSubjectid(subjectid);
119
+            subjectPoint.setPointid(pqvo.getPointid());
120
+            subjectPoint.setClassid(0);
121
+            subjectPoint.setPointname(pqvo.getPointname());
122
+            subjectPoint.setFullscore(pqvo.getScore());
123
+            subjectPoint.setPointlevel(3);//3级知识点分析
124
+            subjectPoint.setMptqids(mptqidStr);
125
+            subjectPoint.setQns(qnStr);
126
+
127
+            //校知识点分析
128
+            MsrSubjectPoint schoolPoint = pointLevelClass(pointStuScores, subjectPoint);
129
+            saveSubjectPoints.add(schoolPoint);
130
+
131
+            //班级知识点分析
132
+            List<Integer> classIds = classStus.stream().map(MsClassStudent::getClassid).distinct().collect(Collectors.toList());
133
+            List<MsrSubjectPoint> classPoints = new ArrayList<>();
134
+            for (Integer classid : classIds) {
135
+                // 获取班级下学生id
136
+                List<Integer> classStuIds = classStus.stream().filter(c -> c.getClassid().equals(classid)).map(MsClassStudent::getStudentid).collect(Collectors.toList());
137
+                // 获取班级下学生试题
138
+                List<PointStudentVo> classStuPoints = pointStuScores.stream().filter(q -> classStuIds.contains(q.getStudentid())).collect(Collectors.toList());
139
+                subjectPoint.setClassid(classid);
140
+                MsrSubjectPoint classPoint = pointLevelClass(classStuPoints, subjectPoint);
141
+                classPoints.add(classPoint);
142
+            }
143
+
144
+            // 班级知识点保存后,要对平均分排序
145
+            List<Double> avgScores = classPoints.stream().map(MsrSubjectPoint::getAvgscore).collect(Collectors.toList());
146
+            Map<Double,Integer> avgScoreRankMap = MarkingUtil.fspm(avgScores);
147
+            for(MsrSubjectPoint sp : classPoints){
148
+                sp.setAvgrank(avgScoreRankMap.get(sp.getAvgscore()));
149
+            }
150
+            saveSubjectPoints.addAll(classPoints);
151
+
152
+            //知识点结构与总分的相关性(三级知识点)
153
+            List<MsrSubjectPointSection> pointSecs = pointSection(pointStuScores, pointSections, pqvo, 3);
154
+            savePointSections.addAll(pointSecs);
155
+
156
+            //知识点机构考生分组分析
157
+
158
+            double schoolSumScore = pointStuScores.stream().mapToDouble(PointStudentVo::getStuscore).sum();
159
+            int stunum = pointStuScores.size();
160
+            double schoolAvgScore = MarkingUtil.div(schoolSumScore, stunum);
161
+            double schoolScoreRate = MarkingUtil.calculateRate(schoolSumScore, pqvo.getScore() * stunum);
162
+
163
+            //处理学生得分情况
164
+            for(PointStudentVo pstuvo : pointStuScores){
165
+                MsrStudentPoint stuPoint = new MsrStudentPoint();
166
+                stuPoint.setExamid(examid);
167
+                stuPoint.setSubjectid(subjectid);
168
+                stuPoint.setStudentid(pstuvo.getStudentid());
169
+                stuPoint.setPointid(pqvo.getPointid());
170
+                stuPoint.setPointname(pqvo.getPointname());
171
+                stuPoint.setFullscore(pqvo.getScore());
172
+                stuPoint.setStuscore(pstuvo.getStuscore());
173
+                stuPoint.setSturate(MarkingUtil.calculateRate(pstuvo.getStuscore(), pqvo.getScore()));
174
+                stuPoint.setSchoolavg(schoolAvgScore);
175
+                stuPoint.setSchoolrate(schoolScoreRate);
176
+                stuPoint.setQns(qnStr);
177
+                stuPoint.setMptqid(mptqidStr);
178
+                saveStuPoints.add(stuPoint);
179
+            }
180
+        }
181
+
182
+    }
183
+
184
+    // 知识点:设置每个学生每个试题知识点得分
185
+    private void setQuestionPointsForStuQuestion(List<PointStudentVo> schoolStuPoints, MsPaperStudentQuestion sq, List<Map<String,Object>> points, String mptqids) {
186
+        if (points.size() == 1) {
187
+            Map<String, Object> pointmap = points.get(0);
188
+            // 说明该试题仅有一个知识点得分直接为改知识点分值
189
+            PointStudentVo pscvo = new PointStudentVo();
190
+            pscvo.setStudentid(sq.getStudentid());
191
+            pscvo.setStuscore(sq.getStuscore());
192
+            pscvo.setPointid(pointmap.get("pointid").toString());
193
+            pscvo.setMptqids(mptqids);
194
+            schoolStuPoints.add(pscvo);
195
+        } else {
196
+            // 计算每个知识点所占分值(平均分配)
197
+            Double[] avgps = N_Utils.getPointAvgScore(points.size(), sq.getStuscore());
198
+            for (int j = 0; j < points.size(); j++) {
199
+                Map<String, Object> pointmap = points.get(j);
200
+                PointStudentVo pscvo = new PointStudentVo();
201
+                pscvo.setStudentid(sq.getStudentid());
202
+                pscvo.setPointid(pointmap.get("pointid").toString());
203
+                pscvo.setMptqids(mptqids);
204
+                if (avgps.length == 2 && (j + 1) == points.size()) {
205
+                    pscvo.setStuscore(avgps[1]);
206
+                } else {
207
+                    pscvo.setStuscore(avgps[0]);
208
+                }
209
+                schoolStuPoints.add(pscvo);
210
+            }
211
+        }
212
+    }
213
+
214
+    //知识点分析--班级知识点
215
+    private MsrSubjectPoint pointLevelClass(List<PointStudentVo> pointStuScores, MsrSubjectPoint subjectPoint){
216
+        List<Double> stuScores = pointStuScores.stream().map(PointStudentVo::getStuscore).collect(Collectors.toList());
217
+        double sumScore = pointStuScores.stream().mapToDouble(PointStudentVo::getStuscore).sum();
218
+        int stuNum = pointStuScores.size();
219
+        double stuScoreRate = MarkingUtil.calculateRate(sumScore, pointStuScores.stream().mapToDouble(PointStudentVo::getScore).sum());
220
+        MsrSubjectPoint classPoint = new MsrSubjectPoint();
221
+        classPoint.setExamid(subjectPoint.getExamid());
222
+        classPoint.setSubjectid(subjectPoint.getSubjectid());
223
+        classPoint.setClassid(subjectPoint.getClassid());
224
+        classPoint.setPointlevel(subjectPoint.getPointlevel());
225
+        classPoint.setPointid(subjectPoint.getPointid());
226
+        classPoint.setPointname(subjectPoint.getPointname());
227
+        classPoint.setFullscore(subjectPoint.getFullscore());
228
+        classPoint.setMaxscore(pointStuScores.stream().mapToDouble(PointStudentVo::getStuscore).max().orElse(0.0));
229
+        classPoint.setMinscore(pointStuScores.stream().mapToDouble(PointStudentVo::getStuscore).min().orElse(0.0));
230
+        classPoint.setScorerate(MarkingUtil.calculateRate(sumScore, subjectPoint.getFullscore() * stuNum));
231
+        classPoint.setAvgscore(MarkingUtil.div(sumScore, stuNum));
232
+        classPoint.setAvgrate(MarkingUtil.calculateRate(classPoint.getAvgscore(), subjectPoint.getFullscore()));
233
+        classPoint.setBzc(MarkingUtil.bzc(stuScores));
234
+        classPoint.setCyxs(MarkingUtil.div(classPoint.getBzc(), classPoint.getAvgscore()));
235
+        classPoint.setQfd(MarkingUtil.qfd(stuScores));
236
+        classPoint.setJbzs(MarkingUtil.jbzs(stuScores, stuScoreRate));
237
+        classPoint.setQns(subjectPoint.getQns());
238
+        classPoint.setMptqids(subjectPoint.getMptqids());
239
+        return classPoint;
240
+    }
241
+
242
+    // 知识点-科目分段-默认5分一段为后续试题在段上学生得分率做准备
243
+    private List<MsrSubjectPointSection> setPointSection(List<MsrStudent> StuPapers, Double pscore) {
244
+        // 把科目总分分段,默认5分一段
245
+        List<RankGroupVo> fdList = MarkingUtil.fdScore(pscore, 5);
246
+        List<MsrSubjectPointSection> sections = new ArrayList<>();
247
+        MsrStudent fdStuPaper = StuPapers.get(0);
248
+        for (RankGroupVo fd : fdList) {
249
+            // 获取学生得分在指定区间的学生
250
+            List<MsrStudent> fdStuPapers;
251
+            if (fd.getMaxvalue() == pscore) {
252
+                fdStuPapers = StuPapers.stream().filter(s -> s.getStuscore() >= fd.getMinvalue()).collect(Collectors.toList());
253
+            } else {
254
+                fdStuPapers = StuPapers.stream().filter(s -> s.getStuscore() >= fd.getMinvalue() && s.getStuscore() < fd.getMaxvalue()).collect(Collectors.toList());
255
+            }
256
+
257
+            MsrSubjectPointSection question = new MsrSubjectPointSection();
258
+            question.setExamid(fdStuPaper.getExamid());
259
+            question.setSubjectid(fdStuPaper.getSubjectid());
260
+            question.setFdfw(fd.getGroupname());
261
+            question.setFdnum(fdStuPapers.size());
262
+            question.setFdids(fdStuPapers.stream().map(s -> s.getStudentid().toString()).collect(Collectors.joining(",")));
263
+            sections.add(question);
264
+        }
265
+        return sections;
266
+    }
267
+    //知识点-与总分分数区间相关性分析
268
+    private List<MsrSubjectPointSection> pointSection(List<PointStudentVo> pointStuScores,List<MsrSubjectPointSection> sections,PointQuestionVo pqvo,Integer pointlevel){
269
+        List<MsrSubjectPointSection> rtnList = new ArrayList<>();
270
+        for(MsrSubjectPointSection section : sections){
271
+            String[] userids = section.getFdids().split(",");
272
+            List<String> useridList = Arrays.asList(userids);
273
+            List<PointStudentVo> sectionStuPoints = pointStuScores.stream().filter(q -> useridList.contains(q.getStudentid().toString())).collect(Collectors.toList());
274
+            // 获取总分
275
+            double sumScore = sectionStuPoints.stream().mapToDouble(PointStudentVo::getStuscore).sum();
276
+            int stuNum = sectionStuPoints.size();
277
+            // 获取平均分
278
+            double avgScore = MarkingUtil.div(sumScore, stuNum);
279
+            // 获取平均得分率
280
+            double avgScoreRate = MarkingUtil.calculateRate(avgScore, pqvo.getScore());
281
+            section.setAvgrate(avgScoreRate);
282
+            section.setAvgscore(avgScore);
283
+            section.setPointlevel(pointlevel);
284
+            section.setPointid(pqvo.getPointid());
285
+            section.setPointname(pqvo.getPointname());
286
+            rtnList.add(section);
287
+        }
288
+        return rtnList;
289
+    }
290
+
291
+    //知识点-考试排名分组分析
292
+    private List<MsrSubjectPointRankgroup> questionScoreRankGroup(List<PointStudentVo> pointStuScores, List<MsrStudent> stuPapers, PointQuestionVo pqvo,Integer examid,String subjectid, Integer pointlevel){
293
+        //获取学生排名最大名次的树
294
+        Integer totalRank = stuPapers.stream().mapToInt(MsrStudent::getSchoolrank).max().orElse(0);
295
+        //获取排名分组,默认分为7组
296
+        List<RankGroupVo> rankGroups = MarkingUtil.rankGroup(totalRank,7);
297
+        //获取知识点分段,1分1段
298
+        List<RankGroupVo> sectionScores = MarkingUtil.fdScore(pqvo.getScore(),5);
299
+
300
+
301
+        List<MsrSubjectPointRankgroup> rtnList = new ArrayList<>();
302
+        for (RankGroupVo rankGroup : rankGroups) {
303
+            //名次下学生信息
304
+            List<MsrStudent> groupStus = stuPapers.stream().filter(s -> s.getSchoolrank() >= rankGroup.getMinvalue() && s.getSchoolrank() <= rankGroup.getMaxvalue()).collect(Collectors.toList());
305
+            MsrSubjectPointRankgroup sqr = new MsrSubjectPointRankgroup();
306
+            sqr.setExamid(examid);
307
+            sqr.setSubjectid(subjectid);
308
+            sqr.setPointid(pqvo.getPointid());
309
+            sqr.setPointname(pqvo.getPointname());
310
+            sqr.setPointlevel(pointlevel);
311
+            sqr.setRgroup(rankGroup.getGroupname());
312
+
313
+            List<Integer> groupStuids;
314
+            List<PointStudentVo> groupStuPoints = null;
315
+            if(!groupStus.isEmpty()){
316
+                groupStuids = groupStus.stream().map(MsrStudent::getStudentid).collect(Collectors.toList());
317
+                //名次下学生试题作答情况
318
+                groupStuPoints = pointStuScores.stream().filter(q -> groupStuids.contains(q.getStudentid())).collect(Collectors.toList());
319
+                sqr.setStunum(groupStuPoints.size());
320
+                sqr.setStuids(groupStuPoints.stream().map(q -> q.getStudentid().toString()).collect(Collectors.joining(",")));
321
+            } else {
322
+                groupStuids = null;
323
+                sqr.setStunum(0);
324
+            }
325
+
326
+            //试题分段区间
327
+            for(RankGroupVo sectionScore : sectionScores){
328
+                MsrSubjectPointRankgroup sqrg = new MsrSubjectPointRankgroup();
329
+                sqrg.setExamid(examid);
330
+                sqrg.setSubjectid(subjectid);
331
+                sqrg.setPointid(pqvo.getPointid());
332
+                sqrg.setPointname(pqvo.getPointname());
333
+                sqrg.setPointlevel(pointlevel);
334
+                sqrg.setRgroup(rankGroup.getGroupname());
335
+                sqrg.setRsection(sectionScore.getGroupname());
336
+
337
+                if(groupStuids != null && !groupStuids.isEmpty()){
338
+                    //名次分组下有学生,进行学生分数段计算
339
+                    List<PointStudentVo> sectionStuQuestions;
340
+                    if(sectionScore.getMinvalue() == pqvo.getScore()){
341
+                        //最小值为满分时分段形式为[qscore,qscore)
342
+                        sectionStuQuestions = groupStuPoints.stream().filter(q -> q.getStuscore() >= sectionScore.getMinvalue()).collect(Collectors.toList());
343
+                    }else{
344
+                        sectionStuQuestions = groupStuPoints.stream().filter(q -> q.getStuscore() >= sectionScore.getMinvalue() && q.getStuscore() < sectionScore.getMaxvalue()).collect(Collectors.toList());
345
+                    }
346
+                    // double sectionStuSumScore = sectionStuQuestions.stream().mapToDouble(PointStudentVo::getStuscore).sum();
347
+                    // double sectionStuAvgScore = MarkingUtil.div(sectionStuSumScore, sectionStuQuestions.size());
348
+                    sqrg.setStunum(sectionStuQuestions.size());
349
+                    sqrg.setStuids(sectionStuQuestions.stream().map(q -> q.getStudentid().toString()).collect(Collectors.joining(",")));
350
+                }else{
351
+                    sqrg.setStunum(0);
352
+                }
353
+
354
+                rtnList.add(sqrg);
355
+            }
356
+
357
+            rtnList.add(sqr);
358
+        }
359
+        return rtnList;
29
     }
360
     }
30
 }
361
 }

+ 4
- 4
smarking/src/main/java/com/xhkjedu/smarking/service/report/generate/ReportGenerateQuestionService.java View File

383
                 sqrg.setMptqid(mptqid);
383
                 sqrg.setMptqid(mptqid);
384
                 sqrg.setRgroup(rankGroup.getGroupname());
384
                 sqrg.setRgroup(rankGroup.getGroupname());
385
                 sqrg.setRgtype(2);
385
                 sqrg.setRgtype(2);
386
-                sqrg.setRgvalue(sectionScore.getSectionname());
386
+                sqrg.setRsection(sectionScore.getSectionname());
387
 
387
 
388
                 if(groupStuids != null && !groupStuids.isEmpty()){
388
                 if(groupStuids != null && !groupStuids.isEmpty()){
389
                     //名次分组下有学生,进行学生分数段计算
389
                     //名次分组下有学生,进行学生分数段计算
423
                     optionObj.setQntype(1);
423
                     optionObj.setQntype(1);
424
                     optionObj.setRgroup(rankGroup.getGroupname());
424
                     optionObj.setRgroup(rankGroup.getGroupname());
425
                     optionObj.setRgtype(1);
425
                     optionObj.setRgtype(1);
426
-                    optionObj.setRgvalue(optionStr);
426
+                    optionObj.setRsection(optionStr);
427
 
427
 
428
                     List<MsPaperStudentQuestion> optionStuQuestions;
428
                     List<MsPaperStudentQuestion> optionStuQuestions;
429
                     if(groupStuQuestions != null && !groupStuQuestions.isEmpty()){
429
                     if(groupStuQuestions != null && !groupStuQuestions.isEmpty()){
464
             // 获取学生得分在指定区间的学生
464
             // 获取学生得分在指定区间的学生
465
             List<MsrStudent> fdStuPapers;
465
             List<MsrStudent> fdStuPapers;
466
             if (fd.getMaxvalue() == pscore) {
466
             if (fd.getMaxvalue() == pscore) {
467
-                fdStuPapers = StuPapers.stream().filter(s -> s.getStuscore() >= fd.getMinvalue() && s.getStuscore() <= fd.getMaxvalue()).collect(Collectors.toList());
467
+                fdStuPapers = StuPapers.stream().filter(s -> s.getStuscore() >= fd.getMinvalue()).collect(Collectors.toList());
468
             } else {
468
             } else {
469
                 fdStuPapers = StuPapers.stream().filter(s -> s.getStuscore() >= fd.getMinvalue() && s.getStuscore() < fd.getMaxvalue()).collect(Collectors.toList());
469
                 fdStuPapers = StuPapers.stream().filter(s -> s.getStuscore() >= fd.getMinvalue() && s.getStuscore() < fd.getMaxvalue()).collect(Collectors.toList());
470
             }
470
             }
480
         return sections;
480
         return sections;
481
     }
481
     }
482
 
482
 
483
-    // 单个试题分析-科目分段区间得分率
483
+    // 单个试题分析-科目分段区间平均得分率
484
     private List<MsrSubjectQuestionSection> subjectSectionQuestion(List<MsPaperStudentQuestion> stuQuestions, List<MsrSubjectQuestionSection> sections,
484
     private List<MsrSubjectQuestionSection> subjectSectionQuestion(List<MsPaperStudentQuestion> stuQuestions, List<MsrSubjectQuestionSection> sections,
485
                             Integer qtype,Double fullScore,Integer mptqid) {
485
                             Integer qtype,Double fullScore,Integer mptqid) {
486
         List<MsrSubjectQuestionSection> rtnList = new ArrayList<>();
486
         List<MsrSubjectQuestionSection> rtnList = new ArrayList<>();

+ 1
- 2
smarking/src/main/java/com/xhkjedu/smarking/utils/MarkingUtil.java View File

466
         if (N_Utils.isListEmpty(list)) return modes;
466
         if (N_Utils.isListEmpty(list)) return modes;
467
 
467
 
468
         // 使用HashMap来统计每个元素出现的次数
468
         // 使用HashMap来统计每个元素出现的次数
469
-        Map<Double, Long> countMap = list.stream()
470
-                                         .collect(Collectors.groupingBy(e -> e, Collectors.counting()));
469
+        Map<Double, Long> countMap = list.stream().collect(Collectors.groupingBy(e -> e, Collectors.counting()));
471
 
470
 
472
         long maxCount = 0;
471
         long maxCount = 0;
473
         // 找出最大的出现次数
472
         // 找出最大的出现次数

+ 25
- 0
smarking/src/main/java/com/xhkjedu/smarking/vo/report/reportstu/PointQuestionVo.java View File

1
+package com.xhkjedu.smarking.vo.report.reportstu;
2
+
3
+import com.xhkjedu.smarking.vo.paper.QuestionPointVo;
4
+import lombok.Data;
5
+
6
+import java.util.List;
7
+
8
+/**
9
+ * @Description:知识点下试题
10
+ * @Author: WN
11
+ * @Date: 2024/12/17 9:51:04
12
+ **/
13
+@Data
14
+public class PointQuestionVo {
15
+
16
+    private String pointid;//知识点id
17
+
18
+    private String pointname;//知识点名称
19
+
20
+    private Double score;//知识点分数
21
+
22
+    private Double srate;//知识点试卷占比
23
+
24
+    private List<QuestionPointVo> ques;//知识点包含试题
25
+}

+ 21
- 0
smarking/src/main/java/com/xhkjedu/smarking/vo/report/reportstu/PointStudentVo.java View File

1
+package com.xhkjedu.smarking.vo.report.reportstu;
2
+
3
+import lombok.Data;
4
+
5
+/**
6
+ * @Description:学生知识点
7
+ * @Author: WN
8
+ * @Date: 2024/12/16 17:49:01
9
+ **/
10
+@Data
11
+public class PointStudentVo {
12
+    private Integer studentid;//学生id
13
+
14
+    private String pointid;//知识点id
15
+
16
+    private Double score;//试题分值
17
+
18
+    private Double stuscore;//学生得分
19
+
20
+    private String mptqids;//试题id
21
+}

+ 1
- 1
smarking/src/main/resources/mapper/paper/MsPaperMapper.xml View File

79
 
79
 
80
     <!--获取试卷ID及考试模式-->
80
     <!--获取试卷ID及考试模式-->
81
     <select id="getPaperAndMxammodeByMsid" resultType="com.xhkjedu.smarking.vo.paper.PExamSubjectVo">
81
     <select id="getPaperAndMxammodeByMsid" resultType="com.xhkjedu.smarking.vo.paper.PExamSubjectVo">
82
-        select p.mpid,e.exammode from ms_paper p left join ms_exam e on p.examid=e.examidwhere p.msid=#{msid}
82
+        select p.mpid,e.exammode from ms_paper p left join ms_exam e on p.examid=e.examid where p.msid=#{msid}
83
     </select>
83
     </select>
84
     <!--根据考试id和科目id获取试卷信息-->
84
     <!--根据考试id和科目id获取试卷信息-->
85
     <select id="getPaperByExamIdAndSubjectId" resultType="com.xhkjedu.smarking.model.paper.MsPaper">
85
     <select id="getPaperByExamIdAndSubjectId" resultType="com.xhkjedu.smarking.model.paper.MsPaper">

+ 1
- 1
smarking/src/main/resources/mapper/paper/MsPaperQtypeQuestionMapper.xml View File

137
 
137
 
138
     <!--试卷中所有试题-考试报告-->
138
     <!--试卷中所有试题-考试报告-->
139
     <select id="listQuestionsForReport" resultType="com.xhkjedu.smarking.model.paper.MsPaperQtypeQuestion">
139
     <select id="listQuestionsForReport" resultType="com.xhkjedu.smarking.model.paper.MsPaperQtypeQuestion">
140
-        select q.mptqid,q.mptid,q.mpid,q.ctype,q.qtype,q.questionid,q.qtypeid,q.qtypename,q.qn,
140
+        select q.mptqid,q.mptid,q.mpid,q.ctype,q.qtype,q.questionid,q.qtypeid,q.qtypename,q.qn,q.questionid,q.questionpid,
141
         q.qscore,q.qorder,q.optionnum,q.qanswer,qt.mptqn,qt.mptnum,qt.mptscore
141
         q.qscore,q.qorder,q.optionnum,q.qanswer,qt.mptqn,qt.mptnum,qt.mptscore
142
         from ms_paper_qtype_question q left join ms_paper_qtype qt on q.mptid=qt.mptid
142
         from ms_paper_qtype_question q left join ms_paper_qtype qt on q.mptid=qt.mptid
143
         where q.mpid=#{mpid} order by qt.mptorder,q.qorder
143
         where q.mpid=#{mpid} order by qt.mptorder,q.qorder

smarking/src/main/resources/mapper/report/reportsubject/MsrSubjectPointGroupMapper.xml → smarking/src/main/resources/mapper/report/reportsubject/MsrSubjectPointRankgroupMapper.xml View File

1
 <?xml version="1.0" encoding="UTF-8"?>
1
 <?xml version="1.0" encoding="UTF-8"?>
2
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
2
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3
-<mapper namespace="com.xhkjedu.smarking.mapper.report.reportsubject.MsrSubjectPointGroupMapper">
3
+<mapper namespace="com.xhkjedu.smarking.mapper.report.reportsubject.MsrSubjectPointRankgroupMapper">
4
 </mapper>
4
 </mapper>

Loading…
Cancel
Save