Scene3dNumServiceImpl.java 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. package com.fdkankan.scene.service.impl;
  2. import cn.hutool.core.collection.CollUtil;
  3. import cn.hutool.core.util.StrUtil;
  4. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  5. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  6. import com.fdkankan.common.constant.CameraTypeEnum;
  7. import com.fdkankan.common.constant.CommonStatus;
  8. import com.fdkankan.common.constant.ErrorCode;
  9. import com.fdkankan.common.constant.TbStatus;
  10. import com.fdkankan.common.exception.BusinessException;
  11. import com.fdkankan.common.util.RandomUtil;
  12. import com.fdkankan.redis.constant.RedisKey;
  13. import com.fdkankan.redis.constant.RedisLockKey;
  14. import com.fdkankan.redis.util.RedisLockUtil;
  15. import com.fdkankan.redis.util.RedisUtil;
  16. import com.fdkankan.scene.entity.Scene3dNum;
  17. import com.fdkankan.scene.mapper.IScene3dNumMapper;
  18. import com.fdkankan.scene.service.IScene3dNumService;
  19. import lombok.extern.slf4j.Slf4j;
  20. import org.springframework.beans.factory.annotation.Autowired;
  21. import org.springframework.beans.factory.annotation.Value;
  22. import org.springframework.cloud.context.config.annotation.RefreshScope;
  23. import org.springframework.stereotype.Service;
  24. import java.util.HashSet;
  25. import java.util.List;
  26. import java.util.Objects;
  27. import java.util.Set;
  28. import java.util.stream.Collectors;
  29. /**
  30. * <p>
  31. * 八目场景编码表 服务实现类
  32. * </p>
  33. *
  34. * @author dengsixing
  35. * @since 2021-12-23
  36. */
  37. @Slf4j
  38. @Service
  39. @RefreshScope
  40. public class Scene3dNumServiceImpl extends ServiceImpl<IScene3dNumMapper, Scene3dNum> implements IScene3dNumService {
  41. private
  42. @Autowired
  43. RedisUtil redisUtil;
  44. @Autowired
  45. RedisLockUtil redisLockUtil;
  46. @Value("${scene.num.threshold:1000}")
  47. private int threshold;
  48. @Value("${scene.num.prefix:V4-}")
  49. private String numPrefix;
  50. @Value("${scene.num.batchSize:100}")
  51. private int batchSize;
  52. @Override
  53. public String generateSceneNum(Integer cameraType){
  54. // 从缓存中获取
  55. String sceneNum = redisUtil.lLeftPop(RedisKey.FDKANKAN_SCENE_NUMS);
  56. if(Objects.nonNull(sceneNum)){
  57. return addPrefix(sceneNum,cameraType);
  58. }
  59. // 分布式加锁
  60. Long loading = redisUtil.incr(RedisLockKey.LOCK_FDKANKAN_SCENE_NUMS, 1);
  61. if (loading.compareTo(1L) == 0) {
  62. try {
  63. log.info("开始从数据库加载场景码");
  64. List<String> nums = this.findSceneNum();
  65. this.updateUsedStatus(nums);
  66. redisUtil.lRightPushAll(RedisKey.FDKANKAN_SCENE_NUMS, nums);
  67. log.info("场景码加载完成");
  68. } catch (Exception e) {
  69. log.error("场景码加载失败", e);
  70. } finally {
  71. redisUtil.decr(RedisLockKey.LOCK_FDKANKAN_SCENE_NUMS, 1);
  72. }
  73. }else{
  74. // 等待1秒加载缓存
  75. try {
  76. Thread.sleep(1000);
  77. } catch (InterruptedException e) {
  78. e.printStackTrace();
  79. }
  80. }
  81. sceneNum = redisUtil.lLeftPop(RedisKey.FDKANKAN_SCENE_NUMS);
  82. if(StrUtil.isEmpty(sceneNum)){
  83. log.error("场景码加载失败");
  84. throw new BusinessException(ErrorCode.FAILURE_CODE_5053);
  85. }
  86. return addPrefix(sceneNum,cameraType);
  87. }
  88. private static String addPrefix( String num,Integer cameraType){
  89. if(cameraType == null){
  90. return num;
  91. }
  92. return CameraTypeEnum.getSceneNumPrefixByType(cameraType) + num;
  93. }
  94. @Override
  95. public void batchCreateSceneNum() {
  96. String lockKey = String.format(RedisLockKey.LOCK_BATCH_CREATE_NUM);
  97. boolean lock = redisLockUtil.lock(lockKey, RedisKey.EXPIRE_TIME_10_MINUTE);
  98. if(!lock){
  99. return;
  100. }
  101. try {
  102. long count = this.count(
  103. new LambdaQueryWrapper<Scene3dNum>().eq(Scene3dNum::getUsed, CommonStatus.NO.code()));
  104. if(count > threshold){
  105. return;
  106. }
  107. int batchCnt = threshold / batchSize + (threshold % batchSize > 0 ? 1 : 0);
  108. for (int i = 0; i < batchCnt; i++){
  109. Set<String> numSet = this.turnCreateSceneNum(batchSize);
  110. List<Scene3dNum> scene3dNumList = numSet.stream().map(num -> {
  111. Scene3dNum scene3dNum = new Scene3dNum();
  112. scene3dNum.setNum(num);
  113. return scene3dNum;
  114. }).collect(Collectors.toList());
  115. this.saveBatch(scene3dNumList);
  116. }
  117. }finally {
  118. redisLockUtil.unlockLua(lockKey);
  119. }
  120. }
  121. private Set<String> turnCreateSceneNum(int cnt){
  122. String num;
  123. Set<String> numSet = new HashSet<>();
  124. for(int i = 0; i < cnt; i++){
  125. num = numPrefix + RandomUtil.generateShortUuid();
  126. numSet.add(num);
  127. }
  128. List<Scene3dNum> existList = this.list(
  129. new LambdaQueryWrapper<Scene3dNum>()
  130. .in(Scene3dNum::getNum, numSet));
  131. Set<String> existNumSet = null;
  132. if(CollUtil.isNotEmpty(existList)){
  133. existNumSet = existList.stream().map(Scene3dNum::getNum).collect(Collectors.toSet());
  134. }
  135. if(CollUtil.isNotEmpty(existNumSet)){
  136. numSet.removeAll(existNumSet);
  137. }
  138. if(numSet.size() < cnt){
  139. numSet.addAll(this.turnCreateSceneNum(cnt - numSet.size()));
  140. }
  141. return numSet;
  142. }
  143. @Override
  144. public List<String> findSceneNum() {
  145. return baseMapper.findSceneNum();
  146. }
  147. @Override
  148. public Scene3dNum findByNum(String sceneCode) {
  149. List<Scene3dNum> list = this.list(new LambdaQueryWrapper<Scene3dNum>()
  150. .eq(Scene3dNum::getTbStatus, TbStatus.VALID.code())
  151. .eq(Scene3dNum::getNum, sceneCode));
  152. if(CollUtil.isEmpty(list)){
  153. return null;
  154. }
  155. return list.get(0);
  156. }
  157. @Override
  158. public void updateUsedStatus(List<String> nums) {
  159. baseMapper.updateUsedStatus(nums);
  160. }
  161. }