CacheService.java 10.6 KB
package com.yohoufo.user.cache;

import com.yoho.core.redis.cluster.annotation.Redis;
import com.yoho.core.redis.cluster.operations.nosync.YHRedisTemplate;
import com.yoho.core.redis.cluster.operations.nosync.YHValueOperations;
import com.yoho.core.redis.cluster.operations.nosync.YHZSetOperations;
import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder;
import com.yohoufo.common.cache.CacheHelper;
import com.yohoufo.common.cache.CacheKeyEnum;
import com.yohoufo.dal.user.model.UserAuthorizeInfo;
import com.yohoufo.dal.user.model.UserFavorite;
import com.yohoufo.dal.user.model.ZhiMaCert;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.DefaultTypedTuple;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * Created by craig.qin on 2018/9/20.
 */
@Service
public class CacheService {
    private final Logger logger = LoggerFactory.getLogger(CacheService.class);
    @Redis("gwNoSyncRedis")
    YHZSetOperations yhZSetOperations;

    @Redis("gwNoSyncRedis")
    YHRedisTemplate yhRedisTemplate;

    @Redis("gwNoSyncRedis")
    YHValueOperations yhValueOperations;

    ///////  相关的key构造
    public static RedisKeyBuilder getProductFavoriteRedisKeyBuilder(Integer uid){
        return RedisKeyBuilder.newInstance().appendFixed(CacheKeyEnum.USER_PRODUCT_FAVORITE_ZSET_KEY.getCacheKey()).appendVar(uid);
    }

    public static RedisKeyBuilder getAuthorizeInfoRedisKeyBuilder(Integer uid){
        return RedisKeyBuilder.newInstance().appendFixed(CacheKeyEnum.AUTHORIZE_INFO_KEY.getCacheKey()).appendVar(uid);
    }


    public static RedisKeyBuilder getZhiMaCertRedisKeyBuilder(Integer uid){
        return RedisKeyBuilder.newInstance().appendFixed(CacheKeyEnum.ZHI_MA_CERT_KEY.getCacheKey()).appendVar(uid);
    }

    private static RedisKeyBuilder getPhotoCheckRedisKeyBuilder(String dayStr,Integer uid){
        return RedisKeyBuilder.newInstance().appendFixed(CacheKeyEnum.PHOTO_CHECK_COUNT_KEY.getCacheKey()).appendVarWithMH(dayStr).appendVar(uid);
    }

    /**************************************************************************
     *     商品收藏相关
     *************************************************************************/

    /**
     * 查询某用户是否已收藏某商品 (如果存在则将失效时间延期)
     * @param productId
     * @param uid
     * @return
     */
    public boolean isExistUserProductFavoriteByProductId(Integer uid, Integer productId,boolean isExtendExpire) {
        if(isExtendExpire){
            try{
                yhRedisTemplate.longExpire(getProductFavoriteRedisKeyBuilder(uid), CacheKeyEnum.USER_PRODUCT_FAVORITE_ZSET_KEY.getDefaultExpireTime(), CacheKeyEnum.USER_PRODUCT_FAVORITE_ZSET_KEY.getTimeUnit());
            }catch(Exception e){
                logger.warn("yhRedisTemplate.longExpire failed!!! e is: {}", e);
            }
        }

        try{
            Double result = yhZSetOperations.score(getProductFavoriteRedisKeyBuilder(uid), "" + productId);
            if (result == null) {
                return false;
            }
            return true;
        }catch(Exception e){
            logger.warn("yhZSetOperations.score failed!!! e is: {}", e);
        }
        return false;
    }


    /**
     * 是否存在该key (如果存在则将失效时间延期)
     * @param userId
     * @return
     */
    public boolean hasUserFavoriteProductKey(Integer userId,boolean isExtendExpire) {
        if(isExtendExpire){
            try{
                yhRedisTemplate.longExpire(getProductFavoriteRedisKeyBuilder(userId), CacheKeyEnum.USER_PRODUCT_FAVORITE_ZSET_KEY.getDefaultExpireTime(), CacheKeyEnum.USER_PRODUCT_FAVORITE_ZSET_KEY.getTimeUnit());
            }catch(Exception e){
                logger.warn("yhRedisTemplate.longExpire failed!!! e is: {}", e);
            }
        }

        return yhRedisTemplate.hasKey(getProductFavoriteRedisKeyBuilder(userId));
    }

    /**
     * 批量收藏
     * @param favoriteList
     * @param uid
     * @return
     */
    public void batchSetFavoriteProduct(Integer uid, List<UserFavorite> favoriteList) {

        if (CollectionUtils.isNotEmpty(favoriteList)) {
            Set<ZSetOperations.TypedTuple<String>> typedTuples = new HashSet<ZSetOperations.TypedTuple<String>>();
            for (UserFavorite item : favoriteList) {
                ZSetOperations.TypedTuple<String> typedTuple = new DefaultTypedTuple("" + item.getProductId(),Double.valueOf("" + item.getCreateTime()));
                typedTuples.add(typedTuple);
            }

            try{
                yhZSetOperations.add(getProductFavoriteRedisKeyBuilder(uid), typedTuples);
            }catch(Exception e){
                logger.warn("yhZSetOperations.add failed!!! e is: {}", e);
            }
        }

        //增加一个不存在的id,防止大量的key为空的情况
        try{
            yhZSetOperations.add(getProductFavoriteRedisKeyBuilder(uid), "0",0);
            yhRedisTemplate.longExpire(getProductFavoriteRedisKeyBuilder(uid), CacheKeyEnum.USER_PRODUCT_FAVORITE_ZSET_KEY.getDefaultExpireTime(), CacheKeyEnum.USER_PRODUCT_FAVORITE_ZSET_KEY.getTimeUnit());
        }catch(Exception e){
            logger.warn("yhZSetOperations.add failed!!! e is: {}", e);
        }
    }

