|
@@ -1,1516 +1,1516 @@
|
|
|
-package com.qmth.teachcloud.mark.service.impl;
|
|
|
-
|
|
|
-import java.awt.*;
|
|
|
-import java.awt.color.ColorSpace;
|
|
|
-import java.awt.image.BufferedImage;
|
|
|
-import java.awt.image.ColorConvertOp;
|
|
|
-import java.io.*;
|
|
|
-import java.math.BigDecimal;
|
|
|
-import java.net.URLEncoder;
|
|
|
-import java.nio.charset.StandardCharsets;
|
|
|
-import java.util.*;
|
|
|
-import java.util.List;
|
|
|
-import java.util.stream.Collectors;
|
|
|
-
|
|
|
-import javax.annotation.Resource;
|
|
|
-import javax.imageio.ImageIO;
|
|
|
-import javax.servlet.ServletOutputStream;
|
|
|
-import javax.servlet.http.HttpServletResponse;
|
|
|
-import javax.validation.constraints.NotNull;
|
|
|
-
|
|
|
-import org.apache.commons.collections4.CollectionUtils;
|
|
|
-import org.apache.commons.io.FilenameUtils;
|
|
|
-import org.apache.commons.lang3.StringUtils;
|
|
|
-import org.springframework.beans.factory.annotation.Autowired;
|
|
|
-import org.springframework.stereotype.Service;
|
|
|
-import org.springframework.transaction.annotation.Transactional;
|
|
|
-import org.springframework.util.FileCopyUtils;
|
|
|
-
|
|
|
-import com.alibaba.fastjson.JSON;
|
|
|
-import com.alibaba.fastjson.JSONObject;
|
|
|
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
-import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
|
-import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
|
|
-import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
|
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
-import com.itextpdf.text.Document;
|
|
|
-import com.itextpdf.text.Image;
|
|
|
-import com.itextpdf.text.PageSize;
|
|
|
-import com.itextpdf.text.Rectangle;
|
|
|
-import com.itextpdf.text.pdf.PdfWriter;
|
|
|
-import com.qmth.boot.core.concurrent.service.ConcurrentService;
|
|
|
-import com.qmth.boot.core.exception.ParameterException;
|
|
|
-import com.qmth.boot.tools.excel.ExcelWriter;
|
|
|
-import com.qmth.boot.tools.excel.enums.ExcelType;
|
|
|
-import com.qmth.boot.tools.io.ZipWriter;
|
|
|
-import com.qmth.teachcloud.common.bean.dto.DataPermissionRule;
|
|
|
-import com.qmth.teachcloud.common.bean.vo.FilePathVo;
|
|
|
-import com.qmth.teachcloud.common.contant.SystemConstant;
|
|
|
-import com.qmth.teachcloud.common.entity.BasicExam;
|
|
|
-import com.qmth.teachcloud.common.entity.MarkQuestion;
|
|
|
-import com.qmth.teachcloud.common.entity.SysUser;
|
|
|
-import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
|
|
|
-import com.qmth.teachcloud.common.enums.PageSizeEnum;
|
|
|
-import com.qmth.teachcloud.common.enums.ScanStatus;
|
|
|
-import com.qmth.teachcloud.common.enums.mark.MarkPaperStatus;
|
|
|
-import com.qmth.teachcloud.common.enums.mark.SubjectiveStatus;
|
|
|
-import com.qmth.teachcloud.common.service.BasicRoleDataPermissionService;
|
|
|
-import com.qmth.teachcloud.common.service.FileUploadService;
|
|
|
-import com.qmth.teachcloud.common.service.TeachcloudCommonService;
|
|
|
-import com.qmth.teachcloud.common.util.*;
|
|
|
-import com.qmth.teachcloud.mark.bean.UpdateTimeVo;
|
|
|
-import com.qmth.teachcloud.mark.bean.archivescore.*;
|
|
|
-import com.qmth.teachcloud.mark.bean.omredit.OmrEditDomain;
|
|
|
-import com.qmth.teachcloud.mark.bean.omredit.OmrEditPaper;
|
|
|
-import com.qmth.teachcloud.mark.bean.scananswer.*;
|
|
|
-import com.qmth.teachcloud.mark.bean.scanexaminfo.CheckTask;
|
|
|
-import com.qmth.teachcloud.mark.bean.scanexaminfo.ScanExamCheckInfoVo;
|
|
|
-import com.qmth.teachcloud.mark.bean.scanexaminfo.ScanExamInfoVo;
|
|
|
-import com.qmth.teachcloud.mark.bean.student.AbsentManualUpdateVo;
|
|
|
-import com.qmth.teachcloud.mark.bean.student.StudentQuery;
|
|
|
-import com.qmth.teachcloud.mark.bean.student.StudentVo;
|
|
|
-import com.qmth.teachcloud.mark.dto.UnexistStudentDto;
|
|
|
-import com.qmth.teachcloud.mark.dto.mark.ScoreInfo;
|
|
|
-import com.qmth.teachcloud.mark.dto.mark.ScoreItem;
|
|
|
-import com.qmth.teachcloud.mark.dto.mark.manage.Task;
|
|
|
-import com.qmth.teachcloud.mark.dto.mark.score.*;
|
|
|
-import com.qmth.teachcloud.mark.entity.*;
|
|
|
-import com.qmth.teachcloud.mark.enums.ExamStatus;
|
|
|
-import com.qmth.teachcloud.mark.enums.LockType;
|
|
|
-import com.qmth.teachcloud.mark.enums.OmrTaskStatus;
|
|
|
-import com.qmth.teachcloud.mark.lock.LockService;
|
|
|
-import com.qmth.teachcloud.mark.mapper.MarkStudentMapper;
|
|
|
-import com.qmth.teachcloud.mark.params.MarkHeaderResult;
|
|
|
-import com.qmth.teachcloud.mark.service.*;
|
|
|
-import com.qmth.teachcloud.mark.utils.BatchGetDataUtil;
|
|
|
-import com.qmth.teachcloud.mark.utils.Calculator;
|
|
|
-import com.qmth.teachcloud.mark.utils.ScoreCalculateUtil;
|
|
|
-
|
|
|
-/**
|
|
|
- * <p>
|
|
|
- * 考试考生库 服务实现类
|
|
|
- * </p>
|
|
|
- *
|
|
|
- * @author xf
|
|
|
- * @since 2023-09-22
|
|
|
- */
|
|
|
-@Service
|
|
|
-public class MarkStudentServiceImpl extends ServiceImpl<MarkStudentMapper, MarkStudent> implements MarkStudentService {
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private MarkPaperService markPaperService;
|
|
|
-
|
|
|
- @Resource
|
|
|
- private MarkPaperPackageService markPaperPackageService;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private ScanPackageService scanPackageService;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private ScanPaperService scanPaperService;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private ScanPaperPageService scanPaperPageService;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private ScanOmrTaskService scanOmrTaskService;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private ScanAnswerCardService answerCardService;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private ScanStudentPaperService studentPaperService;
|
|
|
-
|
|
|
- @Resource
|
|
|
- private MarkQuestionService markQuestionService;
|
|
|
-
|
|
|
- @Resource
|
|
|
- private TeachcloudCommonService teachcloudCommonService;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private ConcurrentService concurrentService;
|
|
|
-
|
|
|
- @Resource
|
|
|
- private MarkService markService;
|
|
|
-
|
|
|
- @Resource
|
|
|
- private LockService lockService;
|
|
|
-
|
|
|
- @Resource
|
|
|
- private TaskService taskService;
|
|
|
-
|
|
|
- @Resource
|
|
|
- private BasicRoleDataPermissionService basicRoleDataPermissionService;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private MarkSubjectiveScoreService markSubjectiveScoreService;
|
|
|
-
|
|
|
- @Resource
|
|
|
- private MarkSyncService markSyncService;
|
|
|
-
|
|
|
- @Resource
|
|
|
- private FileUploadService fileUploadService;
|
|
|
- @Resource
|
|
|
- private MarkTrackService markTrackService;
|
|
|
-
|
|
|
- @Override
|
|
|
- public List<String> listClassByExamIdAndCourseCode(Long examId, String paperNumber) {
|
|
|
- QueryWrapper<MarkStudent> queryWrapper = new QueryWrapper<>();
|
|
|
- queryWrapper.lambda().eq(MarkStudent::getExamId, examId).eq(MarkStudent::getPaperNumber, paperNumber);
|
|
|
- List<MarkStudent> markStudentList = this.list(queryWrapper);
|
|
|
-
|
|
|
- List<String> classNameList = new ArrayList<>();
|
|
|
- if (CollectionUtils.isNotEmpty(markStudentList)) {
|
|
|
- classNameList = markStudentList.stream().filter(m -> StringUtils.isNotBlank(m.getClassName()))
|
|
|
- .map(MarkStudent::getClassName).distinct().collect(Collectors.toList());
|
|
|
- }
|
|
|
- return classNameList;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void updateSubjectiveStatusAndScore(Long studentId, SubjectiveStatus status, Double score,
|
|
|
- String scoreList) {
|
|
|
- UpdateWrapper<MarkStudent> updateWrapper = new UpdateWrapper<>();
|
|
|
- updateWrapper.lambda().set(MarkStudent::getSubjectiveStatus, status).set(MarkStudent::getSubjectiveScore, score)
|
|
|
- .set(MarkStudent::getSubjectiveScoreList, scoreList).eq(MarkStudent::getId, studentId);
|
|
|
- this.update(updateWrapper);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void updateSubjectiveStatusAndScore(Long examId, String paperNumber, SubjectiveStatus status, Double score,
|
|
|
- String scoreList) {
|
|
|
- UpdateWrapper<MarkStudent> updateWrapper = new UpdateWrapper<>();
|
|
|
- updateWrapper.lambda().set(MarkStudent::getSubjectiveStatus, status).set(MarkStudent::getSubjectiveScore, score)
|
|
|
- .set(MarkStudent::getSubjectiveScoreList, scoreList)
|
|
|
- .set(MarkStudent::getCheckUserId, null)
|
|
|
- .set(MarkStudent::getCheckTime, null).eq(MarkStudent::getExamId, examId)
|
|
|
- .eq(MarkStudent::getPaperNumber, paperNumber);
|
|
|
- this.update(updateWrapper);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public ScanExamInfoVo getScanExamInfo(BasicExam exam, String courseCode, String coursePaperId) {
|
|
|
- SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
|
|
|
- DataPermissionRule dpr = basicRoleDataPermissionService.findDataPermission(sysUser.getSchoolId(),
|
|
|
- sysUser.getId(), ServletUtil.getRequest().getServletPath());
|
|
|
- ScanExamInfoVo vo = new ScanExamInfoVo();
|
|
|
- vo.setId(exam.getId());
|
|
|
- vo.setName(exam.getName());
|
|
|
- vo.getAnswerScan().setCourseCount(
|
|
|
- markPaperService.getCourseCount(exam.getId(), courseCode, coursePaperId, MarkPaperStatus.FORMAL, dpr));
|
|
|
- vo.getAnswerScan().setPaperNumberCount(markPaperService.getPaperNumberCount(exam.getId(), courseCode,
|
|
|
- coursePaperId, MarkPaperStatus.FORMAL, dpr));
|
|
|
- vo.getAnswerScan()
|
|
|
- .setTotalCount(getCount(exam.getId(), null, courseCode, coursePaperId, MarkPaperStatus.FORMAL, dpr));
|
|
|
- vo.getAnswerScan().setScannedCount(
|
|
|
- getCount(exam.getId(), ScanStatus.SCANNED, courseCode, coursePaperId, MarkPaperStatus.FORMAL, dpr));
|
|
|
- vo.getPackageScan().setTotalCount(markPaperPackageService.getPackageCountByExamId(exam.getId(), courseCode,
|
|
|
- coursePaperId, MarkPaperStatus.FORMAL, dpr));
|
|
|
- vo.getPackageScan().setScannedCount(
|
|
|
- scanPackageService.getCount(exam.getId(), courseCode, coursePaperId, MarkPaperStatus.FORMAL, dpr));
|
|
|
- return vo;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public IPage<StudentScoreDetailDto> pageStudentScore(Long examId, String paperNumber, String college, String majorName,
|
|
|
- String className, String teacher, Integer filter, String status, Boolean breach, Double startScore,
|
|
|
- Double endScore, Double subScore, Integer objectiveScoreRateLt, String studentName, String studentCode,
|
|
|
- String orderType, String orderField, Integer pageNumber, Integer pageSize) {
|
|
|
- if (startScore != null && endScore == null) {
|
|
|
- throw ExceptionResultEnum.ERROR.exception("请输入结束分数值");
|
|
|
- }
|
|
|
- Page<StudentScoreDetailDto> page = new Page<>(pageNumber, pageSize);
|
|
|
- MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
- Double objectiveScoreLt = objectiveScoreRateLt == null ? null : Calculator.round(Calculator.divide(Calculator.multiply(markPaper.getObjectiveScore(), Double.parseDouble(String.valueOf(objectiveScoreRateLt))), 100), 2);
|
|
|
- IPage<StudentScoreDetailDto> studentScoreDetailDtoIPage = this.baseMapper.pageStudentScore(page, examId,
|
|
|
- paperNumber, college, majorName, className, teacher, filter, status, breach, startScore, endScore, subScore,
|
|
|
- objectiveScoreLt, studentName, studentCode, orderType, orderField);
|
|
|
- for (StudentScoreDetailDto scoreDetailDto : studentScoreDetailDtoIPage.getRecords()) {
|
|
|
- // 原图
|
|
|
- scoreDetailDto.setSheetUrls(buildSheetUrls(scoreDetailDto.getStudentId()));
|
|
|
- scoreDetailDto.setSheetPath(null);
|
|
|
- // 状态
|
|
|
- if (ScanStatus.UNEXIST.equals(scoreDetailDto.getScanStatus())) {
|
|
|
- scoreDetailDto.setStatusDisplay("未扫描");
|
|
|
- } else if (ScanStatus.MANUAL_ABSENT.equals(scoreDetailDto.getScanStatus()) || scoreDetailDto.getAbsent() || scoreDetailDto.getOmrAbsent()) {
|
|
|
- scoreDetailDto.setStatusDisplay("缺考");
|
|
|
- } else if (!scoreDetailDto.getAbsent() && !scoreDetailDto.getOmrAbsent() && scoreDetailDto.getUpload() && ScanStatus.SCANNED.equals(scoreDetailDto.getScanStatus())) {
|
|
|
- scoreDetailDto.setStatusDisplay("正常");
|
|
|
- }
|
|
|
-
|
|
|
- // 主观题检查标记
|
|
|
- scoreDetailDto.setSubjectiveCheckFlag(!scoreDetailDto.getAbsent() && !scoreDetailDto.getOmrAbsent() && scoreDetailDto.getUpload() && ScanStatus.SCANNED.equals(scoreDetailDto.getScanStatus()) && SubjectiveStatus.MARKED.equals(scoreDetailDto.getSubjectiveStatus()) && StringUtils.isNotBlank(scoreDetailDto.getSubjectiveScore()) && StringUtils.isNotBlank(scoreDetailDto.getSubjectiveScoreList()));
|
|
|
- // 客观题检查标记
|
|
|
- scoreDetailDto.setObjectiveCheckFlag(!scoreDetailDto.getAbsent() && !scoreDetailDto.getOmrAbsent() && scoreDetailDto.getUpload() && ScanStatus.SCANNED.equals(scoreDetailDto.getScanStatus()) && StringUtils.isNotBlank(scoreDetailDto.getObjectiveScore()) && StringUtils.isNotBlank(scoreDetailDto.getObjectiveScoreList()));
|
|
|
-
|
|
|
- // 格式化分数
|
|
|
- scoreDetailDto.setObjectiveScore(Calculator.round(scoreDetailDto.getObjectiveScore(), 1));
|
|
|
- scoreDetailDto.setSubjectiveScore(Calculator.round(scoreDetailDto.getSubjectiveScore(), 1));
|
|
|
- scoreDetailDto.setTotalScore(Calculator.round(scoreDetailDto.getTotalScore(), 1));
|
|
|
- }
|
|
|
- return studentScoreDetailDtoIPage;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public List<SheetUrlDto> buildSheetUrls(Long studentId) {
|
|
|
- // 原图
|
|
|
- List<SheetUrlDto> sheetUrls = new ArrayList<>();
|
|
|
- List<StudentPaperDetailDto> studentPaperDetailDtoList = scanPaperService.listStudentPaperDetail(studentId);
|
|
|
- for (int i = 0; i < studentPaperDetailDtoList.size(); i++) {
|
|
|
- StudentPaperDetailDto studentPaperDetailDto = studentPaperDetailDtoList.get(i);
|
|
|
- sheetUrls.add(new SheetUrlDto(
|
|
|
- 2 * (studentPaperDetailDto.getPaperIndex() - 1) + studentPaperDetailDto.getPageIndex(),
|
|
|
- teachcloudCommonService.filePreview(studentPaperDetailDto.getSheetPath()),
|
|
|
- studentPaperDetailDto.getRecogData()));
|
|
|
- }
|
|
|
- return sheetUrls;
|
|
|
- }
|
|
|
-
|
|
|
- private int getCount(Long examId, ScanStatus status, String courseCode, String coursePaperId,
|
|
|
- MarkPaperStatus markPaperStatus, DataPermissionRule dpr) {
|
|
|
- MarkStudent markStudent = new MarkStudent();
|
|
|
- markStudent.setExamId(examId);
|
|
|
- markStudent.setCourseCode(courseCode);
|
|
|
- markStudent.setCoursePaperId(coursePaperId);
|
|
|
- markStudent.setScanStatus(status);
|
|
|
- markStudent.setMarkPaperStatus(markPaperStatus.name());
|
|
|
- return baseMapper.selectCountByQuery(markStudent, dpr);
|
|
|
- }
|
|
|
-
|
|
|
- private int getOmrAbsentCount(Long examId, Boolean checked, String courseCode, String coursePaperId,
|
|
|
- MarkPaperStatus status, DataPermissionRule dpr) {
|
|
|
- MarkStudent markStudent = new MarkStudent();
|
|
|
- markStudent.setExamId(examId);
|
|
|
- markStudent.setCourseCode(courseCode);
|
|
|
- markStudent.setCoursePaperId(coursePaperId);
|
|
|
- markStudent.setOmrAbsent(true);
|
|
|
- markStudent.setOmrAbsentChecked(checked);
|
|
|
- markStudent.setMarkPaperStatus(status.name());
|
|
|
- return baseMapper.selectCountByQuery(markStudent, dpr);
|
|
|
- }
|
|
|
-
|
|
|
- private int getIncompleteCount(Long examId, String courseCode, String coursePaperId, MarkPaperStatus status,
|
|
|
- DataPermissionRule dpr) {
|
|
|
- MarkStudent markStudent = new MarkStudent();
|
|
|
- markStudent.setExamId(examId);
|
|
|
- markStudent.setCourseCode(courseCode);
|
|
|
- markStudent.setCoursePaperId(coursePaperId);
|
|
|
- markStudent.setIncomplete(true);
|
|
|
- markStudent.setMarkPaperStatus(status.name());
|
|
|
- return baseMapper.selectCountByQuery(markStudent, dpr);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public ScanExamCheckInfoVo checkInfo(BasicExam exam, String courseCode, String coursePaperId) {
|
|
|
- SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
|
|
|
- DataPermissionRule dpr = basicRoleDataPermissionService.findDataPermission(sysUser.getSchoolId(),
|
|
|
- sysUser.getId(), ServletUtil.getRequest().getServletPath());
|
|
|
- Long examId = exam.getId();
|
|
|
- ScanExamCheckInfoVo vo = new ScanExamCheckInfoVo();
|
|
|
- vo.setId(exam.getId());
|
|
|
- vo.setName(exam.getName());
|
|
|
- CheckTask ct = vo.getCheckTask();
|
|
|
- ct.setUnexistCount(
|
|
|
- getCount(examId, ScanStatus.UNEXIST, courseCode, coursePaperId, MarkPaperStatus.FORMAL, dpr));
|
|
|
- ct.setUnexistCheckedCount(
|
|
|
- getCount(examId, ScanStatus.MANUAL_ABSENT, courseCode, coursePaperId, MarkPaperStatus.FORMAL, dpr));
|
|
|
- ct.setAssignedCount(getAssignedCount(examId, false, courseCode, coursePaperId, MarkPaperStatus.FORMAL, dpr));
|
|
|
- ct.setAssignedCheckedCount(
|
|
|
- getAssignedCount(examId, true, courseCode, coursePaperId, MarkPaperStatus.FORMAL, dpr));
|
|
|
- ct.setAbsentCheckCount(
|
|
|
- getOmrAbsentCount(examId, false, courseCode, coursePaperId, MarkPaperStatus.FORMAL, dpr));
|
|
|
- ct.setAbsentCheckedCount(
|
|
|
- getOmrAbsentCount(examId, true, courseCode, coursePaperId, MarkPaperStatus.FORMAL, dpr));
|
|
|
- ct.setObjectiveCheckCount(scanOmrTaskService.getFinishStudentCountByExamAndUserId(examId, courseCode, coursePaperId,
|
|
|
- OmrTaskStatus.WAITING.name(), dpr));
|
|
|
- ct.setObjectiveCheckedCount(scanOmrTaskService.getFinishStudentCountByExamAndUserId(examId, courseCode, coursePaperId,
|
|
|
- OmrTaskStatus.PROCESSED.name(), dpr));
|
|
|
- ct.setIncompleteCount(getIncompleteCount(examId, courseCode, coursePaperId, MarkPaperStatus.FORMAL, dpr));
|
|
|
- return vo;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 根据考生当前绑定的paper刷新考生状态,需要在外部调用处对考生上锁
|
|
|
- */
|
|
|
- @Override
|
|
|
- @Transactional
|
|
|
- public void updateStudentByPaper(@NotNull Long userId, @NotNull Long studentId, @NotNull boolean updateOmrTask) {
|
|
|
- MarkStudent student = this.getById(studentId);
|
|
|
- if (student == null) {
|
|
|
- throw new ParameterException("找不到对应的考生");
|
|
|
- }
|
|
|
- // 重置状态
|
|
|
- student.setIncomplete(false);
|
|
|
- student.setAssigned(false);
|
|
|
- student.setInvalid(false);
|
|
|
- student.setQuestionFilled(false);
|
|
|
- // student.setOmrAbsent(false);
|
|
|
- int paperCount = 0;
|
|
|
- List<ScanStudentPaper> studentPaperList = studentPaperService.findByStudentId(studentId);
|
|
|
- List<String> objectiveAnswers = new ArrayList<>();
|
|
|
- for (ScanStudentPaper studentPaper : studentPaperList) {
|
|
|
- paperCount++;
|
|
|
- // 获取paper详情更新考生状态
|
|
|
- ScanPaper paper = scanPaperService.getById(studentPaper.getPaperId());
|
|
|
- student.setAssigned(student.getAssigned() || paper.getAssigned());
|
|
|
- student.setInvalid(student.getInvalid() || paper.getInvalid());
|
|
|
- student.setQuestionFilled(student.getQuestionFilled() || paper.getQuestionFilled());
|
|
|
- student.setCardNumber(paper.getCardNumber());
|
|
|
- // 单独判断首张纸正面的识别结果
|
|
|
- if (studentPaper.getPaperIndex() == 1) {
|
|
|
- // 根据识别结果更新考生属性
|
|
|
- ScanPaperPage page = scanPaperPageService.findPaperIdAndIndex(paper.getId(), 1);
|
|
|
- student.setOmrAbsent(page.getAbsent() == null ? false : page.getAbsent().getResult());
|
|
|
- student.setOmrAbsentChecked(false);
|
|
|
- if (student.getOmrAbsent()) {
|
|
|
- student.setObjectiveScore(null);
|
|
|
- student.setObjectiveScoreList(null);
|
|
|
- }
|
|
|
- // student.setDevice(batchService.findByPaperId(paper.getId()).getDevice());
|
|
|
- }
|
|
|
-
|
|
|
- List<ScanPaperPage> scanPaperPages = scanPaperPageService.listByPaperId(studentPaper.getPaperId());
|
|
|
- for (ScanPaperPage scanPaperPage : scanPaperPages) {
|
|
|
- if (scanPaperPage.getQuestion() != null
|
|
|
- && CollectionUtils.isNotEmpty(scanPaperPage.getQuestion().getResult())) {
|
|
|
- for (String s : scanPaperPage.getQuestion().getResult()) {
|
|
|
- if (s.startsWith("?")) {
|
|
|
- s = s.replace("?", "");
|
|
|
- }
|
|
|
- objectiveAnswers.add(s);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- student.setAnswers(JSON.toJSONString(objectiveAnswers));
|
|
|
- // 更新考生状态
|
|
|
- if (paperCount > 0) {
|
|
|
- ScanAnswerCard answerCard = answerCardService.findByExamAndNumber(student.getExamId(),
|
|
|
- student.getCardNumber());
|
|
|
- student.setUpload(true);
|
|
|
- student.setIncomplete(paperCount != answerCard.getPaperCount());
|
|
|
- student.setScanStatus(ScanStatus.SCANNED);
|
|
|
- student.setAbsent(false);
|
|
|
- student.setManualAbsent(false);
|
|
|
- // 更新图片数量和图片地址
|
|
|
- updateStudentSheetInfo(student, studentPaperList);
|
|
|
- } else {
|
|
|
- student.setScanStatus(ScanStatus.UNEXIST);
|
|
|
- }
|
|
|
- // student.setUpdaterId(userId);
|
|
|
- // student.setUpdateTime(System.currentTimeMillis());
|
|
|
- this.saveOrUpdate(student);
|
|
|
- // 客观题统分
|
|
|
- this.calculateObjectiveScore(student);
|
|
|
-
|
|
|
- // 更新课程表中上传人数
|
|
|
- markPaperService.updateUploadCount(student.getExamId(), student.getPaperNumber(),
|
|
|
- this.countUploadedByExamIdAndPaperNumber(student.getExamId(), student.getPaperNumber()));
|
|
|
- markPaperService.updateAbsentCount(student.getExamId(), student.getPaperNumber(),
|
|
|
- this.countAbsentByExamIdAndPaperNumber(student.getExamId(), student.getPaperNumber()));
|
|
|
- if (updateOmrTask) {
|
|
|
- // 清除识别对照任务
|
|
|
- scanOmrTaskService.deleteByStudentId(student.getExamId(), student.getId());
|
|
|
- // 重新生成识别对照任务
|
|
|
- scanOmrTaskService.saveTask(student.getId());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private MarkStudent updateStudentSheetInfo(MarkStudent student, List<ScanStudentPaper> studentPaperList) {
|
|
|
- List<FilePathVo> filePathVoList = new ArrayList<>();
|
|
|
- for (ScanStudentPaper scanStudentPaper : studentPaperList) {
|
|
|
- List<ScanPaperPage> scanPaperPages = scanPaperPageService.listByPaperId(scanStudentPaper.getPaperId());
|
|
|
- for (ScanPaperPage scanPaperPage : scanPaperPages) {
|
|
|
- String sheetPath = scanPaperPage.getSheetPath();
|
|
|
- if (StringUtils.isNotBlank(sheetPath)) {
|
|
|
- filePathVoList.add(JSON.parseObject(sheetPath, FilePathVo.class));
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- student.setSheetCount(filePathVoList.size());
|
|
|
- student.setSheetPath(JSON.toJSONString(filePathVoList));
|
|
|
- return student;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public MarkStudent findByExamIdAndCoursePaperIdAndStudentCode(Long examId, String coursePaperId,
|
|
|
- String studentCode) {
|
|
|
- QueryWrapper<MarkStudent> wrapper = new QueryWrapper<>();
|
|
|
- LambdaQueryWrapper<MarkStudent> lw = wrapper.lambda();
|
|
|
- lw.eq(MarkStudent::getExamId, examId);
|
|
|
- lw.eq(MarkStudent::getCoursePaperId, coursePaperId);
|
|
|
- lw.eq(MarkStudent::getStudentCode, studentCode);
|
|
|
- return baseMapper.selectOne(wrapper);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public StudentObjectiveDetailDto getObjectiveInspectedTask(Long studentId) {
|
|
|
- MarkStudent markStudent = this.getById(studentId);
|
|
|
- StudentObjectiveDetailDto studentObjectiveDetailDto = new StudentObjectiveDetailDto();
|
|
|
- if (markStudent != null) {
|
|
|
- studentObjectiveDetailDto.setStudentId(markStudent.getId());
|
|
|
- studentObjectiveDetailDto.setStudentName(markStudent.getStudentName());
|
|
|
- studentObjectiveDetailDto.setStudentCode(markStudent.getStudentCode());
|
|
|
- studentObjectiveDetailDto.setExamPlace(markStudent.getExamPlace());
|
|
|
- studentObjectiveDetailDto.setExamRoom(markStudent.getExamRoom());
|
|
|
- studentObjectiveDetailDto.setExamId(markStudent.getExamId());
|
|
|
- studentObjectiveDetailDto.setCourseCode(markStudent.getCourseCode());
|
|
|
- studentObjectiveDetailDto.setCourseName(markStudent.getCourseName());
|
|
|
- studentObjectiveDetailDto.setPaperNumber(markStudent.getPaperNumber());
|
|
|
- studentObjectiveDetailDto
|
|
|
- .setObjectiveScore(markStudent.getObjectiveScore() != null ? markStudent.getObjectiveScore() : 0);
|
|
|
- studentObjectiveDetailDto.setSubjectiveScore(
|
|
|
- markStudent.getSubjectiveScore() != null ? markStudent.getSubjectiveScore() : 0);
|
|
|
- studentObjectiveDetailDto.setUpload(markStudent.getUpload());
|
|
|
- studentObjectiveDetailDto.setAbsent(markStudent.getAbsent());
|
|
|
- studentObjectiveDetailDto.setSheetUrls(this.buildSheetUrls(studentId));
|
|
|
-
|
|
|
- List<MarkQuestion> questions = markQuestionService.listQuestionByExamIdAndPaperNumberAndGroupNumber(
|
|
|
- markStudent.getExamId(), markStudent.getPaperNumber(), null, true);
|
|
|
- List<String> answers = markStudent.getAnswerList();
|
|
|
- int questionCount = questions.size();
|
|
|
- int answerCount = answers.size();
|
|
|
-
|
|
|
- List<StudentObjectiveAnswerDto> answerDtoList = new ArrayList<>();
|
|
|
- Map<Integer, String> titles = new HashMap<>();
|
|
|
- // 已设置客观题
|
|
|
- int maxCount = Math.max(questionCount, answerCount);
|
|
|
- for (int i = 0; i < maxCount; i++) {
|
|
|
- MarkQuestion q = questionCount > i ? questions.get(i) : null;
|
|
|
- String answer = answerCount > i ? answers.get(i) : "#";
|
|
|
- StudentObjectiveAnswerDto studentObjectiveAnswerDto = new StudentObjectiveAnswerDto();
|
|
|
- studentObjectiveAnswerDto.setMainNumber(q != null ? q.getMainNumber() : 0);
|
|
|
- studentObjectiveAnswerDto.setSubNumber(q != null ? q.getSubNumber() : 0);
|
|
|
- studentObjectiveAnswerDto.setAnswer(answer);
|
|
|
- studentObjectiveAnswerDto.setExist(q != null && q.getTotalScore() > 0);
|
|
|
- studentObjectiveAnswerDto.setQuestionType(q.getQuestionType());
|
|
|
- answerDtoList.add(studentObjectiveAnswerDto);
|
|
|
-
|
|
|
- if (q != null) {
|
|
|
- titles.put(q.getMainNumber(), q.getMainTitle());
|
|
|
- }
|
|
|
- }
|
|
|
- studentObjectiveDetailDto.setAnswers(answerDtoList);
|
|
|
- studentObjectiveDetailDto.setTitles(titles);
|
|
|
- }
|
|
|
-
|
|
|
- return studentObjectiveDetailDto;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public Boolean saveObjectiveInspectedTask(Long studentId, String answers) {
|
|
|
- Long userId = ServletUtil.getRequestUserId();
|
|
|
- MarkStudent student = this.getById(studentId);
|
|
|
- MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(student.getExamId(), student.getPaperNumber());
|
|
|
- // 评卷是否结束
|
|
|
- if (markPaper == null || MarkPaperStatus.FINISH.equals(markPaper.getStatus())) {
|
|
|
- throw ExceptionResultEnum.ERROR.exception("科目已结束评卷,无法打分");
|
|
|
- }
|
|
|
- answers = StringUtils.trimToEmpty(answers);
|
|
|
- if (student != null) {
|
|
|
- student.setAnswers(answers.toUpperCase());
|
|
|
- student.setCheckUserId(userId);
|
|
|
- student.setCheckTime(System.currentTimeMillis());
|
|
|
- return saveUploadStudent(student);
|
|
|
- } else {
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public int countUploadedByExamIdAndPaperNumber(Long examId, String paperNumber) {
|
|
|
- QueryWrapper<MarkStudent> queryWrapper = new QueryWrapper<>();
|
|
|
- queryWrapper.lambda().eq(MarkStudent::getExamId, examId).eq(MarkStudent::getPaperNumber, paperNumber)
|
|
|
- .eq(MarkStudent::getUpload, true)
|
|
|
- .eq(MarkStudent::getScanStatus, ScanStatus.SCANNED)
|
|
|
- .eq(MarkStudent::getAbsent, false)
|
|
|
- .eq(MarkStudent::getBreach, false)
|
|
|
- .eq(MarkStudent::getOmrAbsent, false);
|
|
|
- return this.count(queryWrapper);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public boolean updateScanInfo(MarkStudent student) {
|
|
|
- UpdateWrapper<MarkStudent> updateWrapper = new UpdateWrapper<>();
|
|
|
- updateWrapper.lambda().set(MarkStudent::getAnswers, student.getAnswers())
|
|
|
- .set(MarkStudent::getBatchCode, student.getBatchCode()).set(MarkStudent::getAbsent, student.getAbsent())
|
|
|
- .set(MarkStudent::getUploadTime, System.currentTimeMillis())
|
|
|
- .set(MarkStudent::getCardNumber, student.getCardNumber()).eq(MarkStudent::getId, student.getId());
|
|
|
- return this.update(updateWrapper);
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public List<MarkStudent> listAbsentOrBreachMarkTaskStudent(Long examId, String paperNumber) {
|
|
|
- return this.baseMapper.listAbsentOrBreachMarkTaskStudent(examId, paperNumber);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public List<MarkStudent> listUnMarkTaskStudent(Long examId, String paperNumber, Integer groupNumber, int pageSize) {
|
|
|
- Page<MarkStudent> page = new Page<>(1, pageSize);
|
|
|
- IPage<MarkStudent> markStudentIPage = this.baseMapper.listUnMarkTaskStudent(page, examId, paperNumber,
|
|
|
- groupNumber);
|
|
|
- return markStudentIPage.getRecords();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 客观题统分 统分场景: 1.后台-成绩检查-客观题检查 2.扫描端-考生图片上传 3.扫描端-客观题二次识别
|
|
|
- *
|
|
|
- * @param student
|
|
|
- * @return
|
|
|
- */
|
|
|
- @Override
|
|
|
- public boolean saveUploadStudent(MarkStudent student) {
|
|
|
- MarkStudent old = this.getById(student.getId());
|
|
|
- if (!student.getAbsent()) {// 正考
|
|
|
- MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(student.getExamId(),
|
|
|
- student.getPaperNumber());
|
|
|
- if (markPaper.getStatus().equals(MarkPaperStatus.FINISH)) {
|
|
|
- markPaperService.updateStatus(markPaper.getExamId(), markPaper.getPaperNumber(), MarkPaperStatus.FORMAL,
|
|
|
- MarkPaperStatus.FINISH);
|
|
|
- }
|
|
|
- }
|
|
|
- calculateObjectiveScore(student);
|
|
|
- if (student.getAbsent()) {// 转缺考
|
|
|
- student.setObjectiveScore(null);
|
|
|
- student.setObjectiveScoreList(null);
|
|
|
- }
|
|
|
- if (!old.getAbsent() && student.getAbsent()) {// 正考转缺考
|
|
|
- student.setSubjectiveScore(null);
|
|
|
- student.setSubjectiveScoreList(null);
|
|
|
- student.setSubjectiveStatus(SubjectiveStatus.UNMARK);
|
|
|
- this.updateById(student);
|
|
|
- }
|
|
|
- boolean success = this.updateScanInfo(student);
|
|
|
- if (success) {
|
|
|
- markPaperService.updateUploadCount(student.getExamId(), student.getPaperNumber(),
|
|
|
- this.countUploadedByExamIdAndPaperNumber(student.getExamId(), student.getPaperNumber()));
|
|
|
- }
|
|
|
- return success;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void calculateObjectiveScore(MarkStudent student) {
|
|
|
- // 缺考状态不统分(人工指定缺考、识别缺考)
|
|
|
- if (!ScanStatus.MANUAL_ABSENT.equals(student.getScanStatus()) && !student.getAbsent() && !student.getOmrAbsent()) {
|
|
|
- ScoreCalculateUtil util = ScoreCalculateUtil.instance(student);
|
|
|
- ScoreInfo info = util.calculate(markQuestionService.listQuestionByExamIdAndPaperNumberAndGroupNumber(
|
|
|
- student.getExamId(), student.getPaperNumber(), null, true), null);
|
|
|
- student.setObjectiveScore(info.getObjectiveScore());
|
|
|
- student.setScoreList(info.getScoreList(), true);
|
|
|
- this.updateObjectiveScoreAndScoreList(student);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- @Transactional
|
|
|
- public void updateStudentAndPaper(@NotNull SysUser user, @NotNull Long id,
|
|
|
- @NotNull List<ScanStudentPaper> studentPaperList) {
|
|
|
- if (CollectionUtils.isNotEmpty(studentPaperList)) {
|
|
|
- for (ScanStudentPaper studentPaper : studentPaperList) {
|
|
|
- studentPaper.setStudentId(id);
|
|
|
- }
|
|
|
- }
|
|
|
- // 清空原有绑定关系
|
|
|
- if (studentPaperService.removeByStudentId(id) > 0) {
|
|
|
- // 删除评卷任务
|
|
|
- MarkStudent student = this.getById(id);
|
|
|
- markService.deleteMarkTaskByStudent(student);
|
|
|
- }
|
|
|
- if (CollectionUtils.isNotEmpty(studentPaperList)) {
|
|
|
- // 保存绑定关系
|
|
|
- studentPaperService.saveOrUpdateBatch(studentPaperList);
|
|
|
- }
|
|
|
- // 更新考生状态
|
|
|
- updateStudentByPaper(user.getId(), id, true);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public StudentVo findOne(StudentQuery query) {
|
|
|
- return baseMapper.findOne(query);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public int countByExamIdAndSecretNumber(Long examId, String secretNumber) {
|
|
|
- QueryWrapper<MarkStudent> queryWrapper = new QueryWrapper<>();
|
|
|
- queryWrapper.lambda().eq(MarkStudent::getExamId, examId).eq(MarkStudent::getSecretNumber, secretNumber);
|
|
|
- return this.count(queryWrapper);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public List<MarkStudent> listByExamIdAndCoursePaperId(Long examId, String coursePaperId) {
|
|
|
- QueryWrapper<MarkStudent> queryWrapper = new QueryWrapper<>();
|
|
|
- queryWrapper.lambda().eq(MarkStudent::getExamId, examId).eq(MarkStudent::getCoursePaperId, coursePaperId);
|
|
|
- return this.list(queryWrapper);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public IPage<AnswerQueryVo> query(AnswerQueryDomain query) {
|
|
|
- SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
|
|
|
- DataPermissionRule dpr = basicRoleDataPermissionService.findDataPermission(sysUser.getSchoolId(),
|
|
|
- sysUser.getId(), ServletUtil.getRequest().getServletPath());
|
|
|
- // 查询考生分页信息
|
|
|
- query.setMarkPaperStatus(MarkPaperStatus.FORMAL.name());
|
|
|
- IPage<AnswerQueryVo> iPage = baseMapper.queryPage(new Page<>(query.getPageNumber(), query.getPageSize()), query,
|
|
|
- dpr);
|
|
|
- if (CollectionUtils.isNotEmpty(iPage.getRecords())) {
|
|
|
- for (AnswerQueryVo vo : iPage.getRecords()) {
|
|
|
- if (vo.getIsAbsent() != null && vo.getIsAbsent()) {
|
|
|
- vo.setExamStatus(ExamStatus.ABSENT);
|
|
|
- } else {
|
|
|
- vo.setExamStatus(ExamStatus.OK);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- if (CollectionUtils.isNotEmpty(iPage.getRecords()) && (query.getWithPaper() != null && query.getWithPaper())) {
|
|
|
- Map<Long, AnswerQueryVo> map = new HashMap<>();
|
|
|
-
|
|
|
- for (AnswerQueryVo vo : iPage.getRecords()) {
|
|
|
- List<AnswerPaperVo> papers = new ArrayList<>();
|
|
|
- vo.setPapers(papers);
|
|
|
- if (vo.getCardPaperCount() != null) {
|
|
|
- for (int i = 1; i <= vo.getCardPaperCount(); i++) {
|
|
|
- AnswerPaperVo pv = new AnswerPaperVo();
|
|
|
- pv.setNumber(i);
|
|
|
- papers.add(pv);
|
|
|
- }
|
|
|
- }
|
|
|
- map.put(vo.getId(), vo);
|
|
|
- }
|
|
|
- // 根据考生id查找绑定paper
|
|
|
- List<Long> studentIds = iPage.getRecords().stream().map(p -> p.getId()).collect(Collectors.toList());
|
|
|
- List<StudentPaperVo> paperList = new BatchGetDataUtil<StudentPaperVo, Long>() {
|
|
|
-
|
|
|
- @Override
|
|
|
- public List<StudentPaperVo> getData(List<Long> paramList) {
|
|
|
- return scanPaperService.listByStudentIds(paramList);
|
|
|
- }
|
|
|
- }.getDataForBatch(studentIds, 200);
|
|
|
-
|
|
|
- if (CollectionUtils.isNotEmpty(paperList)) {
|
|
|
- Map<Long, AnswerPaperVo> paperMap = new HashMap<>();
|
|
|
- for (StudentPaperVo p : paperList) {
|
|
|
- AnswerQueryVo vo = map.get(p.getStudentId());
|
|
|
- if (vo == null) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- List<AnswerPaperVo> papers = vo.getPapers();
|
|
|
- if (papers == null) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- if (papers.size() < p.getNumber()) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- AnswerPaperVo pvo = papers.get(p.getNumber() - 1);
|
|
|
- pvo.setId(p.getPaperId());
|
|
|
- pvo.setNumber(p.getNumber());
|
|
|
- pvo.setAssigned(p.getAssigned());
|
|
|
- pvo.setInvalid(p.getInvalid());
|
|
|
- paperMap.put(p.getPaperId(), pvo);
|
|
|
- }
|
|
|
- // 查找page
|
|
|
- List<Long> paperIds = paperList.stream().map(p -> p.getPaperId()).collect(Collectors.toList());
|
|
|
- List<ScanPaperPage> paperPageList = new BatchGetDataUtil<ScanPaperPage, Long>() {
|
|
|
-
|
|
|
- @Override
|
|
|
- public List<ScanPaperPage> getData(List<Long> paramList) {
|
|
|
- return scanPaperPageService.listByPaperList(paramList);
|
|
|
- }
|
|
|
- }.getDataForBatch(paperIds, 200);
|
|
|
-
|
|
|
- if (CollectionUtils.isNotEmpty(paperPageList)) {
|
|
|
- for (ScanPaperPage p : paperPageList) {
|
|
|
- AnswerPaperVo pvo = paperMap.get(p.getPaperId());
|
|
|
- if (pvo == null) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- List<AnswerPageVo> pages = pvo.getPages();
|
|
|
- if (pages == null) {
|
|
|
- pages = new ArrayList<>();
|
|
|
- pvo.setPages(pages);
|
|
|
- }
|
|
|
- AnswerPageVo pageVo = new AnswerPageVo();
|
|
|
- pageVo.setIndex(p.getPageIndex());
|
|
|
- pageVo.setSheetUri(teachcloudCommonService.filePreview(p.getSheetPath()));
|
|
|
- if (query.getWithOmrDetail() != null && query.getWithOmrDetail()) {
|
|
|
- pageVo.setAbsent(p.getAbsent() != null ? p.getAbsent().getResult() : null);
|
|
|
- pageVo.setBreach(p.getBreach() != null ? p.getBreach().getResult() : null);
|
|
|
- pageVo.setQuestion(p.getQuestion() != null ? p.getQuestion().getResult() : null);
|
|
|
- pageVo.setRecogData(p.getRecogData());
|
|
|
- }
|
|
|
- pages.add(pageVo);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return iPage;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public List<String> summary(AnswerQueryDomain query) {
|
|
|
- SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
|
|
|
- DataPermissionRule dpr = basicRoleDataPermissionService.findDataPermission(sysUser.getSchoolId(),
|
|
|
- sysUser.getId(), ServletUtil.getRequest().getServletPath());
|
|
|
-
|
|
|
- // 不分页查询考生准考证号
|
|
|
- query.setMarkPaperStatus(MarkPaperStatus.FORMAL.name());
|
|
|
- return baseMapper.querySummary(query, dpr);
|
|
|
- }
|
|
|
-
|
|
|
- @Transactional
|
|
|
- @Override
|
|
|
- public UpdateTimeVo omrEdit(Long userId, OmrEditDomain domain) {
|
|
|
- MarkStudent student = findByExamIdAndCoursePaperIdAndStudentCode(domain.getExamId(), domain.getCoursePaperId(),
|
|
|
- domain.getStudentCode());
|
|
|
- if (student == null) {
|
|
|
- throw new ParameterException("考生信息未找到");
|
|
|
- }
|
|
|
- concurrentService.getReadWriteLock(LockType.STUDENT + "-" + student.getId()).writeLock().lock();
|
|
|
- try {
|
|
|
- for (OmrEditPaper paperEdit : domain.getPapers()) {
|
|
|
- ScanStudentPaper sp = studentPaperService.findByStudentIdAndPaperNumber(student.getId(),
|
|
|
- paperEdit.getNumber());
|
|
|
- if (sp == null) {
|
|
|
- throw new ParameterException("未找到绑定扫描结果");
|
|
|
- }
|
|
|
- ScanPaper paperEntity = scanPaperService.getById(sp.getPaperId());
|
|
|
- if (paperEntity == null) {
|
|
|
- throw new ParameterException("未找到paper信息结果");
|
|
|
- }
|
|
|
- paperEntity.setUpdaterId(userId);
|
|
|
- paperEntity.setUpdateTime(System.currentTimeMillis());
|
|
|
- List<ScanPaperPage> pages = scanPaperPageService.listByPaperId(paperEntity.getId());
|
|
|
- for (ScanPaperPage pageEntity : pages) {
|
|
|
- paperEdit.updatePage(pageEntity);
|
|
|
- }
|
|
|
- scanPaperService.savePaperAndPages(paperEntity, pages);
|
|
|
- }
|
|
|
- updateStudentByPaper(userId, student.getId(), true);
|
|
|
- return UpdateTimeVo.create();
|
|
|
- } finally {
|
|
|
- concurrentService.getReadWriteLock(LockType.STUDENT + "-" + student.getId()).writeLock().unlock();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public long countByExamIdAndPaperNumber(Long examId, String paperNumber, String paperType) {
|
|
|
- QueryWrapper<MarkStudent> queryWrapper = new QueryWrapper<>();
|
|
|
- queryWrapper.lambda().eq(MarkStudent::getExamId, examId).eq(MarkStudent::getPaperNumber, paperNumber)
|
|
|
- .eq(MarkStudent::getPaperType, paperType);
|
|
|
- return this.count(queryWrapper);
|
|
|
- }
|
|
|
-
|
|
|
- @Transactional
|
|
|
- @Override
|
|
|
- public AbsentManualUpdateVo absentManualUpdate(Long examId, String coursePaperId, String studentCode,
|
|
|
- ScanStatus status) {
|
|
|
- MarkStudent student = findByExamIdAndCoursePaperIdAndStudentCode(examId, coursePaperId, studentCode);
|
|
|
- if (student == null) {
|
|
|
- throw new ParameterException("考生未找到");
|
|
|
- }
|
|
|
- if (ScanStatus.MANUAL_ABSENT.equals(status) && !ScanStatus.UNEXIST.equals(student.getScanStatus())) {
|
|
|
- throw new ParameterException("考生不是未扫描状态");
|
|
|
- }
|
|
|
- LambdaUpdateWrapper<MarkStudent> lw = new LambdaUpdateWrapper<>();
|
|
|
- lw.set(MarkStudent::getScanStatus, status);
|
|
|
- lw.set(MarkStudent::getManualAbsent, ScanStatus.MANUAL_ABSENT.equals(status));
|
|
|
- lw.set(MarkStudent::getAbsent, ScanStatus.MANUAL_ABSENT.equals(status));
|
|
|
- lw.eq(MarkStudent::getId, student.getId());
|
|
|
- update(lw);
|
|
|
- markPaperService.updateAbsentCount(examId, student.getPaperNumber(),
|
|
|
- this.countAbsentByExamIdAndPaperNumber(examId, student.getPaperNumber()));
|
|
|
- return AbsentManualUpdateVo.create(status);
|
|
|
- }
|
|
|
-
|
|
|
- @Transactional
|
|
|
- @Override
|
|
|
- public UpdateTimeVo confirm(Long examId, String coursePaperId, String studentCode, Boolean omrAbsent) {
|
|
|
- MarkStudent student = findByExamIdAndCoursePaperIdAndStudentCode(examId, coursePaperId, studentCode);
|
|
|
- LambdaUpdateWrapper<MarkStudent> lw = new LambdaUpdateWrapper<>();
|
|
|
- lw.set(MarkStudent::getOmrAbsentChecked, omrAbsent);
|
|
|
- if (omrAbsent) {
|
|
|
- lw.set(MarkStudent::getObjectiveScore, null);
|
|
|
- lw.set(MarkStudent::getObjectiveScoreList, null);
|
|
|
- } else {
|
|
|
- lw.set(MarkStudent::getOmrAbsent, false);
|
|
|
- }
|
|
|
- lw.eq(MarkStudent::getId, student.getId());
|
|
|
- update(lw);
|
|
|
- scanOmrTaskService.deleteByStudentId(student.getExamId(), student.getId());
|
|
|
- if (!omrAbsent) {
|
|
|
- calculateObjectiveScore(student);
|
|
|
- scanOmrTaskService.saveTask(student.getId());
|
|
|
- }
|
|
|
- markPaperService.updateAbsentCount(examId, student.getPaperNumber(),
|
|
|
- this.countAbsentByExamIdAndPaperNumber(examId, student.getPaperNumber()));
|
|
|
- return UpdateTimeVo.create();
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public List<Long> findIdByExamIdAndPaperNumber(Long examId, String paperNumber) {
|
|
|
- return this.baseMapper.findIdByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public Task getSubjectiveInspectedTask(Long studentId) {
|
|
|
- Task task = null;
|
|
|
- if (studentId != null) {
|
|
|
- Long userId = ServletUtil.getRequestUserId();
|
|
|
- MarkStudent markStudent = this.getById(studentId);
|
|
|
- markService.releaseByStudent(markStudent);
|
|
|
- if (markService.applyStudent(markStudent, userId)) {
|
|
|
- task = taskService.build(studentId);
|
|
|
- }
|
|
|
- }
|
|
|
- return task;
|
|
|
- }
|
|
|
-
|
|
|
- @Transactional
|
|
|
- @Override
|
|
|
- public void saveSubjectiveInspectedTask(MarkHeaderResult markResult) {
|
|
|
- MarkStudent markStudent = this.getById(markResult.getStudentId());
|
|
|
- if (markStudent == null) {
|
|
|
- throw ExceptionResultEnum.ERROR.exception("考生不存在");
|
|
|
- }
|
|
|
- MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(markStudent.getExamId(),
|
|
|
- markStudent.getPaperNumber());
|
|
|
- // 评卷是否结束
|
|
|
- if (markPaper == null || MarkPaperStatus.FINISH.equals(markPaper.getStatus())) {
|
|
|
- throw ExceptionResultEnum.ERROR.exception("科目已结束评卷,无法打分");
|
|
|
- }
|
|
|
- try {
|
|
|
- lockService.watch(LockType.EXAM_SUBJECT, markStudent.getExamId(), markStudent.getPaperNumber());
|
|
|
- lockService.waitlock(LockType.STUDENT, markResult.getStudentId());
|
|
|
- markService.submitHeaderTask(markResult.getGroups(), markStudent);
|
|
|
- } catch (Exception e) {
|
|
|
- throw ExceptionResultEnum.ERROR.exception(e.getMessage());
|
|
|
- } finally {
|
|
|
- lockService.unlock(LockType.STUDENT, markResult.getStudentId());
|
|
|
- lockService.unwatch(LockType.EXAM_SUBJECT, markStudent.getExamId(), markStudent.getPaperNumber());
|
|
|
- markService.releaseByStudent(markStudent);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public IPage<ArchiveStudentVo> studentList(ArchiveStudentQuery query) {
|
|
|
- Page<ArchiveStudentVo> page = new Page<>(query.getPageNumber(), query.getPageSize());
|
|
|
- IPage<ArchiveStudentVo> ret = baseMapper.studentList(page, query);
|
|
|
- for (ArchiveStudentVo record : ret.getRecords()) {
|
|
|
- List<String> list = new ArrayList<>();
|
|
|
- List<FilePathVo> vos = JSON.parseArray(StringUtils.trimToNull(record.getSheetPath()), FilePathVo.class);
|
|
|
- if (CollectionUtils.isEmpty(vos)) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- for (FilePathVo filePathVo : vos) {
|
|
|
- list.add(JSON.toJSONString(filePathVo));
|
|
|
- }
|
|
|
- record.setSheetUrls(teachcloudCommonService.filePreview(list));
|
|
|
- }
|
|
|
- return ret;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void scoreExport(ArchiveStudentQuery query, HttpServletResponse response) {
|
|
|
- //生成表头
|
|
|
- String[] columnName = new String[]{"学生姓名", "学号", "学院", "班级", "课程代码", "课程名称", "客观分", "主观分",
|
|
|
- "成绩"};
|
|
|
- List<MarkQuestion> oQuestionList = markQuestionService.listQuestionByExamIdAndPaperNumberAndGroupNumber(query.getExamId(), query.getPaperNumber(), null, true);
|
|
|
- List<MarkQuestion> sQuestionList = markQuestionService.listQuestionByExamIdAndPaperNumberAndGroupNumber(query.getExamId(), query.getPaperNumber(), null, false);
|
|
|
- List<String> columnNameList = new ArrayList<>(Arrays.asList(columnName));
|
|
|
- for (MarkQuestion question : oQuestionList) {
|
|
|
- columnNameList.add(question.getMainTitle() + " " + question.getMainNumber() + "-" + question.getSubNumber() + "选项");
|
|
|
- columnNameList.add(question.getMainTitle() + " " + question.getMainNumber() + "-" + question.getSubNumber() + "得分");
|
|
|
- }
|
|
|
- for (MarkQuestion question : oQuestionList) {
|
|
|
- columnNameList.add(question.getMainTitle() + " " + question.getMainNumber() + "-" + question.getSubNumber());
|
|
|
- }
|
|
|
- String[] columnNames = columnNameList.toArray(new String[0]);
|
|
|
- //生成动态内容
|
|
|
- List<String[]> columnValues = new ArrayList<>();
|
|
|
- List<ArchiveStudentVo> ret = baseMapper.studentList(query);
|
|
|
- for (ArchiveStudentVo s : ret) {
|
|
|
- List<String> valueList = new ArrayList<>();
|
|
|
- valueList.add(s.getStudentName());
|
|
|
- valueList.add(s.getStudentCode());
|
|
|
- valueList.add(s.getCollege());
|
|
|
- valueList.add(s.getClassName());
|
|
|
- valueList.add(s.getCourseCode());
|
|
|
- valueList.add(s.getCourseName());
|
|
|
- valueList.add(s.getObjectiveScore() == null ? "" : s.getObjectiveScore().toString());
|
|
|
- valueList.add(s.getSubjectiveScore() == null ? "" : s.getSubjectiveScore().toString());
|
|
|
- valueList.add(s.getTotalScore() == null ? "" : s.getTotalScore().toString());
|
|
|
- for (ScoreItem item : s.getScoreList(true, oQuestionList)) {
|
|
|
- valueList.add(item.getAnswer());
|
|
|
- valueList.add(item.getScore() == null ? "" : item.getScore().toString());
|
|
|
- }
|
|
|
- for (ScoreItem item : s.getScoreList(false, sQuestionList)) {
|
|
|
- valueList.add(item.getScore().toString());
|
|
|
- }
|
|
|
- String[] columnValue = valueList.toArray(new String[valueList.size()]);
|
|
|
- columnValues.add(columnValue);
|
|
|
- }
|
|
|
- try {
|
|
|
- log.debug("导出Excel开始...");
|
|
|
- response.setHeader("Content-Disposition", "inline;filename=" + URLEncoder.encode("成绩导出", SystemConstant.CHARSET_NAME) + ".xlsx");
|
|
|
- response.setContentType("application/vnd.ms-excel");
|
|
|
- ServletOutputStream outputStream = response.getOutputStream();
|
|
|
- ExcelWriter writer = ExcelWriter.create(ExcelType.XLSX);
|
|
|
- writer.writeDataArrays("成绩导出", null, columnNames, columnValues.listIterator());
|
|
|
- writer.output(outputStream);
|
|
|
- outputStream.flush();
|
|
|
- outputStream.close();
|
|
|
- log.debug("导出Excel结束");
|
|
|
- } catch (Exception e) {
|
|
|
- throw new RuntimeException(e);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public ScoreReportVo scoreReport(ArchiveStudentQuery query) {
|
|
|
- ScoreReportVo ret = new ScoreReportVo();
|
|
|
- ret.setOverview(baseMapper.overview(query));
|
|
|
- if (ret.getOverview() != null) {
|
|
|
- double total = ret.getOverview().getStudentCount() - ret.getOverview().getAbsentCount();
|
|
|
- ret.getOverview().setPassRate(
|
|
|
- Calculator.divide2String(Calculator.multiply(ret.getOverview().getPassCount(), 100), total, 2));
|
|
|
- ret.getOverview().setExcellentRate(Calculator
|
|
|
- .divide2String(Calculator.multiply(ret.getOverview().getExcellentCount(), 100), total, 2));
|
|
|
- ret.getOverview().setAvgScore(Calculator.round(ret.getOverview().getAvgScore(), 2));
|
|
|
- }
|
|
|
- List<ArchiveStudentVo> studentList = baseMapper.studentList(query);
|
|
|
- fillScoreRange(ret, studentList);
|
|
|
-
|
|
|
- ret.setCollege(baseMapper.college(query));
|
|
|
- if (CollectionUtils.isNotEmpty(ret.getCollege())) {
|
|
|
- for (CollegeVo vo : ret.getCollege()) {
|
|
|
- double total = vo.getStudentCount() - vo.getAbsentCount();
|
|
|
- vo.setPassRate(Calculator.divide2String(Calculator.multiply(vo.getPassCount(), 100), total, 2));
|
|
|
- vo.setExcellentRate(
|
|
|
- Calculator.divide2String(Calculator.multiply(vo.getExcellentCount(), 100), total, 2));
|
|
|
- vo.setAvgScore(Calculator.round(vo.getAvgScore(), 2));
|
|
|
- vo.setMinScore(Calculator.round(vo.getMinScore(), 2));
|
|
|
- vo.setMaxScore(Calculator.round(vo.getMaxScore(), 2));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- ret.setClassData(baseMapper.classData(query));
|
|
|
- if (CollectionUtils.isNotEmpty(ret.getClassData())) {
|
|
|
- for (ClassVo vo : ret.getClassData()) {
|
|
|
- double total = vo.getStudentCount() - vo.getAbsentCount();
|
|
|
- vo.setPassRate(Calculator.divide2String(Calculator.multiply(vo.getPassCount(), 100), total, 2));
|
|
|
- vo.setExcellentRate(
|
|
|
- Calculator.divide2String(Calculator.multiply(vo.getExcellentCount(), 100), total, 2));
|
|
|
- vo.setAvgScore(Calculator.round(vo.getAvgScore(), 2));
|
|
|
- vo.setMinScore(Calculator.round(vo.getMinScore(), 2));
|
|
|
- vo.setMaxScore(Calculator.round(vo.getMaxScore(), 2));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- ret.setTeacher(baseMapper.teacher(query));
|
|
|
- if (CollectionUtils.isNotEmpty(ret.getTeacher())) {
|
|
|
- for (TeacherVo vo : ret.getTeacher()) {
|
|
|
- double total = vo.getStudentCount() - vo.getAbsentCount();
|
|
|
- vo.setPassRate(Calculator.divide2String(Calculator.multiply(vo.getPassCount(), 100), total, 2));
|
|
|
- vo.setExcellentRate(
|
|
|
- Calculator.divide2String(Calculator.multiply(vo.getExcellentCount(), 100), total, 2));
|
|
|
- vo.setAvgScore(Calculator.round(vo.getAvgScore(), 2));
|
|
|
- vo.setMinScore(Calculator.round(vo.getMinScore(), 2));
|
|
|
- vo.setMaxScore(Calculator.round(vo.getMaxScore(), 2));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- ret.setTeacherClass(baseMapper.teacherClass(query));
|
|
|
- if (CollectionUtils.isNotEmpty(ret.getTeacherClass())) {
|
|
|
- for (TeacherClassVo vo : ret.getTeacherClass()) {
|
|
|
- double total = vo.getStudentCount() - vo.getAbsentCount();
|
|
|
- vo.setPassRate(Calculator.divide2String(Calculator.multiply(vo.getPassCount(), 100), total, 2));
|
|
|
- vo.setExcellentRate(
|
|
|
- Calculator.divide2String(Calculator.multiply(vo.getExcellentCount(), 100), total, 2));
|
|
|
- vo.setAvgScore(Calculator.round(vo.getAvgScore(), 2));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- fillObjective(ret, studentList, query.getExamId(), query.getPaperNumber());
|
|
|
- List<Long> studentIds = studentList.stream().map(ArchiveStudentVo::getStudentId).collect(Collectors.toList());
|
|
|
- ret.setSubjective(markSubjectiveScoreService.getSubjectiveVo(studentIds));
|
|
|
- if (CollectionUtils.isNotEmpty(ret.getSubjective())) {
|
|
|
- for (QuestionVo vo : ret.getSubjective()) {
|
|
|
- double total = vo.getStudentCount();
|
|
|
- vo.setScoreRate(Calculator.divide(vo.getScoreCount(), total, 2));
|
|
|
- vo.setFullScoreRate(Calculator.divide(vo.getFullScoreCount(), total, 2));
|
|
|
- vo.setAvgScore(Calculator.round(vo.getAvgScore(), 2));
|
|
|
- }
|
|
|
- }
|
|
|
- return ret;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void exportUnexist(Long examId, String courseCode, String coursePaperId, HttpServletResponse response) {
|
|
|
- try {
|
|
|
- SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
|
|
|
- DataPermissionRule dpr = basicRoleDataPermissionService.findDataPermission(sysUser.getSchoolId(),
|
|
|
- sysUser.getId(), ServletUtil.getRequest().getServletPath());
|
|
|
- List<UnexistStudentDto> unexistStudentDtoList = this.baseMapper.listUnexistStudentByExamIdAndCoursePaperId(
|
|
|
- examId, courseCode, coursePaperId, MarkPaperStatus.FORMAL.name(), dpr);
|
|
|
- ExcelUtil.excelExport("评卷员工作量", UnexistStudentDto.class, unexistStudentDtoList, response);
|
|
|
- } catch (Exception e) {
|
|
|
- throw ExceptionResultEnum.ERROR.exception("导出评卷员工作量失败");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public int countByExamIdAndPaperNumberAndMarkStatus(Long examId, String paperNumber, SubjectiveStatus status) {
|
|
|
- QueryWrapper<MarkStudent> queryWrapper = new QueryWrapper<>();
|
|
|
- LambdaQueryWrapper<MarkStudent> lambdaQueryWrapper = queryWrapper.lambda();
|
|
|
- lambdaQueryWrapper.eq(MarkStudent::getExamId, examId).eq(MarkStudent::getPaperNumber, paperNumber);
|
|
|
- if (status != null) {
|
|
|
- lambdaQueryWrapper.eq(MarkStudent::getSubjectiveStatus, status);
|
|
|
- }
|
|
|
- lambdaQueryWrapper.eq(MarkStudent::getUpload, true).eq(MarkStudent::getAbsent, false)
|
|
|
- .eq(MarkStudent::getBreach, false).eq(MarkStudent::getOmrAbsent, false);
|
|
|
- return this.count(queryWrapper);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void updateCheckInfo(Long studentId, Long userId) {
|
|
|
- UpdateWrapper<MarkStudent> updateWrapper = new UpdateWrapper<>();
|
|
|
- updateWrapper.lambda().set(MarkStudent::getCheckUserId, userId)
|
|
|
- .set(MarkStudent::getCheckTime, System.currentTimeMillis()).eq(MarkStudent::getId, studentId);
|
|
|
- this.update(updateWrapper);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public int countOmrAbsentStudent(Long examId, String paperNumber, String paperType, boolean isOmrAbsentConfirm) {
|
|
|
- QueryWrapper<MarkStudent> queryWrapper = new QueryWrapper<>();
|
|
|
- queryWrapper.lambda().eq(MarkStudent::getExamId, examId).eq(MarkStudent::getPaperNumber, paperNumber)
|
|
|
- .eq(MarkStudent::getPaperType, paperType).eq(MarkStudent::getOmrAbsent, true)
|
|
|
- .eq(MarkStudent::getOmrAbsentChecked, isOmrAbsentConfirm);
|
|
|
- return this.count(queryWrapper);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void scoreReportDownload(JSONObject jsonObject, HttpServletResponse response) {
|
|
|
- String rootPath = null;
|
|
|
- File htmlFile;
|
|
|
- File pdfFile;
|
|
|
- try {
|
|
|
- // 本地保存目录
|
|
|
- File tempFile = SystemConstant.getFileTempDirVar(
|
|
|
- System.currentTimeMillis() + File.separator + SystemConstant.getNanoId(),
|
|
|
- SystemConstant.TEMP_PREFIX);
|
|
|
- rootPath = tempFile.getParent();
|
|
|
-
|
|
|
- // 删除临时目录中创建的临时文件
|
|
|
- if (Objects.nonNull(tempFile)) {
|
|
|
- tempFile.delete();
|
|
|
- }
|
|
|
- // html文件
|
|
|
- String cardHtmlPath = rootPath + File.separator + System.currentTimeMillis() + File.separator + "temp"
|
|
|
- + SystemConstant.HTML_PREFIX;
|
|
|
- htmlFile = new File(cardHtmlPath);
|
|
|
- if (!htmlFile.exists()) {
|
|
|
- htmlFile.getParentFile().mkdirs();
|
|
|
- htmlFile.createNewFile();
|
|
|
- }
|
|
|
- // 生成html文件
|
|
|
- FileCopyUtils.copy(jsonObject.getString("htmlContent").getBytes(StandardCharsets.UTF_8), htmlFile);
|
|
|
-
|
|
|
- // pdf文件
|
|
|
- String cardPdfPath = rootPath + File.separator + System.currentTimeMillis() + File.separator + "temp"
|
|
|
- + SystemConstant.PDF_PREFIX;
|
|
|
- pdfFile = new File(cardPdfPath);
|
|
|
- if (!pdfFile.exists()) {
|
|
|
- pdfFile.getParentFile().mkdirs();
|
|
|
- pdfFile.createNewFile();
|
|
|
- }
|
|
|
- HtmlToPdfUtil.convert(cardHtmlPath, cardPdfPath, PageSizeEnum.A4);
|
|
|
- FileUtil.outputFile(response, pdfFile, "报告" + SystemConstant.PDF_PREFIX);
|
|
|
- } catch (Exception e) {
|
|
|
- e.printStackTrace();
|
|
|
- } finally {
|
|
|
- if (Objects.nonNull(rootPath)) {
|
|
|
- ConvertUtil.delFolder(rootPath);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void deleteByExamIdAndPaperNumber(Long examId, String paperNumber) {
|
|
|
- UpdateWrapper<MarkStudent> updateWrapper = new UpdateWrapper<>();
|
|
|
- updateWrapper.lambda().eq(MarkStudent::getExamId, examId).eq(MarkStudent::getPaperNumber, paperNumber);
|
|
|
- this.remove(updateWrapper);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public boolean calcObjectiveScore(Long examId, String paperNumber) {
|
|
|
- MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
- if (markPaper != null) {
|
|
|
- if (lockService.trylock(LockType.SCORE_CALCULATE, markPaper.getId())) {
|
|
|
- markSyncService.calcObjectiveScore(markPaper);
|
|
|
- return true;
|
|
|
- } else {
|
|
|
- throw ExceptionResultEnum.ERROR.exception("评卷员正在重置");
|
|
|
- }
|
|
|
- }
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public IPage<MarkStudent> pageByExamAndPaperNumber(Long examId, String paperNumber, int pageNumber, int pageSize) {
|
|
|
- QueryWrapper<MarkStudent> queryWrapper = new QueryWrapper<>();
|
|
|
- queryWrapper.lambda().eq(MarkStudent::getExamId, examId).eq(MarkStudent::getPaperNumber, paperNumber)
|
|
|
- .orderByAsc(MarkStudent::getId);
|
|
|
- return this.page(new Page<>(pageNumber, pageSize), queryWrapper);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void updateObjectiveScoreAndScoreList(MarkStudent markStudent) {
|
|
|
- UpdateWrapper<MarkStudent> objectiveUpdateWrapper = new UpdateWrapper<>();
|
|
|
- LambdaUpdateWrapper<MarkStudent> lambdaUpdateWrapper = objectiveUpdateWrapper.lambda();
|
|
|
- lambdaUpdateWrapper.set(MarkStudent::getObjectiveScore, markStudent.getObjectiveScore())
|
|
|
- .set(MarkStudent::getObjectiveScoreList, markStudent.getObjectiveScoreList());
|
|
|
- if (markStudent.getCheckUserId() != null) {
|
|
|
- lambdaUpdateWrapper.set(MarkStudent::getCheckUserId, markStudent.getCheckUserId());
|
|
|
- }
|
|
|
- if (markStudent.getCheckTime() != null) {
|
|
|
- lambdaUpdateWrapper.set(MarkStudent::getCheckTime, markStudent.getCheckTime());
|
|
|
- }
|
|
|
- lambdaUpdateWrapper.eq(MarkStudent::getId, markStudent.getId());
|
|
|
- this.update(objectiveUpdateWrapper);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public boolean updateAssignConfirm(Long studentId, boolean assignConfirm) {
|
|
|
- UpdateWrapper<MarkStudent> updateWrapper = new UpdateWrapper<>();
|
|
|
- updateWrapper.lambda().set(MarkStudent::getAssignConfirmed, assignConfirm).eq(MarkStudent::getId, studentId);
|
|
|
- return this.update(updateWrapper);
|
|
|
- }
|
|
|
-
|
|
|
- private void fillObjective(ScoreReportVo ret, List<ArchiveStudentVo> studentList, Long examId, String paperNumber) {
|
|
|
- List<MarkQuestion> qs = markQuestionService.listByExamIdAndPaperNumberAndPaperType(examId, paperNumber, null, true);
|
|
|
- Map<String, QuestionVo> map = new HashMap<>();
|
|
|
- List<QuestionVo> list = new ArrayList<>();
|
|
|
- for (ArchiveStudentVo s : studentList) {
|
|
|
- List<ScoreItem> sis = s.getScoreList(true, qs);
|
|
|
- if (CollectionUtils.isNotEmpty(sis)) {
|
|
|
- for (ScoreItem si : sis) {
|
|
|
- String key = si.getMainNumber() + "-" + si.getSubNumber();
|
|
|
- QuestionVo vo = map.get(key);
|
|
|
- if (vo == null) {
|
|
|
- vo = new QuestionVo();
|
|
|
- vo.setScoreCount(0);
|
|
|
- vo.setFullScoreCount(0);
|
|
|
- vo.setStudentCount(0);
|
|
|
- vo.setScoreSum(0.0);
|
|
|
- vo.setMainNumber(si.getMainNumber());
|
|
|
- vo.setSubNumber(si.getSubNumber());
|
|
|
- vo.setTitle(si.getTitle());
|
|
|
- vo.setScore(si.getTotalScore());
|
|
|
- map.put(key, vo);
|
|
|
- }
|
|
|
- vo.setStudentCount(vo.getStudentCount() + 1);
|
|
|
- vo.setScoreSum(vo.getScoreSum() + si.getScore());
|
|
|
- if (si.getScore() == si.getTotalScore()) {
|
|
|
- vo.setFullScoreCount(vo.getFullScoreCount() + 1);
|
|
|
- }
|
|
|
- if (si.getScore() > 0) {
|
|
|
- vo.setScoreCount(vo.getScoreCount() + 1);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- if (map.isEmpty()) {
|
|
|
- ret.setObjective(list);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- list = new ArrayList<>(map.values());
|
|
|
- for (QuestionVo questionVo : list) {
|
|
|
- // 平均分
|
|
|
- if (questionVo.getStudentCount() == null || questionVo.getStudentCount() == 0) {
|
|
|
- questionVo.setAvgScore(0D);
|
|
|
- } else {
|
|
|
- questionVo.setAvgScore(Calculator.round(Calculator.divide(questionVo.getScoreSum(), questionVo.getStudentCount()), 2));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- Collections.sort(list, (o1, o2) -> {
|
|
|
- if (o1.getMainNumber() > o2.getMainNumber()) {
|
|
|
- return 1;
|
|
|
- } else if (o1.getSubNumber() < o2.getSubNumber()) {
|
|
|
- return -1;
|
|
|
- } else {
|
|
|
- return 0;
|
|
|
- }
|
|
|
- });
|
|
|
- for (QuestionVo vo : list) {
|
|
|
- double total = vo.getStudentCount();
|
|
|
- vo.setScoreRate(Calculator.divide(vo.getScoreCount(), total, 2));
|
|
|
- vo.setFullScoreRate(Calculator.divide(vo.getFullScoreCount(), total, 2));
|
|
|
- }
|
|
|
- ret.setObjective(list);
|
|
|
- }
|
|
|
-
|
|
|
- private List<MarkStudent> listByExamIdAndPaperNumberAndNotAbsent(Long examId, String paperNumber) {
|
|
|
- QueryWrapper<MarkStudent> wrapper = new QueryWrapper<>();
|
|
|
- LambdaQueryWrapper<MarkStudent> lw = wrapper.lambda();
|
|
|
- lw.eq(MarkStudent::getExamId, examId);
|
|
|
- lw.eq(MarkStudent::getPaperNumber, paperNumber);
|
|
|
- lw.eq(MarkStudent::getUpload, true);
|
|
|
- lw.eq(MarkStudent::getAbsent, false);
|
|
|
- lw.eq(MarkStudent::getBreach, false);
|
|
|
- lw.eq(MarkStudent::getOmrAbsent, false);
|
|
|
-
|
|
|
- return this.list(wrapper);
|
|
|
- }
|
|
|
-
|
|
|
- private void fillScoreRange(ScoreReportVo ret, List<ArchiveStudentVo> list) {
|
|
|
- List<ScoreRangeVo> scoreRange = new ArrayList<>();
|
|
|
- ret.setScoreRange(scoreRange);
|
|
|
- scoreRange.add(getScoreRangeVo(list, 1.0, 9.5));
|
|
|
- scoreRange.add(getScoreRangeVo(list, 10.0, 19.5));
|
|
|
- scoreRange.add(getScoreRangeVo(list, 20.0, 29.5));
|
|
|
- scoreRange.add(getScoreRangeVo(list, 30.0, 39.5));
|
|
|
- scoreRange.add(getScoreRangeVo(list, 40.0, 49.5));
|
|
|
- scoreRange.add(getScoreRangeVo(list, 50.0, 59.5));
|
|
|
- scoreRange.add(getScoreRangeVo(list, 60.0, 69.5));
|
|
|
- scoreRange.add(getScoreRangeVo(list, 70.0, 79.5));
|
|
|
- scoreRange.add(getScoreRangeVo(list, 80.0, 89.5));
|
|
|
- scoreRange.add(getScoreRangeVo(list, 90.0, 100.0));
|
|
|
- }
|
|
|
-
|
|
|
- private ScoreRangeVo getScoreRangeVo(List<ArchiveStudentVo> list, Double start, Double end) {
|
|
|
- int count = (int) list.stream().filter(s -> s.getTotalScore() >= start && s.getTotalScore() <= end).count();
|
|
|
- Double rate = null;
|
|
|
- if (list.size() != 0) {
|
|
|
- rate = Calculator.multiply(count, list.size(), 2);
|
|
|
- }
|
|
|
- ScoreRangeVo vo = new ScoreRangeVo(count, start, end, rate);
|
|
|
- return vo;
|
|
|
- }
|
|
|
-
|
|
|
- private int getCountByPaperNumber(Long examId, String paperNumber) {
|
|
|
- QueryWrapper<MarkStudent> wrapper = new QueryWrapper<>();
|
|
|
- LambdaQueryWrapper<MarkStudent> lw = wrapper.lambda();
|
|
|
- lw.eq(MarkStudent::getExamId, examId);
|
|
|
- lw.eq(MarkStudent::getPaperNumber, paperNumber);
|
|
|
- return this.count(wrapper);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public int getAssignedCount(Long examId, Boolean checked, String courseCode, String coursePaperId,
|
|
|
- MarkPaperStatus status, DataPermissionRule dpr) {
|
|
|
- MarkStudent markStudent = new MarkStudent();
|
|
|
- markStudent.setExamId(examId);
|
|
|
- markStudent.setCourseCode(courseCode);
|
|
|
- markStudent.setCoursePaperId(coursePaperId);
|
|
|
- markStudent.setAssigned(true);
|
|
|
- markStudent.setAssignConfirmed(checked);
|
|
|
- markStudent.setMarkPaperStatus(status.name());
|
|
|
- return baseMapper.countAssigned(markStudent, dpr);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public int countAbsentByExamIdAndPaperNumber(Long examId, String paperNumber) {
|
|
|
- QueryWrapper<MarkStudent> queryWrapper = new QueryWrapper<>();
|
|
|
- queryWrapper.lambda().eq(MarkStudent::getExamId, examId).eq(MarkStudent::getPaperNumber, paperNumber)
|
|
|
- .and(o -> o.eq(MarkStudent::getAbsent, true).or().eq(MarkStudent::getOmrAbsent, true));
|
|
|
- return this.count(queryWrapper);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public List<MarkStudent> listScanCollegeByExamIdAndCourseCodeAndCoursePaperId(Long examId, String courseCode,
|
|
|
- String coursePaperId, String status, DataPermissionRule dpr) {
|
|
|
- return this.baseMapper.listScanCollegeByExamIdAndCourseCodeAndCoursePaperId(examId, courseCode, coursePaperId,
|
|
|
- status, dpr);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public int countUnexistByExamIdAndPaperNumberAndPaperType(Long examId, String paperNumber, String paperType) {
|
|
|
- MarkStudent markStudent = new MarkStudent();
|
|
|
- markStudent.setExamId(examId);
|
|
|
- markStudent.setPaperNumber(paperNumber);
|
|
|
- markStudent.setScanStatus(ScanStatus.UNEXIST);
|
|
|
- markStudent.setPaperType(paperType);
|
|
|
- markStudent.setMarkPaperStatus(MarkPaperStatus.FORMAL.name());
|
|
|
- return baseMapper.selectCountByQuery(markStudent, null);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void updateStudentAnswer(Long studentId) {
|
|
|
- List<String> objectiveAnswers = new ArrayList<>();
|
|
|
- MarkStudent student = this.getById(studentId);
|
|
|
- List<ScanStudentPaper> studentPaperList = studentPaperService.findByStudentId(studentId);
|
|
|
- for (ScanStudentPaper studentPaper : studentPaperList) {
|
|
|
- List<ScanPaperPage> scanPaperPages = scanPaperPageService.listByPaperId(studentPaper.getPaperId());
|
|
|
- for (ScanPaperPage scanPaperPage : scanPaperPages) {
|
|
|
- if (scanPaperPage.getQuestion() != null
|
|
|
- && CollectionUtils.isNotEmpty(scanPaperPage.getQuestion().getResult())) {
|
|
|
- for (String s : scanPaperPage.getQuestion().getResult()) {
|
|
|
- if (s.startsWith("?")) {
|
|
|
- s = s.replace("?", "");
|
|
|
- }
|
|
|
- objectiveAnswers.add(s);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- student.setAnswers(JSON.toJSONString(objectiveAnswers));
|
|
|
- this.saveOrUpdate(student);
|
|
|
- // 客观题统分
|
|
|
- this.calculateObjectiveScore(student);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public List<MarkStudentScoreVo> listMarkStudentScoreList(Long examId, String paperNumber) {
|
|
|
- MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
- if (!MarkPaperStatus.FINISH.equals(markPaper.getStatus())) {
|
|
|
- throw ExceptionResultEnum.ERROR.exception("科目未结束评卷,不能同步考生成绩");
|
|
|
- }
|
|
|
-
|
|
|
- List<MarkStudent> markStudentList = this.listByExamIdAndPaperNumberAndNotAbsent(examId, paperNumber);
|
|
|
- List<MarkQuestion> objectiveQuestionList = markQuestionService.listByExamIdAndPaperNumberAndPaperType(examId, paperNumber, null, true);
|
|
|
- List<MarkQuestion> subjectiveQuestionList = markQuestionService.listByExamIdAndPaperNumberAndPaperType(examId, paperNumber, null, false);
|
|
|
- List<MarkStudentScoreVo> markStudentScoreVoList = new ArrayList<>();
|
|
|
- for (MarkStudent markStudent : markStudentList) {
|
|
|
- MarkStudentScoreVo markStudentScoreVo = new MarkStudentScoreVo();
|
|
|
- markStudentScoreVo.setExamId(markStudent.getExamId());
|
|
|
- markStudentScoreVo.setCourseCode(markStudent.getCourseCode());
|
|
|
- markStudentScoreVo.setCourseName(markStudent.getCourseName());
|
|
|
- markStudentScoreVo.setPaperNumber(markStudent.getPaperNumber());
|
|
|
- markStudentScoreVo.setStudentCode(markStudent.getStudentCode());
|
|
|
- markStudentScoreVo.setStudentName(markStudent.getStudentName());
|
|
|
- // 客观题
|
|
|
- markStudentScoreVo.setObjectiveScore(markStudent.getObjectiveScore());
|
|
|
- markStudentScoreVo.setObjectiveScoreList(markStudent.getScoreList(true, objectiveQuestionList));
|
|
|
- // 主观题
|
|
|
- markStudentScoreVo.setSubjectiveScore(markStudent.getSubjectiveScore());
|
|
|
- markStudentScoreVo.setSubjectiveScoreList(markStudent.getScoreList(false, subjectiveQuestionList));
|
|
|
-
|
|
|
- // 总分
|
|
|
- markStudentScoreVo.setTotalScore(markStudent.getTotalScore());
|
|
|
- List<ScoreItem> totalScoreItemList = new ArrayList<>();
|
|
|
- totalScoreItemList.addAll(markStudentScoreVo.getObjectiveScoreList());
|
|
|
- totalScoreItemList.addAll(markStudentScoreVo.getSubjectiveScoreList());
|
|
|
- totalScoreItemList.stream().sorted(Comparator.comparing(ScoreItem::getMainNumber).thenComparing(ScoreItem::getSubNumber));
|
|
|
- markStudentScoreVo.setTotalScoreList(totalScoreItemList);
|
|
|
- markStudentScoreVoList.add(markStudentScoreVo);
|
|
|
- }
|
|
|
- return markStudentScoreVoList;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void trackExport(Long examId, String coursePaperId, HttpServletResponse response) {
|
|
|
- {
|
|
|
- List<MarkStudent> list = this.listByExamIdAndCoursePaperId(examId,coursePaperId);
|
|
|
- if (CollectionUtils.isNotEmpty(list)) {
|
|
|
- try {
|
|
|
- response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("轨迹图.zip","UTF-8"));
|
|
|
- ZipWriter writer = ZipWriter.create(response.getOutputStream());
|
|
|
- ByteArrayOutputStream os = new ByteArrayOutputStream();
|
|
|
- for (MarkStudent s:list) {
|
|
|
- if(!s.getUpload()){
|
|
|
- continue;
|
|
|
- }
|
|
|
- List<FilePathVo> vos = JSON.parseArray(s.getSheetPath(), FilePathVo.class);
|
|
|
- List<MarkTrack> trackList = markTrackService.listByStudentId(s.getId());
|
|
|
- Document document = new Document(new Rectangle(PageSize.A3.getHeight(),PageSize.A3.getWidth()));
|
|
|
- // 本地保存目录
|
|
|
- File tempFile = SystemConstant.getFileTempParentDirVar(SystemConstant.TEMP_PREFIX);
|
|
|
- File file =new File(tempFile.getPath()+File.separator + s.getStudentCode()+".pdf");
|
|
|
- PdfWriter pdfWriter = PdfWriter.getInstance(document,new FileOutputStream(file));
|
|
|
- document.open();
|
|
|
- for (int i = 0; i < vos.size(); i++) {
|
|
|
- FilePathVo vo = vos.get(i);
|
|
|
- File sheet = fileUploadService.downloadFile(JSON.toJSONString(vo),vo.getPath());
|
|
|
- File track = new File(tempFile.getPath()+File.separator + s.getStudentCode()+"-"+(i+1)+".jpg");
|
|
|
- int offsetIndex = i+1;
|
|
|
- List<MarkTrack> tracks = trackList.stream().filter(t->t.getOffsetIndex().equals(offsetIndex)).collect(Collectors.toList());
|
|
|
- this.createTrack(sheet,track,tracks);
|
|
|
- Image image = Image.getInstance(track.getPath());
|
|
|
- image.scaleAbsolute(PageSize.A3.getHeight()-100,PageSize.A3.getWidth()-100);
|
|
|
- if(i!=0){
|
|
|
- document.newPage();
|
|
|
- }
|
|
|
- document.add(image);
|
|
|
- sheet.delete();
|
|
|
- track.delete();
|
|
|
- }
|
|
|
- document.close();
|
|
|
- pdfWriter.close();
|
|
|
- writer.write(file,s.getStudentCode()+".pdf");
|
|
|
- }
|
|
|
- writer.close();
|
|
|
- }catch (Exception e){
|
|
|
- e.printStackTrace();
|
|
|
- throw new ParameterException("文件下载失败", e);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private void createTrack(File sheet, File track, List<MarkTrack> trackList)throws IOException {
|
|
|
- {
|
|
|
- FileOutputStream output = null;
|
|
|
- try {
|
|
|
- BufferedImage image = ImageIO.read(new FileInputStream(sheet));
|
|
|
- image = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_sRGB), null).filter(image, null);
|
|
|
- Graphics2D g = image.createGraphics();// 得到图形上下文
|
|
|
- g.setColor(Color.red); // 设置画笔颜色
|
|
|
- // 设置字体
|
|
|
- g.setFont(new Font("微软雅黑", Font.LAYOUT_LEFT_TO_RIGHT, 30));
|
|
|
- // 写入签名
|
|
|
- if (trackList != null && !trackList.isEmpty()) {
|
|
|
- for (int i = 0; i < trackList.size(); i++) {
|
|
|
- MarkTrack t = trackList.get(i);
|
|
|
- BigDecimal left = new BigDecimal(t.getOffsetY());
|
|
|
- BigDecimal top = new BigDecimal(t.getOffsetX());
|
|
|
- g.drawString(t.getScore().toString(), left.intValue(), top.intValue());
|
|
|
- }
|
|
|
- }
|
|
|
- g.dispose();
|
|
|
-
|
|
|
- output = new FileOutputStream(track);
|
|
|
- ImageIO.write(image, "jpg", output);
|
|
|
- } catch (Exception e) {
|
|
|
- log.error(SystemConstant.LOG_ERROR, e);
|
|
|
- } finally {
|
|
|
- if (Objects.nonNull(output)) {
|
|
|
- output.flush();
|
|
|
- output.close();
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void sheetExport(Long examId, String coursePaperId, HttpServletResponse response) {
|
|
|
- List<MarkStudent> list = this.listByExamIdAndCoursePaperId(examId,coursePaperId);
|
|
|
- if (CollectionUtils.isNotEmpty(list)) {
|
|
|
- try {
|
|
|
- response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("原图.zip","UTF-8"));
|
|
|
- ZipWriter writer = ZipWriter.create(response.getOutputStream());
|
|
|
- ByteArrayOutputStream os = new ByteArrayOutputStream();
|
|
|
- for (MarkStudent s:list) {
|
|
|
- if(!s.getUpload()){
|
|
|
- continue;
|
|
|
- }
|
|
|
- List<FilePathVo> vos = JSON.parseArray(s.getSheetPath(), FilePathVo.class);
|
|
|
- for (int i = 0; i < vos.size(); i++) {
|
|
|
- FilePathVo vo = vos.get(i);
|
|
|
- File file = fileUploadService.downloadFile(JSON.toJSONString(vo),vo.getPath());
|
|
|
- String format = FilenameUtils.getExtension(file.getName());
|
|
|
- writer.write(file, s.getStudentCode()+"-"+(i+1)+"."+format);
|
|
|
- file.delete();
|
|
|
- }
|
|
|
- }
|
|
|
- writer.close();
|
|
|
- }catch (Exception e){
|
|
|
- e.printStackTrace();
|
|
|
- throw new ParameterException("文件下载失败", e);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
+package com.qmth.teachcloud.mark.service.impl;
|
|
|
+
|
|
|
+import java.awt.*;
|
|
|
+import java.awt.color.ColorSpace;
|
|
|
+import java.awt.image.BufferedImage;
|
|
|
+import java.awt.image.ColorConvertOp;
|
|
|
+import java.io.*;
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.net.URLEncoder;
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
+import java.util.*;
|
|
|
+import java.util.List;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import javax.imageio.ImageIO;
|
|
|
+import javax.servlet.ServletOutputStream;
|
|
|
+import javax.servlet.http.HttpServletResponse;
|
|
|
+import javax.validation.constraints.NotNull;
|
|
|
+
|
|
|
+import org.apache.commons.collections4.CollectionUtils;
|
|
|
+import org.apache.commons.io.FilenameUtils;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+import org.springframework.util.FileCopyUtils;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
|
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
+import com.itextpdf.text.Document;
|
|
|
+import com.itextpdf.text.Image;
|
|
|
+import com.itextpdf.text.PageSize;
|
|
|
+import com.itextpdf.text.Rectangle;
|
|
|
+import com.itextpdf.text.pdf.PdfWriter;
|
|
|
+import com.qmth.boot.core.concurrent.service.ConcurrentService;
|
|
|
+import com.qmth.boot.core.exception.ParameterException;
|
|
|
+import com.qmth.boot.tools.excel.ExcelWriter;
|
|
|
+import com.qmth.boot.tools.excel.enums.ExcelType;
|
|
|
+import com.qmth.boot.tools.io.ZipWriter;
|
|
|
+import com.qmth.teachcloud.common.bean.dto.DataPermissionRule;
|
|
|
+import com.qmth.teachcloud.common.bean.vo.FilePathVo;
|
|
|
+import com.qmth.teachcloud.common.contant.SystemConstant;
|
|
|
+import com.qmth.teachcloud.common.entity.BasicExam;
|
|
|
+import com.qmth.teachcloud.common.entity.MarkQuestion;
|
|
|
+import com.qmth.teachcloud.common.entity.SysUser;
|
|
|
+import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
|
|
|
+import com.qmth.teachcloud.common.enums.PageSizeEnum;
|
|
|
+import com.qmth.teachcloud.common.enums.ScanStatus;
|
|
|
+import com.qmth.teachcloud.common.enums.mark.MarkPaperStatus;
|
|
|
+import com.qmth.teachcloud.common.enums.mark.SubjectiveStatus;
|
|
|
+import com.qmth.teachcloud.common.service.BasicRoleDataPermissionService;
|
|
|
+import com.qmth.teachcloud.common.service.FileUploadService;
|
|
|
+import com.qmth.teachcloud.common.service.TeachcloudCommonService;
|
|
|
+import com.qmth.teachcloud.common.util.*;
|
|
|
+import com.qmth.teachcloud.mark.bean.UpdateTimeVo;
|
|
|
+import com.qmth.teachcloud.mark.bean.archivescore.*;
|
|
|
+import com.qmth.teachcloud.mark.bean.omredit.OmrEditDomain;
|
|
|
+import com.qmth.teachcloud.mark.bean.omredit.OmrEditPaper;
|
|
|
+import com.qmth.teachcloud.mark.bean.scananswer.*;
|
|
|
+import com.qmth.teachcloud.mark.bean.scanexaminfo.CheckTask;
|
|
|
+import com.qmth.teachcloud.mark.bean.scanexaminfo.ScanExamCheckInfoVo;
|
|
|
+import com.qmth.teachcloud.mark.bean.scanexaminfo.ScanExamInfoVo;
|
|
|
+import com.qmth.teachcloud.mark.bean.student.AbsentManualUpdateVo;
|
|
|
+import com.qmth.teachcloud.mark.bean.student.StudentQuery;
|
|
|
+import com.qmth.teachcloud.mark.bean.student.StudentVo;
|
|
|
+import com.qmth.teachcloud.mark.dto.UnexistStudentDto;
|
|
|
+import com.qmth.teachcloud.mark.dto.mark.ScoreInfo;
|
|
|
+import com.qmth.teachcloud.mark.dto.mark.ScoreItem;
|
|
|
+import com.qmth.teachcloud.mark.dto.mark.manage.Task;
|
|
|
+import com.qmth.teachcloud.mark.dto.mark.score.*;
|
|
|
+import com.qmth.teachcloud.mark.entity.*;
|
|
|
+import com.qmth.teachcloud.mark.enums.ExamStatus;
|
|
|
+import com.qmth.teachcloud.mark.enums.LockType;
|
|
|
+import com.qmth.teachcloud.mark.enums.OmrTaskStatus;
|
|
|
+import com.qmth.teachcloud.mark.lock.LockService;
|
|
|
+import com.qmth.teachcloud.mark.mapper.MarkStudentMapper;
|
|
|
+import com.qmth.teachcloud.mark.params.MarkHeaderResult;
|
|
|
+import com.qmth.teachcloud.mark.service.*;
|
|
|
+import com.qmth.teachcloud.mark.utils.BatchGetDataUtil;
|
|
|
+import com.qmth.teachcloud.mark.utils.Calculator;
|
|
|
+import com.qmth.teachcloud.mark.utils.ScoreCalculateUtil;
|
|
|
+
|
|
|
+/**
|
|
|
+ * <p>
|
|
|
+ * 考试考生库 服务实现类
|
|
|
+ * </p>
|
|
|
+ *
|
|
|
+ * @author xf
|
|
|
+ * @since 2023-09-22
|
|
|
+ */
|
|
|
+@Service
|
|
|
+public class MarkStudentServiceImpl extends ServiceImpl<MarkStudentMapper, MarkStudent> implements MarkStudentService {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private MarkPaperService markPaperService;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private MarkPaperPackageService markPaperPackageService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ScanPackageService scanPackageService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ScanPaperService scanPaperService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ScanPaperPageService scanPaperPageService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ScanOmrTaskService scanOmrTaskService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ScanAnswerCardService answerCardService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ScanStudentPaperService studentPaperService;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private MarkQuestionService markQuestionService;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private TeachcloudCommonService teachcloudCommonService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ConcurrentService concurrentService;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private MarkService markService;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private LockService lockService;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private TaskService taskService;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private BasicRoleDataPermissionService basicRoleDataPermissionService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private MarkSubjectiveScoreService markSubjectiveScoreService;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private MarkSyncService markSyncService;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private FileUploadService fileUploadService;
|
|
|
+ @Resource
|
|
|
+ private MarkTrackService markTrackService;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<String> listClassByExamIdAndCourseCode(Long examId, String paperNumber) {
|
|
|
+ QueryWrapper<MarkStudent> queryWrapper = new QueryWrapper<>();
|
|
|
+ queryWrapper.lambda().eq(MarkStudent::getExamId, examId).eq(MarkStudent::getPaperNumber, paperNumber);
|
|
|
+ List<MarkStudent> markStudentList = this.list(queryWrapper);
|
|
|
+
|
|
|
+ List<String> classNameList = new ArrayList<>();
|
|
|
+ if (CollectionUtils.isNotEmpty(markStudentList)) {
|
|
|
+ classNameList = markStudentList.stream().filter(m -> StringUtils.isNotBlank(m.getClassName()))
|
|
|
+ .map(MarkStudent::getClassName).distinct().collect(Collectors.toList());
|
|
|
+ }
|
|
|
+ return classNameList;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void updateSubjectiveStatusAndScore(Long studentId, SubjectiveStatus status, Double score,
|
|
|
+ String scoreList) {
|
|
|
+ UpdateWrapper<MarkStudent> updateWrapper = new UpdateWrapper<>();
|
|
|
+ updateWrapper.lambda().set(MarkStudent::getSubjectiveStatus, status).set(MarkStudent::getSubjectiveScore, score)
|
|
|
+ .set(MarkStudent::getSubjectiveScoreList, scoreList).eq(MarkStudent::getId, studentId);
|
|
|
+ this.update(updateWrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void updateSubjectiveStatusAndScore(Long examId, String paperNumber, SubjectiveStatus status, Double score,
|
|
|
+ String scoreList) {
|
|
|
+ UpdateWrapper<MarkStudent> updateWrapper = new UpdateWrapper<>();
|
|
|
+ updateWrapper.lambda().set(MarkStudent::getSubjectiveStatus, status).set(MarkStudent::getSubjectiveScore, score)
|
|
|
+ .set(MarkStudent::getSubjectiveScoreList, scoreList)
|
|
|
+ .set(MarkStudent::getCheckUserId, null)
|
|
|
+ .set(MarkStudent::getCheckTime, null).eq(MarkStudent::getExamId, examId)
|
|
|
+ .eq(MarkStudent::getPaperNumber, paperNumber);
|
|
|
+ this.update(updateWrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ScanExamInfoVo getScanExamInfo(BasicExam exam, String courseCode, String coursePaperId) {
|
|
|
+ SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
|
|
|
+ DataPermissionRule dpr = basicRoleDataPermissionService.findDataPermission(sysUser.getSchoolId(),
|
|
|
+ sysUser.getId(), ServletUtil.getRequest().getServletPath());
|
|
|
+ ScanExamInfoVo vo = new ScanExamInfoVo();
|
|
|
+ vo.setId(exam.getId());
|
|
|
+ vo.setName(exam.getName());
|
|
|
+ vo.getAnswerScan().setCourseCount(
|
|
|
+ markPaperService.getCourseCount(exam.getId(), courseCode, coursePaperId, MarkPaperStatus.FORMAL, dpr));
|
|
|
+ vo.getAnswerScan().setPaperNumberCount(markPaperService.getPaperNumberCount(exam.getId(), courseCode,
|
|
|
+ coursePaperId, MarkPaperStatus.FORMAL, dpr));
|
|
|
+ vo.getAnswerScan()
|
|
|
+ .setTotalCount(getCount(exam.getId(), null, courseCode, coursePaperId, MarkPaperStatus.FORMAL, dpr));
|
|
|
+ vo.getAnswerScan().setScannedCount(
|
|
|
+ getCount(exam.getId(), ScanStatus.SCANNED, courseCode, coursePaperId, MarkPaperStatus.FORMAL, dpr));
|
|
|
+ vo.getPackageScan().setTotalCount(markPaperPackageService.getPackageCountByExamId(exam.getId(), courseCode,
|
|
|
+ coursePaperId, MarkPaperStatus.FORMAL, dpr));
|
|
|
+ vo.getPackageScan().setScannedCount(
|
|
|
+ scanPackageService.getCount(exam.getId(), courseCode, coursePaperId, MarkPaperStatus.FORMAL, dpr));
|
|
|
+ return vo;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public IPage<StudentScoreDetailDto> pageStudentScore(Long examId, String paperNumber, String college, String majorName,
|
|
|
+ String className, String teacher, Integer filter, String status, Boolean breach, Double startScore,
|
|
|
+ Double endScore, Double subScore, Integer objectiveScoreRateLt, String studentName, String studentCode,
|
|
|
+ String orderType, String orderField, Integer pageNumber, Integer pageSize) {
|
|
|
+ if (startScore != null && endScore == null) {
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("请输入结束分数值");
|
|
|
+ }
|
|
|
+ Page<StudentScoreDetailDto> page = new Page<>(pageNumber, pageSize);
|
|
|
+ MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
+ Double objectiveScoreLt = objectiveScoreRateLt == null ? null : Calculator.round(Calculator.divide(Calculator.multiply(markPaper.getObjectiveScore(), Double.parseDouble(String.valueOf(objectiveScoreRateLt))), 100), 2);
|
|
|
+ IPage<StudentScoreDetailDto> studentScoreDetailDtoIPage = this.baseMapper.pageStudentScore(page, examId,
|
|
|
+ paperNumber, college, majorName, className, teacher, filter, status, breach, startScore, endScore, subScore,
|
|
|
+ objectiveScoreLt, studentName, studentCode, orderType, orderField);
|
|
|
+ for (StudentScoreDetailDto scoreDetailDto : studentScoreDetailDtoIPage.getRecords()) {
|
|
|
+ // 原图
|
|
|
+ scoreDetailDto.setSheetUrls(buildSheetUrls(scoreDetailDto.getStudentId()));
|
|
|
+ scoreDetailDto.setSheetPath(null);
|
|
|
+ // 状态
|
|
|
+ if (ScanStatus.UNEXIST.equals(scoreDetailDto.getScanStatus())) {
|
|
|
+ scoreDetailDto.setStatusDisplay("未扫描");
|
|
|
+ } else if (ScanStatus.MANUAL_ABSENT.equals(scoreDetailDto.getScanStatus()) || scoreDetailDto.getAbsent() || scoreDetailDto.getOmrAbsent()) {
|
|
|
+ scoreDetailDto.setStatusDisplay("缺考");
|
|
|
+ } else if (!scoreDetailDto.getAbsent() && !scoreDetailDto.getOmrAbsent() && scoreDetailDto.getUpload() && ScanStatus.SCANNED.equals(scoreDetailDto.getScanStatus())) {
|
|
|
+ scoreDetailDto.setStatusDisplay("正常");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 主观题检查标记
|
|
|
+ scoreDetailDto.setSubjectiveCheckFlag(!scoreDetailDto.getAbsent() && !scoreDetailDto.getOmrAbsent() && scoreDetailDto.getUpload() && ScanStatus.SCANNED.equals(scoreDetailDto.getScanStatus()) && SubjectiveStatus.MARKED.equals(scoreDetailDto.getSubjectiveStatus()) && StringUtils.isNotBlank(scoreDetailDto.getSubjectiveScore()) && StringUtils.isNotBlank(scoreDetailDto.getSubjectiveScoreList()));
|
|
|
+ // 客观题检查标记
|
|
|
+ scoreDetailDto.setObjectiveCheckFlag(!scoreDetailDto.getAbsent() && !scoreDetailDto.getOmrAbsent() && scoreDetailDto.getUpload() && ScanStatus.SCANNED.equals(scoreDetailDto.getScanStatus()) && StringUtils.isNotBlank(scoreDetailDto.getObjectiveScore()) && StringUtils.isNotBlank(scoreDetailDto.getObjectiveScoreList()));
|
|
|
+
|
|
|
+ // 格式化分数
|
|
|
+ scoreDetailDto.setObjectiveScore(Calculator.round(scoreDetailDto.getObjectiveScore(), 1));
|
|
|
+ scoreDetailDto.setSubjectiveScore(Calculator.round(scoreDetailDto.getSubjectiveScore(), 1));
|
|
|
+ scoreDetailDto.setTotalScore(Calculator.round(scoreDetailDto.getTotalScore(), 1));
|
|
|
+ }
|
|
|
+ return studentScoreDetailDtoIPage;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<SheetUrlDto> buildSheetUrls(Long studentId) {
|
|
|
+ // 原图
|
|
|
+ List<SheetUrlDto> sheetUrls = new ArrayList<>();
|
|
|
+ List<StudentPaperDetailDto> studentPaperDetailDtoList = scanPaperService.listStudentPaperDetail(studentId);
|
|
|
+ for (int i = 0; i < studentPaperDetailDtoList.size(); i++) {
|
|
|
+ StudentPaperDetailDto studentPaperDetailDto = studentPaperDetailDtoList.get(i);
|
|
|
+ sheetUrls.add(new SheetUrlDto(
|
|
|
+ 2 * (studentPaperDetailDto.getPaperIndex() - 1) + studentPaperDetailDto.getPageIndex(),
|
|
|
+ teachcloudCommonService.filePreview(studentPaperDetailDto.getSheetPath()),
|
|
|
+ studentPaperDetailDto.getRecogData()));
|
|
|
+ }
|
|
|
+ return sheetUrls;
|
|
|
+ }
|
|
|
+
|
|
|
+ private int getCount(Long examId, ScanStatus status, String courseCode, String coursePaperId,
|
|
|
+ MarkPaperStatus markPaperStatus, DataPermissionRule dpr) {
|
|
|
+ MarkStudent markStudent = new MarkStudent();
|
|
|
+ markStudent.setExamId(examId);
|
|
|
+ markStudent.setCourseCode(courseCode);
|
|
|
+ markStudent.setCoursePaperId(coursePaperId);
|
|
|
+ markStudent.setScanStatus(status);
|
|
|
+ markStudent.setMarkPaperStatus(markPaperStatus.name());
|
|
|
+ return baseMapper.selectCountByQuery(markStudent, dpr);
|
|
|
+ }
|
|
|
+
|
|
|
+ private int getOmrAbsentCount(Long examId, Boolean checked, String courseCode, String coursePaperId,
|
|
|
+ MarkPaperStatus status, DataPermissionRule dpr) {
|
|
|
+ MarkStudent markStudent = new MarkStudent();
|
|
|
+ markStudent.setExamId(examId);
|
|
|
+ markStudent.setCourseCode(courseCode);
|
|
|
+ markStudent.setCoursePaperId(coursePaperId);
|
|
|
+ markStudent.setOmrAbsent(true);
|
|
|
+ markStudent.setOmrAbsentChecked(checked);
|
|
|
+ markStudent.setMarkPaperStatus(status.name());
|
|
|
+ return baseMapper.selectCountByQuery(markStudent, dpr);
|
|
|
+ }
|
|
|
+
|
|
|
+ private int getIncompleteCount(Long examId, String courseCode, String coursePaperId, MarkPaperStatus status,
|
|
|
+ DataPermissionRule dpr) {
|
|
|
+ MarkStudent markStudent = new MarkStudent();
|
|
|
+ markStudent.setExamId(examId);
|
|
|
+ markStudent.setCourseCode(courseCode);
|
|
|
+ markStudent.setCoursePaperId(coursePaperId);
|
|
|
+ markStudent.setIncomplete(true);
|
|
|
+ markStudent.setMarkPaperStatus(status.name());
|
|
|
+ return baseMapper.selectCountByQuery(markStudent, dpr);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ScanExamCheckInfoVo checkInfo(BasicExam exam, String courseCode, String coursePaperId) {
|
|
|
+ SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
|
|
|
+ DataPermissionRule dpr = basicRoleDataPermissionService.findDataPermission(sysUser.getSchoolId(),
|
|
|
+ sysUser.getId(), ServletUtil.getRequest().getServletPath());
|
|
|
+ Long examId = exam.getId();
|
|
|
+ ScanExamCheckInfoVo vo = new ScanExamCheckInfoVo();
|
|
|
+ vo.setId(exam.getId());
|
|
|
+ vo.setName(exam.getName());
|
|
|
+ CheckTask ct = vo.getCheckTask();
|
|
|
+ ct.setUnexistCount(
|
|
|
+ getCount(examId, ScanStatus.UNEXIST, courseCode, coursePaperId, MarkPaperStatus.FORMAL, dpr));
|
|
|
+ ct.setUnexistCheckedCount(
|
|
|
+ getCount(examId, ScanStatus.MANUAL_ABSENT, courseCode, coursePaperId, MarkPaperStatus.FORMAL, dpr));
|
|
|
+ ct.setAssignedCount(getAssignedCount(examId, false, courseCode, coursePaperId, MarkPaperStatus.FORMAL, dpr));
|
|
|
+ ct.setAssignedCheckedCount(
|
|
|
+ getAssignedCount(examId, true, courseCode, coursePaperId, MarkPaperStatus.FORMAL, dpr));
|
|
|
+ ct.setAbsentCheckCount(
|
|
|
+ getOmrAbsentCount(examId, false, courseCode, coursePaperId, MarkPaperStatus.FORMAL, dpr));
|
|
|
+ ct.setAbsentCheckedCount(
|
|
|
+ getOmrAbsentCount(examId, true, courseCode, coursePaperId, MarkPaperStatus.FORMAL, dpr));
|
|
|
+ ct.setObjectiveCheckCount(scanOmrTaskService.getFinishStudentCountByExamAndUserId(examId, courseCode, coursePaperId,
|
|
|
+ OmrTaskStatus.WAITING.name(), dpr));
|
|
|
+ ct.setObjectiveCheckedCount(scanOmrTaskService.getFinishStudentCountByExamAndUserId(examId, courseCode, coursePaperId,
|
|
|
+ OmrTaskStatus.PROCESSED.name(), dpr));
|
|
|
+ ct.setIncompleteCount(getIncompleteCount(examId, courseCode, coursePaperId, MarkPaperStatus.FORMAL, dpr));
|
|
|
+ return vo;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据考生当前绑定的paper刷新考生状态,需要在外部调用处对考生上锁
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ @Transactional
|
|
|
+ public void updateStudentByPaper(@NotNull Long userId, @NotNull Long studentId, @NotNull boolean updateOmrTask) {
|
|
|
+ MarkStudent student = this.getById(studentId);
|
|
|
+ if (student == null) {
|
|
|
+ throw new ParameterException("找不到对应的考生");
|
|
|
+ }
|
|
|
+ // 重置状态
|
|
|
+ student.setIncomplete(false);
|
|
|
+ student.setAssigned(false);
|
|
|
+ student.setInvalid(false);
|
|
|
+ student.setQuestionFilled(false);
|
|
|
+ // student.setOmrAbsent(false);
|
|
|
+ int paperCount = 0;
|
|
|
+ List<ScanStudentPaper> studentPaperList = studentPaperService.findByStudentId(studentId);
|
|
|
+ List<String> objectiveAnswers = new ArrayList<>();
|
|
|
+ for (ScanStudentPaper studentPaper : studentPaperList) {
|
|
|
+ paperCount++;
|
|
|
+ // 获取paper详情更新考生状态
|
|
|
+ ScanPaper paper = scanPaperService.getById(studentPaper.getPaperId());
|
|
|
+ student.setAssigned(student.getAssigned() || paper.getAssigned());
|
|
|
+ student.setInvalid(student.getInvalid() || paper.getInvalid());
|
|
|
+ student.setQuestionFilled(student.getQuestionFilled() || paper.getQuestionFilled());
|
|
|
+ student.setCardNumber(paper.getCardNumber());
|
|
|
+ // 单独判断首张纸正面的识别结果
|
|
|
+ if (studentPaper.getPaperIndex() == 1) {
|
|
|
+ // 根据识别结果更新考生属性
|
|
|
+ ScanPaperPage page = scanPaperPageService.findPaperIdAndIndex(paper.getId(), 1);
|
|
|
+ student.setOmrAbsent(page.getAbsent() == null ? false : page.getAbsent().getResult());
|
|
|
+ student.setOmrAbsentChecked(false);
|
|
|
+ if (student.getOmrAbsent()) {
|
|
|
+ student.setObjectiveScore(null);
|
|
|
+ student.setObjectiveScoreList(null);
|
|
|
+ }
|
|
|
+ // student.setDevice(batchService.findByPaperId(paper.getId()).getDevice());
|
|
|
+ }
|
|
|
+
|
|
|
+ List<ScanPaperPage> scanPaperPages = scanPaperPageService.listByPaperId(studentPaper.getPaperId());
|
|
|
+ for (ScanPaperPage scanPaperPage : scanPaperPages) {
|
|
|
+ if (scanPaperPage.getQuestion() != null
|
|
|
+ && CollectionUtils.isNotEmpty(scanPaperPage.getQuestion().getResult())) {
|
|
|
+ for (String s : scanPaperPage.getQuestion().getResult()) {
|
|
|
+ if (s.startsWith("?")) {
|
|
|
+ s = s.replace("?", "");
|
|
|
+ }
|
|
|
+ objectiveAnswers.add(s);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ student.setAnswers(JSON.toJSONString(objectiveAnswers));
|
|
|
+ // 更新考生状态
|
|
|
+ if (paperCount > 0) {
|
|
|
+ ScanAnswerCard answerCard = answerCardService.findByExamAndNumber(student.getExamId(),
|
|
|
+ student.getCardNumber());
|
|
|
+ student.setUpload(true);
|
|
|
+ student.setIncomplete(paperCount != answerCard.getPaperCount());
|
|
|
+ student.setScanStatus(ScanStatus.SCANNED);
|
|
|
+ student.setAbsent(false);
|
|
|
+ student.setManualAbsent(false);
|
|
|
+ // 更新图片数量和图片地址
|
|
|
+ updateStudentSheetInfo(student, studentPaperList);
|
|
|
+ } else {
|
|
|
+ student.setScanStatus(ScanStatus.UNEXIST);
|
|
|
+ }
|
|
|
+ // student.setUpdaterId(userId);
|
|
|
+ // student.setUpdateTime(System.currentTimeMillis());
|
|
|
+ this.saveOrUpdate(student);
|
|
|
+ // 客观题统分
|
|
|
+ this.calculateObjectiveScore(student);
|
|
|
+
|
|
|
+ // 更新课程表中上传人数
|
|
|
+ markPaperService.updateUploadCount(student.getExamId(), student.getPaperNumber(),
|
|
|
+ this.countUploadedByExamIdAndPaperNumber(student.getExamId(), student.getPaperNumber()));
|
|
|
+ markPaperService.updateAbsentCount(student.getExamId(), student.getPaperNumber(),
|
|
|
+ this.countAbsentByExamIdAndPaperNumber(student.getExamId(), student.getPaperNumber()));
|
|
|
+ if (updateOmrTask) {
|
|
|
+ // 清除识别对照任务
|
|
|
+ scanOmrTaskService.deleteByStudentId(student.getExamId(), student.getId());
|
|
|
+ // 重新生成识别对照任务
|
|
|
+ scanOmrTaskService.saveTask(student.getId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private MarkStudent updateStudentSheetInfo(MarkStudent student, List<ScanStudentPaper> studentPaperList) {
|
|
|
+ List<FilePathVo> filePathVoList = new ArrayList<>();
|
|
|
+ for (ScanStudentPaper scanStudentPaper : studentPaperList) {
|
|
|
+ List<ScanPaperPage> scanPaperPages = scanPaperPageService.listByPaperId(scanStudentPaper.getPaperId());
|
|
|
+ for (ScanPaperPage scanPaperPage : scanPaperPages) {
|
|
|
+ String sheetPath = scanPaperPage.getSheetPath();
|
|
|
+ if (StringUtils.isNotBlank(sheetPath)) {
|
|
|
+ filePathVoList.add(JSON.parseObject(sheetPath, FilePathVo.class));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ student.setSheetCount(filePathVoList.size());
|
|
|
+ student.setSheetPath(JSON.toJSONString(filePathVoList));
|
|
|
+ return student;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public MarkStudent findByExamIdAndCoursePaperIdAndStudentCode(Long examId, String coursePaperId,
|
|
|
+ String studentCode) {
|
|
|
+ QueryWrapper<MarkStudent> wrapper = new QueryWrapper<>();
|
|
|
+ LambdaQueryWrapper<MarkStudent> lw = wrapper.lambda();
|
|
|
+ lw.eq(MarkStudent::getExamId, examId);
|
|
|
+ lw.eq(MarkStudent::getCoursePaperId, coursePaperId);
|
|
|
+ lw.eq(MarkStudent::getStudentCode, studentCode);
|
|
|
+ return baseMapper.selectOne(wrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public StudentObjectiveDetailDto getObjectiveInspectedTask(Long studentId) {
|
|
|
+ MarkStudent markStudent = this.getById(studentId);
|
|
|
+ StudentObjectiveDetailDto studentObjectiveDetailDto = new StudentObjectiveDetailDto();
|
|
|
+ if (markStudent != null) {
|
|
|
+ studentObjectiveDetailDto.setStudentId(markStudent.getId());
|
|
|
+ studentObjectiveDetailDto.setStudentName(markStudent.getStudentName());
|
|
|
+ studentObjectiveDetailDto.setStudentCode(markStudent.getStudentCode());
|
|
|
+ studentObjectiveDetailDto.setExamPlace(markStudent.getExamPlace());
|
|
|
+ studentObjectiveDetailDto.setExamRoom(markStudent.getExamRoom());
|
|
|
+ studentObjectiveDetailDto.setExamId(markStudent.getExamId());
|
|
|
+ studentObjectiveDetailDto.setCourseCode(markStudent.getCourseCode());
|
|
|
+ studentObjectiveDetailDto.setCourseName(markStudent.getCourseName());
|
|
|
+ studentObjectiveDetailDto.setPaperNumber(markStudent.getPaperNumber());
|
|
|
+ studentObjectiveDetailDto
|
|
|
+ .setObjectiveScore(markStudent.getObjectiveScore() != null ? markStudent.getObjectiveScore() : 0);
|
|
|
+ studentObjectiveDetailDto.setSubjectiveScore(
|
|
|
+ markStudent.getSubjectiveScore() != null ? markStudent.getSubjectiveScore() : 0);
|
|
|
+ studentObjectiveDetailDto.setUpload(markStudent.getUpload());
|
|
|
+ studentObjectiveDetailDto.setAbsent(markStudent.getAbsent());
|
|
|
+ studentObjectiveDetailDto.setSheetUrls(this.buildSheetUrls(studentId));
|
|
|
+
|
|
|
+ List<MarkQuestion> questions = markQuestionService.listQuestionByExamIdAndPaperNumberAndGroupNumber(
|
|
|
+ markStudent.getExamId(), markStudent.getPaperNumber(), null, true);
|
|
|
+ List<String> answers = markStudent.getAnswerList();
|
|
|
+ int questionCount = questions.size();
|
|
|
+ int answerCount = answers.size();
|
|
|
+
|
|
|
+ List<StudentObjectiveAnswerDto> answerDtoList = new ArrayList<>();
|
|
|
+ Map<Integer, String> titles = new HashMap<>();
|
|
|
+ // 已设置客观题
|
|
|
+ int maxCount = Math.max(questionCount, answerCount);
|
|
|
+ for (int i = 0; i < maxCount; i++) {
|
|
|
+ MarkQuestion q = questionCount > i ? questions.get(i) : null;
|
|
|
+ String answer = answerCount > i ? answers.get(i) : "#";
|
|
|
+ StudentObjectiveAnswerDto studentObjectiveAnswerDto = new StudentObjectiveAnswerDto();
|
|
|
+ studentObjectiveAnswerDto.setMainNumber(q != null ? q.getMainNumber() : 0);
|
|
|
+ studentObjectiveAnswerDto.setSubNumber(q != null ? q.getSubNumber() : 0);
|
|
|
+ studentObjectiveAnswerDto.setAnswer(answer);
|
|
|
+ studentObjectiveAnswerDto.setExist(q != null && q.getTotalScore() > 0);
|
|
|
+ studentObjectiveAnswerDto.setQuestionType(q.getQuestionType());
|
|
|
+ answerDtoList.add(studentObjectiveAnswerDto);
|
|
|
+
|
|
|
+ if (q != null) {
|
|
|
+ titles.put(q.getMainNumber(), q.getMainTitle());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ studentObjectiveDetailDto.setAnswers(answerDtoList);
|
|
|
+ studentObjectiveDetailDto.setTitles(titles);
|
|
|
+ }
|
|
|
+
|
|
|
+ return studentObjectiveDetailDto;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Boolean saveObjectiveInspectedTask(Long studentId, String answers) {
|
|
|
+ Long userId = ServletUtil.getRequestUserId();
|
|
|
+ MarkStudent student = this.getById(studentId);
|
|
|
+ MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(student.getExamId(), student.getPaperNumber());
|
|
|
+ // 评卷是否结束
|
|
|
+ if (markPaper == null || MarkPaperStatus.FINISH.equals(markPaper.getStatus())) {
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("科目已结束评卷,无法打分");
|
|
|
+ }
|
|
|
+ answers = StringUtils.trimToEmpty(answers);
|
|
|
+ if (student != null) {
|
|
|
+ student.setAnswers(answers.toUpperCase());
|
|
|
+ student.setCheckUserId(userId);
|
|
|
+ student.setCheckTime(System.currentTimeMillis());
|
|
|
+ return saveUploadStudent(student);
|
|
|
+ } else {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int countUploadedByExamIdAndPaperNumber(Long examId, String paperNumber) {
|
|
|
+ QueryWrapper<MarkStudent> queryWrapper = new QueryWrapper<>();
|
|
|
+ queryWrapper.lambda().eq(MarkStudent::getExamId, examId).eq(MarkStudent::getPaperNumber, paperNumber)
|
|
|
+ .eq(MarkStudent::getUpload, true)
|
|
|
+ .eq(MarkStudent::getScanStatus, ScanStatus.SCANNED)
|
|
|
+ .eq(MarkStudent::getAbsent, false)
|
|
|
+ .eq(MarkStudent::getBreach, false)
|
|
|
+ .eq(MarkStudent::getOmrAbsent, false);
|
|
|
+ return this.count(queryWrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean updateScanInfo(MarkStudent student) {
|
|
|
+ UpdateWrapper<MarkStudent> updateWrapper = new UpdateWrapper<>();
|
|
|
+ updateWrapper.lambda().set(MarkStudent::getAnswers, student.getAnswers())
|
|
|
+ .set(MarkStudent::getBatchCode, student.getBatchCode()).set(MarkStudent::getAbsent, student.getAbsent())
|
|
|
+ .set(MarkStudent::getUploadTime, System.currentTimeMillis())
|
|
|
+ .set(MarkStudent::getCardNumber, student.getCardNumber()).eq(MarkStudent::getId, student.getId());
|
|
|
+ return this.update(updateWrapper);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<MarkStudent> listAbsentOrBreachMarkTaskStudent(Long examId, String paperNumber) {
|
|
|
+ return this.baseMapper.listAbsentOrBreachMarkTaskStudent(examId, paperNumber);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<MarkStudent> listUnMarkTaskStudent(Long examId, String paperNumber, Integer groupNumber, int pageSize) {
|
|
|
+ Page<MarkStudent> page = new Page<>(1, pageSize);
|
|
|
+ IPage<MarkStudent> markStudentIPage = this.baseMapper.listUnMarkTaskStudent(page, examId, paperNumber,
|
|
|
+ groupNumber);
|
|
|
+ return markStudentIPage.getRecords();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 客观题统分 统分场景: 1.后台-成绩检查-客观题检查 2.扫描端-考生图片上传 3.扫描端-客观题二次识别
|
|
|
+ *
|
|
|
+ * @param student
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public boolean saveUploadStudent(MarkStudent student) {
|
|
|
+ MarkStudent old = this.getById(student.getId());
|
|
|
+ if (!student.getAbsent()) {// 正考
|
|
|
+ MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(student.getExamId(),
|
|
|
+ student.getPaperNumber());
|
|
|
+ if (markPaper.getStatus().equals(MarkPaperStatus.FINISH)) {
|
|
|
+ markPaperService.updateStatus(markPaper.getExamId(), markPaper.getPaperNumber(), MarkPaperStatus.FORMAL,
|
|
|
+ MarkPaperStatus.FINISH);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ calculateObjectiveScore(student);
|
|
|
+ if (student.getAbsent()) {// 转缺考
|
|
|
+ student.setObjectiveScore(null);
|
|
|
+ student.setObjectiveScoreList(null);
|
|
|
+ }
|
|
|
+ if (!old.getAbsent() && student.getAbsent()) {// 正考转缺考
|
|
|
+ student.setSubjectiveScore(null);
|
|
|
+ student.setSubjectiveScoreList(null);
|
|
|
+ student.setSubjectiveStatus(SubjectiveStatus.UNMARK);
|
|
|
+ this.updateById(student);
|
|
|
+ }
|
|
|
+ boolean success = this.updateScanInfo(student);
|
|
|
+ if (success) {
|
|
|
+ markPaperService.updateUploadCount(student.getExamId(), student.getPaperNumber(),
|
|
|
+ this.countUploadedByExamIdAndPaperNumber(student.getExamId(), student.getPaperNumber()));
|
|
|
+ }
|
|
|
+ return success;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void calculateObjectiveScore(MarkStudent student) {
|
|
|
+ // 缺考状态不统分(人工指定缺考、识别缺考)
|
|
|
+ if (!ScanStatus.MANUAL_ABSENT.equals(student.getScanStatus()) && !student.getAbsent() && !student.getOmrAbsent()) {
|
|
|
+ ScoreCalculateUtil util = ScoreCalculateUtil.instance(student);
|
|
|
+ ScoreInfo info = util.calculate(markQuestionService.listQuestionByExamIdAndPaperNumberAndGroupNumber(
|
|
|
+ student.getExamId(), student.getPaperNumber(), null, true), null);
|
|
|
+ student.setObjectiveScore(info.getObjectiveScore());
|
|
|
+ student.setScoreList(info.getScoreList(), true);
|
|
|
+ this.updateObjectiveScoreAndScoreList(student);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional
|
|
|
+ public void updateStudentAndPaper(@NotNull SysUser user, @NotNull Long id,
|
|
|
+ @NotNull List<ScanStudentPaper> studentPaperList) {
|
|
|
+ if (CollectionUtils.isNotEmpty(studentPaperList)) {
|
|
|
+ for (ScanStudentPaper studentPaper : studentPaperList) {
|
|
|
+ studentPaper.setStudentId(id);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 清空原有绑定关系
|
|
|
+ if (studentPaperService.removeByStudentId(id) > 0) {
|
|
|
+ // 删除评卷任务
|
|
|
+ MarkStudent student = this.getById(id);
|
|
|
+ markService.deleteMarkTaskByStudent(student);
|
|
|
+ }
|
|
|
+ if (CollectionUtils.isNotEmpty(studentPaperList)) {
|
|
|
+ // 保存绑定关系
|
|
|
+ studentPaperService.saveOrUpdateBatch(studentPaperList);
|
|
|
+ }
|
|
|
+ // 更新考生状态
|
|
|
+ updateStudentByPaper(user.getId(), id, true);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public StudentVo findOne(StudentQuery query) {
|
|
|
+ return baseMapper.findOne(query);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int countByExamIdAndSecretNumber(Long examId, String secretNumber) {
|
|
|
+ QueryWrapper<MarkStudent> queryWrapper = new QueryWrapper<>();
|
|
|
+ queryWrapper.lambda().eq(MarkStudent::getExamId, examId).eq(MarkStudent::getSecretNumber, secretNumber);
|
|
|
+ return this.count(queryWrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<MarkStudent> listByExamIdAndCoursePaperId(Long examId, String coursePaperId) {
|
|
|
+ QueryWrapper<MarkStudent> queryWrapper = new QueryWrapper<>();
|
|
|
+ queryWrapper.lambda().eq(MarkStudent::getExamId, examId).eq(MarkStudent::getCoursePaperId, coursePaperId);
|
|
|
+ return this.list(queryWrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public IPage<AnswerQueryVo> query(AnswerQueryDomain query) {
|
|
|
+ SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
|
|
|
+ DataPermissionRule dpr = basicRoleDataPermissionService.findDataPermission(sysUser.getSchoolId(),
|
|
|
+ sysUser.getId(), ServletUtil.getRequest().getServletPath());
|
|
|
+ // 查询考生分页信息
|
|
|
+ query.setMarkPaperStatus(MarkPaperStatus.FORMAL.name());
|
|
|
+ IPage<AnswerQueryVo> iPage = baseMapper.queryPage(new Page<>(query.getPageNumber(), query.getPageSize()), query,
|
|
|
+ dpr);
|
|
|
+ if (CollectionUtils.isNotEmpty(iPage.getRecords())) {
|
|
|
+ for (AnswerQueryVo vo : iPage.getRecords()) {
|
|
|
+ if (vo.getIsAbsent() != null && vo.getIsAbsent()) {
|
|
|
+ vo.setExamStatus(ExamStatus.ABSENT);
|
|
|
+ } else {
|
|
|
+ vo.setExamStatus(ExamStatus.OK);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (CollectionUtils.isNotEmpty(iPage.getRecords()) && (query.getWithPaper() != null && query.getWithPaper())) {
|
|
|
+ Map<Long, AnswerQueryVo> map = new HashMap<>();
|
|
|
+
|
|
|
+ for (AnswerQueryVo vo : iPage.getRecords()) {
|
|
|
+ List<AnswerPaperVo> papers = new ArrayList<>();
|
|
|
+ vo.setPapers(papers);
|
|
|
+ if (vo.getCardPaperCount() != null) {
|
|
|
+ for (int i = 1; i <= vo.getCardPaperCount(); i++) {
|
|
|
+ AnswerPaperVo pv = new AnswerPaperVo();
|
|
|
+ pv.setNumber(i);
|
|
|
+ papers.add(pv);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ map.put(vo.getId(), vo);
|
|
|
+ }
|
|
|
+ // 根据考生id查找绑定paper
|
|
|
+ List<Long> studentIds = iPage.getRecords().stream().map(p -> p.getId()).collect(Collectors.toList());
|
|
|
+ List<StudentPaperVo> paperList = new BatchGetDataUtil<StudentPaperVo, Long>() {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<StudentPaperVo> getData(List<Long> paramList) {
|
|
|
+ return scanPaperService.listByStudentIds(paramList);
|
|
|
+ }
|
|
|
+ }.getDataForBatch(studentIds, 200);
|
|
|
+
|
|
|
+ if (CollectionUtils.isNotEmpty(paperList)) {
|
|
|
+ Map<Long, AnswerPaperVo> paperMap = new HashMap<>();
|
|
|
+ for (StudentPaperVo p : paperList) {
|
|
|
+ AnswerQueryVo vo = map.get(p.getStudentId());
|
|
|
+ if (vo == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ List<AnswerPaperVo> papers = vo.getPapers();
|
|
|
+ if (papers == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (papers.size() < p.getNumber()) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ AnswerPaperVo pvo = papers.get(p.getNumber() - 1);
|
|
|
+ pvo.setId(p.getPaperId());
|
|
|
+ pvo.setNumber(p.getNumber());
|
|
|
+ pvo.setAssigned(p.getAssigned());
|
|
|
+ pvo.setInvalid(p.getInvalid());
|
|
|
+ paperMap.put(p.getPaperId(), pvo);
|
|
|
+ }
|
|
|
+ // 查找page
|
|
|
+ List<Long> paperIds = paperList.stream().map(p -> p.getPaperId()).collect(Collectors.toList());
|
|
|
+ List<ScanPaperPage> paperPageList = new BatchGetDataUtil<ScanPaperPage, Long>() {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<ScanPaperPage> getData(List<Long> paramList) {
|
|
|
+ return scanPaperPageService.listByPaperList(paramList);
|
|
|
+ }
|
|
|
+ }.getDataForBatch(paperIds, 200);
|
|
|
+
|
|
|
+ if (CollectionUtils.isNotEmpty(paperPageList)) {
|
|
|
+ for (ScanPaperPage p : paperPageList) {
|
|
|
+ AnswerPaperVo pvo = paperMap.get(p.getPaperId());
|
|
|
+ if (pvo == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ List<AnswerPageVo> pages = pvo.getPages();
|
|
|
+ if (pages == null) {
|
|
|
+ pages = new ArrayList<>();
|
|
|
+ pvo.setPages(pages);
|
|
|
+ }
|
|
|
+ AnswerPageVo pageVo = new AnswerPageVo();
|
|
|
+ pageVo.setIndex(p.getPageIndex());
|
|
|
+ pageVo.setSheetUri(teachcloudCommonService.filePreview(p.getSheetPath()));
|
|
|
+ if (query.getWithOmrDetail() != null && query.getWithOmrDetail()) {
|
|
|
+ pageVo.setAbsent(p.getAbsent() != null ? p.getAbsent().getResult() : null);
|
|
|
+ pageVo.setBreach(p.getBreach() != null ? p.getBreach().getResult() : null);
|
|
|
+ pageVo.setQuestion(p.getQuestion() != null ? p.getQuestion().getResult() : null);
|
|
|
+ pageVo.setRecogData(p.getRecogData());
|
|
|
+ }
|
|
|
+ pages.add(pageVo);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return iPage;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<String> summary(AnswerQueryDomain query) {
|
|
|
+ SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
|
|
|
+ DataPermissionRule dpr = basicRoleDataPermissionService.findDataPermission(sysUser.getSchoolId(),
|
|
|
+ sysUser.getId(), ServletUtil.getRequest().getServletPath());
|
|
|
+
|
|
|
+ // 不分页查询考生准考证号
|
|
|
+ query.setMarkPaperStatus(MarkPaperStatus.FORMAL.name());
|
|
|
+ return baseMapper.querySummary(query, dpr);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Transactional
|
|
|
+ @Override
|
|
|
+ public UpdateTimeVo omrEdit(Long userId, OmrEditDomain domain) {
|
|
|
+ MarkStudent student = findByExamIdAndCoursePaperIdAndStudentCode(domain.getExamId(), domain.getCoursePaperId(),
|
|
|
+ domain.getStudentCode());
|
|
|
+ if (student == null) {
|
|
|
+ throw new ParameterException("考生信息未找到");
|
|
|
+ }
|
|
|
+ concurrentService.getReadWriteLock(LockType.STUDENT + "-" + student.getId()).writeLock().lock();
|
|
|
+ try {
|
|
|
+ for (OmrEditPaper paperEdit : domain.getPapers()) {
|
|
|
+ ScanStudentPaper sp = studentPaperService.findByStudentIdAndPaperNumber(student.getId(),
|
|
|
+ paperEdit.getNumber());
|
|
|
+ if (sp == null) {
|
|
|
+ throw new ParameterException("未找到绑定扫描结果");
|
|
|
+ }
|
|
|
+ ScanPaper paperEntity = scanPaperService.getById(sp.getPaperId());
|
|
|
+ if (paperEntity == null) {
|
|
|
+ throw new ParameterException("未找到paper信息结果");
|
|
|
+ }
|
|
|
+ paperEntity.setUpdaterId(userId);
|
|
|
+ paperEntity.setUpdateTime(System.currentTimeMillis());
|
|
|
+ List<ScanPaperPage> pages = scanPaperPageService.listByPaperId(paperEntity.getId());
|
|
|
+ for (ScanPaperPage pageEntity : pages) {
|
|
|
+ paperEdit.updatePage(pageEntity);
|
|
|
+ }
|
|
|
+ scanPaperService.savePaperAndPages(paperEntity, pages);
|
|
|
+ }
|
|
|
+ updateStudentByPaper(userId, student.getId(), true);
|
|
|
+ return UpdateTimeVo.create();
|
|
|
+ } finally {
|
|
|
+ concurrentService.getReadWriteLock(LockType.STUDENT + "-" + student.getId()).writeLock().unlock();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public long countByExamIdAndPaperNumber(Long examId, String paperNumber, String paperType) {
|
|
|
+ QueryWrapper<MarkStudent> queryWrapper = new QueryWrapper<>();
|
|
|
+ queryWrapper.lambda().eq(MarkStudent::getExamId, examId).eq(MarkStudent::getPaperNumber, paperNumber)
|
|
|
+ .eq(MarkStudent::getPaperType, paperType);
|
|
|
+ return this.count(queryWrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Transactional
|
|
|
+ @Override
|
|
|
+ public AbsentManualUpdateVo absentManualUpdate(Long examId, String coursePaperId, String studentCode,
|
|
|
+ ScanStatus status) {
|
|
|
+ MarkStudent student = findByExamIdAndCoursePaperIdAndStudentCode(examId, coursePaperId, studentCode);
|
|
|
+ if (student == null) {
|
|
|
+ throw new ParameterException("考生未找到");
|
|
|
+ }
|
|
|
+ if (ScanStatus.MANUAL_ABSENT.equals(status) && !ScanStatus.UNEXIST.equals(student.getScanStatus())) {
|
|
|
+ throw new ParameterException("考生不是未扫描状态");
|
|
|
+ }
|
|
|
+ LambdaUpdateWrapper<MarkStudent> lw = new LambdaUpdateWrapper<>();
|
|
|
+ lw.set(MarkStudent::getScanStatus, status);
|
|
|
+ lw.set(MarkStudent::getManualAbsent, ScanStatus.MANUAL_ABSENT.equals(status));
|
|
|
+ lw.set(MarkStudent::getAbsent, ScanStatus.MANUAL_ABSENT.equals(status));
|
|
|
+ lw.eq(MarkStudent::getId, student.getId());
|
|
|
+ update(lw);
|
|
|
+ markPaperService.updateAbsentCount(examId, student.getPaperNumber(),
|
|
|
+ this.countAbsentByExamIdAndPaperNumber(examId, student.getPaperNumber()));
|
|
|
+ return AbsentManualUpdateVo.create(status);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Transactional
|
|
|
+ @Override
|
|
|
+ public UpdateTimeVo confirm(Long examId, String coursePaperId, String studentCode, Boolean omrAbsent) {
|
|
|
+ MarkStudent student = findByExamIdAndCoursePaperIdAndStudentCode(examId, coursePaperId, studentCode);
|
|
|
+ LambdaUpdateWrapper<MarkStudent> lw = new LambdaUpdateWrapper<>();
|
|
|
+ lw.set(MarkStudent::getOmrAbsentChecked, omrAbsent);
|
|
|
+ if (omrAbsent) {
|
|
|
+ lw.set(MarkStudent::getObjectiveScore, null);
|
|
|
+ lw.set(MarkStudent::getObjectiveScoreList, null);
|
|
|
+ } else {
|
|
|
+ lw.set(MarkStudent::getOmrAbsent, false);
|
|
|
+ }
|
|
|
+ lw.eq(MarkStudent::getId, student.getId());
|
|
|
+ update(lw);
|
|
|
+ scanOmrTaskService.deleteByStudentId(student.getExamId(), student.getId());
|
|
|
+ if (!omrAbsent) {
|
|
|
+ calculateObjectiveScore(student);
|
|
|
+ scanOmrTaskService.saveTask(student.getId());
|
|
|
+ }
|
|
|
+ markPaperService.updateAbsentCount(examId, student.getPaperNumber(),
|
|
|
+ this.countAbsentByExamIdAndPaperNumber(examId, student.getPaperNumber()));
|
|
|
+ return UpdateTimeVo.create();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<Long> findIdByExamIdAndPaperNumber(Long examId, String paperNumber) {
|
|
|
+ return this.baseMapper.findIdByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Task getSubjectiveInspectedTask(Long studentId) {
|
|
|
+ Task task = null;
|
|
|
+ if (studentId != null) {
|
|
|
+ Long userId = ServletUtil.getRequestUserId();
|
|
|
+ MarkStudent markStudent = this.getById(studentId);
|
|
|
+ markService.releaseByStudent(markStudent);
|
|
|
+ if (markService.applyStudent(markStudent, userId)) {
|
|
|
+ task = taskService.build(studentId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return task;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Transactional
|
|
|
+ @Override
|
|
|
+ public void saveSubjectiveInspectedTask(MarkHeaderResult markResult) {
|
|
|
+ MarkStudent markStudent = this.getById(markResult.getStudentId());
|
|
|
+ if (markStudent == null) {
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("考生不存在");
|
|
|
+ }
|
|
|
+ MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(markStudent.getExamId(),
|
|
|
+ markStudent.getPaperNumber());
|
|
|
+ // 评卷是否结束
|
|
|
+ if (markPaper == null || MarkPaperStatus.FINISH.equals(markPaper.getStatus())) {
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("科目已结束评卷,无法打分");
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ lockService.watch(LockType.EXAM_SUBJECT, markStudent.getExamId(), markStudent.getPaperNumber());
|
|
|
+ lockService.waitlock(LockType.STUDENT, markResult.getStudentId());
|
|
|
+ markService.submitHeaderTask(markResult.getGroups(), markStudent);
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw ExceptionResultEnum.ERROR.exception(e.getMessage());
|
|
|
+ } finally {
|
|
|
+ lockService.unlock(LockType.STUDENT, markResult.getStudentId());
|
|
|
+ lockService.unwatch(LockType.EXAM_SUBJECT, markStudent.getExamId(), markStudent.getPaperNumber());
|
|
|
+ markService.releaseByStudent(markStudent);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public IPage<ArchiveStudentVo> studentList(ArchiveStudentQuery query) {
|
|
|
+ Page<ArchiveStudentVo> page = new Page<>(query.getPageNumber(), query.getPageSize());
|
|
|
+ IPage<ArchiveStudentVo> ret = baseMapper.studentList(page, query);
|
|
|
+ for (ArchiveStudentVo record : ret.getRecords()) {
|
|
|
+ List<String> list = new ArrayList<>();
|
|
|
+ List<FilePathVo> vos = JSON.parseArray(StringUtils.trimToNull(record.getSheetPath()), FilePathVo.class);
|
|
|
+ if (CollectionUtils.isEmpty(vos)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ for (FilePathVo filePathVo : vos) {
|
|
|
+ list.add(JSON.toJSONString(filePathVo));
|
|
|
+ }
|
|
|
+ record.setSheetUrls(teachcloudCommonService.filePreview(list));
|
|
|
+ }
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void scoreExport(ArchiveStudentQuery query, HttpServletResponse response) {
|
|
|
+ //生成表头
|
|
|
+ String[] columnName = new String[]{"学生姓名", "学号", "学院", "班级", "课程代码", "课程名称", "客观分", "主观分",
|
|
|
+ "成绩"};
|
|
|
+ List<MarkQuestion> oQuestionList = markQuestionService.listQuestionByExamIdAndPaperNumberAndGroupNumber(query.getExamId(), query.getPaperNumber(), null, true);
|
|
|
+ List<MarkQuestion> sQuestionList = markQuestionService.listQuestionByExamIdAndPaperNumberAndGroupNumber(query.getExamId(), query.getPaperNumber(), null, false);
|
|
|
+ List<String> columnNameList = new ArrayList<>(Arrays.asList(columnName));
|
|
|
+ for (MarkQuestion question : oQuestionList) {
|
|
|
+ columnNameList.add(question.getMainTitle() + " " + question.getMainNumber() + "-" + question.getSubNumber() + "选项");
|
|
|
+ columnNameList.add(question.getMainTitle() + " " + question.getMainNumber() + "-" + question.getSubNumber() + "得分");
|
|
|
+ }
|
|
|
+ for (MarkQuestion question : oQuestionList) {
|
|
|
+ columnNameList.add(question.getMainTitle() + " " + question.getMainNumber() + "-" + question.getSubNumber());
|
|
|
+ }
|
|
|
+ String[] columnNames = columnNameList.toArray(new String[0]);
|
|
|
+ //生成动态内容
|
|
|
+ List<String[]> columnValues = new ArrayList<>();
|
|
|
+ List<ArchiveStudentVo> ret = baseMapper.studentList(query);
|
|
|
+ for (ArchiveStudentVo s : ret) {
|
|
|
+ List<String> valueList = new ArrayList<>();
|
|
|
+ valueList.add(s.getStudentName());
|
|
|
+ valueList.add(s.getStudentCode());
|
|
|
+ valueList.add(s.getCollege());
|
|
|
+ valueList.add(s.getClassName());
|
|
|
+ valueList.add(s.getCourseCode());
|
|
|
+ valueList.add(s.getCourseName());
|
|
|
+ valueList.add(s.getObjectiveScore() == null ? "" : s.getObjectiveScore().toString());
|
|
|
+ valueList.add(s.getSubjectiveScore() == null ? "" : s.getSubjectiveScore().toString());
|
|
|
+ valueList.add(s.getTotalScore() == null ? "" : s.getTotalScore().toString());
|
|
|
+ for (ScoreItem item : s.getScoreList(true, oQuestionList)) {
|
|
|
+ valueList.add(item.getAnswer());
|
|
|
+ valueList.add(item.getScore() == null ? "" : item.getScore().toString());
|
|
|
+ }
|
|
|
+ for (ScoreItem item : s.getScoreList(false, sQuestionList)) {
|
|
|
+ valueList.add(item.getScore().toString());
|
|
|
+ }
|
|
|
+ String[] columnValue = valueList.toArray(new String[valueList.size()]);
|
|
|
+ columnValues.add(columnValue);
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ log.debug("导出Excel开始...");
|
|
|
+ response.setHeader("Content-Disposition", "inline;filename=" + URLEncoder.encode("成绩导出", SystemConstant.CHARSET_NAME) + ".xlsx");
|
|
|
+ response.setContentType("application/vnd.ms-excel");
|
|
|
+ ServletOutputStream outputStream = response.getOutputStream();
|
|
|
+ ExcelWriter writer = ExcelWriter.create(ExcelType.XLSX);
|
|
|
+ writer.writeDataArrays("成绩导出", null, columnNames, columnValues.listIterator());
|
|
|
+ writer.output(outputStream);
|
|
|
+ outputStream.flush();
|
|
|
+ outputStream.close();
|
|
|
+ log.debug("导出Excel结束");
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ScoreReportVo scoreReport(ArchiveStudentQuery query) {
|
|
|
+ ScoreReportVo ret = new ScoreReportVo();
|
|
|
+ ret.setOverview(baseMapper.overview(query));
|
|
|
+ if (ret.getOverview() != null) {
|
|
|
+ double total = ret.getOverview().getStudentCount() - ret.getOverview().getAbsentCount();
|
|
|
+ ret.getOverview().setPassRate(
|
|
|
+ Calculator.divide2String(Calculator.multiply(ret.getOverview().getPassCount(), 100), total, 2));
|
|
|
+ ret.getOverview().setExcellentRate(Calculator
|
|
|
+ .divide2String(Calculator.multiply(ret.getOverview().getExcellentCount(), 100), total, 2));
|
|
|
+ ret.getOverview().setAvgScore(Calculator.round(ret.getOverview().getAvgScore(), 2));
|
|
|
+ }
|
|
|
+ List<ArchiveStudentVo> studentList = baseMapper.studentList(query);
|
|
|
+ fillScoreRange(ret, studentList);
|
|
|
+
|
|
|
+ ret.setCollege(baseMapper.college(query));
|
|
|
+ if (CollectionUtils.isNotEmpty(ret.getCollege())) {
|
|
|
+ for (CollegeVo vo : ret.getCollege()) {
|
|
|
+ double total = vo.getStudentCount() - vo.getAbsentCount();
|
|
|
+ vo.setPassRate(Calculator.divide2String(Calculator.multiply(vo.getPassCount(), 100), total, 2));
|
|
|
+ vo.setExcellentRate(
|
|
|
+ Calculator.divide2String(Calculator.multiply(vo.getExcellentCount(), 100), total, 2));
|
|
|
+ vo.setAvgScore(Calculator.round(vo.getAvgScore(), 2));
|
|
|
+ vo.setMinScore(Calculator.round(vo.getMinScore(), 2));
|
|
|
+ vo.setMaxScore(Calculator.round(vo.getMaxScore(), 2));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ret.setClassData(baseMapper.classData(query));
|
|
|
+ if (CollectionUtils.isNotEmpty(ret.getClassData())) {
|
|
|
+ for (ClassVo vo : ret.getClassData()) {
|
|
|
+ double total = vo.getStudentCount() - vo.getAbsentCount();
|
|
|
+ vo.setPassRate(Calculator.divide2String(Calculator.multiply(vo.getPassCount(), 100), total, 2));
|
|
|
+ vo.setExcellentRate(
|
|
|
+ Calculator.divide2String(Calculator.multiply(vo.getExcellentCount(), 100), total, 2));
|
|
|
+ vo.setAvgScore(Calculator.round(vo.getAvgScore(), 2));
|
|
|
+ vo.setMinScore(Calculator.round(vo.getMinScore(), 2));
|
|
|
+ vo.setMaxScore(Calculator.round(vo.getMaxScore(), 2));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ret.setTeacher(baseMapper.teacher(query));
|
|
|
+ if (CollectionUtils.isNotEmpty(ret.getTeacher())) {
|
|
|
+ for (TeacherVo vo : ret.getTeacher()) {
|
|
|
+ double total = vo.getStudentCount() - vo.getAbsentCount();
|
|
|
+ vo.setPassRate(Calculator.divide2String(Calculator.multiply(vo.getPassCount(), 100), total, 2));
|
|
|
+ vo.setExcellentRate(
|
|
|
+ Calculator.divide2String(Calculator.multiply(vo.getExcellentCount(), 100), total, 2));
|
|
|
+ vo.setAvgScore(Calculator.round(vo.getAvgScore(), 2));
|
|
|
+ vo.setMinScore(Calculator.round(vo.getMinScore(), 2));
|
|
|
+ vo.setMaxScore(Calculator.round(vo.getMaxScore(), 2));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ret.setTeacherClass(baseMapper.teacherClass(query));
|
|
|
+ if (CollectionUtils.isNotEmpty(ret.getTeacherClass())) {
|
|
|
+ for (TeacherClassVo vo : ret.getTeacherClass()) {
|
|
|
+ double total = vo.getStudentCount() - vo.getAbsentCount();
|
|
|
+ vo.setPassRate(Calculator.divide2String(Calculator.multiply(vo.getPassCount(), 100), total, 2));
|
|
|
+ vo.setExcellentRate(
|
|
|
+ Calculator.divide2String(Calculator.multiply(vo.getExcellentCount(), 100), total, 2));
|
|
|
+ vo.setAvgScore(Calculator.round(vo.getAvgScore(), 2));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ fillObjective(ret, studentList, query.getExamId(), query.getPaperNumber());
|
|
|
+ List<Long> studentIds = studentList.stream().map(ArchiveStudentVo::getStudentId).collect(Collectors.toList());
|
|
|
+ ret.setSubjective(markSubjectiveScoreService.getSubjectiveVo(studentIds));
|
|
|
+ if (CollectionUtils.isNotEmpty(ret.getSubjective())) {
|
|
|
+ for (QuestionVo vo : ret.getSubjective()) {
|
|
|
+ double total = vo.getStudentCount();
|
|
|
+ vo.setScoreRate(Calculator.divide(vo.getScoreCount(), total, 2));
|
|
|
+ vo.setFullScoreRate(Calculator.divide(vo.getFullScoreCount(), total, 2));
|
|
|
+ vo.setAvgScore(Calculator.round(vo.getAvgScore(), 2));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void exportUnexist(Long examId, String courseCode, String coursePaperId, HttpServletResponse response) {
|
|
|
+ try {
|
|
|
+ SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
|
|
|
+ DataPermissionRule dpr = basicRoleDataPermissionService.findDataPermission(sysUser.getSchoolId(),
|
|
|
+ sysUser.getId(), ServletUtil.getRequest().getServletPath());
|
|
|
+ List<UnexistStudentDto> unexistStudentDtoList = this.baseMapper.listUnexistStudentByExamIdAndCoursePaperId(
|
|
|
+ examId, courseCode, coursePaperId, MarkPaperStatus.FORMAL.name(), dpr);
|
|
|
+ ExcelUtil.excelExport("评卷员工作量", UnexistStudentDto.class, unexistStudentDtoList, response);
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("导出评卷员工作量失败");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int countByExamIdAndPaperNumberAndMarkStatus(Long examId, String paperNumber, SubjectiveStatus status) {
|
|
|
+ QueryWrapper<MarkStudent> queryWrapper = new QueryWrapper<>();
|
|
|
+ LambdaQueryWrapper<MarkStudent> lambdaQueryWrapper = queryWrapper.lambda();
|
|
|
+ lambdaQueryWrapper.eq(MarkStudent::getExamId, examId).eq(MarkStudent::getPaperNumber, paperNumber);
|
|
|
+ if (status != null) {
|
|
|
+ lambdaQueryWrapper.eq(MarkStudent::getSubjectiveStatus, status);
|
|
|
+ }
|
|
|
+ lambdaQueryWrapper.eq(MarkStudent::getUpload, true).eq(MarkStudent::getAbsent, false)
|
|
|
+ .eq(MarkStudent::getBreach, false).eq(MarkStudent::getOmrAbsent, false);
|
|
|
+ return this.count(queryWrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void updateCheckInfo(Long studentId, Long userId) {
|
|
|
+ UpdateWrapper<MarkStudent> updateWrapper = new UpdateWrapper<>();
|
|
|
+ updateWrapper.lambda().set(MarkStudent::getCheckUserId, userId)
|
|
|
+ .set(MarkStudent::getCheckTime, System.currentTimeMillis()).eq(MarkStudent::getId, studentId);
|
|
|
+ this.update(updateWrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int countOmrAbsentStudent(Long examId, String paperNumber, String paperType, boolean isOmrAbsentConfirm) {
|
|
|
+ QueryWrapper<MarkStudent> queryWrapper = new QueryWrapper<>();
|
|
|
+ queryWrapper.lambda().eq(MarkStudent::getExamId, examId).eq(MarkStudent::getPaperNumber, paperNumber)
|
|
|
+ .eq(MarkStudent::getPaperType, paperType).eq(MarkStudent::getOmrAbsent, true)
|
|
|
+ .eq(MarkStudent::getOmrAbsentChecked, isOmrAbsentConfirm);
|
|
|
+ return this.count(queryWrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void scoreReportDownload(JSONObject jsonObject, HttpServletResponse response) {
|
|
|
+ String rootPath = null;
|
|
|
+ File htmlFile;
|
|
|
+ File pdfFile;
|
|
|
+ try {
|
|
|
+ // 本地保存目录
|
|
|
+ File tempFile = SystemConstant.getFileTempDirVar(
|
|
|
+ System.currentTimeMillis() + File.separator + SystemConstant.getNanoId(),
|
|
|
+ SystemConstant.TEMP_PREFIX);
|
|
|
+ rootPath = tempFile.getParent();
|
|
|
+
|
|
|
+ // 删除临时目录中创建的临时文件
|
|
|
+ if (Objects.nonNull(tempFile)) {
|
|
|
+ tempFile.delete();
|
|
|
+ }
|
|
|
+ // html文件
|
|
|
+ String cardHtmlPath = rootPath + File.separator + System.currentTimeMillis() + File.separator + "temp"
|
|
|
+ + SystemConstant.HTML_PREFIX;
|
|
|
+ htmlFile = new File(cardHtmlPath);
|
|
|
+ if (!htmlFile.exists()) {
|
|
|
+ htmlFile.getParentFile().mkdirs();
|
|
|
+ htmlFile.createNewFile();
|
|
|
+ }
|
|
|
+ // 生成html文件
|
|
|
+ FileCopyUtils.copy(jsonObject.getString("htmlContent").getBytes(StandardCharsets.UTF_8), htmlFile);
|
|
|
+
|
|
|
+ // pdf文件
|
|
|
+ String cardPdfPath = rootPath + File.separator + System.currentTimeMillis() + File.separator + "temp"
|
|
|
+ + SystemConstant.PDF_PREFIX;
|
|
|
+ pdfFile = new File(cardPdfPath);
|
|
|
+ if (!pdfFile.exists()) {
|
|
|
+ pdfFile.getParentFile().mkdirs();
|
|
|
+ pdfFile.createNewFile();
|
|
|
+ }
|
|
|
+ HtmlToPdfUtil.convert(cardHtmlPath, cardPdfPath, PageSizeEnum.A4);
|
|
|
+ FileUtil.outputFile(response, pdfFile, "报告" + SystemConstant.PDF_PREFIX);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ } finally {
|
|
|
+ if (Objects.nonNull(rootPath)) {
|
|
|
+ ConvertUtil.delFolder(rootPath);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void deleteByExamIdAndPaperNumber(Long examId, String paperNumber) {
|
|
|
+ UpdateWrapper<MarkStudent> updateWrapper = new UpdateWrapper<>();
|
|
|
+ updateWrapper.lambda().eq(MarkStudent::getExamId, examId).eq(MarkStudent::getPaperNumber, paperNumber);
|
|
|
+ this.remove(updateWrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean calcObjectiveScore(Long examId, String paperNumber) {
|
|
|
+ MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
+ if (markPaper != null) {
|
|
|
+ if (lockService.trylock(LockType.SCORE_CALCULATE, markPaper.getId())) {
|
|
|
+ markSyncService.calcObjectiveScore(markPaper);
|
|
|
+ return true;
|
|
|
+ } else {
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("评卷员正在重置");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public IPage<MarkStudent> pageByExamAndPaperNumber(Long examId, String paperNumber, int pageNumber, int pageSize) {
|
|
|
+ QueryWrapper<MarkStudent> queryWrapper = new QueryWrapper<>();
|
|
|
+ queryWrapper.lambda().eq(MarkStudent::getExamId, examId).eq(MarkStudent::getPaperNumber, paperNumber)
|
|
|
+ .orderByAsc(MarkStudent::getId);
|
|
|
+ return this.page(new Page<>(pageNumber, pageSize), queryWrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void updateObjectiveScoreAndScoreList(MarkStudent markStudent) {
|
|
|
+ UpdateWrapper<MarkStudent> objectiveUpdateWrapper = new UpdateWrapper<>();
|
|
|
+ LambdaUpdateWrapper<MarkStudent> lambdaUpdateWrapper = objectiveUpdateWrapper.lambda();
|
|
|
+ lambdaUpdateWrapper.set(MarkStudent::getObjectiveScore, markStudent.getObjectiveScore())
|
|
|
+ .set(MarkStudent::getObjectiveScoreList, markStudent.getObjectiveScoreList());
|
|
|
+ if (markStudent.getCheckUserId() != null) {
|
|
|
+ lambdaUpdateWrapper.set(MarkStudent::getCheckUserId, markStudent.getCheckUserId());
|
|
|
+ }
|
|
|
+ if (markStudent.getCheckTime() != null) {
|
|
|
+ lambdaUpdateWrapper.set(MarkStudent::getCheckTime, markStudent.getCheckTime());
|
|
|
+ }
|
|
|
+ lambdaUpdateWrapper.eq(MarkStudent::getId, markStudent.getId());
|
|
|
+ this.update(objectiveUpdateWrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean updateAssignConfirm(Long studentId, boolean assignConfirm) {
|
|
|
+ UpdateWrapper<MarkStudent> updateWrapper = new UpdateWrapper<>();
|
|
|
+ updateWrapper.lambda().set(MarkStudent::getAssignConfirmed, assignConfirm).eq(MarkStudent::getId, studentId);
|
|
|
+ return this.update(updateWrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void fillObjective(ScoreReportVo ret, List<ArchiveStudentVo> studentList, Long examId, String paperNumber) {
|
|
|
+ List<MarkQuestion> qs = markQuestionService.listByExamIdAndPaperNumberAndPaperType(examId, paperNumber, null, true);
|
|
|
+ Map<String, QuestionVo> map = new HashMap<>();
|
|
|
+ List<QuestionVo> list = new ArrayList<>();
|
|
|
+ for (ArchiveStudentVo s : studentList) {
|
|
|
+ List<ScoreItem> sis = s.getScoreList(true, qs);
|
|
|
+ if (CollectionUtils.isNotEmpty(sis)) {
|
|
|
+ for (ScoreItem si : sis) {
|
|
|
+ String key = si.getMainNumber() + "-" + si.getSubNumber();
|
|
|
+ QuestionVo vo = map.get(key);
|
|
|
+ if (vo == null) {
|
|
|
+ vo = new QuestionVo();
|
|
|
+ vo.setScoreCount(0);
|
|
|
+ vo.setFullScoreCount(0);
|
|
|
+ vo.setStudentCount(0);
|
|
|
+ vo.setScoreSum(0.0);
|
|
|
+ vo.setMainNumber(si.getMainNumber());
|
|
|
+ vo.setSubNumber(si.getSubNumber());
|
|
|
+ vo.setTitle(si.getTitle());
|
|
|
+ vo.setScore(si.getTotalScore());
|
|
|
+ map.put(key, vo);
|
|
|
+ }
|
|
|
+ vo.setStudentCount(vo.getStudentCount() + 1);
|
|
|
+ vo.setScoreSum(vo.getScoreSum() + si.getScore());
|
|
|
+ if (Objects.nonNull(si.getScore()) && Objects.nonNull(si.getTotalScore()) && si.getScore().doubleValue() == si.getTotalScore().doubleValue()) {
|
|
|
+ vo.setFullScoreCount(vo.getFullScoreCount() + 1);
|
|
|
+ }
|
|
|
+ if (si.getScore() > 0) {
|
|
|
+ vo.setScoreCount(vo.getScoreCount() + 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (map.isEmpty()) {
|
|
|
+ ret.setObjective(list);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ list = new ArrayList<>(map.values());
|
|
|
+ for (QuestionVo questionVo : list) {
|
|
|
+ // 平均分
|
|
|
+ if (questionVo.getStudentCount() == null || questionVo.getStudentCount() == 0) {
|
|
|
+ questionVo.setAvgScore(0D);
|
|
|
+ } else {
|
|
|
+ questionVo.setAvgScore(Calculator.round(Calculator.divide(questionVo.getScoreSum(), questionVo.getStudentCount()), 2));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Collections.sort(list, (o1, o2) -> {
|
|
|
+ if (o1.getMainNumber() > o2.getMainNumber()) {
|
|
|
+ return 1;
|
|
|
+ } else if (o1.getSubNumber() < o2.getSubNumber()) {
|
|
|
+ return -1;
|
|
|
+ } else {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ for (QuestionVo vo : list) {
|
|
|
+ double total = vo.getStudentCount();
|
|
|
+ vo.setScoreRate(Calculator.divide(vo.getScoreCount(), total, 2));
|
|
|
+ vo.setFullScoreRate(Calculator.divide(vo.getFullScoreCount(), total, 2));
|
|
|
+ }
|
|
|
+ ret.setObjective(list);
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<MarkStudent> listByExamIdAndPaperNumberAndNotAbsent(Long examId, String paperNumber) {
|
|
|
+ QueryWrapper<MarkStudent> wrapper = new QueryWrapper<>();
|
|
|
+ LambdaQueryWrapper<MarkStudent> lw = wrapper.lambda();
|
|
|
+ lw.eq(MarkStudent::getExamId, examId);
|
|
|
+ lw.eq(MarkStudent::getPaperNumber, paperNumber);
|
|
|
+ lw.eq(MarkStudent::getUpload, true);
|
|
|
+ lw.eq(MarkStudent::getAbsent, false);
|
|
|
+ lw.eq(MarkStudent::getBreach, false);
|
|
|
+ lw.eq(MarkStudent::getOmrAbsent, false);
|
|
|
+
|
|
|
+ return this.list(wrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void fillScoreRange(ScoreReportVo ret, List<ArchiveStudentVo> list) {
|
|
|
+ List<ScoreRangeVo> scoreRange = new ArrayList<>();
|
|
|
+ ret.setScoreRange(scoreRange);
|
|
|
+ scoreRange.add(getScoreRangeVo(list, 1.0, 9.5));
|
|
|
+ scoreRange.add(getScoreRangeVo(list, 10.0, 19.5));
|
|
|
+ scoreRange.add(getScoreRangeVo(list, 20.0, 29.5));
|
|
|
+ scoreRange.add(getScoreRangeVo(list, 30.0, 39.5));
|
|
|
+ scoreRange.add(getScoreRangeVo(list, 40.0, 49.5));
|
|
|
+ scoreRange.add(getScoreRangeVo(list, 50.0, 59.5));
|
|
|
+ scoreRange.add(getScoreRangeVo(list, 60.0, 69.5));
|
|
|
+ scoreRange.add(getScoreRangeVo(list, 70.0, 79.5));
|
|
|
+ scoreRange.add(getScoreRangeVo(list, 80.0, 89.5));
|
|
|
+ scoreRange.add(getScoreRangeVo(list, 90.0, 100.0));
|
|
|
+ }
|
|
|
+
|
|
|
+ private ScoreRangeVo getScoreRangeVo(List<ArchiveStudentVo> list, Double start, Double end) {
|
|
|
+ int count = (int) list.stream().filter(s -> s.getTotalScore() >= start && s.getTotalScore() <= end).count();
|
|
|
+ Double rate = null;
|
|
|
+ if (list.size() != 0) {
|
|
|
+ rate = Calculator.multiply(count, list.size(), 2);
|
|
|
+ }
|
|
|
+ ScoreRangeVo vo = new ScoreRangeVo(count, start, end, rate);
|
|
|
+ return vo;
|
|
|
+ }
|
|
|
+
|
|
|
+ private int getCountByPaperNumber(Long examId, String paperNumber) {
|
|
|
+ QueryWrapper<MarkStudent> wrapper = new QueryWrapper<>();
|
|
|
+ LambdaQueryWrapper<MarkStudent> lw = wrapper.lambda();
|
|
|
+ lw.eq(MarkStudent::getExamId, examId);
|
|
|
+ lw.eq(MarkStudent::getPaperNumber, paperNumber);
|
|
|
+ return this.count(wrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int getAssignedCount(Long examId, Boolean checked, String courseCode, String coursePaperId,
|
|
|
+ MarkPaperStatus status, DataPermissionRule dpr) {
|
|
|
+ MarkStudent markStudent = new MarkStudent();
|
|
|
+ markStudent.setExamId(examId);
|
|
|
+ markStudent.setCourseCode(courseCode);
|
|
|
+ markStudent.setCoursePaperId(coursePaperId);
|
|
|
+ markStudent.setAssigned(true);
|
|
|
+ markStudent.setAssignConfirmed(checked);
|
|
|
+ markStudent.setMarkPaperStatus(status.name());
|
|
|
+ return baseMapper.countAssigned(markStudent, dpr);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int countAbsentByExamIdAndPaperNumber(Long examId, String paperNumber) {
|
|
|
+ QueryWrapper<MarkStudent> queryWrapper = new QueryWrapper<>();
|
|
|
+ queryWrapper.lambda().eq(MarkStudent::getExamId, examId).eq(MarkStudent::getPaperNumber, paperNumber)
|
|
|
+ .and(o -> o.eq(MarkStudent::getAbsent, true).or().eq(MarkStudent::getOmrAbsent, true));
|
|
|
+ return this.count(queryWrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<MarkStudent> listScanCollegeByExamIdAndCourseCodeAndCoursePaperId(Long examId, String courseCode,
|
|
|
+ String coursePaperId, String status, DataPermissionRule dpr) {
|
|
|
+ return this.baseMapper.listScanCollegeByExamIdAndCourseCodeAndCoursePaperId(examId, courseCode, coursePaperId,
|
|
|
+ status, dpr);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int countUnexistByExamIdAndPaperNumberAndPaperType(Long examId, String paperNumber, String paperType) {
|
|
|
+ MarkStudent markStudent = new MarkStudent();
|
|
|
+ markStudent.setExamId(examId);
|
|
|
+ markStudent.setPaperNumber(paperNumber);
|
|
|
+ markStudent.setScanStatus(ScanStatus.UNEXIST);
|
|
|
+ markStudent.setPaperType(paperType);
|
|
|
+ markStudent.setMarkPaperStatus(MarkPaperStatus.FORMAL.name());
|
|
|
+ return baseMapper.selectCountByQuery(markStudent, null);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void updateStudentAnswer(Long studentId) {
|
|
|
+ List<String> objectiveAnswers = new ArrayList<>();
|
|
|
+ MarkStudent student = this.getById(studentId);
|
|
|
+ List<ScanStudentPaper> studentPaperList = studentPaperService.findByStudentId(studentId);
|
|
|
+ for (ScanStudentPaper studentPaper : studentPaperList) {
|
|
|
+ List<ScanPaperPage> scanPaperPages = scanPaperPageService.listByPaperId(studentPaper.getPaperId());
|
|
|
+ for (ScanPaperPage scanPaperPage : scanPaperPages) {
|
|
|
+ if (scanPaperPage.getQuestion() != null
|
|
|
+ && CollectionUtils.isNotEmpty(scanPaperPage.getQuestion().getResult())) {
|
|
|
+ for (String s : scanPaperPage.getQuestion().getResult()) {
|
|
|
+ if (s.startsWith("?")) {
|
|
|
+ s = s.replace("?", "");
|
|
|
+ }
|
|
|
+ objectiveAnswers.add(s);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ student.setAnswers(JSON.toJSONString(objectiveAnswers));
|
|
|
+ this.saveOrUpdate(student);
|
|
|
+ // 客观题统分
|
|
|
+ this.calculateObjectiveScore(student);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<MarkStudentScoreVo> listMarkStudentScoreList(Long examId, String paperNumber) {
|
|
|
+ MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
+ if (!MarkPaperStatus.FINISH.equals(markPaper.getStatus())) {
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("科目未结束评卷,不能同步考生成绩");
|
|
|
+ }
|
|
|
+
|
|
|
+ List<MarkStudent> markStudentList = this.listByExamIdAndPaperNumberAndNotAbsent(examId, paperNumber);
|
|
|
+ List<MarkQuestion> objectiveQuestionList = markQuestionService.listByExamIdAndPaperNumberAndPaperType(examId, paperNumber, null, true);
|
|
|
+ List<MarkQuestion> subjectiveQuestionList = markQuestionService.listByExamIdAndPaperNumberAndPaperType(examId, paperNumber, null, false);
|
|
|
+ List<MarkStudentScoreVo> markStudentScoreVoList = new ArrayList<>();
|
|
|
+ for (MarkStudent markStudent : markStudentList) {
|
|
|
+ MarkStudentScoreVo markStudentScoreVo = new MarkStudentScoreVo();
|
|
|
+ markStudentScoreVo.setExamId(markStudent.getExamId());
|
|
|
+ markStudentScoreVo.setCourseCode(markStudent.getCourseCode());
|
|
|
+ markStudentScoreVo.setCourseName(markStudent.getCourseName());
|
|
|
+ markStudentScoreVo.setPaperNumber(markStudent.getPaperNumber());
|
|
|
+ markStudentScoreVo.setStudentCode(markStudent.getStudentCode());
|
|
|
+ markStudentScoreVo.setStudentName(markStudent.getStudentName());
|
|
|
+ // 客观题
|
|
|
+ markStudentScoreVo.setObjectiveScore(markStudent.getObjectiveScore());
|
|
|
+ markStudentScoreVo.setObjectiveScoreList(markStudent.getScoreList(true, objectiveQuestionList));
|
|
|
+ // 主观题
|
|
|
+ markStudentScoreVo.setSubjectiveScore(markStudent.getSubjectiveScore());
|
|
|
+ markStudentScoreVo.setSubjectiveScoreList(markStudent.getScoreList(false, subjectiveQuestionList));
|
|
|
+
|
|
|
+ // 总分
|
|
|
+ markStudentScoreVo.setTotalScore(markStudent.getTotalScore());
|
|
|
+ List<ScoreItem> totalScoreItemList = new ArrayList<>();
|
|
|
+ totalScoreItemList.addAll(markStudentScoreVo.getObjectiveScoreList());
|
|
|
+ totalScoreItemList.addAll(markStudentScoreVo.getSubjectiveScoreList());
|
|
|
+ totalScoreItemList.stream().sorted(Comparator.comparing(ScoreItem::getMainNumber).thenComparing(ScoreItem::getSubNumber));
|
|
|
+ markStudentScoreVo.setTotalScoreList(totalScoreItemList);
|
|
|
+ markStudentScoreVoList.add(markStudentScoreVo);
|
|
|
+ }
|
|
|
+ return markStudentScoreVoList;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void trackExport(Long examId, String coursePaperId, HttpServletResponse response) {
|
|
|
+ {
|
|
|
+ List<MarkStudent> list = this.listByExamIdAndCoursePaperId(examId,coursePaperId);
|
|
|
+ if (CollectionUtils.isNotEmpty(list)) {
|
|
|
+ try {
|
|
|
+ response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("轨迹图.zip","UTF-8"));
|
|
|
+ ZipWriter writer = ZipWriter.create(response.getOutputStream());
|
|
|
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
|
|
|
+ for (MarkStudent s:list) {
|
|
|
+ if(!s.getUpload()){
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ List<FilePathVo> vos = JSON.parseArray(s.getSheetPath(), FilePathVo.class);
|
|
|
+ List<MarkTrack> trackList = markTrackService.listByStudentId(s.getId());
|
|
|
+ Document document = new Document(new Rectangle(PageSize.A3.getHeight(),PageSize.A3.getWidth()));
|
|
|
+ // 本地保存目录
|
|
|
+ File tempFile = SystemConstant.getFileTempParentDirVar(SystemConstant.TEMP_PREFIX);
|
|
|
+ File file =new File(tempFile.getPath()+File.separator + s.getStudentCode()+".pdf");
|
|
|
+ PdfWriter pdfWriter = PdfWriter.getInstance(document,new FileOutputStream(file));
|
|
|
+ document.open();
|
|
|
+ for (int i = 0; i < vos.size(); i++) {
|
|
|
+ FilePathVo vo = vos.get(i);
|
|
|
+ File sheet = fileUploadService.downloadFile(JSON.toJSONString(vo),vo.getPath());
|
|
|
+ File track = new File(tempFile.getPath()+File.separator + s.getStudentCode()+"-"+(i+1)+".jpg");
|
|
|
+ int offsetIndex = i+1;
|
|
|
+ List<MarkTrack> tracks = trackList.stream().filter(t->t.getOffsetIndex().equals(offsetIndex)).collect(Collectors.toList());
|
|
|
+ this.createTrack(sheet,track,tracks);
|
|
|
+ Image image = Image.getInstance(track.getPath());
|
|
|
+ image.scaleAbsolute(PageSize.A3.getHeight()-100,PageSize.A3.getWidth()-100);
|
|
|
+ if(i!=0){
|
|
|
+ document.newPage();
|
|
|
+ }
|
|
|
+ document.add(image);
|
|
|
+ sheet.delete();
|
|
|
+ track.delete();
|
|
|
+ }
|
|
|
+ document.close();
|
|
|
+ pdfWriter.close();
|
|
|
+ writer.write(file,s.getStudentCode()+".pdf");
|
|
|
+ }
|
|
|
+ writer.close();
|
|
|
+ }catch (Exception e){
|
|
|
+ e.printStackTrace();
|
|
|
+ throw new ParameterException("文件下载失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void createTrack(File sheet, File track, List<MarkTrack> trackList)throws IOException {
|
|
|
+ {
|
|
|
+ FileOutputStream output = null;
|
|
|
+ try {
|
|
|
+ BufferedImage image = ImageIO.read(new FileInputStream(sheet));
|
|
|
+ image = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_sRGB), null).filter(image, null);
|
|
|
+ Graphics2D g = image.createGraphics();// 得到图形上下文
|
|
|
+ g.setColor(Color.red); // 设置画笔颜色
|
|
|
+ // 设置字体
|
|
|
+ g.setFont(new Font("微软雅黑", Font.LAYOUT_LEFT_TO_RIGHT, 30));
|
|
|
+ // 写入签名
|
|
|
+ if (trackList != null && !trackList.isEmpty()) {
|
|
|
+ for (int i = 0; i < trackList.size(); i++) {
|
|
|
+ MarkTrack t = trackList.get(i);
|
|
|
+ BigDecimal left = new BigDecimal(t.getOffsetY());
|
|
|
+ BigDecimal top = new BigDecimal(t.getOffsetX());
|
|
|
+ g.drawString(t.getScore().toString(), left.intValue(), top.intValue());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ g.dispose();
|
|
|
+
|
|
|
+ output = new FileOutputStream(track);
|
|
|
+ ImageIO.write(image, "jpg", output);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error(SystemConstant.LOG_ERROR, e);
|
|
|
+ } finally {
|
|
|
+ if (Objects.nonNull(output)) {
|
|
|
+ output.flush();
|
|
|
+ output.close();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void sheetExport(Long examId, String coursePaperId, HttpServletResponse response) {
|
|
|
+ List<MarkStudent> list = this.listByExamIdAndCoursePaperId(examId,coursePaperId);
|
|
|
+ if (CollectionUtils.isNotEmpty(list)) {
|
|
|
+ try {
|
|
|
+ response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("原图.zip","UTF-8"));
|
|
|
+ ZipWriter writer = ZipWriter.create(response.getOutputStream());
|
|
|
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
|
|
|
+ for (MarkStudent s:list) {
|
|
|
+ if(!s.getUpload()){
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ List<FilePathVo> vos = JSON.parseArray(s.getSheetPath(), FilePathVo.class);
|
|
|
+ for (int i = 0; i < vos.size(); i++) {
|
|
|
+ FilePathVo vo = vos.get(i);
|
|
|
+ File file = fileUploadService.downloadFile(JSON.toJSONString(vo),vo.getPath());
|
|
|
+ String format = FilenameUtils.getExtension(file.getName());
|
|
|
+ writer.write(file, s.getStudentCode()+"-"+(i+1)+"."+format);
|
|
|
+ file.delete();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ writer.close();
|
|
|
+ }catch (Exception e){
|
|
|
+ e.printStackTrace();
|
|
|
+ throw new ParameterException("文件下载失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|