Selaa lähdekoodia

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

ywx
王宁 3 viikkoa sitten
vanhempi
commit
0fa2a5fd3b
16 muutettua tiedostoa jossa 423 lisäystä ja 38 poistoa
  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 Näytä tiedosto

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

+ 1
- 1
smarking/src/main/java/com/xhkjedu/smarking/mapper/paper/MsPaperMapper.java Näytä tiedosto

@@ -55,7 +55,7 @@ public interface MsPaperMapper extends TkMapper<MsPaper> {
55 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 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 Näytä tiedosto

@@ -1,12 +1,12 @@
1 1
 package com.xhkjedu.smarking.mapper.report.reportsubject;
2 2
 
3 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 7
  * @Description 阅卷报告-学科知识点分段区间表 Mapper 接口
8 8
  * @Author auto
9 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 Näytä tiedosto

@@ -25,18 +25,18 @@ public class MsrStudentPoint extends BaseBean {
25 25
     private Integer studentid;
26 26
     //知识点ID
27 27
     private String pointid;
28
+    //知识点名称
29
+    private String pointname;
30
+    //知识点分数
31
+    private Double fullscore;
28 32
     //学生得分
29 33
     private Double stuscore;
30 34
     //学生得分率
31 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 41
     private String qns;
42 42
     //知识点对应试题ID

+ 5
- 9
smarking/src/main/java/com/xhkjedu/smarking/model/report/reportsubject/MsrSubjectPoint.java Näytä tiedosto

@@ -25,22 +25,18 @@ public class MsrSubjectPoint extends BaseBean {
25 25
     private Integer classid;
26 26
     //知识点ID
27 27
     private String pointid;
28
+    //知识点名称
29
+    private String pointname;
28 30
     //知识点级别1一级2二级3三级
29 31
     private Integer pointlevel;
30 32
     //满分
31 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 35
     private Double maxscore;
42 36
     //最低分
43 37
     private Double minscore;
38
+    //得分率
39
+    private Double scorerate;
44 40
     //平均分
45 41
     private Double avgscore;
46 42
     //平均得分率%
@@ -54,7 +50,7 @@ public class MsrSubjectPoint extends BaseBean {
54 50
     //区分度
55 51
     private Double qfd;
56 52
     //鉴定指数
57
-    private Double jdzs;
53
+    private Double jbzs;
58 54
     //对应试题ids
59 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 Näytä tiedosto

@@ -12,8 +12,8 @@ import javax.persistence.Table;
12 12
  * @Date 2024-12-09
13 13
  */
14 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 17
     @Id
18 18
     //阅卷报告-学科知识点排名分组
19 19
     private Integer spgid;
@@ -23,12 +23,14 @@ public class MsrSubjectPointGroup extends BaseBean {
23 23
     private String subjectid;
24 24
     //知识点ID
25 25
     private String pointid;
26
+    //知识点名称
27
+    private String pointname;
26 28
     //知识点层级1一级2二级3三级
27 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 35
     private Integer stunum;
34 36
     //学生ids

+ 11
- 1
smarking/src/main/java/com/xhkjedu/smarking/model/report/reportsubject/MsrSubjectPointSection.java Näytä tiedosto

@@ -5,6 +5,7 @@ import lombok.Data;
5 5
 
6 6
 import javax.persistence.Id;
7 7
 import javax.persistence.Table;
8
+import javax.persistence.Transient;
8 9
 
9 10
 /**
10 11
  * @Description 阅卷报告-学科知识点分段区间表
@@ -23,10 +24,19 @@ public class MsrSubjectPointSection extends BaseBean {
23 24
     private String subjectid;
24 25
     //知识点ID
25 26
     private String pointid;
27
+    //知识点名称
28
+    private String pointname;
26 29
     //知识点层级1一级2二级3三级
27 30
     private Integer pointlevel;
28 31
     //分数段范围
29
-    private String scoresection;
32
+    private String fdfw;
33
+    //平均分
34
+    private Double avgscore;
30 35
     //平均得分率
31 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 Näytä tiedosto

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

+ 334
- 3
smarking/src/main/java/com/xhkjedu/smarking/service/report/generate/ReportGeneratePointService.java Näytä tiedosto

@@ -2,13 +2,29 @@ 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.model.exam.MsClassStudent;
5 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 13
 import com.xhkjedu.smarking.model.stupaper.MsPaperStudentQuestion;
14
+import com.xhkjedu.smarking.utils.MarkingUtil;
7 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 20
 import org.springframework.stereotype.Service;
9 21
 
10 22
 import javax.annotation.Resource;
23
+import java.util.ArrayList;
24
+import java.util.Arrays;
11 25
 import java.util.List;
26
+import java.util.Map;
27
+import java.util.stream.Collectors;
12 28
 
13 29
 /**
14 30
  * @Description:生成知识点相关分析
@@ -20,11 +36,326 @@ public class ReportGeneratePointService {
20 36
     @Resource
21 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 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 Näytä tiedosto

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

+ 1
- 2
smarking/src/main/java/com/xhkjedu/smarking/utils/MarkingUtil.java Näytä tiedosto

@@ -466,8 +466,7 @@ public class MarkingUtil {
466 466
         if (N_Utils.isListEmpty(list)) return modes;
467 467
 
468 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 471
         long maxCount = 0;
473 472
         // 找出最大的出现次数

+ 25
- 0
smarking/src/main/java/com/xhkjedu/smarking/vo/report/reportstu/PointQuestionVo.java Näytä tiedosto

@@ -0,0 +1,25 @@
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 Näytä tiedosto

@@ -0,0 +1,21 @@
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 Näytä tiedosto

@@ -79,7 +79,7 @@
79 79
 
80 80
     <!--获取试卷ID及考试模式-->
81 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 83
     </select>
84 84
     <!--根据考试id和科目id获取试卷信息-->
85 85
     <select id="getPaperByExamIdAndSubjectId" resultType="com.xhkjedu.smarking.model.paper.MsPaper">

+ 1
- 1
smarking/src/main/resources/mapper/paper/MsPaperQtypeQuestionMapper.xml Näytä tiedosto

@@ -137,7 +137,7 @@
137 137
 
138 138
     <!--试卷中所有试题-考试报告-->
139 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 141
         q.qscore,q.qorder,q.optionnum,q.qanswer,qt.mptqn,qt.mptnum,qt.mptscore
142 142
         from ms_paper_qtype_question q left join ms_paper_qtype qt on q.mptid=qt.mptid
143 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 Näytä tiedosto

@@ -1,4 +1,4 @@
1 1
 <?xml version="1.0" encoding="UTF-8"?>
2 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 4
 </mapper>

Loading…
Peruuta
Tallenna