    /**
     * 增加一条收藏数据
     * @param userId
     * @return
     */
    public void addFavoriteProductKey(Integer userId,Integer productId,long now) {
        try{
            yhZSetOperations.add(getProductFavoriteRedisKeyBuilder(userId), "" + productId, now);
        }catch(Exception e){
            logger.warn("yhZSetOperations.add failed!!! e is: {}", e);
        }
    }

    public void removeUserFavoriteProduct(Integer uid, Integer productId) {
        try{
            yhZSetOperations.remove(getProductFavoriteRedisKeyBuilder(uid), "" + productId);
        }catch(Exception e){
            logger.warn("yhZSetOperations.add failed!!! e is: {}", e);
        }
    }


    public long queryUserProductFavoriteCount(Integer uid) {
        try{
            Long count = yhZSetOperations.size(getProductFavoriteRedisKeyBuilder(uid));
            return null == count ? 0 : count;
        }catch(Exception e){
            logger.warn("yhZSetOperations.size failed!!! e is: {}", e);
        }
        return 0;
    }

    /**
     *获取用户收藏列表id
     */
    public Set<String> queryAllProductFavoriteByUid(Integer uid, int startIndex, int endIndex) {
        Set<String> set = yhZSetOperations.reverseRange(getProductFavoriteRedisKeyBuilder(uid), startIndex, endIndex);
        return set;
    }

    /**************************************************************************
     *     实名认证相关
     *************************************************************************/
    public UserAuthorizeInfo getUserAuthorizeInfo(Integer uid){
        return get(getAuthorizeInfoRedisKeyBuilder(uid),UserAuthorizeInfo.class);
    }

    public void setUserAuthorizeInfo(UserAuthorizeInfo authorizeInfo){
        set(getAuthorizeInfoRedisKeyBuilder(authorizeInfo.getUid()),authorizeInfo,CacheKeyEnum.AUTHORIZE_INFO_KEY.getDefaultExpireTime(),CacheKeyEnum.AUTHORIZE_INFO_KEY.getTimeUnit());
    }


    /**************************************************************************
     *     芝麻认证相关
     *************************************************************************/
    public ZhiMaCert getZhiMaCert(Integer uid){
        return get(getZhiMaCertRedisKeyBuilder(uid),ZhiMaCert.class);
    }

    public void setZhiMaCert(ZhiMaCert zhiMaCert){
        set(getZhiMaCertRedisKeyBuilder(zhiMaCert.getUid()),zhiMaCert,CacheKeyEnum.ZHI_MA_CERT_KEY.getDefaultExpireTime(),CacheKeyEnum.ZHI_MA_CERT_KEY.getTimeUnit());
    }

    public void delZhiMaCert(Integer uid){
        yhRedisTemplate.delete(getZhiMaCertRedisKeyBuilder(uid));
    }

    public Long getPhotoCheckCount(String dayStr,Integer uid){
        RedisKeyBuilder cacheKey = getPhotoCheckRedisKeyBuilder(dayStr,uid);
        Long count = get(cacheKey,Long.class);
        return count;
    }

    public Long incrementPhotoCheckCount(String dayStr,Integer uid) {
        RedisKeyBuilder cacheKey = getPhotoCheckRedisKeyBuilder(dayStr,uid);
        return this.incrementWithExpire(cacheKey,  1L ,  CacheKeyEnum.PHOTO_CHECK_COUNT_KEY.getDefaultExpireTime(),  CacheKeyEnum.PHOTO_CHECK_COUNT_KEY.getTimeUnit()) ;
    }


    /**************************************************************************
     *     通用
     *************************************************************************/

    /**
     * 取值
     *
     * @param cacheKey
     * @param clazz
     */
    public <T> T get(RedisKeyBuilder cacheKey, Class<T> clazz) {
        logger.debug("Enter get valueOperation redis value.key is {}", cacheKey);
        try {
            String value = yhValueOperations.get(cacheKey);
            return CacheHelper.string2Value(value, clazz);
        } catch (Exception e) {
            logger.warn("Redis exception. value redis get,key {}, error msg is {}", cacheKey, e);
        }
        return null;
    }


    /**
     * 设置值
     *
     * @param cacheKey
     * @param value
     * @param timeout
     * @param unit
     * @param <T>
     */
    public <T> void set(RedisKeyBuilder cacheKey, T value, long timeout, TimeUnit unit) {
        logger.debug("Enter set valueOperation redis value.key is {},value is {}", cacheKey, value);
        try {
            String v = CacheHelper.value2String(value);
            yhValueOperations.set(cacheKey, v, timeout, unit);
        } catch (Exception e) {
            logger.warn("Redis exception. value redis set,key {},value is {}, error msg is {}", cacheKey, value, e);
        }
    }



    public Long incrementWithExpire(RedisKeyBuilder cacheKey, long delta , long timeout, TimeUnit unit) {
        logger.debug("Enter increment valueOperation redis.key is {},delta is {}", cacheKey, delta);
        try {
            Long num =  yhValueOperations.increment(cacheKey, delta);
            yhRedisTemplate.longExpire(cacheKey, timeout, unit);
            return num;
        } catch (Exception e) {
            try{
                yhRedisTemplate.longExpire(cacheKey, timeout, unit);
            }catch (Exception e1){
                logger.error("RedisValueHelper expire redis again error. with key={}", cacheKey, e1);
            }
            logger.warn("Redis exception. increment fail,key {},delta is {}, error msg is {}", cacheKey, delta, e);
        }
        return 0L;
    }

}