|
@@ -6,6 +6,7 @@ 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.qmth.boot.core.collection.PageResult;
|
|
|
+import com.qmth.boot.core.concurrent.service.ConcurrentService;
|
|
|
import com.qmth.boot.core.exception.StatusException;
|
|
|
import com.qmth.boot.tools.excel.ExcelReader;
|
|
|
import com.qmth.boot.tools.excel.enums.ExcelType;
|
|
@@ -14,6 +15,7 @@ import com.qmth.exam.reserve.bean.login.LoginUser;
|
|
|
import com.qmth.exam.reserve.bean.room.ExamRoomReq;
|
|
|
import com.qmth.exam.reserve.bean.room.ExamRoomSaveReq;
|
|
|
import com.qmth.exam.reserve.bean.room.ExamRoomVO;
|
|
|
+import com.qmth.exam.reserve.cache.CacheConstants;
|
|
|
import com.qmth.exam.reserve.cache.impl.ApplyTaskCacheService;
|
|
|
import com.qmth.exam.reserve.dao.ExamRoomDao;
|
|
|
import com.qmth.exam.reserve.entity.ExamRoomEntity;
|
|
@@ -24,6 +26,7 @@ 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;
|
|
@@ -33,7 +36,10 @@ import org.springframework.transaction.annotation.Transactional;
|
|
|
import org.springframework.transaction.interceptor.TransactionAspectSupport;
|
|
|
|
|
|
import java.io.InputStream;
|
|
|
-import java.util.*;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
import java.util.function.Function;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
@@ -58,6 +64,9 @@ public class ExamRoomServiceImpl extends ServiceImpl<ExamRoomDao, ExamRoomEntity
|
|
|
@Autowired
|
|
|
private TimePeriodExamRoomService timePeriodExamRoomService;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private ConcurrentService concurrentService;
|
|
|
+
|
|
|
|
|
|
@Override
|
|
|
public PageResult<ExamRoomVO> pageExamRoom(ExamRoomReq req) {
|
|
@@ -69,20 +78,26 @@ public class ExamRoomServiceImpl extends ServiceImpl<ExamRoomDao, ExamRoomEntity
|
|
|
@Transactional
|
|
|
@Override
|
|
|
public void saveExamRoom(LoginUser user, ExamRoomSaveReq req) {
|
|
|
+ if (concurrentService.isLocked(CacheConstants.LOCK_AUTO_APPLY)) {
|
|
|
+ log.warn("[考场保存]系统自动预约中,不允许修改考场!lockKey:{}", CacheConstants.LOCK_AUTO_APPLY);
|
|
|
+ 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;
|
|
|
if (req.getId() == null) {
|
|
|
examRoomEntity.setEnable(Boolean.TRUE);
|
|
|
save(examRoomEntity);
|
|
|
- //刷新缓存
|
|
|
- refreshApplyCountCache(examRoomEntity.getId(), examRoomEntity.getExamSiteId(), 0, examRoomEntity.getCapacity());
|
|
|
} else {
|
|
|
beforeUpdateRoom = getById(req.getId());
|
|
|
updateById(examRoomEntity);
|
|
|
- //刷新缓存
|
|
|
- refreshApplyCountCache(examRoomEntity.getId(), examRoomEntity.getExamSiteId(), beforeUpdateRoom.getCapacity(), examRoomEntity.getCapacity());
|
|
|
+// refreshApplyCountCache(examRoomEntity.getId(), examRoomEntity.getExamSiteId(), beforeUpdateRoom.getCapacity(), examRoomEntity.getCapacity());
|
|
|
}
|
|
|
//更新考点容量和教学点容量
|
|
|
updateExamSiteAndTeachingCapacity(req.getExamSiteId());
|
|
@@ -90,12 +105,29 @@ public class ExamRoomServiceImpl extends ServiceImpl<ExamRoomDao, ExamRoomEntity
|
|
|
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);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
@Transactional
|
|
|
@Override
|
|
|
public void enable(Long id, Boolean enable) {
|
|
|
+ if (concurrentService.isLocked(CacheConstants.LOCK_AUTO_APPLY)) {
|
|
|
+ log.warn("[考场禁用/启用]系统自动预约中,不允许修改考场!lockKey:{}", CacheConstants.LOCK_AUTO_APPLY);
|
|
|
+ throw new StatusException("系统正在自动预约中,不允许启用/禁用考场");
|
|
|
+ }
|
|
|
+
|
|
|
ExamRoomEntity examRoom = getById(id);
|
|
|
+ //考点容量
|
|
|
+ ExamSiteEntity examSite = examSiteService.getById(examRoom.getExamSiteId());
|
|
|
+ int oldCapacity = examSite.getCapacity();
|
|
|
+
|
|
|
LambdaUpdateWrapper<ExamRoomEntity> wrapper = new LambdaUpdateWrapper<>();
|
|
|
wrapper.set(ExamRoomEntity::getEnable, enable);
|
|
|
wrapper.eq(ExamRoomEntity::getId, id);
|
|
@@ -103,12 +135,21 @@ public class ExamRoomServiceImpl extends ServiceImpl<ExamRoomDao, ExamRoomEntity
|
|
|
|
|
|
updateExamSiteAndTeachingCapacity(examRoom.getExamSiteId());
|
|
|
|
|
|
- refreshApplyCountCache(id, examRoom.getExamSiteId(), enable ? 0 : examRoom.getCapacity(), enable ? examRoom.getCapacity() : 0);
|
|
|
+ //更新之后考点的容量
|
|
|
+ examSite = examSiteService.getById(examRoom.getExamSiteId());
|
|
|
+
|
|
|
+ //刷新缓存
|
|
|
+ refreshApplyCountCache(id, examRoom.getExamSiteId(), oldCapacity, examSite.getCapacity());
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public List<Map<String, Object>> importExamRoom(LoginUser user, InputStream inputStream) {
|
|
|
- List<DataMap> lineList = null;
|
|
|
+ if (concurrentService.isLocked(CacheConstants.LOCK_AUTO_APPLY)) {
|
|
|
+ log.warn("[考场导入]系统自动预约中,不允许修改考场!lockKey:{}", CacheConstants.LOCK_AUTO_APPLY);
|
|
|
+ throw new StatusException("系统正在自动预约中,不允许导入考场");
|
|
|
+ }
|
|
|
+
|
|
|
+ List<DataMap> lineList;
|
|
|
ExcelReader reader = ExcelReader.create(ExcelType.XLSX, inputStream, 0);
|
|
|
try {
|
|
|
lineList = reader.getDataMapList();
|
|
@@ -224,9 +265,14 @@ public class ExamRoomServiceImpl extends ServiceImpl<ExamRoomDao, ExamRoomEntity
|
|
|
|
|
|
private void saveRoom(ExamRoomEntity room) {
|
|
|
ExamRoomEntity examRoom = getExamRoom(room.getExamSiteId(), room.getCode());
|
|
|
- int capacity;
|
|
|
+ int oldCapacity = 0;
|
|
|
+ ExamSiteEntity examSite;
|
|
|
if (examRoom != null) {
|
|
|
- capacity = examRoom.getCapacity();
|
|
|
+ examSite = examSiteService.getById(examRoom.getExamSiteId());
|
|
|
+ if(examSite == null) {
|
|
|
+ throw new StatusException("找不到考点");
|
|
|
+ }
|
|
|
+ oldCapacity = examSite.getCapacity();
|
|
|
examRoom.setCapacity(room.getCapacity());
|
|
|
LambdaUpdateWrapper<ExamRoomEntity> wrapper = new LambdaUpdateWrapper<>();
|
|
|
wrapper.set(ExamRoomEntity::getName, room.getName());
|
|
@@ -235,15 +281,15 @@ public class ExamRoomServiceImpl extends ServiceImpl<ExamRoomDao, ExamRoomEntity
|
|
|
wrapper.set(ExamRoomEntity::getEnable, Boolean.TRUE);
|
|
|
wrapper.eq(ExamRoomEntity::getId, examRoom.getId());
|
|
|
update(null, wrapper);
|
|
|
- if(capacity != room.getCapacity()) {
|
|
|
- refreshApplyCountCache(room.getId(), room.getExamSiteId(), capacity, room.getCapacity());
|
|
|
- }
|
|
|
} else {
|
|
|
save(room);
|
|
|
- refreshApplyCountCache(room.getId(), room.getExamSiteId(), 0, room.getCapacity());
|
|
|
-
|
|
|
}
|
|
|
+ //更新考点、教学点容量
|
|
|
updateExamSiteAndTeachingCapacity(room.getExamSiteId());
|
|
|
+ //更新之后的容量
|
|
|
+ examSite = examSiteService.getById(room.getExamSiteId());
|
|
|
+ //刷新缓存
|
|
|
+ refreshApplyCountCache(room.getId(), room.getExamSiteId(), oldCapacity, examSite.getCapacity());
|
|
|
}
|
|
|
|
|
|
private List<ExamSiteEntity> listExamSite(String examSiteCode, String examSiteName, Long categoryId) {
|
|
@@ -255,24 +301,11 @@ public class ExamRoomServiceImpl extends ServiceImpl<ExamRoomDao, ExamRoomEntity
|
|
|
}
|
|
|
|
|
|
private void updateExamSiteAndTeachingCapacity(Long examSiteId) {
|
|
|
-// ExamSiteEntity oldExamSite = examSiteService.getById(examSiteId);
|
|
|
// 更新考点容量
|
|
|
examSiteService.updateExamSiteCapacity(examSiteId);
|
|
|
-
|
|
|
ExamSiteEntity newExamSite = examSiteService.getById(examSiteId);
|
|
|
//更新教学点容量
|
|
|
categoryService.updateTeachingCapacity(newExamSite.getCategoryId());
|
|
|
-
|
|
|
- /* // 考点下没有启用的考场,容量设置为0
|
|
|
- if (oldExamSite.getCapacity() == null) {
|
|
|
- oldExamSite.setCapacity(0);
|
|
|
- }
|
|
|
- if (newExamSite.getCapacity() == null) {
|
|
|
- newExamSite.setCapacity(0);
|
|
|
- }*/
|
|
|
-
|
|
|
- //刷新考点容量缓存(以前的逻辑)
|
|
|
- //cacheService.refreshApplyAvailableCountCache(examSiteId, oldExamSite.getCapacity(), newExamSite.getCapacity());
|
|
|
}
|
|
|
|
|
|
private void refreshApplyCountCache(Long examRoomId,Long examSiteId, int oldCapacity, int newCapacity) {
|
|
@@ -283,12 +316,34 @@ public class ExamRoomServiceImpl extends ServiceImpl<ExamRoomDao, ExamRoomEntity
|
|
|
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);
|
|
|
+ for (TimePeriodEntity timePeriod : timePeriods) {
|
|
|
+ String examSiteTimePeriodLockKey = String.format(CacheConstants.LOCK_EXAM_SITE_TIME_PERIOD, examSiteId, timePeriod.getId());
|
|
|
+ RLock examSiteTimePeriodLock = (RLock) concurrentService.getLock(examSiteTimePeriodLockKey);
|
|
|
+ try {
|
|
|
+ if (!examSiteTimePeriodLock.tryLock()) {
|
|
|
+ log.warn("[考场容量更新] 获取锁失败,不能同时修改考点考场容量, lockKey:{}", examSiteTimePeriodLock);
|
|
|
+ throw new StatusException("考场保存失败,请稍后再试");
|
|
|
+ } else {
|
|
|
+ //刷新缓存
|
|
|
+ TimePeriodExamRoomEntity timePeriodExamRoomEntity = timePeriodExamRoomMap.get(timePeriod.getId());
|
|
|
+ if (timePeriodExamRoomEntity == null || timePeriodExamRoomEntity.getEnable()) {
|
|
|
+ cacheService.refreshApplyAvailableCountCache(examSiteId, timePeriod.getId(), oldCapacity, newCapacity);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("[考场容量更新] 考场保存失败, msg:{}", e.getMessage());
|
|
|
+ throw new StatusException("考场保存失败,请稍后再试");
|
|
|
+ } finally {
|
|
|
+ try {
|
|
|
+ if (examSiteTimePeriodLock.isLocked() && examSiteTimePeriodLock.isHeldByCurrentThread()) {
|
|
|
+ examSiteTimePeriodLock.unlock();
|
|
|
+ log.info("[考场容量更新] 解锁成功,lockKey:{}", examSiteTimePeriodLock);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn(e.getMessage());
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
}
|
|
|
|