Kaynağa Gözat

工具类,题型分析

ywx
王宁 1 ay önce
ebeveyn
işleme
dcde82a7e9

+ 0
- 12
smarking/src/main/java/com/xhkjedu/smarking/mapper/report/reportclass/MsrClassQuestionRankgroupMapper.java Dosyayı Görüntüle

@@ -1,12 +0,0 @@
1
-package com.xhkjedu.smarking.mapper.report.reportclass;
2
-
3
-import com.xhkjedu.base.TkMapper;
4
-import com.xhkjedu.smarking.model.report.reportclass.MsrClassQuestionRankgroup;
5
-
6
-/**
7
- * @Description 阅卷报告-试题小题排名分组分析表 Mapper 接口
8
- * @Author auto
9
- * @Date 2024-12-09
10
- */
11
-public interface MsrClassQuestionRankgroupMapper extends TkMapper<MsrClassQuestionRankgroup> {
12
-}

+ 12
- 0
smarking/src/main/java/com/xhkjedu/smarking/mapper/report/reportsubject/MsrSubjectQuestionRankgroupMapper.java Dosyayı Görüntüle

@@ -0,0 +1,12 @@
1
+package com.xhkjedu.smarking.mapper.report.reportsubject;
2
+
3
+import com.xhkjedu.base.TkMapper;
4
+import com.xhkjedu.smarking.model.report.reportsubject.MsrSubjectQuestionRankgroup;
5
+
6
+/**
7
+ * @Description 阅卷报告-试题小题排名分组分析表 Mapper 接口
8
+ * @Author auto
9
+ * @Date 2024-12-09
10
+ */
11
+public interface MsrSubjectQuestionRankgroupMapper extends TkMapper<MsrSubjectQuestionRankgroup> {
12
+}

smarking/src/main/java/com/xhkjedu/smarking/mapper/report/reportsubject/MsrSubjectSectionQuestionMapper.java → smarking/src/main/java/com/xhkjedu/smarking/mapper/report/reportsubject/MsrSubjectQuestionSectionMapper.java Dosyayı Görüntüle

@@ -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.MsrSubjectSectionQuestion;
4
+import com.xhkjedu.smarking.model.report.reportsubject.MsrSubjectQuestionSection;
5 5
 
6 6
 /**
7 7
  * @Description 阅卷报告-科目区间试题得分率表 Mapper 接口
8 8
  * @Author auto
9 9
  * @Date 2024-12-12
10 10
  */
