|
@@ -2,7 +2,9 @@ package com.xhkjedu.sexam.service.report;
|
2
|
2
|
|
3
|
3
|
import com.alibaba.fastjson.JSON;
|
4
|
4
|
import com.xhkjedu.sexam.mapper.exam.EClassMapper;
|
|
5
|
+import com.xhkjedu.sexam.mapper.paper.EPaperQtypeMapper;
|
5
|
6
|
import com.xhkjedu.sexam.mapper.paperstudent.EPaperStudentMapper;
|
|
7
|
+import com.xhkjedu.sexam.mapper.paperstudent.EPaperStudentQuestionMapper;
|
6
|
8
|
import com.xhkjedu.sexam.mapper.report.ERbaseMapper;
|
7
|
9
|
import com.xhkjedu.sexam.mapper.report.EReportGenerateMapper;
|
8
|
10
|
import com.xhkjedu.sexam.mapper.report.ERsubjectMapper;
|
|
@@ -12,6 +14,7 @@ import com.xhkjedu.sexam.mapper.reportclass.ERclassQuestionErrorMapper;
|
12
|
14
|
import com.xhkjedu.sexam.mapper.reportclass.ERclassQuestionMapper;
|
13
|
15
|
import com.xhkjedu.sexam.mapper.reportclass.ERclassQuestionPointMapper;
|
14
|
16
|
import com.xhkjedu.sexam.mapper.reportstu.ERstudentMapper;
|
|
17
|
+import com.xhkjedu.sexam.model.paperstudent.EPaperStudentQuestion;
|
15
|
18
|
import com.xhkjedu.sexam.model.report.ERbase;
|
16
|
19
|
import com.xhkjedu.sexam.model.report.ERsubject;
|
17
|
20
|
import com.xhkjedu.sexam.model.reportclass.ERclass;
|
|
@@ -20,16 +23,19 @@ import com.xhkjedu.sexam.model.reportclass.ERclassQuestion;
|
20
|
23
|
import com.xhkjedu.sexam.model.reportclass.ERclassQuestionError;
|
21
|
24
|
import com.xhkjedu.sexam.model.reportclass.ERclassQuestionPoint;
|
22
|
25
|
import com.xhkjedu.sexam.model.reportstu.ERstudent;
|
|
26
|
+import com.xhkjedu.sexam.utils.ExamUtil;
|
|
27
|
+import com.xhkjedu.sexam.vo.paper.EPaperQPointVo;
|
23
|
28
|
import com.xhkjedu.sexam.vo.paper.EPaperQsVo;
|
|
29
|
+import com.xhkjedu.sexam.vo.paper.EPaperQtypeQuestionVo;
|
|
30
|
+import com.xhkjedu.sexam.vo.paper.EPaperQtypeVo;
|
|
31
|
+import com.xhkjedu.sexam.vo.report.ERClassScoreVo;
|
24
|
32
|
import com.xhkjedu.sexam.vo.report.ERPaperVo;
|
|
33
|
+import com.xhkjedu.utils.N_Utils;
|
|
34
|
+import org.springframework.beans.BeanUtils;
|
25
|
35
|
import org.springframework.stereotype.Service;
|
26
|
36
|
|
27
|
37
|
import javax.annotation.Resource;
|
28
|
|
-import java.util.ArrayList;
|
29
|
|
-import java.util.DoubleSummaryStatistics;
|
30
|
|
-import java.util.HashMap;
|
31
|
|
-import java.util.List;
|
32
|
|
-import java.util.Map;
|
|
38
|
+import java.util.*;
|
33
|
39
|
import java.util.stream.Collectors;
|
34
|
40
|
|
35
|
41
|
/**
|
|
@@ -46,6 +52,11 @@ public class EReportGenerateService {
|
46
|
52
|
private EClassMapper eClassMapper;
|
47
|
53
|
@Resource
|
48
|
54
|
private EPaperStudentMapper ePaperStudentMapper;
|
|
55
|
+ @Resource
|
|
56
|
+ private EPaperQtypeMapper ePaperQtypeMapper;
|
|
57
|
+ @Resource
|
|
58
|
+ private EPaperStudentQuestionMapper ePaperStudentQuestionMapper;
|
|
59
|
+
|
49
|
60
|
|
50
|
61
|
@Resource
|
51
|
62
|
private ERbaseMapper eRbaseMapper;
|
|
@@ -64,6 +75,7 @@ public class EReportGenerateService {
|
64
|
75
|
@Resource
|
65
|
76
|
private ERclassQuestionErrorMapper eRclassQuestionErrorMapper;
|
66
|
77
|
|
|
78
|
+
|
67
|
79
|
//生成考试报告
|
68
|
80
|
public void generateExamReport(Integer examid) {
|
69
|
81
|
List<Map> classes = eClassMapper.listByExamId(examid);
|
|
@@ -288,4 +300,275 @@ public class EReportGenerateService {
|
288
|
300
|
index = index + entry.getValue().size();
|
289
|
301
|
}
|
290
|
302
|
}
|
|
303
|
+
|
|
304
|
+ //题型试题
|
|
305
|
+ private void setClassQuestion(Integer examid,List<Map> subjects,List<Map> classes){
|
|
306
|
+ //考试所有学生提交试卷情况
|
|
307
|
+ List<EPaperStudentQuestion> stulist = ePaperStudentQuestionMapper.listExamStudentsAnswer(examid);
|
|
308
|
+
|
|
309
|
+ List<ERclassQtype> rtypelist = new ArrayList<>();
|
|
310
|
+ List<ERclassQuestion> rqlist = new ArrayList<>();
|
|
311
|
+
|
|
312
|
+ for(Map map : subjects){
|
|
313
|
+ String subjectid = map.get("subjectid").toString();
|
|
314
|
+ Integer epid = Integer.parseInt(map.get("epid").toString());//获取试卷id
|
|
315
|
+ Integer ptype = Integer.parseInt(map.get("ptype").toString());//试卷类型1题库2附件
|
|
316
|
+ Double pscore = Double.parseDouble(map.get("pscore").toString());
|
|
317
|
+ List<EPaperQtypeVo> fjtypelist = new ArrayList<>();
|
|
318
|
+ if(ptype == 1){
|
|
319
|
+ fjtypelist = ePaperQtypeMapper.listPaperQtypeQuestions(epid);//试卷题型试题信息(题库)
|
|
320
|
+ setEPaperQtypeForQues(fjtypelist);
|
|
321
|
+ }else{
|
|
322
|
+ fjtypelist = ePaperQtypeMapper.listPaperQtypeQuesitonsForFj(epid);//试卷题型试题信息(附件)
|
|
323
|
+ }
|
|
324
|
+
|
|
325
|
+ //遍及试卷处理题型下各班级得分情况
|
|
326
|
+ for(EPaperQtypeVo t : fjtypelist){
|
|
327
|
+ Double eptscore = t.getEptscore();
|
|
328
|
+ Double tgscore = 0.0;//题型下年级得分
|
|
329
|
+ int stunum = 0;
|
|
330
|
+ Map<Integer, ERClassScoreVo> tcmap = new HashMap<>();//题型下班级得分
|
|
331
|
+ String qnstr = "";
|
|
332
|
+ List<EPaperQtypeQuestionVo> questionVos = t.getQuestions();
|
|
333
|
+ for(int i=0;i<questionVos.size();i++){
|
|
334
|
+ EPaperQtypeQuestionVo q = questionVos.get(i);
|
|
335
|
+ if (i ==0){
|
|
336
|
+ qnstr = q.getQn();
|
|
337
|
+ }else{
|
|
338
|
+ qnstr = qnstr + "," + q.getQn();
|
|
339
|
+ }
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+ //获取指定试题试题得分
|
|
343
|
+ List<EPaperStudentQuestion> qstu = stulist.stream().filter(o -> o.getEpid().equals(t.getEpid())
|
|
344
|
+ && o.getEptqid().equals(q.getEptqid())).collect(Collectors.toList());
|
|
345
|
+ if(i == 0){
|
|
346
|
+ stunum = qstu.size();
|
|
347
|
+ }
|
|
348
|
+ EPaperStudentQuestion maxscoreStu = qstu.stream().max(Comparator.comparing(EPaperStudentQuestion::getStuscore)).get();//最高分
|
|
349
|
+ Double qgscore = qstu.stream().mapToDouble(EPaperStudentQuestion::getStuscore).sum();
|
|
350
|
+ Double qgavgscore = N_Utils.getDoubleDivideAndMulitiply(qgscore,qstu.size());//年级平均分
|
|
351
|
+ Double qgsrate = N_Utils.getDoubleDivideAndMulitiply(qgscore,q.getScore() * qstu.size());
|
|
352
|
+ tgscore = ExamUtil.add(tgscore,qgscore);
|
|
353
|
+
|
|
354
|
+ for(Map classm : classes){
|
|
355
|
+ Integer classid = Integer.parseInt(classm.get("classid").toString());
|
|
356
|
+ List<EPaperStudentQuestion> classStu = qstu.stream().filter(o -> o.getClassid().equals(classid)).collect(Collectors.toList());
|
|
357
|
+ EPaperStudentQuestion maxclassstu = classStu.stream().max(Comparator.comparing(EPaperStudentQuestion::getStuscore)).get();//最高分
|
|
358
|
+ Double qallstu = classStu.stream().mapToDouble(EPaperStudentQuestion::getStuscore).sum();
|
|
359
|
+ Double qcavgscore = N_Utils.getDoubleDivideAndMulitiply(qallstu,classStu.size());//年级平均分
|
|
360
|
+ Double qcsrate = N_Utils.getDoubleDivideAndMulitiply(qallstu,q.getScore() * classStu.size());
|
|
361
|
+
|
|
362
|
+ ERclassQuestion ercq = new ERclassQuestion();
|
|
363
|
+ ercq.setExamid(examid);
|
|
364
|
+ ercq.setClassid(classid);
|
|
365
|
+ ercq.setSubjectid(subjectid);
|
|
366
|
+ ercq.setEptqid(q.getEptqid());
|
|
367
|
+ ercq.setQn(q.getQn());
|
|
368
|
+ ercq.setQorder(q.getQorder());
|
|
369
|
+ if(ptype == 1){
|
|
370
|
+ ercq.setComplexity(q.getComplexity());
|
|
371
|
+ }
|
|
372
|
+ ercq.setClassmaxscore(maxclassstu.getStuscore());
|
|
373
|
+ ercq.setClassavgscore(qcavgscore);
|
|
374
|
+ ercq.setClasssrate(qcsrate);
|
|
375
|
+ ercq.setGrademaxscore(maxscoreStu.getStuscore());
|
|
376
|
+ ercq.setGradeavgscore(qgavgscore);
|
|
377
|
+ ercq.setGradesrate(qgsrate);
|
|
378
|
+ //处理单选题选项情况
|
|
379
|
+ Map stuansmap = setPaperQuestionsForStu(q,classStu);
|
|
380
|
+ ercq.setAnswerjson(stuansmap.get("answerlist").toString());
|
|
381
|
+ ercq.setGoodstujson(stuansmap.get("goodlist").toString());
|
|
382
|
+ ercq.setBadstujson(stuansmap.get("badlist").toString());
|
|
383
|
+ rqlist.add(ercq);//单个试题统计
|
|
384
|
+
|
|
385
|
+ if(tcmap.containsKey(classid)){
|
|
386
|
+ ERClassScoreVo erClassScoreVo = tcmap.get(classid);
|
|
387
|
+ if(i ==0){
|
|
388
|
+ erClassScoreVo.setStunum(classStu.size());
|
|
389
|
+ erClassScoreVo.setTcscore(0.0);
|
|
390
|
+ }
|
|
391
|
+ erClassScoreVo.setTcscore(ExamUtil.add(erClassScoreVo.getTcscore(), qallstu));
|
|
392
|
+
|
|
393
|
+ }else{
|
|
394
|
+ ERClassScoreVo erClassScoreVo = new ERClassScoreVo();
|
|
395
|
+ erClassScoreVo.setStunum(classStu.size());
|
|
396
|
+ erClassScoreVo.setTcscore(0.0);
|
|
397
|
+ erClassScoreVo.setTcscore(ExamUtil.add(erClassScoreVo.getTcscore(), qallstu));
|
|
398
|
+ tcmap.put(classid,erClassScoreVo);
|
|
399
|
+ }
|
|
400
|
+
|
|
401
|
+ }
|
|
402
|
+
|
|
403
|
+ }
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+ Double tgavescore = N_Utils.getDoubleDivideAndMulitiply(tgscore,stunum);//题型下年级平均分
|
|
407
|
+ Double tgsrate = N_Utils.getDoubleDivideAndMulitiply(tgscore,eptscore * stunum);//年级得分率
|
|
408
|
+
|
|
409
|
+ for(Map.Entry<Integer,ERClassScoreVo> entry : tcmap.entrySet()){
|
|
410
|
+ ERClassScoreVo erClassScoreVo = entry.getValue();
|
|
411
|
+ ERclassQtype eRclassQtype = new ERclassQtype();
|
|
412
|
+ eRclassQtype.setExamid(examid);
|
|
413
|
+ eRclassQtype.setSubjectid(subjectid);
|
|
414
|
+ eRclassQtype.setEpid(epid);
|
|
415
|
+ eRclassQtype.setClassid(entry.getKey());
|
|
416
|
+ eRclassQtype.setQtypename(t.getEptname());
|
|
417
|
+ eRclassQtype.setQn(t.getEptorder().toString());
|
|
418
|
+ eRclassQtype.setScore(eptscore);
|
|
419
|
+ eRclassQtype.setNum(t.getEptnum());
|
|
420
|
+ eRclassQtype.setSrate(N_Utils.getDoubleDivideAndMulitiply(eptscore,pscore));
|
|
421
|
+ eRclassQtype.setGradeavgscore(tgavescore);
|
|
422
|
+ eRclassQtype.setGradesrate(tgsrate);
|
|
423
|
+ eRclassQtype.setClassavgscore(N_Utils.getDoubleDivideAndMulitiply(erClassScoreVo.getTcscore(),erClassScoreVo.getStunum()));
|
|
424
|
+ eRclassQtype.setClasssrate(N_Utils.getDoubleDivideAndMulitiply(erClassScoreVo.getTcscore(),eptscore * erClassScoreVo.getStunum() ));
|
|
425
|
+ eRclassQtype.setQn(qnstr);
|
|
426
|
+
|
|
427
|
+ rtypelist.add(eRclassQtype);
|
|
428
|
+ }
|
|
429
|
+ }
|
|
430
|
+ }
|
|
431
|
+ eRclassQtypeMapper.insertList(rtypelist);
|
|
432
|
+ eRclassQuestionMapper.insertList(rqlist);
|
|
433
|
+ }
|
|
434
|
+ //处理题库试卷中子母题
|
|
435
|
+ private void setEPaperQtypeForQues(List<EPaperQtypeVo> fjtypelist){
|
|
436
|
+ for(EPaperQtypeVo qt : fjtypelist){
|
|
437
|
+ List<EPaperQtypeQuestionVo> qlist = qt.getQuestions();
|
|
438
|
+ List<EPaperQtypeQuestionVo> rtnqlist = new ArrayList<>();//保存处理后的试题
|
|
439
|
+ String qpid = "";//母题id
|
|
440
|
+ List<EPaperQtypeQuestionVo> sonqlist = new ArrayList<>();
|
|
441
|
+ for(EPaperQtypeQuestionVo q : qlist){
|
|
442
|
+ //试题类型1单题2母题3子题
|
|
443
|
+ if(q.getQlevel() == 3){
|
|
444
|
+ if(!q.getQuestionpid().equals(qpid)){
|
|
445
|
+ sonqlist = qlist.stream().filter(o -> o.getQuestionpid().equals(q.getQuestionpid())).collect(Collectors.toList());
|
|
446
|
+ EPaperQtypeQuestionVo mq = new EPaperQtypeQuestionVo();
|
|
447
|
+ mq.setQuestionid(q.getQuestionpid());
|
|
448
|
+ mq.setCtype(q.getMctype());
|
|
449
|
+ mq.setQtypeid(q.getMqtypeid());
|
|
450
|
+ mq.setQtypename(q.getMqtypename());
|
|
451
|
+ mq.setQstem(q.getMqstem());
|
|
452
|
+ mq.setComplexity(q.getMcomplexity());
|
|
453
|
+ mq.setQanalyze(q.getMqanalyze());
|
|
454
|
+ mq.setQanswer(q.getMqanswer());
|
|
455
|
+ mq.setQorder(q.getQorder());
|
|
456
|
+ mq.setQlevel(q.getMqlevel());
|
|
457
|
+ List<EPaperQPointVo> allpoint = new ArrayList<>();
|
|
458
|
+ for(EPaperQtypeQuestionVo sq : sonqlist){
|
|
459
|
+ List<EPaperQPointVo> sqpoints = sq.getPoints();
|
|
460
|
+ for(EPaperQPointVo p : sqpoints){
|
|
461
|
+ if(!isExistEPaperPoints(allpoint,p)){
|
|
462
|
+ allpoint.add(p);
|
|
463
|
+ }
|
|
464
|
+ }
|
|
465
|
+ }
|
|
466
|
+ Double mscore = sonqlist.stream().collect(Collectors.summingDouble(EPaperQtypeQuestionVo:: getScore));
|
|
467
|
+ mq.setScore(mscore);
|
|
468
|
+ mq.setSonques(sonqlist);
|
|
469
|
+ mq.setPoints(allpoint);
|
|
470
|
+ rtnqlist.add(mq);
|
|
471
|
+ }
|
|
472
|
+ qpid = q.getQuestionpid();
|
|
473
|
+ }else{
|
|
474
|
+ EPaperQtypeQuestionVo mq = new EPaperQtypeQuestionVo();
|
|
475
|
+ BeanUtils.copyProperties(q,mq);
|
|
476
|
+ mq.setCtype(mq.getCtype());
|
|
477
|
+ rtnqlist.add(mq);
|
|
478
|
+ }
|
|
479
|
+ }
|
|
480
|
+ qt.setQuestions(rtnqlist);
|
|
481
|
+ }
|
|
482
|
+
|
|
483
|
+ }
|
|
484
|
+ private boolean isExistEPaperPoints(List<EPaperQPointVo> allpoint,EPaperQPointVo p){
|
|
485
|
+ for(EPaperQPointVo pvo : allpoint){
|
|
486
|
+ if(p.getPointid().equals(pvo.getPointid())){
|
|
487
|
+ return true;
|
|
488
|
+ }
|
|
489
|
+ }
|
|
490
|
+ return false;
|
|
491
|
+ }
|
|
492
|
+ //处理学生选项情况和得分情况
|
|
493
|
+ private Map setPaperQuestionsForStu(EPaperQtypeQuestionVo q,List<EPaperStudentQuestion> classStu){
|
|
494
|
+ Map<String,List<Map>> answermap = new HashMap<>();
|
|
495
|
+ List<Map> goodlist = new ArrayList<>();
|
|
496
|
+ List<Map> badlist = new ArrayList<>();
|
|
497
|
+
|
|
498
|
+ Double score8 = 0.0;
|
|
499
|
+ Double score5 = 0.0;
|
|
500
|
+ String key1 = "";
|
|
501
|
+ String key2 = "";
|
|
502
|
+ String key3 = "";
|
|
503
|
+
|
|
504
|
+ for(int i=0;i<classStu.size();i++){
|
|
505
|
+ EPaperStudentQuestion sq = classStu.get(i);
|
|
506
|
+ String stuanswer = sq.getStuanswer();
|
|
507
|
+ if(q.getCtype() == 1 || q.getCtype() == 2 || q.getCtype() == 4 || q.getCtype() == 5 || q.getCtype() == 6){
|
|
508
|
+ String answeroption = "未选择";
|
|
509
|
+ if(N_Utils.isNotEmpty(stuanswer)){
|
|
510
|
+ List<String> stuanswers = JSON.parseArray(stuanswer,String.class);
|
|
511
|
+ answeroption = stuanswers.get(0);
|
|
512
|
+ }
|
|
513
|
+
|
|
514
|
+ Map stumap = new HashMap();
|
|
515
|
+ stumap.put("studentid",sq.getStudentid());
|
|
516
|
+ stumap.put("stuname",sq.getStuname());
|
|
517
|
+ if(answermap.containsKey(answeroption)){
|
|
518
|
+ List<Map> stulist = answermap.get(answeroption);
|
|
519
|
+ stulist.add(stumap);
|
|
520
|
+ }else{
|
|
521
|
+ List<Map> stulist = new ArrayList<>();
|
|
522
|
+ stulist.add(stumap);
|
|
523
|
+ answermap.put(answeroption,stulist);
|
|
524
|
+ }
|
|
525
|
+ }else{
|
|
526
|
+ //主观题
|
|
527
|
+ if(i==0){
|
|
528
|
+ //处理分数分段对应,用于分数段[0,50%) [50%,80%), [80%,100%]
|
|
529
|
+ score8 = ExamUtil.getScoreRateScore(q.getScore(),0.8);
|
|
530
|
+ score5 = ExamUtil.getScoreRateScore(q.getScore(),0.8);
|
|
531
|
+ key1 = score8+"-"+q.getScore();
|
|
532
|
+ key2 = score8 + "-" + score5;
|
|
533
|
+ key3 = score5 + "-" + 0;
|
|
534
|
+ answermap.put(key1,new ArrayList<>());
|
|
535
|
+ answermap.put(key2,new ArrayList<>());
|
|
536
|
+ answermap.put(key3,new ArrayList<>());
|
|
537
|
+ }
|
|
538
|
+
|
|
539
|
+ List<Map> stulist = null;
|
|
540
|
+ if(sq.getStuscore()>=score8){
|
|
541
|
+ stulist = answermap.get(key1);
|
|
542
|
+ }else if(sq.getStuscore() >= score5 && sq.getStuscore()<score8){
|
|
543
|
+ stulist = answermap.get(key2);
|
|
544
|
+ }else{
|
|
545
|
+ stulist = answermap.get(key3);
|
|
546
|
+ }
|
|
547
|
+
|
|
548
|
+ Map stumap = new HashMap();
|
|
549
|
+ stumap.put("studentid",sq.getStudentid());
|
|
550
|
+ stumap.put("stuname",sq.getStuname());
|
|
551
|
+ stulist.add(stumap);
|
|
552
|
+ }
|
|
553
|
+
|
|
554
|
+ if(sq.getGood() == 1){
|
|
555
|
+ Map goodmap = new HashMap();
|
|
556
|
+ goodmap.put("studentid",sq.getStudentid());
|
|
557
|
+ goodmap.put("stuname",sq.getStuname());
|
|
558
|
+ goodlist.add(goodmap);
|
|
559
|
+ }
|
|
560
|
+ if(sq.getBad() == 1){
|
|
561
|
+ Map badmap = new HashMap();
|
|
562
|
+ badmap.put("studentid",sq.getStudentid());
|
|
563
|
+ badmap.put("stuname",sq.getStuname());
|
|
564
|
+ badlist.add(badmap);
|
|
565
|
+ }
|
|
566
|
+ }
|
|
567
|
+
|
|
568
|
+ Map rtnmap = new HashMap();
|
|
569
|
+ rtnmap.put("answerlist",JSON.toJSONString(answermap));
|
|
570
|
+ rtnmap.put("goodlist",JSON.toJSONString(goodlist));
|
|
571
|
+ rtnmap.put("badlist",JSON.toJSONString(badlist));
|
|
572
|
+ return rtnmap;
|
|
573
|
+ }
|
291
|
574
|
}
|