ソースを参照

update CACHE_APPLY_AVAILABLE_COUNT

deason 8 ヶ月 前
コミット
5734802091

+ 18 - 0
src/main/java/com/qmth/exam/reserve/bean/examsite/ExamSiteCapacityInfo.java

@@ -0,0 +1,18 @@
+package com.qmth.exam.reserve.bean.examsite;
+
+import com.qmth.exam.reserve.bean.IModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class ExamSiteCapacityInfo implements IModel {
+
+    @ApiModelProperty("考点ID")
+    private Long examSiteId;
+
+    @ApiModelProperty("总容量")
+    private Integer capacity;
+
+}

+ 6 - 0
src/main/java/com/qmth/exam/reserve/cache/CacheConstants.java

@@ -47,6 +47,12 @@ public interface CacheConstants {
      */
     String CACHE_APPLY_TOTAL = "$cache:apply_total:%s";
 
+    /**
+     * 预约任务 - 某考点某时段的“剩余可约数量”的缓存
+     * $cache:apply_available_count:{examSiteId}_{timePeriodId}
+     */
+    String CACHE_APPLY_AVAILABLE_COUNT = "$cache:apply_available_count:%s_%s";
+
     /**
      * 预约任务 - 某考点某时段的“已预约数量”的缓存
      * $cache:apply_finish:{examSiteId}_{timePeriodId}

+ 80 - 4
src/main/java/com/qmth/exam/reserve/cache/impl/ApplyTaskCacheService.java

@@ -3,13 +3,12 @@ package com.qmth.exam.reserve.cache.impl;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.qmth.exam.reserve.bean.apply.ApplyRecordCacheBean;
 import com.qmth.exam.reserve.bean.applytask.CurrentApplyTaskVO;
+import com.qmth.exam.reserve.bean.examsite.ExamSiteCapacityInfo;
 import com.qmth.exam.reserve.cache.CacheConstants;
 import com.qmth.exam.reserve.cache.RedisClient;
 import com.qmth.exam.reserve.entity.StudentApplyEntity;
-import com.qmth.exam.reserve.service.ApplyTaskService;
-import com.qmth.exam.reserve.service.ExamSiteService;
-import com.qmth.exam.reserve.service.StudentApplyService;
-import com.qmth.exam.reserve.service.StudentService;
+import com.qmth.exam.reserve.entity.TimePeriodEntity;
+import com.qmth.exam.reserve.service.*;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.MapUtils;
 import org.redisson.api.RAtomicLong;
@@ -38,6 +37,9 @@ public class ApplyTaskCacheService implements CacheConstants {
     @Autowired
     private ExamSiteService examSiteService;
 
+    @Autowired
+    private TimePeriodService timePeriodService;
+
     @Autowired
     private StudentService studentService;
 
@@ -161,6 +163,80 @@ public class ApplyTaskCacheService implements CacheConstants {
         return Math.max(availableCount, 0);
     }
 
+    /**
+     * 获取某考点某时段的“剩余可约数量”缓存
+     */
+    public int getApplyAvailableCount2(Long examSiteId, Long timePeriodId) {
+        String cacheKey = String.format(CACHE_APPLY_AVAILABLE_COUNT, examSiteId, timePeriodId);
+        RAtomicLong atomic = redisClient.getRedissonClient().getAtomicLong(cacheKey);
+        return (int) atomic.get();
+    }
+
+    /**
+     * 累加 某考点某时段的“剩余可约数量”缓存
+     */
+    public void increaseApplyAvailableCount(Long examSiteId, Long timePeriodId) {
+        String cacheKey = String.format(CACHE_APPLY_AVAILABLE_COUNT, examSiteId, timePeriodId);
+        RAtomicLong atomic = redisClient.getRedissonClient().getAtomicLong(cacheKey);
+        atomic.incrementAndGet();
+    }
+
+    /**
+     * 累减 某考点某时段的“剩余可约数量”缓存
+     */
+    public void decreaseApplyAvailableCount(Long examSiteId, Long timePeriodId) {
+        String cacheKey = String.format(CACHE_APPLY_AVAILABLE_COUNT, examSiteId, timePeriodId);
+        RAtomicLong atomic = redisClient.getRedissonClient().getAtomicLong(cacheKey);
+        if (atomic.get() > 0) {
+            atomic.decrementAndGet();
+        }
+    }
+
+    /**
+     * 初始化 某考点某时段的“剩余可约数量”缓存
+     */
+    public void initApplyAvailableCountCache(Long examSiteId, int oldCapacity, int newCapacity) {
+        // 获取所有时段ID集合
+        List<TimePeriodEntity> timePeriods = timePeriodService.list(new LambdaQueryWrapper<TimePeriodEntity>().select(TimePeriodEntity::getId));
+        if (CollectionUtils.isEmpty(timePeriods)) {
+            return;
+        }
+
+        // 新、旧考点容量差额
+        int diffCapacity = newCapacity - oldCapacity;
+
+        for (TimePeriodEntity timePeriod : timePeriods) {
+            String cacheKey = String.format(CACHE_APPLY_AVAILABLE_COUNT, examSiteId, timePeriod.getId());
+            if (redisClient.exist(cacheKey)) {
+                if (diffCapacity == 0) {
+                    // 考点总容量未变化,不用更新缓存
+                    continue;
+                }
+
+                // 总容量变化时,则更新考点剩余容量缓存
+                RAtomicLong atomic = redisClient.getRedissonClient().getAtomicLong(cacheKey);
+                long availableCount = Math.max(atomic.get() + diffCapacity, 0);
+                atomic.set(availableCount);
+                log.warn("SET cacheKey:{} value:{}", cacheKey, availableCount);
+            } else {
+                // 初始考点剩余容量缓存
+                RAtomicLong atomic = redisClient.getRedissonClient().getAtomicLong(cacheKey);
+                atomic.set(newCapacity);
+                log.debug("SET cacheKey:{} value:{}", cacheKey, newCapacity);
+            }
+        }
+    }
+
+    /**
+     * 初始化 所有考点所有时段的“剩余可约数量”缓存
+     */
+    public void initApplyAvailableCountCacheForAllExamSites() {
+        List<ExamSiteCapacityInfo> examSites = examSiteService.findAllExamSiteCapacityList();
+        for (ExamSiteCapacityInfo examSite : examSites) {
+            this.initApplyAvailableCountCache(examSite.getExamSiteId(), examSite.getCapacity(), examSite.getCapacity());
+        }
+    }
+
     /**
      * 累加 某考点某时段的“已预约数量”缓存
      */

+ 26 - 0
src/main/java/com/qmth/exam/reserve/config/InitApplyTaskCacheData.java

@@ -0,0 +1,26 @@
+package com.qmth.exam.reserve.config;
+
+import com.qmth.exam.reserve.cache.impl.ApplyTaskCacheService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.stereotype.Component;
+
+@Component
+public class InitApplyTaskCacheData implements CommandLineRunner {
+
+    private static final Logger log = LoggerFactory.getLogger(InitApplyTaskCacheData.class);
+
+    @Autowired
+    private ApplyTaskCacheService applyTaskCacheService;
+
+    @Override
+    public void run(String... args) throws Exception {
+        log.info("initApplyTaskCacheData start...");
+        long startTime = System.currentTimeMillis();
+        applyTaskCacheService.initApplyAvailableCountCacheForAllExamSites();
+        log.info("initApplyTaskCacheData ok... cost:{}ms", System.currentTimeMillis() - startTime);
+    }
+
+}

+ 6 - 0
src/main/java/com/qmth/exam/reserve/dao/ExamSiteDao.java

@@ -4,18 +4,24 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.qmth.exam.reserve.bean.examsite.ExamSiteCacheBean;
+import com.qmth.exam.reserve.bean.examsite.ExamSiteCapacityInfo;
 import com.qmth.exam.reserve.bean.examsite.ExamSiteReq;
 import com.qmth.exam.reserve.bean.examsite.ExamSiteVO;
 import com.qmth.exam.reserve.entity.ExamSiteEntity;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.List;
+
 public interface ExamSiteDao extends BaseMapper<ExamSiteEntity> {
 
     Integer countExamSiteCapacityById(@Param("examSiteId") Long examSiteId);
 
+    List<ExamSiteCapacityInfo> findAllExamSiteCapacityList();
+
     ExamSiteCacheBean findInfoById(@Param("examSiteId") Long examSiteId);
 
     IPage<ExamSiteVO> page(Page<ExamSiteVO> page, @Param("req") ExamSiteReq req);
 
     void updateExamSiteCapacity(@Param("examSiteId") Long examSiteId);
+
 }

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

@@ -19,6 +19,8 @@ public interface ExamSiteService extends IService<ExamSiteEntity> {
 
     int countExamSiteCapacityById(Long examSiteId);
 
+    List<ExamSiteCapacityInfo> findAllExamSiteCapacityList();
+
     PageResult<ExamSiteVO> page(ExamSiteReq req);
 
     void saveExamSite(LoginUser user, ExamSiteSaveReq req);
@@ -30,4 +32,5 @@ public interface ExamSiteService extends IService<ExamSiteEntity> {
     void updateExamSiteCapacity(Long examSiteId);
 
     void saveGuide(ExamSiteGuideReq req);
+
 }

+ 17 - 4
src/main/java/com/qmth/exam/reserve/service/impl/ExamSiteServiceImpl.java

@@ -30,7 +30,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;
 
 @Service
 public class ExamSiteServiceImpl extends ServiceImpl<ExamSiteDao, ExamSiteEntity> implements ExamSiteService {
@@ -95,6 +98,16 @@ public class ExamSiteServiceImpl extends ServiceImpl<ExamSiteDao, ExamSiteEntity
         return capacity != null ? capacity : 0;
     }
 
+    @Override
+    public List<ExamSiteCapacityInfo> findAllExamSiteCapacityList() {
+        List<ExamSiteCapacityInfo> list = baseMapper.findAllExamSiteCapacityList();
+        if (CollectionUtils.isEmpty(list)) {
+            return new ArrayList<>();
+        }
+        list.forEach(e -> e.setCapacity(e.getCapacity() != null ? e.getCapacity() : 0));
+        return list;
+    }
+
     @Override
     public PageResult<ExamSiteVO> page(ExamSiteReq req) {
         IPage<ExamSiteVO> iPage = baseMapper.page(new Page<>(req.getPageNumber(), req.getPageSize()),
@@ -117,7 +130,7 @@ public class ExamSiteServiceImpl extends ServiceImpl<ExamSiteDao, ExamSiteEntity
             beforeUpdateSite = getById(req.getId());
             updateById(site);
             //更新教学点的容量
-            if(!req.getTeachingId().equals(beforeUpdateSite.getCategoryId())) {
+            if (!req.getTeachingId().equals(beforeUpdateSite.getCategoryId())) {
                 categoryService.updateTeachingCapacity(req.getTeachingId());
                 categoryService.updateTeachingCapacity(beforeUpdateSite.getCategoryId());
             }
@@ -172,7 +185,7 @@ public class ExamSiteServiceImpl extends ServiceImpl<ExamSiteDao, ExamSiteEntity
                 msg.append(" 考点名称不能超过50个字符");
             } else {
                 List<ExamSiteEntity> examSiteEntities = listExamSiteByName(name);
-                if(examSiteEntities != null && !examSiteEntities.isEmpty()){
+                if (examSiteEntities != null && !examSiteEntities.isEmpty()) {
                     msg.append(" 考点名称不能重复");
                 } else {
                     site.setName(name);
@@ -247,7 +260,7 @@ public class ExamSiteServiceImpl extends ServiceImpl<ExamSiteDao, ExamSiteEntity
         LambdaUpdateWrapper<ExamSiteEntity> updateWrapper = new LambdaUpdateWrapper<>();
         updateWrapper.set(ExamSiteEntity::getGuide, req.getGuide());
         updateWrapper.eq(ExamSiteEntity::getId, req.getId());
-        update(null , updateWrapper);
+        update(null, updateWrapper);
     }
 
     private void saveExamSite(ExamSiteEntity examSite) {

+ 20 - 15
src/main/resources/mapper/ExamSiteMapper.xml

@@ -9,6 +9,12 @@
           and enable = 1
     </select>
 
+    <select id="findAllExamSiteCapacityList" resultType="com.qmth.exam.reserve.bean.examsite.ExamSiteCapacityInfo">
+        select es.id                                                                                         as examSiteId,
+               (select sum(er.capacity) from t_exam_room er where er.exam_site_id = es.id and er.enable = 1) as capacity
+        from t_exam_site es
+    </select>
+
     <select id="findInfoById" resultType="com.qmth.exam.reserve.bean.examsite.ExamSiteCacheBean">
         select es.id          examSiteId,
                es.name        examSiteName,
@@ -22,19 +28,19 @@
 
     <select id="page" resultType="com.qmth.exam.reserve.bean.examsite.ExamSiteVO">
         SELECT
-            s.id,
-            s.NAME,
-            s.CODE,
-            g.NAME teachingName,
-            g.id teachingId,
-            s.address,
-            s.capacity,
-            s.enable
+        s.id,
+        s.NAME,
+        s.CODE,
+        g.NAME teachingName,
+        g.id teachingId,
+        s.address,
+        s.capacity,
+        s.enable
         FROM
-            t_exam_site s,
-            t_category g
+        t_exam_site s,
+        t_category g
         WHERE
-            s.category_id = g.id
+        s.category_id = g.id
         <if test="req.teachingId != null">
             and s.category_id=#{req.teachingId}
         </if>
@@ -46,12 +52,11 @@
         </if>
         order by s.update_time desc
     </select>
-    
+
     <update id="updateExamSiteCapacity">
         UPDATE t_exam_site
-        SET capacity = ( SELECT sum( capacity ) FROM t_exam_room WHERE exam_site_id = #{examSiteId} AND ENABLE = 1 )
-        WHERE
-            id =  #{examSiteId};
+        SET capacity = (SELECT sum(capacity) FROM t_exam_room WHERE exam_site_id = #{examSiteId} AND ENABLE = 1)
+        WHERE id = #{examSiteId};
     </update>
 
 </mapper>