11
-public interface MsrSubjectSectionQuestionMapper extends TkMapper<MsrSubjectSectionQuestion> {
11
+public interface MsrSubjectQuestionSectionMapper extends TkMapper<MsrSubjectQuestionSection> {
12 12
 }

+ 2
- 0
smarking/src/main/java/com/xhkjedu/smarking/model/report/reportclass/MsrClassQtype.java Dosyayı Görüntüle

@@ -25,6 +25,8 @@ public class MsrClassQtype extends BaseBean {
25 25
     private Integer classid;
26 26
     //题型ID
27 27
     private Integer mptid;
28
+    //题型题号
29
+    private String mptqn;
28 30
     //平均分
29 31
     private Double avgscore;
30 32
     //标准差

smarking/src/main/java/com/xhkjedu/smarking/model/report/reportclass/MsrClassQuestionRankgroup.java → smarking/src/main/java/com/xhkjedu/smarking/model/report/reportsubject/MsrSubjectQuestionRankgroup.java Dosyayı Görüntüle

@@ -1,4 +1,4 @@
1
-package com.xhkjedu.smarking.model.report.reportclass;
1
+package com.xhkjedu.smarking.model.report.reportsubject;
2 2
 
3 3
 import com.xhkjedu.model.BaseBean;
4 4
 import lombok.Data;
@@ -7,36 +7,36 @@ import javax.persistence.Id;
7 7
 import javax.persistence.Table;
8 8
 
9 9
 /**
10
- * @Description 阅卷报告-试题小题排名分组分析
10
+ * @Description 阅卷报告-科目下试题排名分组分析
11 11
  * @Author auto
12 12
  * @Date 2024-12-09
13 13
  */
14 14
 @Data
15
-@Table(name = "msr_class_question_rankgroup")
16
-public class MsrClassQuestionRankgroup extends BaseBean {
15
+@Table(name = "msr_subject_question_rankgroup")
16
+public class MsrSubjectQuestionRankgroup extends BaseBean {
17 17
     @Id
18
-    //阅卷报告-试题小题排名分组分析
19
-    private Integer cqrgid;
18
+    //阅卷报告-科目下试题排名分组分析
19
+    private Integer sqrgid;
20 20
     //考试ID
21 21
     private Integer examid;
22 22
     //科目ID
23 23
     private String subjectid;
24
+    //类型1小题2客观题3主观题
25
+    private Integer qntype;
24 26
     //试题ID
25 27
     private Integer mptqid;
26
-    //试题题号类型1小题题号2客观题3主观题
27
-    private Integer qntype;
28 28
     //分数值
29 29
     private Double rgscore;
30 30
     //组别和名次 第1组(1~70名)
31 31
     private String rgroup;
32 32
     //类型1客观题 选项 2主观题 分值
33 33
     private Integer rgtype;
34
-    //分值范围/选项
34
+    //分值范围/选项:为空代表该组情况
35 35
     private String rgvalue;
36 36
     //人数
37 37
     private Integer stunum;
38 38
     //人数ids
39 39
     private String stuids;
40
-    //占比
41
-    private Double rgrate;
40
+    //得分率
41
+    private Double scorerate;
42 42
 }

smarking/src/main/java/com/xhkjedu/smarking/model/report/reportsubject/MsrSubjectSectionQuestion.java → smarking/src/main/java/com/xhkjedu/smarking/model/report/reportsubject/MsrSubjectQuestionSection.java Dosyayı Görüntüle

@@ -12,8 +12,8 @@ import javax.persistence.Table;
12 12
  * @Date 2024-12-12
13 13
  */
14 14
 @Data
15
-@Table(name = "msr_subject_section_question")
16
-public class MsrSubjectSectionQuestion extends BaseBean {
15
+@Table(name = "msr_subject_question_section")
16
+public class MsrSubjectQuestionSection extends BaseBean {
17 17
     @Id
18 18
     //阅卷报告-科目区间试题得分率表
19 19
     private Integer sqsid;
@@ -21,6 +21,8 @@ public class MsrSubjectSectionQuestion extends BaseBean {
21 21
     private Integer examid;
22 22
     //科目ID
23 23
     private String subjectid;
24
+    //类型1小题2客观题3主观题
25
+    private Integer qntype;
24 26
     //试题ID
25 27
     private Integer mptqid;
26 28
     //分数区间范围
@@ -32,5 +34,5 @@ public class MsrSubjectSectionQuestion extends BaseBean {
32 34
     //平均分
33 35
     private Double avgscore;
34 36
     //平均得分率
35
-    private Double avgscorerate;
37
+    private Double avgrate;
36 38
 }

+ 262
- 109
smarking/src/main/java/com/xhkjedu/smarking/service/report/generate/ReportGenerateQuestionService.java Dosyayı Görüntüle

@@ -10,19 +10,22 @@ import com.xhkjedu.smarking.mapper.stupaper.MsPaperStudentQuestionMapper;
10 10
 import com.xhkjedu.smarking.model.exam.MsClassStudent;
11 11
 import com.xhkjedu.smarking.model.paper.MsPaper;
12 12
 import com.xhkjedu.smarking.model.paper.MsPaperQtypeQuestion;
13
+import com.xhkjedu.smarking.model.report.reportclass.MsrClassQtype;
13 14
 import com.xhkjedu.smarking.model.report.reportclass.MsrClassQuestion;
14 15
 import com.xhkjedu.smarking.model.report.reportclass.MsrClassQuestionObj;
15 16
 import com.xhkjedu.smarking.model.report.reportother.MsrReportparam;
16 17
 import com.xhkjedu.smarking.model.report.reportstu.MsrStudent;
17
-import com.xhkjedu.smarking.model.report.reportsubject.MsrSubjectSectionQuestion;
18
+import com.xhkjedu.smarking.model.report.reportsubject.MsrSubjectQuestionSection;
18 19
 import com.xhkjedu.smarking.model.stupaper.MsPaperStudentQuestion;
19 20
 import com.xhkjedu.smarking.utils.MarkingUtil;
21
+import com.xhkjedu.smarking.vo.report.reportother.RankGroupVo;
20 22
 import com.xhkjedu.smarking.vo.report.reportother.SzJsonVo;
21 23
 import com.xhkjedu.utils.N_Utils;
22 24
 import org.springframework.stereotype.Service;
23 25
 
24 26
 import javax.annotation.Resource;
25 27
 import java.util.ArrayList;
28
+import java.util.Arrays;
26 29
 import java.util.List;
27 30
 import java.util.Map;
28 31
 import java.util.stream.Collectors;
@@ -47,128 +50,140 @@ public class ReportGenerateQuestionService {
47 50
     @Resource
48 51
     private MsPaperStudentMapper msPaperStudentMapper;
49 52
 
50
-    public void generateQuestion(Integer examid,Integer exammode){
51
-        //查询所有学生试题
53
+    public void generateQuestion(Integer examid, Integer exammode) {
54
+        // 查询所有学生试题
52 55
         List<MsPaperStudentQuestion> stuQuestions = msPaperStudentQuestionMapper.listAllStuQuesByExamid(examid);
53 56
         List<MsClassStudent> classStudents = msClassStudentMapper.listStudentByExamId(examid);
54 57
         List<MsPaper> subjects = msSubjectMapper.listReportSubject(examid, exammode);
55 58
         List<MsrStudent> stuPapers = msPaperStudentMapper.listPaperStudentByExamId(examid, null);
56
-        //获取考试参数
57
-        List<MsrReportparam> params = msrReportparamMapper.listReportparamByRpbelong(examid,"quesummary",null);
59
+        // 获取考试参数
60
+        List<MsrReportparam> params = msrReportparamMapper.listReportparamByRpbelong(examid, "quesummary", null);
58 61
 
59
-        //根据科目进行区分
60
-        for(MsPaper subject : subjects){
62
+        // 根据科目进行区分
63
+        for (MsPaper subject : subjects) {
61 64
             String subjectid = subject.getSubjectid();
62
-            //获取科目下所有学生试题
63
-            List<MsPaperStudentQuestion> subjectStuQuestions = stuQuestions.stream().filter(stuQuestion -> stuQuestion.getSubjectid().equals(subjectid)).collect(Collectors.toList());
64
-            //科目下所有班级学生
65
+            // 获取科目下所有学生试题
66
+            List<MsPaperStudentQuestion> subjectStuQuestions =
67
+                    stuQuestions.stream().filter(stuQuestion -> stuQuestion.getSubjectid().equals(subjectid)).collect(Collectors.toList());
68
+            // 科目下所有班级学生
65 69
             List<MsClassStudent> subjectClassStudents = classStudents.stream().filter(classStudent -> classStudent.getSubjectid().equals(subjectid)).collect(Collectors.toList());
66
-            //获取试卷中所有小题基础信息包含大题信息
70
+            // 获取试卷中所有小题基础信息包含大题信息
67 71
             List<MsPaperQtypeQuestion> questions = msPaperQtypeQuestionMapper.listQuestionsForReport(subject.getMpid());
68
-            //获取科目参数
72
+            // 获取科目参数
69 73
             List<MsrReportparam> subjectParams = params.stream().filter(p -> p.getSubjectid().equals(subjectid)).collect(Collectors.toList());
70
-            //获取学生科目得分
74
+            // 获取学生科目得分
71 75
             List<MsrStudent> subjectStuPapers = stuPapers.stream().filter(p -> p.getSubjectid().equals(subjectid)).collect(Collectors.toList());
72
-
73
-            //处理小题
74
-            handleQuestion(subjectStuQuestions,subjectClassStudents,questions,subjectParams,examid,subjectid);
76
+            // 获取学生科目得分-科目默认分段学生
77
+            List<MsrSubjectQuestionSection> subjectSectionQuestions = subjectSectionForQuestion(subjectStuPapers, subject.getPscore());
78
+            // 处理小题
79
+            handleQuestion(subjectStuQuestions, subjectClassStudents, questions, subjectParams, subjectSectionQuestions, examid, subjectid);
80
+            //处理题型
81
+            handleQtype(subjectStuQuestions, subjectClassStudents, questions, subjectParams, examid, subjectid);
75 82
         }
76 83
     }
77 84
 
78
-    //处理单个试题分析
79
-    private void handleQuestion(List<MsPaperStudentQuestion> subjectStuQuestions, List<MsClassStudent> subjectClassStudents,List<MsPaperQtypeQuestion> questions,List<MsrReportparam> params,Integer examid,String subjectid){
85
+    // 单个试题分析
86
+    private void handleQuestion(List<MsPaperStudentQuestion> subjectStuQuestions, List<MsClassStudent> subjectClassStudents, List<MsPaperQtypeQuestion> questions,
87
+                                List<MsrReportparam> params, List<MsrSubjectQuestionSection> subjectSectionQuestions, Integer examid, String subjectid) {
80 88
 
81
-        List<MsrClassQuestion> saveQuestions = new ArrayList<>();//小题分析
82
-        List<MsrClassQuestionObj> saveQuestionObjs = new ArrayList<>();//小题-客观题选项分析
89
+        List<MsrClassQuestion> saveQuestions = new ArrayList<>();// 小题分析
90
+        List<MsrClassQuestionObj> saveQuestionObjs = new ArrayList<>();// 小题-客观题选项分析
91
+        List<MsrSubjectQuestionSection> saveSectionQuestions = new ArrayList<>();// 学科分段之间学生在该题的整体得分率
83 92
 
84
-        //处理小题信息
85
-        for(MsPaperQtypeQuestion question : questions){
86
-            //获取第一小题所有作答情况,全校作答情况
93
+        // 处理小题信息
94
+        for (MsPaperQtypeQuestion question : questions) {
95
+            // 获取第一小题所有作答情况,全校作答情况
87 96
             List<MsPaperStudentQuestion> stuQuestions = subjectStuQuestions.stream().filter(q -> q.getMptqid().equals(question.getMptqid())).collect(Collectors.toList());
88
-            int stunum = stuQuestions.size();//学生数量
89
-            Double sumQScore = question.getQscore() * stunum;//小题得分
90
-            List<Double> stuScores = stuQuestions.stream().map(MsPaperStudentQuestion::getStuscore).collect(Collectors.toList());//所有学生得分
97
+            int stunum = stuQuestions.size();// 学生数量
98
+            Double sumQScore = question.getQscore() * stunum;// 小题得分
99
+            List<Double> stuScores = stuQuestions.stream().map(MsPaperStudentQuestion::getStuscore).collect(Collectors.toList());// 所有学生得分
91 100
 
92
-            Double maxScore = stuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).max().orElse(0.0);//最高分
93
-            Double minScore = stuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).min().orElse(0.0);//最低分
94
-            Double avgScore = MarkingUtil.calculateAverage(stuScores);//平均分
95
-            Double avgScoreRate = MarkingUtil.calculateRate(avgScore,sumQScore);//平均得分率
101
+            Double maxScore = stuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).max().orElse(0.0);// 最高分
102
+            Double minScore = stuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).min().orElse(0.0);// 最低分
103
+            Double avgScore = MarkingUtil.calculateAverage(stuScores);// 平均分
104
+            Double avgScoreRate = MarkingUtil.calculateRate(avgScore, sumQScore);// 平均得分率
96 105
 
97 106
             MsrClassQuestion schoolQ = new MsrClassQuestion();
98
-            schoolQ.setClassid(0);//全体班级
107
+            schoolQ.setClassid(0);// 全体班级
99 108
             schoolQ.setExamid(examid);
100 109
             schoolQ.setSubjectid(subjectid);
101 110
             schoolQ.setSchoolmaxscore(maxScore);
102 111
             schoolQ.setSchoolminscore(minScore);
103 112
             schoolQ.setSchoolavgscore(avgScore);
104 113
             schoolQ.setSchoolavgrate(avgScoreRate);
105
-            //班级试题情况
106
-            MsrClassQuestion schoolQue = handleQuestionClass(stuQuestions,question,params,schoolQ);
114
+            // 全校班级试题情况
115
+            MsrClassQuestion schoolQue = questionClass(stuQuestions, question, params, schoolQ);
107 116
             saveQuestions.add(schoolQue);
108 117
 
109
-            //班级试题--客观题选项情况
118
+            // 班级试题--客观题选项情况
110 119
             MsrClassQuestionObj qobj = new MsrClassQuestionObj();
111
-            if(question.getQtype() == 1){
120
+            if (question.getQtype() == 1) {
112 121
                 qobj.setExamid(examid);
113 122
                 qobj.setSubjectid(subjectid);
114 123
                 qobj.setClassid(0);
115 124
                 qobj.setMptqid(question.getMptqid());
116
-                List<MsrClassQuestionObj> qobjList = handleQuestionXuanxiang(stuQuestions,qobj);
125
+                List<MsrClassQuestionObj> qobjList = questionXuanxiang(stuQuestions, qobj);
117 126
                 saveQuestionObjs.addAll(qobjList);
118 127
             }
119 128
 
120
-            //班级试题分析
121
-            //获取所有班级
129
+            // 学科分段之间学生在该题的整体得分率
130
+            List<MsrSubjectQuestionSection> sectionQuestions = subjectSectionQuestion(stuQuestions, subjectSectionQuestions, question);
131
+            saveSectionQuestions.addAll(sectionQuestions);
132
+
133
+
134
+            // 班级试题分析
135
+            // 获取所有班级
122 136
             List<Integer> classIds = subjectClassStudents.stream().map(MsClassStudent::getClassid).distinct().collect(Collectors.toList());
123
-            for(Integer classid : classIds){
124
-                //获取班级下学生id
125
-                List<Integer> classStuIds = subjectClassStudents.stream().filter(c -> c.getClassid().equals(classid)).map(MsClassStudent::getStudentid).collect(Collectors.toList());
126
-                //获取班级下学生试题
137
+            for (Integer classid : classIds) {
138
+                // 获取班级下学生id
139
+                List<Integer> classStuIds =
140
+                        subjectClassStudents.stream().filter(c -> c.getClassid().equals(classid)).map(MsClassStudent::getStudentid).collect(Collectors.toList());
141
+                // 获取班级下学生试题
127 142
                 List<MsPaperStudentQuestion> classStuQuestions = stuQuestions.stream().filter(q -> classStuIds.contains(q.getStudentid())).collect(Collectors.toList());
128 143
                 schoolQ.setClassid(classid);
129
-                MsrClassQuestion classQue = handleQuestionClass(classStuQuestions,question,params,schoolQ);
144
+                MsrClassQuestion classQue = questionClass(classStuQuestions, question, params, schoolQ);
130 145
                 saveQuestions.add(classQue);
131 146
 
132
-                //班级试题--客观题选项情况
133
-                if(question.getQtype() == 1) {
147
+                // 班级试题--客观题选项情况
148
+                if (question.getQtype() == 1) {
134 149
                     qobj.setClassid(classid);
135
-                    List<MsrClassQuestionObj> qobjList = handleQuestionXuanxiang(classStuQuestions,qobj);
150
+                    List<MsrClassQuestionObj> qobjList = questionXuanxiang(classStuQuestions, qobj);
136 151
                     saveQuestionObjs.addAll(qobjList);
137 152
                 }
138 153
             }
139 154
         }
140 155
     }
141 156
 
142
-    //处理单个试题分析-学校、班级分析
143
-    private MsrClassQuestion handleQuestionClass(List<MsPaperStudentQuestion> stuQuestions,MsPaperQtypeQuestion question,List<MsrReportparam> params,MsrClassQuestion schoolQ){
144
-        int stunum = stuQuestions.size();//学生数量
145
-        Double qScore = question.getQscore();//试题分值
146
-        Double sumQScore = question.getQscore() * stunum;//小题得分
147
-        List<Double> stuScores = stuQuestions.stream().map(MsPaperStudentQuestion::getStuscore).collect(Collectors.toList());//所有学生得分
148
-        Double sumStuScore = stuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).sum();//综合
149
-
150
-        Double maxScore;//最高分
151
-        Double minScore;//最低分
152
-        Double avgScore;//平均分
153
-        Double avgScoreRate;//平均得分率
154
-        if(schoolQ.getClassid() == 0){
155
-            //代表是校级
157
+    // 单个试题分析-学校、班级分析
158
+    private MsrClassQuestion questionClass(List<MsPaperStudentQuestion> stuQuestions, MsPaperQtypeQuestion question, List<MsrReportparam> params, MsrClassQuestion schoolQ) {
159
+        int stunum = stuQuestions.size();// 学生数量
160
+        Double qScore = question.getQscore();// 试题分值
161
+        Double sumQScore = question.getQscore() * stunum;// 小题得分
162
+        List<Double> stuScores = stuQuestions.stream().map(MsPaperStudentQuestion::getStuscore).collect(Collectors.toList());// 所有学生得分
163
+        Double sumStuScore = stuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).sum();// 综合
164
+
165
+        Double maxScore;// 最高分
166
+        Double minScore;// 最低分
167
+        Double avgScore;// 平均分
168
+        Double avgScoreRate;// 平均得分率
169
+        if (schoolQ.getClassid() == 0) {
170
+            // 代表是校级
156 171
             maxScore = schoolQ.getSchoolmaxscore();
157 172
             minScore = schoolQ.getSchoolminscore();
158 173
             avgScore = schoolQ.getSchoolavgscore();
159 174
             avgScoreRate = schoolQ.getSchoolavgrate();
160
-        }else{
161
-            //指定班级
162
-            maxScore = stuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).max().orElse(0.0);//最高分
163
-            minScore = stuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).min().orElse(0.0);//最低分
164
-            avgScore = MarkingUtil.calculateAverage(stuScores);//平均分
165
-            avgScoreRate = MarkingUtil.calculateRate(avgScore,sumQScore);//平均得分率
175
+        } else {
176
+            // 指定班级
177
+            maxScore = stuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).max().orElse(0.0);// 最高分
178
+            minScore = stuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).min().orElse(0.0);// 最低分
179
+            avgScore = MarkingUtil.calculateAverage(stuScores);// 平均分
180
+            avgScoreRate = MarkingUtil.calculateRate(avgScore, sumQScore);// 平均得分率
166 181
         }
167
-        Double stuScoreRate = MarkingUtil.calculateRate(sumStuScore,sumQScore);//学生得分率
182
+        Double stuScoreRate = MarkingUtil.calculateRate(sumStuScore, sumQScore);// 学生得分率
168 183
         MsrClassQuestion classQ = new MsrClassQuestion();
169 184
         classQ.setExamid(schoolQ.getExamid());
170 185
         classQ.setSubjectid(schoolQ.getSubjectid());
171
-        classQ.setClassid(schoolQ.getClassid());//班级id
186
+        classQ.setClassid(schoolQ.getClassid());// 班级id
172 187
         classQ.setMptqid(question.getMptqid());
173 188
         classQ.setQtype(question.getQtype());
174 189
         classQ.setQn(question.getMptqn() + "." + question.getQn());
@@ -185,39 +200,40 @@ public class ReportGenerateQuestionService {
185 200
         classQ.setSchoolavgrate(schoolQ.getSchoolavgrate());
186 201
 
187 202
         classQ.setScorerate(stuScoreRate);
188
-        classQ.setScoreratec(MarkingUtil.sub(MarkingUtil.calculateRate(maxScore,qScore),MarkingUtil.calculateRate(minScore,qScore)));//得分率差=最高得分率-最低得分率
189
-        classQ.setNd(MarkingUtil.div(stuScoreRate,qScore));//难度
190
-        String[] ndStr = handleQuestionNdAndQfd(params,1,classQ.getNd());
191
-        classQ.setNdms(ndStr[0]);//难度描述
192
-        classQ.setNdfw(ndStr[1]);//难度范围
193
-        classQ.setQfd(MarkingUtil.qfd(stuScores));//区分度
194
-        String[] qfdStr = handleQuestionNdAndQfd(params,2,classQ.getNd());
195
-        classQ.setQfdms(qfdStr[0]);//区分度描述
196
-        classQ.setQfdfw(qfdStr[1]);//区分度范围
197
-        classQ.setBzc(MarkingUtil.bzc(stuScores));//标准差
198
-        classQ.setCyxs(MarkingUtil.div(classQ.getBzc(),avgScore));//差异系数
199
-        classQ.setJbzs(MarkingUtil.jbzs(stuScores,stuScoreRate));//鉴别指数
200
-        //获取所有满分学生
203
+        classQ.setScoreratec(MarkingUtil.sub(MarkingUtil.calculateRate(maxScore, qScore), MarkingUtil.calculateRate(minScore, qScore)));// 得分率差=最高得分率-最低得分率
204
+        classQ.setNd(MarkingUtil.div(stuScoreRate, qScore));// 难度
205
+        String[] ndStr = questionNdAndQfd(params, 1, classQ.getNd());
206
+        classQ.setNdms(ndStr[0]);// 难度描述
207
+        classQ.setNdfw(ndStr[1]);// 难度范围
208
+        classQ.setQfd(MarkingUtil.qfd(stuScores));// 区分度
209
+        String[] qfdStr = questionNdAndQfd(params, 2, classQ.getQfd());
210
+        classQ.setQfdms(qfdStr[0]);// 区分度描述
211
+        classQ.setQfdfw(qfdStr[1]);// 区分度范围
212
+        classQ.setBzc(MarkingUtil.bzc(stuScores));// 标准差
213
+        classQ.setCyxs(MarkingUtil.div(classQ.getBzc(), avgScore));// 差异系数
214
+        classQ.setJbzs(MarkingUtil.jbzs(stuScores, stuScoreRate));// 鉴别指数
215
+        // 获取所有满分学生
201 216
         List<MsPaperStudentQuestion> fullStuQuestions = stuQuestions.stream().filter(q -> q.getStuscore().equals(q.getQscore())).collect(Collectors.toList());
202
-        String mfids = fullStuQuestions.stream().map(p -> p.getStudentid().toString()).collect(Collectors.joining(","));//满分学生id
217
+        String mfids = fullStuQuestions.stream().map(p -> p.getStudentid().toString()).collect(Collectors.joining(","));// 满分学生id
203 218
         classQ.setMfnum(fullStuQuestions.size());
204 219
         classQ.setMfrate(MarkingUtil.div(classQ.getMfnum(), stunum));////正确率、满分人数占比
205 220
         classQ.setMfids(mfids);
206
-        //获取零分学生
207
-        List<MsPaperStudentQuestion> lfStuQuestions = stuQuestions.stream().filter(q -> q.getStuscore()==0).collect(Collectors.toList());
208
-        String lfids = lfStuQuestions.stream().map(p -> p.getStudentid().toString()).collect(Collectors.joining(","));//零分学生id
221
+        // 获取零分学生
222
+        List<MsPaperStudentQuestion> lfStuQuestions = stuQuestions.stream().filter(q -> q.getStuscore() == 0).collect(Collectors.toList());
223
+        String lfids = lfStuQuestions.stream().map(p -> p.getStudentid().toString()).collect(Collectors.joining(","));// 零分学生id
209 224
         classQ.setLfnum(lfStuQuestions.size());
210
-        classQ.setLfrate(MarkingUtil.div(lfStuQuestions.size(),stunum));////零分人数占比
225
+        classQ.setLfrate(MarkingUtil.div(lfStuQuestions.size(), stunum));////零分人数占比
211 226
         classQ.setLfids(lfids);
212 227
         return classQ;
213 228
     }
214
-    //处理单个试题分析-试题难度、区分度
215
-    private String[] handleQuestionNdAndQfd(List<MsrReportparam> params,Integer rptype,Double nd){
216
-        //获取难度或者区分度
217
-        MsrReportparam ndParam = params.stream().filter(p -> p.getRptype().equals(rptype)).findFirst().orElse(null);//难度
229
+
230
+    // 单个试题分析-试题难度、区分度
231
+    private String[] questionNdAndQfd(List<MsrReportparam> params, Integer rptype, Double nd) {
232
+        // 获取难度或者区分度
233
+        MsrReportparam ndParam = params.stream().filter(p -> p.getRptype().equals(rptype)).findFirst().orElse(null);// 难度
218 234
         String ndms = "";
219 235
         String ndfw = "";
220
-        if(ndParam!= null){
236
+        if (ndParam != null) {
221 237
             List<SzJsonVo> szList = JSON.parseArray(ndParam.getSzjson(), SzJsonVo.class);
222 238
             for (SzJsonVo sz : szList) {
223 239
                 if (nd == 1 && sz.getMaxvalue() == 1) {
@@ -228,21 +244,22 @@ public class ReportGenerateQuestionService {
228 244
                     ndms = sz.getDjkey();
229 245
                     ndfw = "[0" + "~" + sz.getMaxvalue() + ")";
230 246
                     break;
231
-                } else if(nd >= sz.getMinvalue() && nd < sz.getMaxvalue()) {
247
+                } else if (nd >= sz.getMinvalue() && nd < sz.getMaxvalue()) {
232 248
                     ndms = sz.getDjkey();
233 249
                     ndfw = "[" + sz.getMinvalue() + "~" + sz.getMaxvalue() + ")";
234 250
                     break;
235 251
                 }
236 252
             }
237 253
         }
238
-        return new String[]{ndms,ndfw};
254
+        return new String[]{ndms, ndfw};
239 255
     }
240
-    //处理单个试题分析-客观题选项情况
241
-    private List<MsrClassQuestionObj> handleQuestionXuanxiang(List<MsPaperStudentQuestion> stuQuestions,MsrClassQuestionObj questionObj){
242
-        Map<String,List<MsPaperStudentQuestion>> optionMap = stuQuestions.stream().collect(Collectors.groupingBy(MsPaperStudentQuestion::getStuanswer));
256
+
257
+    // 单个试题分析-客观题选项情况
258
+    private List<MsrClassQuestionObj> questionXuanxiang(List<MsPaperStudentQuestion> stuQuestions, MsrClassQuestionObj questionObj) {
259
+        Map<String, List<MsPaperStudentQuestion>> optionMap = stuQuestions.stream().collect(Collectors.groupingBy(MsPaperStudentQuestion::getStuanswer));
243 260
         int totalNum = stuQuestions.size();
244 261
         List<MsrClassQuestionObj> qobjList = new ArrayList<>();
245
-        for(Map.Entry<String,List<MsPaperStudentQuestion>> entry : optionMap.entrySet()){
262
+        for (Map.Entry<String, List<MsPaperStudentQuestion>> entry : optionMap.entrySet()) {
246 263
             String option = entry.getKey();
247 264
             List<MsPaperStudentQuestion> optionStuQuestions = entry.getValue();
248 265
 
@@ -251,13 +268,13 @@ public class ReportGenerateQuestionService {
251 268
             qobj.setSubjectid(questionObj.getSubjectid());
252 269
             qobj.setClassid(questionObj.getClassid());
253 270
             qobj.setMptqid(questionObj.getMptqid());
254
-            if(N_Utils.isNotEmpty(option)){
271
+            if (N_Utils.isNotEmpty(option)) {
255 272
                 qobj.setXxda(option);
256
-            }else{
273
+            } else {
257 274
                 qobj.setXxda("未选");
258 275
             }
259 276
             qobj.setXxnum(optionStuQuestions.size());
260
-            qobj.setXxrate(MarkingUtil.calculateRate(optionStuQuestions.size(),totalNum));
277
+            qobj.setXxrate(MarkingUtil.calculateRate(optionStuQuestions.size(), totalNum));
261 278
             String stuids = optionStuQuestions.stream().map(q -> q.getStudentid().toString()).collect(Collectors.joining(","));
262 279
             qobj.setStuids(stuids);
263 280
             qobjList.add(qobj);
@@ -265,15 +282,151 @@ public class ReportGenerateQuestionService {
265 282
         return qobjList;
266 283
     }
267 284
 
268
-    //处理科目分段-默认5分一段为后续试题做准备
269
-    private void handleSubjectSectionForQuestion(List<MsrStudent> StuPapers,Double pscore){
270
-        //把科目总分分段,默认5分一段
271
-        List<int[]> fdList = MarkingUtil.fdScore(pscore,5);
272
-        List<MsrSubjectSectionQuestion> sections = new ArrayList<>();
273
-        for(int[] fd : fdList){
274
-            //获取学生得分在指定区间的学生
275
-            List<MsrStudent> fdStuPapers = StuPapers.stream().filter(s -> s.getStuscore() >= fd[0] && s.getStuscore() < fd[1]).collect(Collectors.toList());
276
-            //计算分段平均分
285
+    // 单个试题-科目分段-默认5分一段为后续试题在段上学生得分率做准备
286
+    private List<MsrSubjectQuestionSection> subjectSectionForQuestion(List<MsrStudent> StuPapers, Double pscore) {
287
+        // 把科目总分分段,默认5分一段
288
+        List<RankGroupVo> fdList = MarkingUtil.fdScore(pscore, 5);
289
+        List<MsrSubjectQuestionSection> sections = new ArrayList<>();
290
+        MsrStudent fdStuPaper = StuPapers.get(0);
291
+        for (RankGroupVo fd : fdList) {
292
+            // 获取学生得分在指定区间的学生
293
+            List<MsrStudent> fdStuPapers;
294
+            if (fd.getMaxvalue() == pscore) {
295
+                fdStuPapers = StuPapers.stream().filter(s -> s.getStuscore() >= fd.getMinvalue() && s.getStuscore() <= fd.getMaxvalue()).collect(Collectors.toList());
296
+            } else {
297
+                fdStuPapers = StuPapers.stream().filter(s -> s.getStuscore() >= fd.getMinvalue() && s.getStuscore() < fd.getMaxvalue()).collect(Collectors.toList());
298
+            }
299
+
300
+            MsrSubjectQuestionSection question = new MsrSubjectQuestionSection();
301
+            question.setExamid(fdStuPaper.getExamid());
302
+            question.setSubjectid(fdStuPaper.getSubjectid());
303
+            question.setFdfw(fd.getGroupname());
304
+            question.setFdnum(fdStuPapers.size());
305
+            question.setFdids(fdStuPapers.stream().map(s -> s.getStudentid().toString()).collect(Collectors.joining(",")));
306
+            sections.add(question);
307
+        }
308
+        return sections;
309
+    }
310
+
311
+    // 单个试题分析-科目分段区间得分率
312
+    private List<MsrSubjectQuestionSection> subjectSectionQuestion(List<MsPaperStudentQuestion> stuQuestions, List<MsrSubjectQuestionSection> sections,
313
+                                                                         MsPaperQtypeQuestion question) {
314
+        List<MsrSubjectQuestionSection> rtnList = new ArrayList<>();
315
+        for (MsrSubjectQuestionSection section : sections) {
316
+            String[] userids = section.getFdids().split(",");
317
+            List<String> useridList = Arrays.asList(userids);
318
+            List<MsPaperStudentQuestion> sectionStuQuestions = stuQuestions.stream().filter(q -> useridList.contains(q.getStudentid().toString())).collect(Collectors.toList());
319
+            // 获取总分
320
+            double sumScore = sectionStuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).sum();
321
+            int stuNum = sectionStuQuestions.size();
322
+            // 获取平均分
323
+            double avgScore = MarkingUtil.div(sumScore, stuNum);
324
+            // 获取平均得分率
325
+            double avgScoreRate = MarkingUtil.calculateRate(avgScore, question.getQscore());
326
+            section.setAvgscore(avgScore);
327
+            section.setAvgrate(avgScoreRate);
328
+            section.setQntype(1);
329
+            section.setMptqid(question.getMptqid());
330
+            rtnList.add(section);
277 331
         }
332
+        return rtnList;
278 333
     }
334
+
335
+    // 题型分析
336
+    private void handleQtype(List<MsPaperStudentQuestion> subjectStuQuestions,List<MsClassStudent> subjectClassStudents, List<MsPaperQtypeQuestion> questions,
337
+                             List<MsrReportparam> params,Integer examid, String subjectid) {
338
+        List<MsrClassQtype> saveQtypes = new ArrayList<>();//班级题型分析
339
+        // 处理大题
340
+        Map<Integer, List<MsPaperQtypeQuestion>> qtypeMap = questions.stream().collect(Collectors.groupingBy(MsPaperQtypeQuestion::getMptid));
341
+        for (Map.Entry<Integer, List<MsPaperQtypeQuestion>> entry : qtypeMap.entrySet()) {
342
+            List<MsPaperQtypeQuestion> qtypeQuestions = entry.getValue();
343
+            Double fullScore = qtypeQuestions.stream().mapToDouble(MsPaperQtypeQuestion::getQscore).sum();// 题型满分
344
+
345
+            // 获取所有题型下试题id集合
346
+            List<Integer> mptqids = qtypeQuestions.stream().map(MsPaperQtypeQuestion::getMptqid).distinct().collect(Collectors.toList());
347
+            // 获取题型下所有学生试题情况
348
+            List<MsPaperStudentQuestion> stuQuestions = subjectStuQuestions.stream().filter(q -> mptqids.contains(q.getMptqid())).collect(Collectors.toList());
349
+            //初始化信息
350
+            MsrClassQtype schoolQtype = new MsrClassQtype();
351
+            schoolQtype.setExamid(examid);
352
+            schoolQtype.setSubjectid(subjectid);
353
+            schoolQtype.setClassid(0);
354
+            schoolQtype.setMptid(entry.getKey());
355
+            schoolQtype.setMptqn(qtypeQuestions.get(0).getMptqn());
356
+            schoolQtype.setFullscore(fullScore);
357
+
358
+            //全校班级题型情况
359
+            MsrClassQtype qtypeSchool = qtypeClass(stuQuestions, params, schoolQtype);
360
+            saveQtypes.add(qtypeSchool);
361
+
362
+            // 班级题型分析
363
+            // 获取所有班级
364
+            List<Integer> classIds = subjectClassStudents.stream().map(MsClassStudent::getClassid).distinct().collect(Collectors.toList());
365
+            for (Integer classid : classIds) {
366
+                schoolQtype.setClassid(classid);
367
+                // 获取班级下学生id
368
+                List<Integer> classStuIds =
369
+                        subjectClassStudents.stream().filter(c -> c.getClassid().equals(classid)).map(MsClassStudent::getStudentid).collect(Collectors.toList());
370
+                // 获取班级下学生试题
371
+                List<MsPaperStudentQuestion> classStuQuestions = stuQuestions.stream().filter(q -> classStuIds.contains(q.getStudentid())).collect(Collectors.toList());
372
+                 // 班级题型分析
373
+                MsrClassQtype qtypeClass = qtypeClass(classStuQuestions, params, schoolQtype);
374
+                saveQtypes.add(qtypeClass);
375
+            }
376
+        }
377
+    }
378
+    // 题型分析-学校、班级分析
379
+    private MsrClassQtype qtypeClass(List<MsPaperStudentQuestion> stuQuestions, List<MsrReportparam> params,MsrClassQtype schoolQtype){
380
+        // 获取所有学生id
381
+        List<Integer> studentIds = stuQuestions.stream().map(MsPaperStudentQuestion::getStudentid).distinct().collect(Collectors.toList());
382
+        int stuNum = stuQuestions.size();
383
+        List<Double> stuScores = new ArrayList<>();
384
+        int mfnum = 0;
385
+        String mfids = "";
386
+        int lfnum = 0;
387
+        String lfids = "";
388
+        for (Integer studentId : studentIds) {
389
+            List<MsPaperStudentQuestion> stuQtype = stuQuestions.stream().filter(q -> studentId.equals(q.getMptqid())).collect(Collectors.toList());
390
+            Double stuQtypeScore = stuQtype.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).sum();
391
+            stuScores.add(stuQtypeScore);
392
+            if(schoolQtype.getFullscore() == stuQtypeScore){
393
+                mfnum++;
394
+                mfids += studentId + ",";
395
+            }else{
396
+                lfnum++;
397
+                lfids += studentId + ",";
398
+            }
399
+        }
400
+
401
+        Double stuSumScore = stuQuestions.stream().mapToDouble(MsPaperStudentQuestion::getStuscore).sum();// 学生总分
402
+        Double avgScore = MarkingUtil.div(stuSumScore, stuNum);// 平均分
403
+
404
+        MsrClassQtype classQtype = new MsrClassQtype();
405
+        classQtype.setExamid(schoolQtype.getExamid());
406
+        classQtype.setSubjectid(schoolQtype.getSubjectid());
407
+        classQtype.setClassid(schoolQtype.getClassid());
408
+        classQtype.setMptid(schoolQtype.getMptid());
409
+        classQtype.setMptqn(schoolQtype.getMptqn());
410
+        classQtype.setFullscore(schoolQtype.getFullscore());
411
+        classQtype.setAvgscore(avgScore);
412
+        classQtype.setBzc(MarkingUtil.bzc(stuScores));
413
+        classQtype.setNd(MarkingUtil.div(avgScore, schoolQtype.getFullscore()));
414
+        classQtype.setNdms(questionNdAndQfd(params, 1, schoolQtype.getNd())[0]);
415
+        classQtype.setQfd(MarkingUtil.qfd(stuScores));
416
+        classQtype.setQfdms(questionNdAndQfd(params, 2, schoolQtype.getQfd())[0]);
417
+        classQtype.setMfnum(mfnum);
418
+        classQtype.setMfrate(MarkingUtil.div(mfnum, stuNum));
419
+        if(mfnum > 0){
420
+            schoolQtype.setMfids(mfids.substring(0,mfids.length()-1));
421
+        }
422
+        classQtype.setMfids(mfids);
423
+        classQtype.setLfnum(lfnum);
424
+        classQtype.setLfrate(MarkingUtil.div(lfnum, stuNum));
425
+        if(lfnum > 0){
426
+            classQtype.setMfids(lfids.substring(0,lfids.length()-1));
427
+        }
428
+
429
+        return classQtype;
430
+    }
431
+
279 432
 }

+ 38
- 21
smarking/src/main/java/com/xhkjedu/smarking/utils/MarkingUtil.java Dosyayı Görüntüle

@@ -539,24 +539,29 @@ public class MarkingUtil {
539 539
         return sub(topRate, bottomRate);
540 540
     }
541 541
 
542
-    //排名分组计算 用于第一组(第1-10名)
543
-    public static List<RankGroupVo> rankGroup(Integer total) {
542
+    //排名分组计算 参数[总名次,分组数] 如:第一组(第1-10名)
543
+    public static List<RankGroupVo> rankGroup(Integer total,Integer groupNum) {
544 544
         List<RankGroupVo> rtnList = new ArrayList<>();
545 545
 
546
-        int count = total / 10;
547
-        for (int i = 0; i < count; i++) {
548
-            RankGroupVo rg = new RankGroupVo();
549
-            rg.setMaxvalue((i + 1) * 10);
550
-            rg.setMinvalue(i * 10 + 1);
551
-            rtnList.add(rg);
552
-        }
546
+        int average = total / groupNum;
547
+        int remainder = total % groupNum;
548
+
549
+        for (int i = 0; i < groupNum; i++) {
550
+            int min;
551
+            int max;
552
+            if (i < remainder) {
553
+                min = average * i + i + 1;
554
+                max = average * (i + 1) + i + 1;
555
+            } else {
556
+                min = average * i + remainder + 1;
557
+                max = average * (i + 1) + remainder;
558
+            }
553 559
 
554
-        if (total % 10 > 0) {
555
-            //未被整除,添加最后一组
556
-            RankGroupVo rg = new RankGroupVo();
557
-            rg.setMaxvalue(total);
558
-            rg.setMinvalue(count * 10 + 1);
559
-            rtnList.add(rg);
560
+            RankGroupVo rgvo = new RankGroupVo();
561
+            rgvo.setGroupname("第" + (i + 1) + "组(" + min + "~" + max + ")");
562
+            rgvo.setMinvalue(min);
563
+            rgvo.setMaxvalue(max);
564
+            rtnList.add(rgvo);
560 565
         }
561 566
         return rtnList;
562 567
     }
@@ -582,11 +587,23 @@ public class MarkingUtil {
582 587
     }
583 588
 
584 589
     // 分数段 分数分段
585
-    public static List<int[]> fdScore(Double totalScore,int fdscore){
586
-        List<int[]> rtnList = new ArrayList<>();
590
+    public static List<RankGroupVo> fdScore(Double totalScore,int fdscore){
591
+        List<RankGroupVo> rtnList = new ArrayList<>();
587 592
         for (int i = 0; i < totalScore; i += fdscore) {
588 593
             int end = (int) Math.min(i + fdscore, totalScore);
589
-            rtnList.add(new int[]{i, end});
594
+
595
+            String groupname = "[" + i + "~" + end;
596
+            if(end == totalScore){
597
+                groupname+="]";
598
+            }else {
599
+                groupname+=")";
600
+            }
601
+
602
+            RankGroupVo rgvo = new RankGroupVo();
603
+            rgvo.setGroupname(groupname);
604
+            rgvo.setMinvalue(i);
605
+            rgvo.setMaxvalue(end);
606
+            rtnList.add(rgvo);
590 607
         }
591 608
         return rtnList;
592 609
     }
@@ -607,9 +624,9 @@ public class MarkingUtil {
607 624
         return "";
608 625
     }
609 626
     public static void main(String[] args) {
610
-        List<int[]> rtnList = fdScore(84.0, 5);
611
-        for (int[] rtn : rtnList) {
612
-            System.out.println(rtn[0] + "-" + rtn[1]);
627
+        List<RankGroupVo> rtnList = fdScore(88.0, 6);
628
+        for (RankGroupVo rg : rtnList) {
629
+            System.out.println(rg.getGroupname() + ": " + rg.getMinvalue() + "-" + rg.getMaxvalue());
613 630
         }
614 631
     }
615 632
 }

+ 4
- 2
smarking/src/main/java/com/xhkjedu/smarking/vo/report/reportother/RankGroupVo.java Dosyayı Görüntüle

@@ -10,9 +10,11 @@ import lombok.Data;
10 10
 @Data
11 11
 public class RankGroupVo {
12 12
 
13
+    private String groupname;
14
+
13 15
     //最大值
14
-    private Integer maxvalue;
16
+    private int maxvalue;
15 17
 
16 18
     //最小值
17
-    private Integer minvalue;
19
+    private int minvalue;
18 20
 }

smarking/src/main/resources/mapper/report/reportclass/MsrClassQuestionRankgroupMapper.xml → smarking/src/main/resources/mapper/report/reportsubject/MsrSubjectQuestionRankgroupMapper.xml Dosyayı Görüntüle

@@ -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.reportclass.MsrClassQuestionRankgroupMapper">
3
+<mapper namespace="com.xhkjedu.smarking.mapper.report.reportsubject.MsrSubjectQuestionRankgroupMapper">
4 4
 </mapper>

smarking/src/main/resources/mapper/report/reportsubject/MsrSubjectSectionQuestionMapper.xml → smarking/src/main/resources/mapper/report/reportsubject/MsrSubjectQuestionSectionMapper.xml Dosyayı Görüntüle

@@ -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.MsrSubjectSectionQuestionMapper">
3
+<mapper namespace="com.xhkjedu.smarking.mapper.report.reportsubject.MsrSubjectQuestionSectionMapper">
4 4
 </mapper>

Loading…
İptal
Kaydet