haogh 8 月之前
父节点
当前提交
02c303c1bd

+ 3 - 0
src/main/java/com/qmth/exam/reserve/service/StudentApplyService.java

@@ -10,6 +10,7 @@ import com.qmth.boot.core.collection.PageResult;
 import com.qmth.exam.reserve.bean.login.LoginUser;
 import com.qmth.exam.reserve.bean.login.LoginUser;
 import com.qmth.exam.reserve.bean.stdapply.*;
 import com.qmth.exam.reserve.bean.stdapply.*;
 import com.qmth.exam.reserve.entity.StudentApplyEntity;
 import com.qmth.exam.reserve.entity.StudentApplyEntity;
+import com.qmth.exam.reserve.entity.StudentEntity;
 
 
 public interface StudentApplyService extends IService<StudentApplyEntity> {
 public interface StudentApplyService extends IService<StudentApplyEntity> {
 
 
@@ -38,4 +39,6 @@ public interface StudentApplyService extends IService<StudentApplyEntity> {
     void exportNoApplyStudent(Long teachingId, Long id);
     void exportNoApplyStudent(Long teachingId, Long id);
 
 
     void exportStudentApplyDetail(Long teachingId, Long operateId);
     void exportStudentApplyDetail(Long teachingId, Long operateId);
+
+    void saveOrUpdateStudentApply(StudentApplyEntity studentApplyEntity);
 }
 }

+ 88 - 157
src/main/java/com/qmth/exam/reserve/service/impl/StudentApplyServiceImpl.java

@@ -177,7 +177,18 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
         Date applyDate = DateUtils.truncate(new Date(timePeriod.getStartTime()), Calendar.DATE);
         Date applyDate = DateUtils.truncate(new Date(timePeriod.getStartTime()), Calendar.DATE);
         Date canCancelDay = DateUtil.addValues(applyDate, Calendar.DAY_OF_MONTH, -task.getAllowApplyCancelDays());
         Date canCancelDay = DateUtil.addValues(applyDate, Calendar.DAY_OF_MONTH, -task.getAllowApplyCancelDays());
         if (new Date().after(canCancelDay)) {
         if (new Date().after(canCancelDay)) {
-            throw new StatusException("可取消时间已过,无法在取消");
+            throw new StatusException("[cancel] 可取消时间已过,无法在取消");
+        }
+
+        StudentEntity student = studentService.getById(studentApplyEntity.getStudentId());
+        if(student == null) {
+            log.warn("[cancel] 考生不存在, studentId:{} ",  studentApplyEntity.getStudentId());
+            throw new StatusException("考生不存在");
+        }
+
+        // 教学点管理员,只能取消本教学点的考生
+        if (user.getRole().equals(Role.TEACHING) && !user.getCategoryId().equals(student.getCategoryId())) {
+            throw new StatusException("[cancel] 只能取消本教学点的考生");
         }
         }
 
 
         String studentApplyLockKey = String.format(CacheConstants.LOCK_STUDENT_APPLY, studentApplyEntity.getStudentId());
         String studentApplyLockKey = String.format(CacheConstants.LOCK_STUDENT_APPLY, studentApplyEntity.getStudentId());
@@ -187,11 +198,9 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
                 log.warn("[cancel] 获取锁失败,同一个考生不允许同时操作取消预约, lockKey:{}", studentApplyLockKey);
                 log.warn("[cancel] 获取锁失败,同一个考生不允许同时操作取消预约, lockKey:{}", studentApplyLockKey);
                 throw new StatusException(Constants.SYSTEM_BUSY);
                 throw new StatusException(Constants.SYSTEM_BUSY);
             } else {
             } else {
-                /*
-                //更新数据库
+                //更新预约取消标志
                 studentApplyEntity.setCancel(Boolean.TRUE);
                 studentApplyEntity.setCancel(Boolean.TRUE);
                 updateById(studentApplyEntity);
                 updateById(studentApplyEntity);
-                */
 
 
                 ApplyRecordCacheBean bean = new ApplyRecordCacheBean();
                 ApplyRecordCacheBean bean = new ApplyRecordCacheBean();
                 bean.setStudentId(studentApplyEntity.getStudentId());
                 bean.setStudentId(studentApplyEntity.getStudentId());
@@ -203,11 +212,11 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
                 bean.setBizId(cacheService.increaseBizId());
                 bean.setBizId(cacheService.increaseBizId());
 
 
                 // 推送至预约队列
                 // 推送至预约队列
-                boolean pushSuccess = cacheService.pushStudentApplyRecordQueue(bean);
+                /*boolean pushSuccess = cacheService.pushStudentApplyRecordQueue(bean);
                 if (!pushSuccess) {
                 if (!pushSuccess) {
                     log.error("[cancel] 预约消息推送失败,id:{}", id);
                     log.error("[cancel] 预约消息推送失败,id:{}", id);
                     throw new RuntimeException("取消失败,请稍后再试!");
                     throw new RuntimeException("取消失败,请稍后再试!");
-                }
+                }*/
                 // 保存至预约缓存
                 // 保存至预约缓存
                 cacheService.saveStudentApplyRecord(bean);
                 cacheService.saveStudentApplyRecord(bean);
                 // 某考点某时段的“剩余可约数量”(归还1个被占数量)
                 // 某考点某时段的“剩余可约数量”(归还1个被占数量)
@@ -426,31 +435,75 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
             }
             }
 
 
             //保存数据
             //保存数据
