@ -425,10 +425,22 @@ public class ExamService {
bucket ( "良好" , scores , total . multiply ( new BigDecimal ( "0.80" ) ) , total . multiply ( new BigDecimal ( "0.90" ) ) ) ,
bucket ( "良好" , scores , total . multiply ( new BigDecimal ( "0.80" ) ) , total . multiply ( new BigDecimal ( "0.90" ) ) ) ,
bucket ( "及格" , scores , pass , total . multiply ( new BigDecimal ( "0.80" ) ) ) ,
bucket ( "及格" , scores , pass , total . multiply ( new BigDecimal ( "0.80" ) ) ) ,
bucket ( "不及格" , scores , BigDecimal . ZERO , pass ) ) ;
bucket ( "不及格" , scores , BigDecimal . ZERO , pass ) ) ;
List < Map < String , Object > > hardest = jdbc . query ( "select q.id,q.stem,count(*) wrong_count from exam_attempt_answer a " +
String hardestSql = "select p.question_id id,p.stem,p.question_score, count(distinct t.id) student_count, " +
"join exam_attempt t on t.id=a.attempt_id join exam_question q on q.id=a.question_id where t.exam_id=? and t.attempt_status='SUBMITTED' and a.is_correct=0 " +
"sum(case when coalesce(a.awarded_score,0) < p.question_score then 1 else 0 end) wrong_count, " +
( StringUtils . isBlank ( classId ) ? "" : "and t.teaching_class_id=? " ) + "group by q.id,q.stem order by wrong_count desc limit 3" ,
"coalesce(sum(coalesce(a.awarded_score,0)),0) earned_score " +
( rs , n ) - > map ( "id" , rs . getLong ( "id" ) , "stem" , rs . getString ( "stem" ) , "wrongCount" , rs . getInt ( "wrong_count" ) ) ,
"from exam_assessment_question p join exam_attempt t on t.exam_id=p.exam_id and t.attempt_status='SUBMITTED' " +
"left join exam_attempt_answer a on a.attempt_id=t.id and a.question_id=p.question_id " +
"where p.exam_id=?" + ( StringUtils . isBlank ( classId ) ? "" : " and t.teaching_class_id=? " ) +
"group by p.question_id,p.stem,p.question_score " +
"order by (case when count(distinct t.id)=0 then 100 else coalesce(sum(coalesce(a.awarded_score,0)),0) * 100.0 / (count(distinct t.id) * p.question_score) end) asc, wrong_count desc limit 3" ;
List < Map < String , Object > > hardest = jdbc . query ( hardestSql ,
( rs , n ) - > {
int students = rs . getInt ( "student_count" ) ;
BigDecimal maxScore = rs . getBigDecimal ( "question_score" ) . multiply ( BigDecimal . valueOf ( students ) ) ;
BigDecimal earnedScore = rs . getBigDecimal ( "earned_score" ) ;
BigDecimal scoreRate = maxScore . signum ( ) = = 0 ? BigDecimal . ZERO : earnedScore . multiply ( new BigDecimal ( "100" ) ) . divide ( maxScore , 2 , BigDecimal . ROUND_HALF_UP ) ;
return map ( "id" , rs . getLong ( "id" ) , "stem" , rs . getString ( "stem" ) , "wrongCount" , rs . getInt ( "wrong_count" ) , "scoreRate" , scoreRate ) ;
} ,
StringUtils . isBlank ( classId ) ? new Object [ ] { examId } : new Object [ ] { examId , classId } ) ;
StringUtils . isBlank ( classId ) ? new Object [ ] { examId } : new Object [ ] { examId , classId } ) ;
return map ( "examName" , exam . get ( "name" ) , "expected" , expected , "attended" , scores . size ( ) , "passed" , passed ,
return map ( "examName" , exam . get ( "name" ) , "expected" , expected , "attended" , scores . size ( ) , "passed" , passed ,
"failed" , scores . size ( ) - passed , "highest" , scores . stream ( ) . max ( BigDecimal : : compareTo ) . orElse ( BigDecimal . ZERO ) ,
"failed" , scores . size ( ) - passed , "highest" , scores . stream ( ) . max ( BigDecimal : : compareTo ) . orElse ( BigDecimal . ZERO ) ,