forked from luyan/epmet-cloud-lingshan
				
			
			You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							268 lines
						
					
					
						
							11 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							268 lines
						
					
					
						
							11 KiB
						
					
					
				| package com.epmet.redis; | |
| 
 | |
| 
 | |
| import com.alibaba.fastjson.JSON; | |
| import com.epmet.commons.tools.constant.NumConstant; | |
| import com.epmet.commons.tools.redis.RedisKeys; | |
| import com.epmet.commons.tools.redis.RedisUtils; | |
| import com.epmet.commons.tools.utils.ConvertUtils; | |
| import com.epmet.constant.BadgeConstant; | |
| import com.epmet.dao.BadgeDao; | |
| import com.epmet.dto.form.UserBadgeUnitFormDTO; | |
| import com.epmet.dto.result.UserBadgeInfoResultDTO; | |
| import com.epmet.dto.result.UserBadgeListResultDTO; | |
| import com.epmet.service.UserBadgeService; | |
| import lombok.extern.slf4j.Slf4j; | |
| import org.apache.commons.collections4.CollectionUtils; | |
| import org.apache.commons.lang3.StringUtils; | |
| import org.springframework.beans.factory.annotation.Autowired; | |
| import org.springframework.dao.DataAccessException; | |
| import org.springframework.data.redis.connection.RedisConnection; | |
| import org.springframework.data.redis.core.RedisCallback; | |
| import org.springframework.data.redis.core.RedisTemplate; | |
| import org.springframework.lang.Nullable; | |
| import org.springframework.stereotype.Component; | |
| 
 | |
| import java.util.*; | |
| import java.util.stream.Collectors; | |
| 
 | |
| import static com.epmet.commons.tools.redis.RedisUtils.MINUTE_THIRTY_EXPIRE; | |
| 
 | |