-            int successRow = 0;
             for (int i = 0; i < applyList.size(); i++) {
             for (int i = 0; i < applyList.size(); i++) {
                 StudentImportVO vo = applyList.get(i);
                 StudentImportVO vo = applyList.get(i);
                 try {
                 try {
-                    saveStudentApply(i, vo, user.getId());
+                    List<AgentAndTimeVO> agentTimeList = vo.getAgentTimeList();
+                    String studentApplyLockKey = String.format(CacheConstants.LOCK_STUDENT_APPLY, vo.getStudentId());
+                    RLock studentApplyLock = (RLock) concurrentService.getLock(studentApplyLockKey);
+                    try {
+                        if (!studentApplyLock.tryLock()) {
+                            log.warn("[importPreExam] 获取锁失败,考生在同时操作预约,lockKey:{}", studentApplyLockKey);
+                        } else {
+                            log.warn("[importPreExam] 获取锁成功,lockKey:{}", studentApplyLockKey);
+                            for (AgentAndTimeVO agentTimeVO : agentTimeList) {
+                                StudentApplyEntity entity = new StudentApplyEntity();
+                                entity.setStudentId(vo.getStudentId());
+                                entity.setExamSiteId(agentTimeVO.getAgentId());
+                                entity.setTimePeriodId(agentTimeVO.getTimePeriodId());
+                                entity.setCancel(Boolean.FALSE);
+                                entity.setOperateId(user.getId());
+                                //保存考生预约
+                                saveOrUpdateStudentApply(entity);
+
+                                // 队列bean
+                                ApplyRecordCacheBean bean = new ApplyRecordCacheBean();
+                                bean.setStudentId(vo.getStudentId());
+                                bean.setExamSiteId(agentTimeVO.getAgentId());
+                                bean.setTimePeriodId(agentTimeVO.getTimePeriodId());
+                                bean.setCancel(Boolean.FALSE);
+                                bean.setOperateId(user.getId());
+                                bean.setOperateTime(System.currentTimeMillis());
+                                bean.setBizId(cacheService.increaseBizId());
+
+                                // 某考点某时段的“剩余可约数量”(抢占1个数量)
+                                boolean takeSuccess = cacheService.decreaseApplyAvailableCount(bean.getExamSiteId(), bean.getTimePeriodId());
+                                if (!takeSuccess) {
+                                    log.warn("[importPreExam] 预约失败,当前预约时段已约满!examSiteId:{} timePeriodId:{} studentId:{}",
+                                            bean.getExamSiteId(), bean.getTimePeriodId(), bean.getStudentId());
+                                    //考点
+                                    ExamSiteCacheBean examSiteBean = examSiteCacheService.getExamSiteById(bean.getExamSiteId());
+                                    //时段
+                                    TimePeriodEntity timePeriod = timePeriodService.getById(bean.getTimePeriodId());
+                                    String message = MessageFormat.format("第{0}行,预约考点:{1},预约时段:{2}", i + 1, examSiteBean.getExamSiteName(),
+                                            DateUtil.getStartAndEndTime(timePeriod.getStartTime(), timePeriod.getEndTime()));
+                                    throw new StatusException(message);
+                                }
+
+                                // 保存至预约缓存
+                                cacheService.saveStudentApplyRecord(bean);
+                            }
+                        }
+                    } catch (Exception e) {
+                        log.error("[importPreExam] 导入预约失败,msg:{}", e.getMessage());
+                        throw new StatusException("导入预考失败,错误原因:" + e.getMessage());
+                    } finally {
+                        try {
+                            if (studentApplyLock.isLocked() && studentApplyLock.isHeldByCurrentThread()) {
+                                studentApplyLock.unlock();
+                                log.info("[importPreExam] 解锁成功!lockKey:{}", studentApplyLockKey);
+                            }
+                        } catch (Exception e) {
+                            log.warn(e.getMessage());
+                        }
+                    }
+
                 } catch (StatusException e) {
                 } catch (StatusException e) {
                     failRecords.add(newError(i + 1, "系统异常"));
                     failRecords.add(newError(i + 1, "系统异常"));
                     log.error("[importPreExam] 导入异常", e);
                     log.error("[importPreExam] 导入异常", e);
-                    successRow = i;
                 }
                 }
             }
             }
 
 
