ApplyTaskCacheService.java 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. package com.qmth.exam.reserve.cache.impl;
  2. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  3. import com.qmth.exam.reserve.bean.apply.ApplyRecordCacheBean;
  4. import com.qmth.exam.reserve.bean.applytask.CurrentApplyTaskVO;
  5. import com.qmth.exam.reserve.cache.CacheConstants;
  6. import com.qmth.exam.reserve.cache.RedisClient;
  7. import com.qmth.exam.reserve.entity.StudentApplyEntity;
  8. import com.qmth.exam.reserve.service.ApplyTaskService;
  9. import com.qmth.exam.reserve.service.ExamSiteService;
  10. import com.qmth.exam.reserve.service.StudentApplyService;
  11. import com.qmth.exam.reserve.service.StudentService;
  12. import org.apache.commons.collections4.CollectionUtils;
  13. import org.redisson.api.RAtomicLong;
  14. import org.redisson.api.RBlockingQueue;
  15. import org.slf4j.Logger;
  16. import org.slf4j.LoggerFactory;
  17. import org.springframework.beans.factory.annotation.Autowired;
  18. import org.springframework.stereotype.Component;
  19. import java.util.HashMap;
  20. import java.util.List;
  21. import java.util.Map;
  22. import java.util.concurrent.TimeUnit;
  23. @Component
  24. public class ApplyTaskCacheService implements CacheConstants {
  25. private static final Logger log = LoggerFactory.getLogger(ApplyTaskCacheService.class);
  26. @Autowired
  27. private RedisClient redisClient;
  28. @Autowired
  29. private ApplyTaskService applyTaskService;
  30. @Autowired
  31. private ExamSiteService examSiteService;
  32. @Autowired
  33. private StudentService studentService;
  34. @Autowired
  35. private StudentApplyService studentApplyService;
  36. /**
  37. * 获取当前启用的预约任务缓存
  38. */
  39. public CurrentApplyTaskVO currentApplyTask(Long orgId) {
  40. String cacheKey = String.format(CACHE_CURRENT_APPLY_TASK, orgId);
  41. CurrentApplyTaskVO value = redisClient.get(cacheKey, CurrentApplyTaskVO.class);
  42. if (value != null) {
  43. return value;
  44. }
  45. value = applyTaskService.currentApplyTask(orgId);
  46. if (value == null) {
  47. return null;
  48. }
  49. redisClient.set(cacheKey, value, 5, TimeUnit.MINUTES);
  50. log.info("SET cacheKey:{} curApplyTaskId:{}", cacheKey, value.getTaskId());
  51. return value;
  52. }
  53. public void clearCurrentApplyTaskCache(Long orgId) {
  54. String cacheKey = String.format(CACHE_CURRENT_APPLY_TASK, orgId);
  55. redisClient.delete(cacheKey);
  56. log.warn("DELETE cacheKey:{}", cacheKey);
  57. }
  58. /**
  59. * 获取某考生的“允许预约时段次数”
  60. */
  61. public int getStudentApplyNumber(Long studentId) {
  62. String cacheKey = String.format(CACHE_STUDENT_APPLY_NUMBER, studentId);
  63. Integer value = redisClient.get(cacheKey, Integer.class);
  64. if (value != null) {
  65. return value;
  66. }
  67. value = studentService.findStudentApplyNumberById(studentId);
  68. redisClient.set(cacheKey, value, 5, TimeUnit.MINUTES);
  69. log.info("SET cacheKey:{} value:{}", cacheKey, value);
  70. return value;
  71. }
  72. public void clearStudentApplyNumberCache(Long studentId) {
  73. String cacheKey = String.format(CACHE_STUDENT_APPLY_NUMBER, studentId);
  74. redisClient.delete(cacheKey);
  75. log.warn("DELETE cacheKey:{}", cacheKey);
  76. }
  77. /**
  78. * 获取某考点的“可预约总量”
  79. */
  80. public int getApplyTotalCount(Long examSiteId) {
  81. String cacheKey = String.format(CACHE_APPLY_TOTAL, examSiteId);
  82. Integer value = redisClient.get(cacheKey, Integer.class);
  83. if (value != null) {
  84. return value;
  85. }
  86. value = examSiteService.countExamSiteCapacityById(examSiteId);
  87. redisClient.set(cacheKey, value, 5, TimeUnit.MINUTES);
  88. log.info("SET cacheKey:{} value:{}", cacheKey, value);
  89. return value;
  90. }
  91. public void clearApplyTotalCountCache(Long examSiteId) {
  92. String cacheKey = String.format(CACHE_APPLY_TOTAL, examSiteId);
  93. redisClient.delete(cacheKey);
  94. log.warn("DELETE cacheKey:{}", cacheKey);
  95. }
  96. /**
  97. * 获取某考点某时段的“已预约数量”
  98. */
  99. public int getApplyFinishCount(Long examSiteId, Long timePeriodId) {
  100. String cacheKey = String.format(CACHE_APPLY_FINISH, examSiteId, timePeriodId);
  101. if (redisClient.exist(cacheKey)) {
  102. return (int) redisClient.getRedissonClient().getAtomicLong(cacheKey).get();
  103. }
  104. RAtomicLong atomic = redisClient.getRedissonClient().getAtomicLong(cacheKey);
  105. int value = studentApplyService.countApplyFinishForExamSiteAndTimePeriod(examSiteId, timePeriodId);
  106. atomic.set(value);
  107. atomic.expire(30, TimeUnit.DAYS);
  108. log.info("SET cacheKey:{} value:{}", cacheKey, value);
  109. return value;
  110. }
  111. /**
  112. * 累加 某考点某时段的“已预约数量”
  113. */
  114. public void increaseApplyFinishCount(Long examSiteId, Long timePeriodId) {
  115. String cacheKey = String.format(CACHE_APPLY_FINISH, examSiteId, timePeriodId);
  116. RAtomicLong atomic = redisClient.getRedissonClient().getAtomicLong(cacheKey);
  117. atomic.incrementAndGet();
  118. }
  119. /**
  120. * 累减 某考点某时段的“已预约数量”
  121. */
  122. public void decreaseApplyFinishCount(Long examSiteId, Long timePeriodId) {
  123. String cacheKey = String.format(CACHE_APPLY_FINISH, examSiteId, timePeriodId);
  124. RAtomicLong atomic = redisClient.getRedissonClient().getAtomicLong(cacheKey);
  125. if (atomic.get() > 0) {
  126. atomic.decrementAndGet();
  127. }
  128. }
  129. /**
  130. * 获取某考生的 已完成预约次数
  131. */
  132. public int getStudentApplyFinishCount(Long studentId) {
  133. String cacheKey = String.format(CACHE_STUDENT_APPLY_RECORD, studentId);
  134. if (!redisClient.exist(cacheKey)) {
  135. LambdaQueryWrapper<StudentApplyEntity> wrapper = new LambdaQueryWrapper<>();
  136. wrapper.eq(StudentApplyEntity::getStudentId, studentId);
  137. wrapper.eq(StudentApplyEntity::getCancel, Boolean.FALSE);
  138. return studentApplyService.count(wrapper);
  139. } // todo不走数据库查询,以redis中数据为准
  140. Map<String, ApplyRecordCacheBean> maps = this.getStudentApplyRecords(studentId);
  141. int studentApplyFinishCount = 0;
  142. for (ApplyRecordCacheBean bean : maps.values()) {
  143. if (!bean.getCancel()) {
  144. studentApplyFinishCount++;
  145. }
  146. }
  147. return studentApplyFinishCount;
  148. }
  149. /**
  150. * 获取某考生的 所有的“预约记录”缓存
  151. */
  152. public Map<String, ApplyRecordCacheBean> getStudentApplyRecords(Long studentId) {
  153. String cacheKey = String.format(CACHE_STUDENT_APPLY_RECORD, studentId);
  154. if (!redisClient.exist(cacheKey)) {
  155. LambdaQueryWrapper<StudentApplyEntity> wrapper = new LambdaQueryWrapper<>();
  156. wrapper.eq(StudentApplyEntity::getStudentId, studentId);
  157. List<StudentApplyEntity> list = studentApplyService.list(wrapper);
  158. Map<String, ApplyRecordCacheBean> maps = new HashMap<>();
  159. if (CollectionUtils.isNotEmpty(list)) {
  160. for (StudentApplyEntity entity : list) {
  161. ApplyRecordCacheBean bean = new ApplyRecordCacheBean();
  162. bean.setStudentId(entity.getStudentId());
  163. bean.setExamSiteId(entity.getExamSiteId());
  164. bean.setTimePeriodId(entity.getTimePeriodId());
  165. bean.setCancel(entity.getCancel());
  166. bean.setOperateId(entity.getOperateId());
  167. bean.setOperateTime(entity.getUpdateTime());
  168. this.saveStudentApplyRecord(bean);
  169. String hashKey = String.format("%s_%s", entity.getExamSiteId(), entity.getTimePeriodId());
  170. maps.put(hashKey, bean);
  171. }
  172. redisClient.expire(cacheKey, 30, TimeUnit.DAYS);
  173. }
  174. return maps;
  175. } // todo不走数据库查询,以redis中数据为准
  176. return redisClient.getEntriesForHash(cacheKey, ApplyRecordCacheBean.class);
  177. }
  178. /**
  179. * 获取某考生的 某考点某时段的“预约记录”缓存
  180. */
  181. public ApplyRecordCacheBean getStudentApplyRecord(Long studentId, Long examSiteId, Long timePeriodId) {
  182. String cacheKey = String.format(CACHE_STUDENT_APPLY_RECORD, studentId);
  183. String hashKey = String.format("%s_%s", examSiteId, timePeriodId);
  184. return redisClient.getForHash(cacheKey, hashKey, ApplyRecordCacheBean.class);
  185. }
  186. /**
  187. * 保存某考生的 某考点某时段的“预约记录”缓存
  188. */
  189. public void saveStudentApplyRecord(ApplyRecordCacheBean value) {
  190. String cacheKey = String.format(CACHE_STUDENT_APPLY_RECORD, value.getStudentId());
  191. String hashKey = String.format("%s_%s", value.getExamSiteId(), value.getTimePeriodId());
  192. redisClient.setForHash(cacheKey, hashKey, value);
  193. log.info("SET cacheKey:{} hashKey:{} cancel:{}", cacheKey, hashKey, value.getCancel());
  194. }
  195. /**
  196. * 推送至考生预约记录队列
  197. */
  198. public void pushStudentApplyRecordQueue(ApplyRecordCacheBean value) {
  199. if (value == null) {
  200. return;
  201. }
  202. RBlockingQueue<ApplyRecordCacheBean> queue = redisClient.getRedissonClient()
  203. .getBlockingQueue(QUEUE_STUDENT_APPLY_RECORD);
  204. boolean success = queue.offer(value);
  205. if (!success) {
  206. throw new RuntimeException("推送至考生预约记录队列失败");
  207. }
  208. }
  209. /**
  210. * 获取考生预约记录队列数量
  211. */
  212. public int getStudentApplyRecordQueueSize() {
  213. RBlockingQueue<ApplyRecordCacheBean> queue = redisClient.getRedissonClient()
  214. .getBlockingQueue(QUEUE_STUDENT_APPLY_RECORD);
  215. return queue.size();
  216. }
  217. }