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

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;
}
}