| /** | |
|  * @Author zxc | |
|  * @DateTime 2020/11/3 2:21 下午 | |
|  */ | |
| @Component | |
| @Slf4j | |
| public class UserBadgeRedis { | |
| 
 | |
|     @Autowired | |
|     private RedisUtils redisUtils; | |
|     @Autowired | |
|     private BadgeDao badgeDao; | |
|     @Autowired | |
|     private UserBadgeService badgeService; | |
|     @Autowired | |
|     private RedisTemplate redisTemplate; | |
| 
 | |
|     /** | |
|      * @Description 获取客户徽章信息 | |
|      * @Param customerId | |
|      * @author zxc | |
|      * @date 2020/11/3 2:50 下午 | |
|      */ | |
|     public Object getCustomerBadge(String customerId) { | |
|         Object userBadge = redisUtils.hGet(BadgeConstant.BADGE_KEY + customerId, BadgeConstant.BADGE); | |
|         return userBadge; | |
|     } | |
| 
 | |
|     /** | |
|      * @Description 存放客户徽章信息 | |
|      * @Param userBadge | |
|      * @Param customerId | |
|      * @author zxc | |
|      * @date 2020/11/3 2:51 下午 | |
|      */ | |
|     public void setCustomerBadge(List<UserBadgeListResultDTO> userBadge, String customerId) { | |
|         redisUtils.hSet(BadgeConstant.BADGE_KEY + customerId, BadgeConstant.BADGE, JSON.toJSON(userBadge).toString(), -1); | |
|     } | |
| 
 | |
|     /** | |
|      * @Description 删除客户徽章信息 | |
|      * @Param customerId | |
|      * @author zxc | |
|      * @date 2020/11/5 3:06 下午 | |
|      */ | |
|     public void delCustomerBadge(String customerId) { | |
|         redisUtils.hDel(BadgeConstant.BADGE_KEY + customerId, BadgeConstant.BADGE); | |
|     } | |
| 
 | |
|     /** | |
|      * @Description 存放徽章审核 手机验证码 | |
|      * @Param mobile | |
|      * @author zxc | |
|      * @date 2020/11/5 10:30 上午 | |
|      */ | |
|     public void saveBadgeSmsCode(String mobile, String smsCode) { | |
|         String smsCodeKey = BadgeConstant.SMS_CODE_KEY + mobile; | |
|         redisUtils.set(smsCodeKey, smsCode, MINUTE_THIRTY_EXPIRE); | |
|     } | |
| 
 | |
|     /** | |
|      * @Description 获取徽章审核 手机验证码 | |
|      * @Param mobile | |
|      * @author zxc | |
|      * @date 2020/11/5 10:30 上午 | |
|      */ | |
|     public String getBadgeSmsCode(String mobile) { | |
|         String smsCodeKey = BadgeConstant.SMS_CODE_KEY + mobile; | |
|         String smsCode = (String) redisUtils.get(smsCodeKey); | |
|         return smsCode; | |
|     } | |
| 
 | |
|     /** | |
|      * @param userId | |
|      * @return java.util.List<com.epmet.dto.form.UserBadgeUnitFormDTO> | |
|      * @Description 获取用户的全部勋章信息(点亮的 、 排序从前到后) | |
|      * @author wangc | |
|      * @date 2020.11.05 13:26 | |
|      */ | |
|     public List<UserBadgeUnitFormDTO> obtainUserBadge2List(String userId,String customerId) { | |
|         List<UserBadgeUnitFormDTO> cache = | |
|                 redisUtils.lrange(RedisKeys.getResiUserBadgeKey(customerId, userId), NumConstant.ZERO, NumConstant.ONE_NEG, UserBadgeUnitFormDTO.class); | |
|         if(!CollectionUtils.isEmpty(cache)) return cache; | |
|         //补偿 | |
|         cache = badgeService.getUserSortedBadge(userId,customerId); | |
|         if(CollectionUtils.isEmpty(cache)) return cache; | |
|         final List<UserBadgeUnitFormDTO> sortedBadges = cache; | |
|         redisTemplate.executePipelined((RedisCallback<List<UserBadgeUnitFormDTO>>) connection ->{ | |
|             sortedBadges.forEach(badge -> { | |
|                 connection.listCommands().rPush(RedisKeys.getResiUserBadgeKey(customerId, userId).getBytes(), | |
|                         redisTemplate.getValueSerializer().serialize(badge)); | |
|             }); | |
|             return null; | |
|         }); | |
| 
 | |
|         return cache; | |
|     } | |
| 
 | |
|     /** | |
|      * @Description 批量获取用户显示徽章 | |
|      * @param customerId | |
|      * @param userIds | |
|      * @return java.util.Map<java.lang.String,java.util.List<com.epmet.dto.form.UserBadgeUnitFormDTO>> | |
|      * @author wangc | |
|      * @date 2020.11.10 15:00 | |
|     */ | |
|     public Map<String,List<UserBadgeUnitFormDTO>> batchObtainUserBadge(String customerId,List<String> userIds){ | |
|         if(CollectionUtils.isEmpty(userIds)) return Collections.EMPTY_MAP; | |
|         Map<String,List<UserBadgeUnitFormDTO>> result = new HashMap<>(); | |
|         //存放缓存为空的 | |
|         List<String> cacheBlank = new LinkedList<>(); | |
|         userIds.forEach(userId -> { | |
|             List<UserBadgeUnitFormDTO> badges = | |
|                     redisUtils.lrange(RedisKeys.getResiUserBadgeKey(customerId, userId), NumConstant.ZERO, NumConstant.ONE_NEG, UserBadgeUnitFormDTO.class); | |
|             if(CollectionUtils.isEmpty(badges)){cacheBlank.add(userId);}else{result.put(userId,badges);} | |
|         }); | |
|         if(!CollectionUtils.isEmpty(cacheBlank)){ | |
|             Map<String,List<UserBadgeInfoResultDTO>> | |
|                     map = badgeService.getBatchUserSortedBadge(customerId,cacheBlank); | |
|             if(null != map && !map.isEmpty()){ | |
|                 map.forEach((k,v) -> { | |
|                     List<UserBadgeUnitFormDTO> covert = | |
|                             v.stream().map( o -> { | |
|                                 return ConvertUtils.sourceToTarget(o,UserBadgeUnitFormDTO.class); | |
|                             }).collect(Collectors.toList()); | |
|                     result.put(k,covert); | |
| 
 | |
|                     redisTemplate.executePipelined((RedisCallback<List<UserBadgeUnitFormDTO>>) connection ->{ | |
|                         covert.forEach(badge -> { | |
|                             connection.listCommands().rPush(RedisKeys.getResiUserBadgeKey(customerId, k).getBytes(), | |
|                                     redisTemplate.getValueSerializer().serialize(badge)); | |
|                         }); | |
|                         return null; | |
|                     }); | |
|                 }); | |
|             } | |
|         } | |
|         return result; | |
|     } | |
| 
 | |
|     /** | |
|      * 用户点亮或取消徽章 | |
|      * @param | |
|      * @return int | |
|      * @Description 入栈时使用lpush 出栈时使用lrem | |
|      * @author wangc | |
|      * @date 2020.11.05 13:37 | |
|      */ | |
|     public long pushOrRemoveUserBadge4List(String userId, String badgeId, String customerId) { | |
|         if(StringUtils.isNotBlank(userId)) return illumeOrExtinguishStronglyConsistent(userId,customerId); | |
|         List<UserBadgeUnitFormDTO> orient = redisUtils.lrange(RedisKeys.getResiUserBadgeKey(customerId, userId), NumConstant.ZERO, NumConstant.ONE_NEG, UserBadgeUnitFormDTO.class); | |
|         UserBadgeUnitFormDTO unit = null; | |
| 
 | |
|         if (!CollectionUtils.isEmpty(orient)) { | |
|             Optional<UserBadgeUnitFormDTO> opt = orient.stream().filter(badge -> StringUtils.equals(badgeId, badge.getBadgeId())).findFirst(); | |
|             if (opt.isPresent()) { | |
|                 unit = opt.get(); | |
|                 return redisUtils.lrem(RedisKeys.getResiUserBadgeKey(customerId, userId), NumConstant.ONE, unit); | |
|             } | |
|         } | |
| 
 | |
|             //徽章池 | |
|             Object badgeObj = getCustomerBadge(customerId); | |
| 
 | |
|             List<UserBadgeListResultDTO> badgePool = | |
|                     null == badgeObj ? badgeDao.selectCustomerBadgePool(customerId) : JSON.parseArray(badgeObj.toString(), UserBadgeListResultDTO.class); | |
| 
 | |
|             if (CollectionUtils.isEmpty(badgePool)) { | |
|                 log.error("com.epmet.redis.UserBadgeRedis.pushOrRemoveUserBadge4List,缓存中客户{}下的徽章池为空", customerId); | |
|                 return NumConstant.ZERO; | |
|             } | |
| 
 | |
|             if (null == unit) { | |
|                 Optional<UserBadgeListResultDTO> poolOpt = | |
|                         badgePool.stream().filter(badge -> StringUtils.equals(badge.getBadgeId(), badgeId)).findFirst(); | |
|                 if (poolOpt.isPresent()) unit = ConvertUtils.sourceToTarget(poolOpt.get(), UserBadgeUnitFormDTO.class); | |
|                 else return NumConstant.ZERO; | |
|             } | |
|         redisUtils.leftPush(RedisKeys.getResiUserBadgeKey(customerId, userId), unit, -1); | |
|             return NumConstant.ONE; | |
|         } | |
| 
 | |
|     /** | |
|      * @Description 用户点亮或取消徽章 强一致性 | |
|      * @param | |
|      * @return long | |
|      * @author wangc | |
|      * @date 2020.11.25 14:17 | |
|     */ | |
|     public long illumeOrExtinguishStronglyConsistent(String userId, String customerId){ | |
|         List<UserBadgeUnitFormDTO> db = badgeService.getUserSortedBadge(userId,customerId); | |
|         redisUtils.delete(RedisKeys.getResiUserBadgeKey(customerId, userId)); | |
|         if(CollectionUtils.isNotEmpty(db)) { | |
|             redisTemplate.executePipelined((RedisCallback<List<UserBadgeUnitFormDTO>>) connection -> { | |
|                 db.forEach(badge -> { | |
|                     connection.listCommands().rPush(RedisKeys.getResiUserBadgeKey(customerId, userId).getBytes(), | |
|                             redisTemplate.getValueSerializer().serialize(badge)); | |
|                 }); | |
|                 return null; | |
|             }); | |
|         } | |
|         return NumConstant.ONE; | |
|     } | |
| 
 | |
|         /** | |
|          * @Description 批量清除用户徽章信息,用处:在客户取消点亮某个徽章后,批量清除该客户下所有用户的徽章缓存,当需要查取时再次初始化进缓存中 | |
|          * @param customerId | |
|          * @return void | |
|          * @author wangc | |
|          * @date 2020.11.09 10:02 | |
|         */ | |
|         public void batchClearUserBadgeCache(String customerId){ | |
|             Set<String> key = redisUtils.keys(RedisKeys.getResiUserBadgeKey(customerId, null)); | |
|             if(CollectionUtils.isEmpty(key)) return; | |
|             final Set<String> keys = key; | |
|             redisTemplate.executePipelined((RedisCallback<String>) connection ->{ | |
|                     keys.forEach( ser -> {connection.del(redisTemplate.getKeySerializer().serialize(ser));}); | |
|                 return null; | |
|             }); | |
| 
 | |
|         } | |
| 
 | |
|         public List<String> pipelinedReturnKeys(String customerId){ | |
|             List<String> list = redisTemplate.executePipelined(new RedisCallback<List<String>>() { | |
|                 @Nullable | |
|                 @Override | |
|                 public List<String> doInRedis(RedisConnection connection) throws DataAccessException { | |
|                     connection.openPipeline(); | |
|                     Set<byte[]> keys = connection.keys(redisTemplate.getKeySerializer().serialize(RedisKeys.getResiUserBadgeKey(customerId, null))); | |
|                     return null; | |
|                 } | |
|             },redisTemplate.getKeySerializer()); | |
| 
 | |
|             return list; | |
|         } | |
| 
 | |
|     } | |
| 
 | |
| 
 |