haogh 1 month ago
parent
commit
20e8d3de88

+ 2 - 1
src/main/java/com/qmth/exam/reserve/dao/TimePeriodExamRoomDao.java

@@ -11,7 +11,8 @@ public interface TimePeriodExamRoomDao extends BaseMapper<TimePeriodExamRoomEnti
 
     List<ExamRoomEntity> listExamRoom(@Param("examSiteId") Long examSiteId, @Param("timePeriodId") Long timePeriodId, @Param("enable") Boolean enable);
 
-    List<TimePeriodExamRoomEntity> listByExamRoomIdsAndTimePeriodIds(@Param("examRoomIds") List<Long> examRoomIds, @Param("timePeriodIds") List<Long> timePeriodIds);
+    List<TimePeriodExamRoomEntity> listByExamRoomIdsAndTimePeriodIds(@Param("examRoomIds") List<Long> examRoomIds,
+            @Param("timePeriodIds") List<Long> timePeriodIds, @Param("ids") List<Long> ids);
 
     List<TimePeriodExamRoomEntity> listByExamRoomIdsAndTimePeriodId(@Param("examRoomIds") List<Long> examRoomIds, @Param("timePeriodId") Long timePeriodId);
 }

+ 7 - 5
src/main/java/com/qmth/exam/reserve/service/impl/StudentApplyServiceImpl.java

@@ -206,20 +206,22 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
 
         if (concurrentService.isLocked(CacheConstants.LOCK_AUTO_APPLY)) {
             // 系统自动预约“任务执行期间”不允许取消预约
-            log.warn("系统自动预约中,不允许考生操作预约!lockKey:{}", CacheConstants.LOCK_AUTO_APPLY);
+            log.warn("[cancel] 系统自动预约中,不允许考生操作预约!lockKey:{}", CacheConstants.LOCK_AUTO_APPLY);
             throw new StatusException(Constants.SYSTEM_BUSY);
         }
 
         // 教学点管理员,只能取消本教学点的考生
         if (user.getRole().equals(Role.TEACHING) && !user.getCategoryId().equals(student.getCategoryId())) {
-            throw new StatusException("[cancel] 只能取消本教学点的考生");
+            log.warn("[cancel] 教学点管理员,只能取消本教学点的考生, userId:{}, studentId:{}", user.getId(), studentApplyEntity.getStudentId());
+            throw new StatusException("只能取消本教学点的考生");
         }
 
         // 考生是否已经取消判断
         ApplyRecordCacheBean studentApplyRecord = cacheService.getStudentApplyRecord(studentApplyEntity.getStudentId(), studentApplyEntity.getExamSiteId(),
                 studentApplyEntity.getTimePeriodId());
         if (studentApplyRecord != null && studentApplyRecord.getCancel()) {
-            throw new StatusException("[cancel] 考生已经取消,请稍后查看");
+            log.warn("[cancel] 考生已经取消,请稍后查看, studentId:{}", studentApplyEntity.getStudentId());
+            throw new StatusException("考生已经取消,请稍后查看");
         }
 
         String studentApplyLockKey = String.format(CacheConstants.LOCK_STUDENT_APPLY, studentApplyEntity.getStudentId());
@@ -960,13 +962,13 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
         // 获取所有考场列表
         List<ExamRoomEntity> examRoomList = listExamRoom(examSiteId);
         if (examRoomList == null || examRoomList.isEmpty()) {
-            return Collections.emptyList(); // 如果没有考场,直接返回空列表
+            return Collections.emptyList();
         }
 
         // 获取禁用的考场列表
         List<ExamRoomEntity> disableExamRoomList = timePeriodExamRoomService.listExamRoom(examSiteId, timePeriodId, false);
         if (CollectionUtils.isEmpty(disableExamRoomList)) {
-            return examRoomList; // 如果没有禁用考场,直接返回所有考场
+            return examRoomList;
         }
 
         // 提取禁用考场的 ID 到 Set中

+ 37 - 0
src/main/java/com/qmth/exam/reserve/service/impl/TimePeriodExamRoomServiceImpl.java

@@ -301,9 +301,17 @@ public class TimePeriodExamRoomServiceImpl extends ServiceImpl<TimePeriodExamRoo
 
             // 批量保存或更新
             if (!toBeSaved.isEmpty()) {
+                //防止重复保存
+                checkExistTimePeriodExamRoom(toBeSaved, Collections.emptyList());
                 saveBatch(toBeSaved);
             }
+
             if (!toBeUpdated.isEmpty()) {
+                List<Long> ids = toBeUpdated.stream()
+                        .map(TimePeriodExamRoomEntity::getId)
+                        .collect(Collectors.toList());
+                checkExistTimePeriodExamRoom(toBeUpdated, ids);
+
                 updateBatchById(toBeUpdated);
             }
 
@@ -330,6 +338,35 @@ public class TimePeriodExamRoomServiceImpl extends ServiceImpl<TimePeriodExamRoo
         }
     }
 
+    private void checkExistTimePeriodExamRoom(List<TimePeriodExamRoomEntity> toBeSaved, List<Long> ids) {
+        // 判断考场+时段是否在库中已经存在
+        List<Long> examRoomIds = toBeSaved.stream()
+                .map(TimePeriodExamRoomEntity::getExamRoomId)
+                .distinct()
+                .collect(Collectors.toList());
+        List<Long> timePeriodIds = toBeSaved.stream()
+                .map(TimePeriodExamRoomEntity::getTimePeriodId)
+                .distinct()
+                .collect(Collectors.toList());
+
+        // 批量查询已存在的记录
+        List<TimePeriodExamRoomEntity> existingRecords = getBaseMapper().listByExamRoomIdsAndTimePeriodIds(examRoomIds, timePeriodIds, ids);
+
+        // 构建已存在的记录集合,用于快速查找
+        Set<String> existingKeySet = existingRecords.stream()
+                .map(e -> e.getExamRoomId() + "-" + e.getTimePeriodId())
+                .collect(Collectors.toSet());
+
+        // 检查是否有重复的记录
+        for (TimePeriodExamRoomEntity item : toBeSaved) {
+            String key = item.getExamRoomId() + "-" + item.getTimePeriodId();
+            if (existingKeySet.contains(key)) {
+                log.error("[考场排班设置]保存失败,该时间段已存在: examRoomId={}, timePeriodId={}", item.getExamRoomId(), item.getTimePeriodId());
+                throw new StatusException("保存失败,时段重复");
+            }
+        }
+    }
+
     @Override
     public List<ExamRoomEntity> listExamRoom(Long examSiteId, Long timePeriodId, Boolean enable) {
         return getBaseMapper().listExamRoom(examSiteId, timePeriodId, enable);

+ 6 - 0
src/main/resources/mapper/TimePeriodExamRoomMapper.xml

@@ -28,6 +28,12 @@
         <foreach collection="timePeriodIds" item="id" open="(" separator="," close=")">
             #{id}
         </foreach>
+        <if test="ids != null and ids.size() > 0">
+            AND id NOT IN
+            <foreach collection="ids" item="id" open="(" separator="," close=")">
+                #{id}
+            </foreach>
+        </if>
     </select>
 
     <select id="listByExamRoomIdsAndTimePeriodId" resultType="com.qmth.exam.reserve.entity.TimePeriodExamRoomEntity">