|
@@ -16,7 +16,10 @@ import com.qmth.teachcloud.mark.utils.BigDecimalUtils;
|
|
import com.qmth.teachcloud.mark.utils.TaskLock;
|
|
import com.qmth.teachcloud.mark.utils.TaskLock;
|
|
import com.qmth.teachcloud.mark.utils.TaskLockUtil;
|
|
import com.qmth.teachcloud.mark.utils.TaskLockUtil;
|
|
import org.apache.commons.collections4.CollectionUtils;
|
|
import org.apache.commons.collections4.CollectionUtils;
|
|
|
|
+import org.slf4j.Logger;
|
|
|
|
+import org.slf4j.LoggerFactory;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
import javax.annotation.Resource;
|
|
import java.math.BigDecimal;
|
|
import java.math.BigDecimal;
|
|
@@ -26,6 +29,8 @@ import java.util.concurrent.ConcurrentHashMap;
|
|
@Service
|
|
@Service
|
|
public class MarkServiceImpl implements MarkService {
|
|
public class MarkServiceImpl implements MarkService {
|
|
|
|
|
|
|
|
+ private final static Logger log = LoggerFactory.getLogger(MarkServiceImpl.class);
|
|
|
|
+
|
|
public static final int UN_SELECTIVE_SCORE = -1;
|
|
public static final int UN_SELECTIVE_SCORE = -1;
|
|
|
|
|
|
private Map<Long, Long> markerLastUpdateTime = new ConcurrentHashMap<>();
|
|
private Map<Long, Long> markerLastUpdateTime = new ConcurrentHashMap<>();
|
|
@@ -297,6 +302,155 @@ public class MarkServiceImpl implements MarkService {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ @Override
|
|
|
|
+ public void buildMarkTask(MarkPaper markPaper) {
|
|
|
|
+ try {
|
|
|
|
+ lockService.watch(LockType.EXAM_SUBJECT, markPaper.getExamId(), markPaper.getPaperNumber());
|
|
|
|
+ log.info("start create library for examId=" + markPaper.getExamId() + ", paperNumber=" + markPaper.getPaperNumber());
|
|
|
|
+ // 清除缺考考生和违纪考生
|
|
|
|
+ List<MarkStudent> markStudentList = markStudentService.listAbsentOrBreachMarkTaskStudent(markPaper.getExamId(), markPaper.getPaperNumber());
|
|
|
|
+ if (CollectionUtils.isNotEmpty(markStudentList)) {
|
|
|
|
+ for (MarkStudent student : markStudentList) {
|
|
|
|
+ try {
|
|
|
|
+ lockService.waitlock(LockType.STUDENT, student.getId());
|
|
|
|
+ log.info("delete library for studentId=" + student.getId());
|
|
|
|
+ this.deleteMarkTaskByStudent(student);
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error("delete student library error", e);
|
|
|
|
+ } finally {
|
|
|
|
+ lockService.unlock(LockType.STUDENT, student.getId());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // 处理正常考生
|
|
|
|
+ List<MarkGroup> groups = markGroupService.listGroupByExamIdAndPaperNumber(markPaper.getExamId(), markPaper.getPaperNumber());
|
|
|
|
+ for (MarkGroup group : groups) {
|
|
|
|
+ // 生成正评任务
|
|
|
|
+ buildFormalLibrary(group);
|
|
|
|
+ }
|
|
|
|
+ } finally {
|
|
|
|
+ lockService.unwatch(LockType.EXAM_SUBJECT, markPaper.getExamId(), markPaper.getPaperNumber());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void buildFormalLibrary(MarkGroup group) {
|
|
|
|
+ int pageSize = 100;
|
|
|
|
+ try {
|
|
|
|
+ lockService.watch(LockType.GROUP, group.getExamId(), group.getPaperNumber(), group.getNumber());
|
|
|
|
+ // 上锁后重复验证分组状态
|
|
|
|
+ MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(group.getExamId(), group.getPaperNumber());
|
|
|
|
+ if (MarkPaperStatus.FINISH.equals(markPaper.getStatus())) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ int count = 0;
|
|
|
|
+ List<MarkStudent> studentList = markStudentService.listUnMarkTaskStudent(group.getExamId(), group.getPaperNumber(), group.getNumber(), pageSize);
|
|
|
|
+ while (CollectionUtils.isNotEmpty(studentList)) {
|
|
|
|
+ List<MarkTask> taskList = new ArrayList<>();
|
|
|
|
+ int doubleCount = 0;
|
|
|
|
+ int studentCount = studentList.size();
|
|
|
|
+ for (MarkStudent student : studentList) {
|
|
|
|
+ MarkTask markTask = new MarkTask();
|
|
|
|
+ markTask.setExamId(student.getExamId());
|
|
|
|
+ markTask.setPaperNumber(student.getPaperNumber());
|
|
|
|
+ markTask.setGroupNumber(group.getNumber());
|
|
|
|
+ markTask.setStudentId(student.getId());
|
|
|
|
+ markTask.setStudentCode(student.getStudentCode());
|
|
|
|
+ markTask.setSecretNumber(student.getSecretNumber());
|
|
|
|
+ markTask.setTaskNumber(1);
|
|
|
|
+ markTask.setStatus(MarkTaskStatus.WAITING);
|
|
|
|
+ taskList.add(markTask);
|
|
|
|
+ // 开启双评时需要判断是否生成第二份评卷任务
|
|
|
|
+ if (group.getDoubleRate() != null && group.getDoubleRate() > 0) {
|
|
|
|
+ boolean needDouble = false;
|
|
|
|
+ if (group.getDoubleRate() == 1) {
|
|
|
|
+ needDouble = true;
|
|
|
|
+ } else {
|
|
|
|
+ double libraryCount = taskList.size();
|
|
|
|
+ int expectCount = (int) (studentCount * group.getDoubleRate());
|
|
|
|
+ // 随机数判断加入当前已经生成双评任务的比例加权
|
|
|
|
+ // 实际双评任务数小于理论生成数 &&(剩余未生成双评的考生数量小于剩余应生成的数量||随机比例)
|
|
|
|
+ needDouble = doubleCount < expectCount
|
|
|
|
+ && ((studentCount - libraryCount + doubleCount) <= (expectCount - doubleCount) || Math
|
|
|
|
+ .random() < group.getDoubleRate() + 0.1);
|
|
|
|
+ }
|
|
|
|
+ if (needDouble) {
|
|
|
|
+ markTask = new MarkTask();
|
|
|
|
+ markTask.setExamId(student.getExamId());
|
|
|
|
+ markTask.setPaperNumber(student.getPaperNumber());
|
|
|
|
+ markTask.setGroupNumber(group.getNumber());
|
|
|
|
+ markTask.setStudentId(student.getId());
|
|
|
|
+ markTask.setStudentCode(student.getStudentCode());
|
|
|
|
+ markTask.setSecretNumber(student.getSecretNumber());
|
|
|
|
+ markTask.setTaskNumber(2);
|
|
|
|
+ markTask.setStatus(MarkTaskStatus.WAITING);
|
|
|
|
+ taskList.add(markTask);
|
|
|
|
+ doubleCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // 有新任务创建
|
|
|
|
+ if (CollectionUtils.isNotEmpty(taskList)) {
|
|
|
|
+ count += taskList.size();
|
|
|
|
+ // 任务乱序
|
|
|
|
+ Collections.shuffle(taskList);
|
|
|
|
+ // 批量保存
|
|
|
|
+ markTaskService.saveBatch(taskList);
|
|
|
|
+ // 正评状态才需要更新任务数量
|
|
|
|
+ if (MarkPaperStatus.FORMAL.equals(markPaper.getStatus())) {
|
|
|
|
+ this.updateMarkTaskCount(group.getExamId(), group.getPaperNumber(), group.getNumber());
|
|
|
|
+ this.updateMarkedCount(group.getExamId(), group.getPaperNumber(), group.getNumber());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ studentList = markStudentService.listUnMarkTaskStudent(group.getExamId(), group.getPaperNumber(), group.getNumber(), pageSize);
|
|
|
|
+ }
|
|
|
|
+ if (count != 0) {
|
|
|
|
+ log.info("finish create " + count + " markTask for examId=" + group.getExamId() + ", paperNumber=" + group.getPaperNumber() + ", groupNumber=" + group.getNumber());
|
|
|
|
+ }
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error(
|
|
|
|
+ "build formal markTask error for examId=" + group.getExamId() + ", paperNumber=" + group.getPaperNumber() + ", groupNumber=" + group.getNumber(), e);
|
|
|
|
+ } finally {
|
|
|
|
+ lockService.unwatch(LockType.GROUP, group.getExamId(), group.getPaperNumber(), group.getNumber());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Transactional
|
|
|
|
+ @Override
|
|
|
|
+ public void deleteMarkTaskByStudent(MarkStudent student) {
|
|
|
|
+ // 正评相关数据
|
|
|
|
+ markTrackService.deleteByStudentId(student.getId());
|
|
|
|
+// specialTagDao.deleteByStudentId(student.getId());
|
|
|
|
+// headerTagDao.deleteByStudentId(student.getId());
|
|
|
|
+ markHeaderTrackService.deleteByStudentId(student.getId());
|
|
|
|
+ markArbitrateHistoryService.deleteByStudentId(student.getId());
|
|
|
|
+ markProblemHistoryService.deleteByStudentId(student.getId());
|
|
|
|
+ markTaskService.deleteByStudentId(student.getId());
|
|
|
|
+ // 主观状态与得分明细
|
|
|
|
+ markGroupStudentService.deleteByStudentId(student.getId());
|
|
|
|
+ markSubjectiveScoreService.deleteByStudentId(student.getId());
|
|
|
|
+// selectiveStudentDao.deleteByStudentId(student.getId());
|
|
|
|
+ updateGroupAllCount(student.getExamId(), student.getPaperNumber());
|
|
|
|
+ // 复核记录
|
|
|
|
+// inspectedService.clearByStudent(student.getId());
|
|
|
|
+ // 打回记录
|
|
|
|
+// rejectHistoryDao.deleteByStudentId(student.getId());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Transactional
|
|
|
|
+ @Override
|
|
|
|
+ public void updateGroupAllCount(Long examId, String paperNumber) {
|
|
|
|
+ List<MarkGroup> groups = markGroupService.listGroupByExamIdAndPaperNumber(examId, paperNumber);
|
|
|
|
+ for (MarkGroup group : groups) {
|
|
|
|
+ updateMarkedCount(group.getExamId(), group.getPaperNumber(), group.getNumber());
|
|
|
|
+ updateMarkTaskCount(group.getExamId(), group.getPaperNumber(), group.getNumber());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void updateMarkTaskCount(Long examId, String paperNumber, Integer groupNumber) {
|
|
|
|
+ int count = markTaskService.countByExamIdAndPaperNumberAndGroupNumberAndUserId(examId, paperNumber, groupNumber, null);
|
|
|
|
+ markGroupService.updateTaskCount(examId, paperNumber, groupNumber, count);
|
|
|
|
+ }
|
|
|
|
+
|
|
private boolean calculateGroup(MarkGroup group, Long studentId) {
|
|
private boolean calculateGroup(MarkGroup group, Long studentId) {
|
|
double score = 0;
|
|
double score = 0;
|
|
List<ScoreItem> detail = new ArrayList<>();
|
|
List<ScoreItem> detail = new ArrayList<>();
|