-            // 回滚
-            if (CollectionUtils.isNotEmpty(failRecords)) {
-                try {
-                    for (int i = 0; i <= successRow; i++) {
-                        StudentImportVO vo = applyList.get(i);
-                        rollBackStudentApply(vo, user.getId());
-                    }
-                } catch (StatusException e) {
-                    log.error("[importPreExam] 回滚异常", e);
-                }
-                return failRecords;
-            }
-
         } catch (StatusException e) {
         } catch (StatusException e) {
             log.error("[importPreExam] 导入预考失败,msg:{}", e.getMessage());
             log.error("[importPreExam] 导入预考失败,msg:{}", e.getMessage());
             throw new StatusException(e.getMessage());
             throw new StatusException(e.getMessage());
@@ -468,63 +521,6 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
         return failRecords;
         return failRecords;
     }
     }
 
 
-    private void rollBackStudentApply(StudentImportVO vo, Long operateId) {
-        List<AgentAndTimeVO> agentTimeList = vo.getAgentTimeList();
-        String studentApplyLockKey = String.format(CacheConstants.LOCK_STUDENT_APPLY, vo.getStudentId());
-        RLock studentApplyLock = (RLock) concurrentService.getLock(studentApplyLockKey);
-        try {
-            if (!studentApplyLock.tryLock()) {
-                log.warn("[importPreExam] 获取锁失败,考生在同时操作预约,lockKey:{}", studentApplyLockKey);
-            } else {
-                log.warn("[importPreExam] 获取锁成功,lockKey:{}", studentApplyLockKey);
-                for (AgentAndTimeVO agentTimeVO : agentTimeList) {
-                    // 队列bean
-                    ApplyRecordCacheBean bean = new ApplyRecordCacheBean();
-                    bean.setStudentId(vo.getStudentId());
-                    bean.setExamSiteId(agentTimeVO.getAgentId());
-                    bean.setTimePeriodId(agentTimeVO.getTimePeriodId());
-                    bean.setCancel(Boolean.TRUE);
-                    bean.setOperateId(operateId);
-                    bean.setOperateTime(System.currentTimeMillis());
-                    bean.setBizId(cacheService.increaseBizId());
-
-                    // 某考点某时段 归还1个刚才被占数量
-                    cacheService.increaseApplyAvailableCount(bean.getExamSiteId(), bean.getTimePeriodId());
-
-                    // 保存至预约缓存
-                    cacheService.saveStudentApplyRecord(bean);
-
-                    // 数据写入到数据库
-                    StudentApplyEntity entity = new StudentApplyEntity();
-                    entity.setStudentId(vo.getStudentId());
-                    entity.setExamSiteId(agentTimeVO.getAgentId());
-                    entity.setTimePeriodId(agentTimeVO.getTimePeriodId());
-                    entity.setCancel(Boolean.TRUE);
-                    entity.setOperateId(operateId);
-                    // 取消预约
-                    StudentApplyEntity existStudentApply = findStudentApply(entity);
-                    if (existStudentApply != null) {
-                        existStudentApply.setCancel(Boolean.TRUE);
-                        baseMapper.updateById(existStudentApply);
-                    }
-
-                }
-            }
-        } catch (Exception e) {
-            log.error("[importPreExam] 导入预约失败,msg:{}", e.getMessage());
-            throw new StatusException("导入预考失败,错误原因:" + e.getMessage());
-        } finally {
-            try {
-                if (studentApplyLock.isLocked() && studentApplyLock.isHeldByCurrentThread()) {
-                    studentApplyLock.unlock();
-                    log.info("[importPreExam] 解锁成功!lockKey:{}", studentApplyLockKey);
-                }
-            } catch (Exception e) {
-                log.warn(e.getMessage());
-            }
-        }
-
-    }
 
 
 
 
 
 
@@ -564,84 +560,6 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
         return map;
         return map;
     }
     }
 
 
