package com.fdkankan.ucenter.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.fdkankan.common.exception.BusinessException; import com.fdkankan.common.util.RandomUtil; import com.fdkankan.redis.util.RedisUtil; import com.fdkankan.ucenter.common.CameraTypeEnum; import com.fdkankan.ucenter.common.RedisKeyUtil; import com.fdkankan.ucenter.entity.Scene3dNum; import com.fdkankan.ucenter.mapper.IScene3dNumMapper; import com.fdkankan.ucenter.service.IScene3dNumService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; import java.util.*; import java.util.stream.Collectors; /** *

* 场景编码表 服务实现类 *

* * @author * @since 2022-07-12 */ @Service @Slf4j public class Scene3dNumServiceImpl extends ServiceImpl implements IScene3dNumService { @Autowired RedisUtil redisUtil; @Override public String generateSceneNum(Integer cameraType) { String sceneNum = redisUtil.lLeftPop(RedisKeyUtil.SCENE_UNUSED_NUMS); if(!StringUtils.isEmpty(sceneNum)){ return addPrefix(sceneNum,cameraType); } long incr = redisUtil.incr(RedisKeyUtil.SCENE_NUMS_LOADING, 1); if(incr == 1){ try { log.info("开始从数据库加载场景码"); List numList = this.getSceneNum(); redisUtil.lRightPushAll(RedisKeyUtil.SCENE_UNUSED_NUMS,numList); log.info("场景码加载完成"); }catch ( Exception e){ e.printStackTrace(); }finally { redisUtil.del(RedisKeyUtil.SCENE_NUMS_LOADING); } }else { // 等待1秒加载缓存 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } String num = redisUtil.lLeftPop(RedisKeyUtil.SCENE_UNUSED_NUMS); if(ObjectUtils.isEmpty(num)){ log.error("场景码加载失败"); throw new BusinessException(-1,"场景码生成失败,请重试"); } return addPrefix(num,cameraType); } private static String addPrefix( String num,Integer cameraType){ if(cameraType == null){ return num; } return CameraTypeEnum.getSceneNumPrefixByType(cameraType) + num; } private List getSceneNum() { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(Scene3dNum::getUsed,0); long count = this.count(wrapper); List numList ; if(count < 10){ log.info("场景码数量不足生成场景码"); numList = this.createNum(10); }else { wrapper.last("limit 100"); numList = this.list(wrapper); for (Scene3dNum scene3dNum : numList) { scene3dNum.setUsed(1); } this.updateBatchById(numList); } return numList.parallelStream().map(Scene3dNum::getCode).collect(Collectors.toList()); } private List createNum(Integer size) { //uuid 作为生成批次 List scene3dNums = new ArrayList<>(); String uuid = UUID.randomUUID().toString().replace("-", ""); HashSet codeList = this.createCode(size); while (codeList.size() < size){ codeList.addAll(this.createCode(size - codeList.size())); } for (String code : codeList) { Scene3dNum scene3dNum = new Scene3dNum(); scene3dNum.setUsed(1); scene3dNum.setCode(code); scene3dNum.setFolderName(uuid); scene3dNum.setCreateTime(new Date()); scene3dNum.setUpdateTime(new Date()); scene3dNums.add(scene3dNum); } this.saveBatch(scene3dNums); return scene3dNums; } private HashSet createCode(Integer size) { HashSet codeList = new HashSet<>(); while (codeList.size() < size){ String code = RandomUtil.generateShortUuid().substring(0,8); codeList.add(code); } LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.in(Scene3dNum::getCode,codeList); List list = this.list(wrapper); if(list.size() <=0){ return codeList; } for (Scene3dNum scene3dNum : list) { codeList.remove(scene3dNum.getCode()); } return codeList; } }