|
@@ -26,7 +26,6 @@ import com.qmth.exam.reserve.service.*;
|
|
|
import com.qmth.exam.reserve.util.PageUtil;
|
|
|
import org.apache.commons.collections4.CollectionUtils;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
-import org.redisson.api.RLock;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.BeanUtils;
|
|
@@ -34,12 +33,11 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
import org.springframework.transaction.interceptor.TransactionAspectSupport;
|
|
|
+import org.springframework.transaction.support.TransactionSynchronization;
|
|
|
+import org.springframework.transaction.support.TransactionSynchronizationManager;
|
|
|
|
|
|
import java.io.InputStream;
|
|
|
-import java.util.ArrayList;
|
|
|
-import java.util.HashMap;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
+import java.util.*;
|
|
|
import java.util.function.Function;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
@@ -78,24 +76,31 @@ public class ExamRoomServiceImpl extends ServiceImpl<ExamRoomDao, ExamRoomEntity
|
|
|
@Transactional
|
|
|
@Override
|
|
|
public void saveExamRoom(LoginUser user, ExamRoomSaveReq req) {
|
|
|
+ if (req.getExamSiteId() == null) {
|
|
|
+ throw new StatusException("考点ID不能为空");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 锁检查
|
|
|
if (concurrentService.isLocked(CacheConstants.LOCK_AUTO_APPLY)) {
|
|
|
log.warn("[考场保存]系统自动预约中,不允许修改考场!lockKey:{}", CacheConstants.LOCK_AUTO_APPLY);
|
|
|
throw new StatusException("系统正在自动预约中,不允许修改考场");
|
|
|
}
|
|
|
String lockKey = String.format(CacheConstants.LOCK_EXAM_SITE_CAPACITY, req.getExamSiteId());
|
|
|
if (concurrentService.isLocked(lockKey)) {
|
|
|
- log.warn("[考场保存]考点剩余可约数量更新中,不允许考生操作修改!lockKey:{}", lockKey);
|
|
|
+ log.warn("[考场保存]考点剩余可约数量更新中,不允许操作修改!lockKey:{}", lockKey);
|
|
|
throw new StatusException("系统正在更新可预约数量,不允许修改考场");
|
|
|
}
|
|
|
|
|
|
checkExamRoom(req);
|
|
|
+
|
|
|
ExamRoomEntity examRoomEntity = new ExamRoomEntity();
|
|
|
BeanUtils.copyProperties(req, examRoomEntity);
|
|
|
+
|
|
|
ExamRoomEntity beforeUpdateRoom = new ExamRoomEntity();
|
|
|
//考点容量
|
|
|
ExamSiteEntity examSite = examSiteService.getById(req.getExamSiteId());
|
|
|
int oldCapacity = examSite.getCapacity();
|
|
|
- int newCapacity = 0;
|
|
|
+ int newCapacity;
|
|
|
if (req.getId() == null) {
|
|
|
examRoomEntity.setEnable(Boolean.TRUE);
|
|
|
save(examRoomEntity);
|
|
@@ -106,15 +111,16 @@ public class ExamRoomServiceImpl extends ServiceImpl<ExamRoomDao, ExamRoomEntity
|
|
|
//更新考点容量和教学点容量
|
|
|
updateExamSiteAndTeachingCapacity(req.getExamSiteId());
|
|
|
//考场更换考点
|
|
|
- if(req.getId() != null && !req.getExamSiteId().equals(beforeUpdateRoom.getExamSiteId())) {
|
|
|
+ if (req.getId() != null && !req.getExamSiteId().equals(beforeUpdateRoom.getExamSiteId())) {
|
|
|
updateExamSiteAndTeachingCapacity(beforeUpdateRoom.getExamSiteId());
|
|
|
}
|
|
|
|
|
|
+ // 获取更新后的容量
|
|
|
examSite = examSiteService.getById(req.getExamSiteId());
|
|
|
newCapacity = examSite.getCapacity();
|
|
|
|
|
|
//刷新缓存
|
|
|
- refreshApplyCountCache(examRoomEntity.getId(), examRoomEntity.getExamSiteId(), oldCapacity, newCapacity);
|
|
|
+ doRefreshApplyCountCache(examRoomEntity.getId(), examRoomEntity.getExamSiteId(), oldCapacity, newCapacity);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -123,13 +129,13 @@ public class ExamRoomServiceImpl extends ServiceImpl<ExamRoomDao, ExamRoomEntity
|
|
|
@Override
|
|
|
public void enable(Long id, Boolean enable) {
|
|
|
if (concurrentService.isLocked(CacheConstants.LOCK_AUTO_APPLY)) {
|
|
|
- log.warn("[考场禁用/启用]系统自动预约中,不允许修改考场!lockKey:{}", CacheConstants.LOCK_AUTO_APPLY);
|
|
|
+ log.warn("[考场禁用/启用]系统自动预约中,不允许启用/禁用考场!lockKey:{}", CacheConstants.LOCK_AUTO_APPLY);
|
|
|
throw new StatusException("系统正在自动预约中,不允许启用/禁用考场");
|
|
|
}
|
|
|
ExamRoomEntity examRoom = getById(id);
|
|
|
String lockKey = String.format(CacheConstants.LOCK_EXAM_SITE_CAPACITY, examRoom.getExamSiteId());
|
|
|
if (concurrentService.isLocked(lockKey)) {
|
|
|
- log.warn("[考场保存]考点剩余可约数量更新中,不允许考生操作修改!lockKey:{}", lockKey);
|
|
|
+ log.warn("[考场保存]考点剩余可约数量更新中,不允许启用/禁用考场!lockKey:{}", lockKey);
|
|
|
throw new StatusException("系统正在更新可预约数量,不允许启用/禁用考场");
|
|
|
}
|
|
|
|
|
@@ -148,13 +154,14 @@ public class ExamRoomServiceImpl extends ServiceImpl<ExamRoomDao, ExamRoomEntity
|
|
|
examSite = examSiteService.getById(examRoom.getExamSiteId());
|
|
|
|
|
|
//刷新缓存
|
|
|
- refreshApplyCountCache(id, examRoom.getExamSiteId(), oldCapacity, examSite.getCapacity());
|
|
|
+ doRefreshApplyCountCache(id, examRoom.getExamSiteId(), oldCapacity, examSite.getCapacity());
|
|
|
}
|
|
|
|
|
|
+ @Transactional
|
|
|
@Override
|
|
|
public List<Map<String, Object>> importExamRoom(LoginUser user, InputStream inputStream) {
|
|
|
if (concurrentService.isLocked(CacheConstants.LOCK_AUTO_APPLY)) {
|
|
|
- log.warn("[考场导入]系统自动预约中,不允许修改考场!lockKey:{}", CacheConstants.LOCK_AUTO_APPLY);
|
|
|
+ log.warn("[考场导入]系统自动预约中,不允许导入考场!lockKey:{}", CacheConstants.LOCK_AUTO_APPLY);
|
|
|
throw new StatusException("系统正在自动预约中,不允许导入考场");
|
|
|
}
|
|
|
|
|
@@ -245,7 +252,7 @@ public class ExamRoomServiceImpl extends ServiceImpl<ExamRoomDao, ExamRoomEntity
|
|
|
try {
|
|
|
saveRoom(examRoomEntity);
|
|
|
} catch (Exception e) {
|
|
|
- failRecords.add(newError(i + 1, " 系统异常"));
|
|
|
+ failRecords.add(newError(i + 1, " " + e.getMessage()));
|
|
|
log.error("导入异常", e);
|
|
|
}
|
|
|
}
|
|
@@ -275,19 +282,21 @@ public class ExamRoomServiceImpl extends ServiceImpl<ExamRoomDao, ExamRoomEntity
|
|
|
private void saveRoom(ExamRoomEntity room) {
|
|
|
String lockKey = String.format(CacheConstants.LOCK_EXAM_SITE_CAPACITY, room.getExamSiteId());
|
|
|
if (concurrentService.isLocked(lockKey)) {
|
|
|
- log.warn("[考场保存]考点剩余可约数量更新中,不允许考生操作修改!lockKey:{}", lockKey);
|
|
|
+ log.warn("[考场保存]考点剩余可约数量更新中,不允许导入考场!lockKey:{}", lockKey);
|
|
|
throw new StatusException("系统正在更新可预约数量,不允许导入考场");
|
|
|
}
|
|
|
|
|
|
+ //保存之前的考点容量
|
|
|
+ ExamSiteEntity examSite = examSiteService.getById(room.getExamSiteId());
|
|
|
+ if (examSite == null) {
|
|
|
+ throw new StatusException("找不到考点");
|
|
|
+ }
|
|
|
+ int oldCapacity = examSite.getCapacity();
|
|
|
+ Long roomId;
|
|
|
+
|
|
|
ExamRoomEntity examRoom = getExamRoom(room.getExamSiteId(), room.getCode());
|
|
|
- int oldCapacity = 0;
|
|
|
- ExamSiteEntity examSite;
|
|
|
if (examRoom != null) {
|
|
|
- examSite = examSiteService.getById(examRoom.getExamSiteId());
|
|
|
- if (examSite == null) {
|
|
|
- throw new StatusException("找不到考点");
|
|
|
- }
|
|
|
- oldCapacity = examSite.getCapacity();
|
|
|
+ roomId = examRoom.getId();
|
|
|
examRoom.setCapacity(room.getCapacity());
|
|
|
LambdaUpdateWrapper<ExamRoomEntity> wrapper = new LambdaUpdateWrapper<>();
|
|
|
wrapper.set(ExamRoomEntity::getName, room.getName());
|
|
@@ -298,15 +307,54 @@ public class ExamRoomServiceImpl extends ServiceImpl<ExamRoomDao, ExamRoomEntity
|
|
|
update(null, wrapper);
|
|
|
} else {
|
|
|
save(room);
|
|
|
+ roomId = room.getId();
|
|
|
}
|
|
|
//更新考点、教学点容量
|
|
|
updateExamSiteAndTeachingCapacity(room.getExamSiteId());
|
|
|
//更新之后的容量
|
|
|
examSite = examSiteService.getById(room.getExamSiteId());
|
|
|
//刷新缓存
|
|
|
- refreshApplyCountCache(room.getId(), room.getExamSiteId(), oldCapacity, examSite.getCapacity());
|
|
|
+ refreshApplyCountCacheAfterCommit(roomId, room.getExamSiteId(), oldCapacity, examSite.getCapacity());
|
|
|
}
|
|
|
|
|
|
+ private void refreshApplyCountCacheAfterCommit(Long examRoomId, Long examSiteId, int oldCapacity, int newCapacity) {
|
|
|
+ if (TransactionSynchronizationManager.isActualTransactionActive()) {
|
|
|
+ TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void afterCommit() {
|
|
|
+ doRefreshApplyCountCache(examRoomId, examSiteId, oldCapacity, newCapacity);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ doRefreshApplyCountCache(examRoomId, examSiteId, oldCapacity, newCapacity);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void doRefreshApplyCountCache(Long examRoomId, Long examSiteId, int oldCapacity, int newCapacity) {
|
|
|
+ List<TimePeriodEntity> timePeriods = timePeriodService.list(
|
|
|
+ new LambdaQueryWrapper<TimePeriodEntity>().select(TimePeriodEntity::getId));
|
|
|
+
|
|
|
+ List<TimePeriodExamRoomEntity> timePeriodExamRooms = timePeriodExamRoomService.listExamRoom(examRoomId);
|
|
|
+
|
|
|
+ Map<Long, TimePeriodExamRoomEntity> timePeriodExamRoomMap = Optional.ofNullable(timePeriodExamRooms)
|
|
|
+ .orElse(Collections.emptyList())
|
|
|
+ .stream()
|
|
|
+ .collect(Collectors.toMap(
|
|
|
+ TimePeriodExamRoomEntity::getTimePeriodId,
|
|
|
+ Function.identity(),
|
|
|
+ (existing, replacement) -> existing
|
|
|
+ ));
|
|
|
+
|
|
|
+ for (TimePeriodEntity timePeriod : timePeriods) {
|
|
|
+ TimePeriodExamRoomEntity timePeriodExamRoomEntity = timePeriodExamRoomMap.get(timePeriod.getId());
|
|
|
+ if (timePeriodExamRoomEntity == null || timePeriodExamRoomEntity.getEnable()) {
|
|
|
+ cacheService.refreshApplyAvailableCountCache(examSiteId, timePeriod.getId(), oldCapacity, newCapacity);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
private List<ExamSiteEntity> listExamSite(String examSiteCode, String examSiteName, Long categoryId) {
|
|
|
LambdaQueryWrapper<ExamSiteEntity> wrapper = new LambdaQueryWrapper<>();
|
|
|
wrapper.eq(ExamSiteEntity::getCode, examSiteCode);
|
|
@@ -323,24 +371,6 @@ public class ExamRoomServiceImpl extends ServiceImpl<ExamRoomDao, ExamRoomEntity
|
|
|
categoryService.updateTeachingCapacity(newExamSite.getCategoryId());
|
|
|
}
|
|
|
|
|
|
- private void refreshApplyCountCache(Long examRoomId,Long examSiteId, int oldCapacity, int newCapacity) {
|
|
|
- List<TimePeriodEntity> timePeriods = timePeriodService.list(new LambdaQueryWrapper<TimePeriodEntity>().select(TimePeriodEntity::getId));
|
|
|
- //考场时段列表
|
|
|
- List<TimePeriodExamRoomEntity> timePeriodExamRooms = timePeriodExamRoomService.listExamRoom(examRoomId);
|
|
|
- //将timePeriodExamRooms转Map
|
|
|
- Map<Long, TimePeriodExamRoomEntity> timePeriodExamRoomMap = timePeriodExamRooms.stream().collect(
|
|
|
- Collectors.toMap(TimePeriodExamRoomEntity::getTimePeriodId, Function.identity()));
|
|
|
-
|
|
|
- for (TimePeriodEntity timePeriod : timePeriods) {
|
|
|
- //刷新缓存
|
|
|
- TimePeriodExamRoomEntity timePeriodExamRoomEntity = timePeriodExamRoomMap.get(timePeriod.getId());
|
|
|
- if (timePeriodExamRoomEntity == null || timePeriodExamRoomEntity.getEnable()) {
|
|
|
- cacheService.refreshApplyAvailableCountCache(examSiteId, timePeriod.getId(), oldCapacity, newCapacity);
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
private void checkExamRoom(ExamRoomSaveReq req) {
|
|
|
if (StringUtils.isEmpty(req.getCode())) {
|
|
|
throw new StatusException("考场代码不能为空");
|