|
@@ -0,0 +1,183 @@
|
|
|
+package cn.com.qmth.stmms.biz.report.service.impl;
|
|
|
+
|
|
|
+import cn.com.qmth.stmms.biz.common.BaseQueryService;
|
|
|
+import cn.com.qmth.stmms.biz.exam.dao.ExamQuestionDao;
|
|
|
+import cn.com.qmth.stmms.biz.exam.dao.ExamStudentDao;
|
|
|
+import cn.com.qmth.stmms.biz.exam.dao.ExamSubjectDao;
|
|
|
+import cn.com.qmth.stmms.biz.exam.model.ExamQuestion;
|
|
|
+import cn.com.qmth.stmms.biz.exam.model.ExamStudent;
|
|
|
+import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
|
|
|
+import cn.com.qmth.stmms.biz.report.dao.ReportSubjectGroupDao;
|
|
|
+import cn.com.qmth.stmms.biz.report.model.ReportSubjectGroup;
|
|
|
+import cn.com.qmth.stmms.biz.report.query.ReportSubjectQuery;
|
|
|
+import cn.com.qmth.stmms.biz.report.service.ReportSubjectGroupService;
|
|
|
+import cn.com.qmth.stmms.biz.utils.DoubleUtil;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.data.jpa.domain.Specification;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import javax.persistence.criteria.CriteriaBuilder;
|
|
|
+import javax.persistence.criteria.CriteriaQuery;
|
|
|
+import javax.persistence.criteria.Predicate;
|
|
|
+import javax.persistence.criteria.Root;
|
|
|
+import java.util.Arrays;
|
|
|
+import java.util.Collections;
|
|
|
+import java.util.LinkedList;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 大题型统计分析 service 实现
|
|
|
+ *
|
|
|
+ * @author xuwenjin
|
|
|
+ * @Date 2019-04-18
|
|
|
+ */
|
|
|
+@Service
|
|
|
+public class ReportSubjectGroupServiceImpl extends BaseQueryService<ReportSubjectGroup> implements ReportSubjectGroupService {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ReportSubjectGroupDao reportSubjectGroupDao;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ExamStudentDao examStudentDao;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ExamQuestionDao examQuestionDao;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ExamSubjectDao examSubjectDao;
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void deleteByExamId(Integer examId) {
|
|
|
+ reportSubjectGroupDao.deleteByExamId(examId);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<ReportSubjectGroup> findByQuery(final ReportSubjectQuery query) {
|
|
|
+ List<ReportSubjectGroup> result = reportSubjectGroupDao.findAll(new Specification<ReportSubjectGroup>() {
|
|
|
+ @Override
|
|
|
+ public Predicate toPredicate(Root<ReportSubjectGroup> root, CriteriaQuery<?> cQuery, CriteriaBuilder cb) {
|
|
|
+ List<Predicate> predicates = new LinkedList<Predicate>();
|
|
|
+ if (query.getExamId() != null) {
|
|
|
+ predicates.add(cb.equal(root.get("examId"), query.getExamId()));
|
|
|
+ }
|
|
|
+ if (query.getSubjectCode() != null) {
|
|
|
+ predicates.add(cb.equal(root.get("subjectCode"), query.getSubjectCode()));
|
|
|
+ }
|
|
|
+ return predicates.isEmpty() ? cb.conjunction()
|
|
|
+ : cb.and(predicates.toArray(new Predicate[predicates.size()]));
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void saveReportSubjectGroupData(Integer examId, String subjectCode) {
|
|
|
+ //保存主观题统计分析
|
|
|
+ saveReportSubjectGroupData(examId, subjectCode, true);
|
|
|
+ //保存客观题统计分析
|
|
|
+ saveReportSubjectGroupData(examId, subjectCode, false);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 保存题型统计分析
|
|
|
+ *
|
|
|
+ * @param examId 考试Id
|
|
|
+ * @param subjectCode 科目Code
|
|
|
+ * @param objective 客观题,主观题
|
|
|
+ */
|
|
|
+ private void saveReportSubjectGroupData(Integer examId, String subjectCode, Boolean objective) {
|
|
|
+ ExamSubject subject = examSubjectDao.findByExamIdAndCode(examId, subjectCode);
|
|
|
+ List<Object[]> questionGroups = reportSubjectGroupDao.countGroupByMainNum(examId, subjectCode, objective);
|
|
|
+ List<ExamStudent> examStudentList = examStudentDao.findByExamIdAndSubjectCodeAndUploadTimeNotNullAndAbsent(examId, subjectCode, false);
|
|
|
+ Integer studentCount = examStudentList.size();
|
|
|
+ Integer begin = 0;
|
|
|
+ for (int i = 0; i < questionGroups.size(); i++) {
|
|
|
+ Object[] obj = questionGroups.get(i);
|
|
|
+ ExamQuestion question = new ExamQuestion();
|
|
|
+ question.setMainNumber(Integer.parseInt(obj[0].toString()));
|
|
|
+ question.setMainTitle(obj[1].toString());
|
|
|
+ question.setSubNumber(Integer.parseInt(obj[2].toString()));
|
|
|
+ //满分
|
|
|
+ Double fullScore = examQuestionDao.queryFullScoreByExamIdAndSubjectCodeAndMainNumber(examId, subjectCode, question.getMainNumber());
|
|
|
+ Integer questionCount = question.getSubNumber();
|
|
|
+ Double[] totalScoreArray = new Double[studentCount];
|
|
|
+ //题型 总分
|
|
|
+ Double totalScore = 0d;
|
|
|
+ //0分人数
|
|
|
+ Integer zeroScoreCount = 0;
|
|
|
+ //满分人数
|
|
|
+ Integer fullScoreCount = 0;
|
|
|
+ //方差
|
|
|
+ Double variance = 0d;
|
|
|
+ for (int j = 0; j < studentCount; j++) {
|
|
|
+ ExamStudent student = examStudentList.get(j);
|
|
|
+ String[] answers;
|
|
|
+ if (objective) {
|
|
|
+ answers = student.getObjectiveScoreList().split(";");
|
|
|
+ } else {
|
|
|
+ answers = student.getSubjectiveScoreList().split(";");
|
|
|
+ }
|
|
|
+ Double score = 0d;
|
|
|
+ for (int k = begin; k < begin + questionCount; k++) {
|
|
|
+ Double s = 0d;
|
|
|
+ if (objective) {
|
|
|
+ s = Double.parseDouble(answers[k].split(":")[1]);
|
|
|
+ } else {
|
|
|
+ s = Double.parseDouble(answers[k]);
|
|
|
+ }
|
|
|
+ score = DoubleUtil.sum(score, s);
|
|
|
+ }
|
|
|
+ if (score.doubleValue() == 0) {
|
|
|
+ zeroScoreCount++;
|
|
|
+ }
|
|
|
+ if (score.doubleValue() == fullScore.doubleValue()) {
|
|
|
+ fullScoreCount++;
|
|
|
+ }
|
|
|
+ totalScoreArray[j] = score;
|
|
|
+ totalScore = DoubleUtil.sum(totalScore, score);
|
|
|
+ }
|
|
|
+ //最大分
|
|
|
+ Double maxScore = Collections.max(Arrays.asList(totalScoreArray));
|
|
|
+ //最小分
|
|
|
+ Double minScore = Collections.min(Arrays.asList(totalScoreArray));
|
|
|
+ //平均分
|
|
|
+ Double avgScore = DoubleUtil.div(totalScore, studentCount, 2);
|
|
|
+ //计算方差
|
|
|
+ for (int j = 0; j < studentCount; j++) {
|
|
|
+ ExamStudent student = examStudentList.get(j);
|
|
|
+ String[] objectiveAnswers = student.getObjectiveScoreList().split(";");
|
|
|
+ Double score = 0d;
|
|
|
+ for (int k = begin; k < begin + questionCount; k++) {
|
|
|
+ Double s = Double.parseDouble(objectiveAnswers[i].split(":")[1]);
|
|
|
+ score = DoubleUtil.sum(score, s);
|
|
|
+ }
|
|
|
+ variance = DoubleUtil.sum(variance, DoubleUtil.mul(DoubleUtil.sub(score, avgScore), DoubleUtil.sub(score, avgScore)));
|
|
|
+ }
|
|
|
+ //标准差
|
|
|
+ Double sd = DoubleUtil.format(Math.sqrt(variance / studentCount), "0.000000");
|
|
|
+ //差异系数
|
|
|
+ Double cv = DoubleUtil.mul(DoubleUtil.div(sd, avgScore, 4), 100);
|
|
|
+ ReportSubjectGroup reportSubjectGroup = new ReportSubjectGroup();
|
|
|
+ reportSubjectGroup.setExamId(examId);
|
|
|
+ reportSubjectGroup.setSubjectCode(subjectCode);
|
|
|
+ reportSubjectGroup.setSubjectName(subject.getName());
|
|
|
+ reportSubjectGroup.setGroupName(question.getMainTitle());
|
|
|
+ reportSubjectGroup.setMaxScore(maxScore);
|
|
|
+ reportSubjectGroup.setMinScore(minScore);
|
|
|
+ reportSubjectGroup.setAvgScore(avgScore);
|
|
|
+ reportSubjectGroup.setTotalScore(fullScore);
|
|
|
+ reportSubjectGroup.setSD(sd);
|
|
|
+ reportSubjectGroup.setCV(cv);
|
|
|
+ reportSubjectGroup.setZeroCount(zeroScoreCount);
|
|
|
+ reportSubjectGroup.setFullCount(fullScoreCount);
|
|
|
+
|
|
|
+ begin += questionCount;
|
|
|
+ reportSubjectGroupDao.save(reportSubjectGroup);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+}
|