-    private void saveStudentApply(int row, StudentImportVO vo, Long userId) {
-        List<AgentAndTimeVO> agentTimeList = vo.getAgentTimeList();
-        String studentApplyLockKey = String.format(CacheConstants.LOCK_STUDENT_APPLY, vo.getStudentId());
-        RLock studentApplyLock = (RLock) concurrentService.getLock(studentApplyLockKey);
-        try {
-            if (!studentApplyLock.tryLock()) {
-                log.warn("[importPreExam] 获取锁失败,考生在同时操作预约,lockKey:{}", studentApplyLockKey);
-            } else {
-                log.warn("[importPreExam] 获取锁成功,lockKey:{}", studentApplyLockKey);
-                for (AgentAndTimeVO agentTimeVO : agentTimeList) {
-                    // 队列bean
-                    ApplyRecordCacheBean bean = new ApplyRecordCacheBean();
-                    bean.setStudentId(vo.getStudentId());
-                    bean.setExamSiteId(agentTimeVO.getAgentId());
-                    bean.setTimePeriodId(agentTimeVO.getTimePeriodId());
-                    bean.setCancel(Boolean.FALSE);
-                    bean.setOperateId(userId);
-                    bean.setOperateTime(System.currentTimeMillis());
-                    bean.setBizId(cacheService.increaseBizId());
-
-                    // 某考点某时段的“剩余可约数量”(抢占1个数量)
-                    boolean takeSuccess = cacheService.decreaseApplyAvailableCount(bean.getExamSiteId(), bean.getTimePeriodId());
-                    if (!takeSuccess) {
-                        log.warn("[importPreExam] 预约失败,当前预约时段已约满!examSiteId:{} timePeriodId:{} studentId:{}",
-                                bean.getExamSiteId(), bean.getTimePeriodId(), bean.getStudentId());
-                        //考点
-                        ExamSiteCacheBean examSiteBean = examSiteCacheService.getExamSiteById(bean.getExamSiteId());
-                        //时段
-                        TimePeriodEntity timePeriod = timePeriodService.getById(bean.getTimePeriodId());
-                        String message = MessageFormat.format("第{0}行,预约考点:{1},预约时段:{2}", row + 1, examSiteBean.getExamSiteName(),
-                                DateUtil.getStartAndEndTime(timePeriod.getStartTime(), timePeriod.getEndTime()));
-                        throw new StatusException(message);
-                    }
-                  /*
-                   // 推送至预约队列
-                    boolean pushSuccess = cacheService.pushStudentApplyRecordQueue(bean);
-                    if (!pushSuccess) {
-                        // 推送失败时,归还1个被占数量
-                        cacheService.increaseApplyAvailableCount(bean.getExamSiteId(), bean.getTimePeriodId());
-                        throw new RuntimeException("预约消息推送失败,请稍后再试!");
-                    }*/
-
-                    // 保存至预约缓存
-                    cacheService.saveStudentApplyRecord(bean);
-
-                    // 数据写入到数据库
-                    StudentApplyEntity entity = new StudentApplyEntity();
-                    entity.setStudentId(vo.getStudentId());
-                    entity.setExamSiteId(agentTimeVO.getAgentId());
-                    entity.setTimePeriodId(agentTimeVO.getTimePeriodId());
-                    entity.setCancel(Boolean.FALSE);
-                    entity.setOperateId(userId);
-                    // 预约是否已经存在
-                    StudentApplyEntity existStudentApply = findStudentApply(entity);
-                    if (existStudentApply != null) {
-                        existStudentApply.setCancel(Boolean.FALSE);
-                        baseMapper.updateById(existStudentApply);
-                    } else {
-                        baseMapper.insert(entity);
-                    }
-
-                }
-            }
-        } catch (Exception e) {
-            log.error("[importPreExam] 导入预约失败,msg:{}", e.getMessage());
-            throw new StatusException("导入预考失败,错误原因:" + e.getMessage());
-        } finally {
-            try {
-                if (studentApplyLock.isLocked() && studentApplyLock.isHeldByCurrentThread()) {
-                    studentApplyLock.unlock();
-                    log.info("[importPreExam] 解锁成功!lockKey:{}", studentApplyLockKey);
-                }
-            } catch (Exception e) {
-                log.warn(e.getMessage());
-            }
-        }
-    }
-
     private StudentApplyEntity findStudentApply(StudentApplyEntity studentApply) {
     private StudentApplyEntity findStudentApply(StudentApplyEntity studentApply) {
         LambdaQueryWrapper<StudentApplyEntity> lm = new LambdaQueryWrapper<>();
         LambdaQueryWrapper<StudentApplyEntity> lm = new LambdaQueryWrapper<>();
         lm.eq(StudentApplyEntity::getExamSiteId, studentApply.getExamSiteId());
         lm.eq(StudentApplyEntity::getExamSiteId, studentApply.getExamSiteId());
@@ -1216,4 +1134,17 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
         }
         }
     }
     }
 
 
+    @Transactional
+    @Override
+    public void saveOrUpdateStudentApply(StudentApplyEntity studentApply) {
+        // 预约是否已经存在
+        StudentApplyEntity existStudentApply = findStudentApply(studentApply);
+        if (existStudentApply != null) {
+            existStudentApply.setCancel(Boolean.FALSE);
+            baseMapper.updateById(existStudentApply);
+        } else {
+            baseMapper.insert(studentApply);
+        }
+    }
+
 }
 }

+ 9 - 12
src/main/java/com/qmth/exam/reserve/service/impl/StudentAutoAssignServiceImpl.java

@@ -53,6 +53,9 @@ public class StudentAutoAssignServiceImpl extends ServiceImpl<StudentApplyDao, S
     @Autowired
     @Autowired
     private CategoryCacheService categoryCacheService;
     private CategoryCacheService categoryCacheService;
 
 
+    @Autowired
+    private StudentApplyService studentApplyService;
+
 
 
     @Override
     @Override
     public String autoAssign(Long taskId, Long operateId) {
     public String autoAssign(Long taskId, Long operateId) {
@@ -224,7 +227,6 @@ public class StudentAutoAssignServiceImpl extends ServiceImpl<StudentApplyDao, S
                     }
                     }
 
 
                     if (toApplyNum > 0 && !haveApplySameTimePeriod(siteId, timeId, student.getId())) {
                     if (toApplyNum > 0 && !haveApplySameTimePeriod(siteId, timeId, student.getId())) {
-                        /*
                         //写入数据库
                         //写入数据库
                         StudentApplyEntity studentApply = new StudentApplyEntity();
                         StudentApplyEntity studentApply = new StudentApplyEntity();
                         studentApply.setStudentId(student.getId());
                         studentApply.setStudentId(student.getId());
@@ -232,14 +234,8 @@ public class StudentAutoAssignServiceImpl extends ServiceImpl<StudentApplyDao, S
                         studentApply.setCancel(Boolean.FALSE);
                         studentApply.setCancel(Boolean.FALSE);
                         studentApply.setTimePeriodId(timeId);
                         studentApply.setTimePeriodId(timeId);
                         studentApply.setOperateId(operateId);
                         studentApply.setOperateId(operateId);
-
-                        StudentApplyEntity existStudentApply = findStudentApply(studentApply);
-                        if (existStudentApply != null) {
-                            existStudentApply.setCancel(Boolean.FALSE);
-                            baseMapper.updateById(existStudentApply);
-                        } else {
-                            baseMapper.insert(studentApply);
-                        }*/
+                        // 保存预约
+                        studentApplyService.saveOrUpdateStudentApply(studentApply);
 
 
                         ApplyRecordCacheBean bean = new ApplyRecordCacheBean();
                         ApplyRecordCacheBean bean = new ApplyRecordCacheBean();
                         bean.setStudentId(student.getId());
                         bean.setStudentId(student.getId());
@@ -253,11 +249,12 @@ public class StudentAutoAssignServiceImpl extends ServiceImpl<StudentApplyDao, S
                         // 某考点某时段的“剩余可约数量”(抢占1个数量)
                         // 某考点某时段的“剩余可约数量”(抢占1个数量)
                         boolean takeSuccess = cacheService.decreaseApplyAvailableCount(bean.getExamSiteId(), bean.getTimePeriodId());
                         boolean takeSuccess = cacheService.decreaseApplyAvailableCount(bean.getExamSiteId(), bean.getTimePeriodId());
                         if (!takeSuccess) {
                         if (!takeSuccess) {
-                            log.warn("预约失败,当前预约时段已约满!examSiteId:{} timePeriodId:{} studentId:{}",
+                            log.warn("[autoAssign] 预约失败,当前预约时段已约满!examSiteId:{} timePeriodId:{} studentId:{}",
                                     bean.getExamSiteId(), bean.getTimePeriodId(), bean.getStudentId());
                                     bean.getExamSiteId(), bean.getTimePeriodId(), bean.getStudentId());
                             continue;
                             continue;
                         }
                         }
-                        // 推送至预约队列
+                      /*
+                      // 推送至预约队列
                         boolean pushSuccess = cacheService.pushStudentApplyRecordQueue(bean);
                         boolean pushSuccess = cacheService.pushStudentApplyRecordQueue(bean);
                         if (!pushSuccess) {
                         if (!pushSuccess) {
                             // 推送失败时,归还1个被占数量
                             // 推送失败时,归还1个被占数量
@@ -265,7 +262,7 @@ public class StudentAutoAssignServiceImpl extends ServiceImpl<StudentApplyDao, S
                             log.warn("预约消息推送失败!examSiteId:{} timePeriodId:{} studentId:{}", bean.getExamSiteId(),
                             log.warn("预约消息推送失败!examSiteId:{} timePeriodId:{} studentId:{}", bean.getExamSiteId(),
                                     bean.getTimePeriodId(), bean.getStudentId());
                                     bean.getTimePeriodId(), bean.getStudentId());
                             continue;
                             continue;
-                        }
+                        }*/
                         // 保存至预约缓存
                         // 保存至预约缓存
                         cacheService.saveStudentApplyRecord(bean);
                         cacheService.saveStudentApplyRecord(bean);