package com.liquidnet.service.goblin.util;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.liquidnet.common.cache.redis.util.RedisUtil;
import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.commons.lang.util.RandomUtil;
import com.liquidnet.service.base.ErrorMapping;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.galaxy.constant.GalaxyEnum;
import com.liquidnet.service.goblin.constant.GoblinRedisConst;
import com.liquidnet.service.goblin.constant.GoblinStatusConst;
import com.liquidnet.service.goblin.dto.GoblinStoreMarketDto;
import com.liquidnet.service.goblin.dto.GoblinUserNftAccInfoVo;
import com.liquidnet.service.goblin.dto.GoblinUserSafeConfigDto;
import com.liquidnet.service.goblin.dto.manage.vo.GoblinGoodsAnticipateValueVo;
import com.liquidnet.service.goblin.dto.manage.vo.GoblinMgtCategorySpecVo;
import com.liquidnet.service.goblin.dto.vo.*;
import com.liquidnet.service.goblin.entity.GoblinFrontBanner;
import com.liquidnet.service.goblin.entity.GoblinFrontHotWord;
import com.liquidnet.service.goblin.entity.GoblinFrontNavigation;
import com.liquidnet.service.goblin.service.impl.inner.GoblinNftJobServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

import static com.liquidnet.service.goblin.constant.GoblinRedisConst.REDIS_GOBLIN_TEMP_COUPON_MARKET;

@Slf4j
@Component
public class GoblinRedisUtils {
    @Autowired
    public RedisUtil redisUtil;
    @Autowired
    GoblinMongoUtils goblinMongoUtils;
    @Autowired
    GoblinNftJobServiceImpl goblinNftJobService;

    @Value("${liquidnet.secret.passwd-salt}")
    private String passwdSalt;

    private int randomMax = 10;

    public void del(String... keys) {
        redisUtil.del(keys);
    }

    public Object get(String key) {
        return redisUtil.get(key);
    }

    public boolean expire(String key, long seconds) {
        return redisUtil.expireSet(key, seconds);
    }

    public long incr(String key, long delta) {
        return redisUtil.incr(key, delta);
    }

    /* ---------------------------------------- 短信相关 ---------------------------------------- */

    public boolean setSmsCodeByMobile(String mobile, String smsCode) {
        return redisUtil.set(GoblinRedisConst.VALID_SMS_CODE_MOBILE + mobile, smsCode, 600);
    }

    public Long ttlSmsCodeByMobile(String mobile) {
        return redisUtil.getExpire(GoblinRedisConst.VALID_SMS_CODE_MOBILE + mobile);
    }

    public String getSmsCodeByMobile(String mobile) {
        return (String) redisUtil.get(GoblinRedisConst.VALID_SMS_CODE_MOBILE + mobile);
    }

    /* ---------------------------------------- 预约相关 ---------------------------------------- */

    /**
     * 设置 IOS 支付方式
     *
     * @param value 0-苹果支付|1-微信支付宝
     */
    public void setPayType(int value) {
        if (value != 0 && value != 1) {
            value = 0;
        }
        redisUtil.set(GoblinRedisConst.NFT_PAY_TYPE, value);
    }

    public int getPayType() {
        Object obj = redisUtil.get(GoblinRedisConst.NFT_PAY_TYPE);
        if (obj == null) {
            return 0;
        } else {
            return (int) obj;
        }
    }

    /**
     * 该skuId已开启预约
     */
    public void setValue(GoblinGoodsAnticipateValueVo valueVo) {
        redisUtil.set(GoblinRedisConst.ANTICIPATE_VALUE_SKUID.concat(valueVo.getSkuId()), valueVo);
    }

    /**
     * 根据skuId获取valueVo
     */
    public GoblinGoodsAnticipateValueVo getValueBySkuId(String skuId) {
        return (GoblinGoodsAnticipateValueVo) redisUtil.get(GoblinRedisConst.ANTICIPATE_VALUE_SKUID.concat(skuId));
    }

    /**
     * 获取关联
     */
    public boolean getSkuId(String skuId) {
        return redisUtil.get(GoblinRedisConst.ANTICIPATE_VALUE_SKUID.concat(skuId)) != null;
    }


    /**
     * 删除skuId已开启预约
     */
    public void delSkuId(String skuId) {
        redisUtil.del(GoblinRedisConst.ANTICIPATE_VALUE_SKUID.concat(skuId));
    }

    public GoblinGoodAnticipateUserVo getUserAboutAut(String skuId, String uid) {
        return (GoblinGoodAnticipateUserVo) redisUtil.get(GoblinRedisConst.USER_ANTICIPATE_STATE.concat(skuId).concat(uid));
    }

    /**
     * 新增用户预约
     */
    public void setUserAboutSku(GoblinGoodAnticipateUserVo user) {
        goblinMongoUtils.setGoblinGoodsAnticipateUserVo(user);
        redisUtil.set(GoblinRedisConst.USER_ANTICIPATE_STATE.concat(user.getSkuId()).concat(user.getUid()), user, 60 * 60 * 24 * 180);
    }

    /**
     * 实际预约人数修改
     */
    public void setSkuIdPeople(String skuId) {
        BigInteger num = (BigInteger) redisUtil.get(GoblinRedisConst.ANTICIPATE_PEOPLE.concat(skuId));
        num = num != null ? num : BigInteger.valueOf(0);
        //新预约  +1
        redisUtil.set(GoblinRedisConst.ANTICIPATE_PEOPLE.concat(skuId), num.add(BigInteger.valueOf(1)));

        //跟新valueVo
        GoblinGoodsAnticipateValueVo anticipateValueVo = getValueBySkuId(skuId);
        anticipateValueVo.setAboutPeople(anticipateValueVo.getAboutPeople().add(BigInteger.valueOf(1)));
        setValue(anticipateValueVo);
    }

    /**
     * 获取实际预约人数修改
     */
    public BigInteger getSkuIdPeople(String skuId) {
        return (BigInteger) redisUtil.get(GoblinRedisConst.ANTICIPATE_PEOPLE.concat(skuId));
    }

    /**
     * 保存用户头像
     */
    public void setUserAvatar(String skuId, String avatar) {
        Object list = redisUtil.get(GoblinRedisConst.ANTICIPATE_SKUID_AVATAR.concat(skuId));
        List<String> urlList = list != null ? (List<String>) list : CollectionUtil.arrayListString();
        urlList.add(avatar);
        redisUtil.set(GoblinRedisConst.ANTICIPATE_SKUID_AVATAR.concat(skuId), urlList);
    }

    /**
     * 获取用户预约头像
     */
    public List<String> getUserAvatar(String skuId) {
        String rdk = GoblinRedisConst.ANTICIPATE_SKUID_AVATAR.concat(skuId);
        Object obj = redisUtil.get(rdk);
        if (obj == null) {
            return CollectionUtil.arrayListString();
        } else {
            return (List<String>) obj;
        }
    }

    /**
     * 存用户助力关联
     */
    public void setShare(String skuId, String uid, String sid, Long day) {
        String key = GoblinRedisConst.ANTICIPATE_SHARE_UID_SKUID.concat(uid).concat(":").concat(skuId);
        redisUtil.set(key, sid, (day + 1) * 60 * 60 * 24);
    }

    /**
     * 获取用户是否开启关联助力
     */
    public String getShare(String skuId, String uid) {
        String key = GoblinRedisConst.ANTICIPATE_SHARE_UID_SKUID.concat(uid).concat(":").concat(skuId);
        return (String) redisUtil.get(key);
    }

    /**
     * 缓存sku预约助力人数
     */
    public void delSharePeopleBySkuId(String skuId) {
        String key = GoblinRedisConst.ANTICIPATE_SHARE_SKUID_PEOPLE.concat(skuId);
        redisUtil.del(key);
    }

    /**
     * 保存用户头像
     */
    public void setHelpUserAvatar(String sid, String avatar) {
        GoblinGoodsAnticipateShareVo shareVo = getShareVo(sid);
//        Object list = redisUtil.get(GoblinRedisConst.ANTICIPATE_SHARE_HELP_AVATAR.concat(sid));
        shareVo.getAvatarImgList().add(avatar);
        setShareVo(shareVo);
    }

    /**
     * 获取用户预约头像
     */
    public List<String> getHelpUserAvatar(String sid) {
        GoblinGoodsAnticipateShareVo shareVo = getShareVo(sid);

        if (shareVo != null) {
            return shareVo.getAvatarImgList();
        } else {
            return CollectionUtil.arrayListString();
        }
    }

    /**
     * 存储分享VO
     */
    public void setShareVo(GoblinGoodsAnticipateShareVo goblinGoodsAnticipateShareVo) {
        redisUtil.set(GoblinRedisConst.ANTICIPATE_SHARE_VO.concat(goblinGoodsAnticipateShareVo.getSid()), goblinGoodsAnticipateShareVo);
    }

    /**
     * 获取分享VO
     */
    public GoblinGoodsAnticipateShareVo getShareVo(String sid) {
        return (GoblinGoodsAnticipateShareVo) redisUtil.get(GoblinRedisConst.ANTICIPATE_SHARE_VO.concat(sid));
    }

    /**
     * 缓存助力
     */
    public void setHelpByUidAndSid(String uid, String sid, Long day) {
        redisUtil.set(GoblinRedisConst.ANTICIPATE_SHARE_HELPID_SID.concat(uid).concat(":").concat(sid), 0, (day + 1) * 60 * 60 * 24);
    }

    /**
     * 获取助力
     */
    public Integer getHelpByUidAndSid(String uid, String sid) {
        return (Integer) redisUtil.get(GoblinRedisConst.ANTICIPATE_SHARE_HELPID_SID.concat(uid).concat(":").concat(sid));
    }

    /**
     * 助力id人数+1
     */
    public void setHelpSidAddHelp(String sid) {
        GoblinGoodsAnticipateShareVo shareVo = getShareVo(sid);
        Integer helpPeople = shareVo.getHelpPeople();
        shareVo.setHelpPeople(helpPeople != null ? helpPeople += 1 : 1);
        setShareVo(shareVo);
    }

    /**
     * 获取 助力id人数
     */
    public Integer getHelpSidAddHelp(String sid) {
        GoblinGoodsAnticipateShareVo shareVo = getShareVo(sid);
        Integer people = null;
        if (shareVo != null) {
            people = shareVo.getHelpPeople();
        }
        return people != null ? people : 0;
    }


    /* ---------------------------------------- sku库存相关 ---------------------------------------- */
    public void setSkuStock(String marketPre, String skuId, Integer stock) {
        String rk = GoblinRedisConst.REAL_STOCK_SKU;
        if (marketPre != null) {
            rk = rk.concat(marketPre + ":");
        }
        rk = rk.concat(skuId);
        redisUtil.set(rk, stock);
    }

    public int getSkuStock(String marketPre, String skuId) {
        String rk = GoblinRedisConst.REAL_STOCK_SKU;
        if (marketPre != null && !marketPre.equals("null")) {
            rk = rk.concat(marketPre + ":");
        }
        rk = rk.concat(skuId);
        Object obj = redisUtil.get(rk);
        if (obj == null) {
            return 0;
        } else {
            return (int) obj;
        }
    }

    public int incrSkuStock(String marketPre, String skuId, Integer stock) {
        String rk = GoblinRedisConst.REAL_STOCK_SKU;
        if (marketPre != null && !marketPre.equals("null")) {
            rk = rk.concat(marketPre + ":");
        }
        rk = rk.concat(skuId);
        return (int) redisUtil.incr(rk, stock);
    }

    public int decrSkuStock(String marketPre, String skuId, Integer stock) {
        String rk = GoblinRedisConst.REAL_STOCK_SKU;
        if (marketPre != null && !marketPre.equals("null")) {
            rk = rk.concat(marketPre + ":");
        }
        rk = rk.concat(skuId);
        return (int) redisUtil.decr(rk, stock);
    }

    //添加 skuId 相关的活动 skuId
    public void addSkuRe(String skuId, String marketSkuId) {
        String rk = GoblinRedisConst.SKU_RELATION.concat(skuId);
        List<String> list = getSkuRe(skuId);
        list.add(marketSkuId);
        redisUtil.set(rk, list);
    }

    //删除 skuId 相关的活动 skuId
    public void removeSkuRe(String skuId, String marketSkuId) {
        String rk = GoblinRedisConst.SKU_RELATION.concat(skuId);
        List<String> list = getSkuRe(skuId);
        list.remove(marketSkuId);
        redisUtil.set(rk, list);
    }

    //获取 skuId 相关的活动 skuId
    public List<String> getSkuRe(String skuId) {
        String rk = GoblinRedisConst.SKU_RELATION.concat(skuId);
        Object obj = redisUtil.get(rk);
        if (obj == null) {
            return CollectionUtil.arrayListString();
        } else {
            return ((List<String>) obj).stream().distinct().collect(Collectors.toList());
        }
    }

    /* ---------------------------------------- IOS商品价格集 ---------------------------------------- */

    public ObjectNode getIosProducts() {
        Object obj = redisUtil.get(GoblinRedisConst.BASIC_LIB_IOS_PRODUCTS);
        if (null != obj) {
            return JsonUtils.fromJson((String) obj, ObjectNode.class);
        } else {
            ObjectNode val = JsonUtils.OM().createObjectNode();
            val.put("NGoods1", 1.00);
            val.put("NGoods3", 3.00);
            val.put("NGoods6", 6.00);
            val.put("NGoods8", 8.00);
            val.put("NGoods12", 12.00);
            val.put("NGoods18", 18.00);
            val.put("NGoods25", 25.00);
            val.put("NGoods28", 28.00);
            val.put("NGoods30", 30.00);
            val.put("NGoods40", 40.00);
            val.put("NGoods45", 45.00);
            val.put("NGoods50", 50.00);
            val.put("NGoods60", 60.00);
            val.put("NGoods68", 68.00);
            val.put("NGoods73", 73.00);
            val.put("NGoods78", 78.00);
            val.put("NGoods88", 88.00);
            val.put("NGoods93", 93.00);
            val.put("NGoods98", 98.00);
            val.put("NGoods108", 108.00);
            val.put("NGoods113", 113.00);
            val.put("NGoods118", 118.00);
            val.put("NGoods123", 123.00);
            val.put("NGoods128", 128.00);
            val.put("NGoods138", 138.00);
            val.put("NGoods148", 148.00);
            val.put("NGoods153", 153.00);
            val.put("NGoods158", 158.00);
            val.put("NGoods163", 163.00);
            val.put("NGoods168", 168.00);
            val.put("NGoods178", 178.00);
            val.put("NGoods188", 188.00);
            val.put("NGoods193", 193.00);
            val.put("NGoods198", 198.00);
            val.put("NGoods208", 208.00);
            val.put("NGoods218", 218.00);
            val.put("NGoods223", 223.00);
            val.put("NGoods228", 228.00);
            val.put("NGoods233", 233.00);
            val.put("NGoods238", 238.00);
            val.put("NGoods243", 243.00);
            val.put("NGoods248", 248.00);
            val.put("NGoods253", 253.00);
            val.put("NGoods258", 258.00);
            val.put("NGoods263", 263.00);
            val.put("NGoods268", 268.00);
            val.put("NGoods273", 273.00);
            val.put("NGoods278", 278.00);
            val.put("NGoods283", 283.00);
            val.put("NGoods288", 288.00);
            val.put("NGoods298", 298.00);
            redisUtil.set(GoblinRedisConst.BASIC_LIB_IOS_PRODUCTS, val.toString());
            return val;
        }
    }

    /* ---------------------------------------- 平台标签数据源 ---------------------------------------- */

    /**
     * 普通商品标签
     * {
     * tagType:0-普通商品标签
     * tagBelong:0-普通标签
     * }
     *
     * @return List<GoblinSelfTagVo>
     */
    public List<GoblinSelfTagVo> getSelfTagVos() {
        String valStr = (String) redisUtil.get(GoblinRedisConst.BASIC_SELF_TAG);
        boolean valStrIsEmptyFlg = StringUtils.isEmpty(valStr);
        List<GoblinSelfTagVo> vos;
        if (valStrIsEmptyFlg) {
            if (!CollectionUtils.isEmpty(vos = goblinMongoUtils.getSelfTagVos("0"))) {
                redisUtil.set(GoblinRedisConst.BASIC_SELF_TAG, JsonUtils.toJson(vos), 60 * 60);
            }
        } else {
            vos = JsonUtils.fromJson(valStr, new TypeReference<List<GoblinSelfTagVo>>() {
            });
        }
        return vos;
    }

    /**
     * 专属标签
     * {
     * tagType:1-音乐人|2-艺术家|3-品牌方|4-厂牌|5-AR
     * tagBelong:1-专属标签
     * }
     *
     * @return List<GoblinSelfTagVo>
     */
    public List<GoblinSelfTagVo> getSelfExtagVos() {
        String valStr = (String) redisUtil.get(GoblinRedisConst.BASIC_SELF_EXTAG);
        List<GoblinSelfTagVo> vos;
        if (StringUtils.isEmpty(valStr)) {
            if (!CollectionUtils.isEmpty(vos = goblinMongoUtils.getSelfTagVos("1"))) {
                redisUtil.set(GoblinRedisConst.BASIC_SELF_EXTAG, JsonUtils.toJson(vos), 60 * 60);
            }
        } else {
            vos = JsonUtils.fromJson(valStr, new TypeReference<List<GoblinSelfTagVo>>() {
            });
        }
        return vos;
    }

    /* ---------------------------------------- 平台分类数据源 ---------------------------------------- */

    public List<GoblinSelfGoodsCategoryVo> getSelfGoodsCategoryVos() {
        String valStr = (String) redisUtil.get(GoblinRedisConst.BASIC_SELF_GOODS_CATEGORY);
        boolean valStrIsEmptyFlg = StringUtils.isEmpty(valStr);
        List<GoblinSelfGoodsCategoryVo> vos;
        if (valStrIsEmptyFlg) {
            if (!CollectionUtils.isEmpty(vos = goblinMongoUtils.getSelfGoodsCategoryVos())) {
                redisUtil.set(GoblinRedisConst.BASIC_SELF_GOODS_CATEGORY, JsonUtils.toJson(vos));
            }
        } else {
            vos = JsonUtils.fromJson(valStr, new TypeReference<List<GoblinSelfGoodsCategoryVo>>() {
            });
        }
        return vos;
    }

    /* ---------------------------------------- 店铺分类数据源 ---------------------------------------- */

    public boolean setStoreGoodsCategoryVos(String storeId, List<GoblinStoreGoodsCategoryVo> vos) {
        return redisUtil.set(GoblinRedisConst.BASIC_STORE_GOODS_CATEGORY.concat(storeId), JsonUtils.toJson(vos));
    }

    public List<GoblinStoreGoodsCategoryVo> getStoreGoodsCategoryVos(String storeId) {
        String rk = GoblinRedisConst.BASIC_STORE_GOODS_CATEGORY.concat(storeId);
        String valStr = (String) redisUtil.get(rk);
        boolean valStrIsEmptyFlg = StringUtils.isEmpty(valStr);
        List<GoblinStoreGoodsCategoryVo> vos = null;
        if (valStrIsEmptyFlg && !CollectionUtils.isEmpty(vos = goblinMongoUtils.getStoreGoodsCategoryVos(storeId))) {
            valStr = JsonUtils.toJson(vos);
            redisUtil.set(rk, valStr);
        } else if (!valStrIsEmptyFlg) {
            vos = JsonUtils.fromJson(valStr, new TypeReference<List<GoblinStoreGoodsCategoryVo>>() {
            });
        }
        return vos;
    }

    /* ---------------------------------------- 平台分类规格数据源 ---------------------------------------- */

    public boolean setCategorySpec(String cateId, GoblinMgtCategorySpecVo vo) {
        return redisUtil.set(GoblinRedisConst.BASIC_SELF_GOODS_CATEGORY_SPEC.concat(cateId), vo);
    }

    public GoblinMgtCategorySpecVo getCategorySpec(String cateId) {
        String rk = GoblinRedisConst.BASIC_SELF_GOODS_CATEGORY_SPEC.concat(cateId);
        GoblinMgtCategorySpecVo vo = (GoblinMgtCategorySpecVo) redisUtil.get(rk);
        if (null == vo && null != (vo = goblinMongoUtils.getCategorySpecVo(cateId))) {
            redisUtil.set(rk, vo);
        }
        return vo;
    }

    /* ---------------------------------------- 服务支持数据源 ---------------------------------------- */

    public List<GoblinServiceSupportVo> getServiceSupportVos() {
        String valStr = (String) redisUtil.get(GoblinRedisConst.BASIC_SERVICE_SUPPORT);
        boolean valStrIsEmptyFlg = StringUtils.isEmpty(valStr);
        List<GoblinServiceSupportVo> vos;
        if (valStrIsEmptyFlg) {
            if (!CollectionUtils.isEmpty(vos = goblinMongoUtils.getMgtServiceSupportVos())) {
                redisUtil.set(GoblinRedisConst.BASIC_SERVICE_SUPPORT, JsonUtils.toJson(vos));
            }
        } else {
            vos = JsonUtils.fromJson(valStr, new TypeReference<List<GoblinServiceSupportVo>>() {
            });
        }
        return vos;
    }

    /* ---------------------------------------- 店铺公告数据源 ---------------------------------------- */

    public GoblinStoreNoticeVo getStoreNoticeVo(String storeId, LocalDateTime nowTime) {
        List<GoblinStoreNoticeVo> noticeVos = this.getStoreNoticeVos(storeId, nowTime);
        int size = noticeVos.size();
        for (int i = size - 1; i >= 0; i--) {
            GoblinStoreNoticeVo noticeVo = noticeVos.get(i);
            if (noticeVo.getReleaseTime().isBefore(nowTime)) {
                noticeVos.removeIf(r -> (
                        (r.getLongLasting().equals("0") && r.getCancellTime().isBefore(nowTime))
                                || r.getReleaseTime().isBefore(noticeVo.getReleaseTime())
                ));
                this.setStoreNoticeVos(storeId, noticeVos);
                return noticeVo;
            }
        }
        return null;
    }

    public List<GoblinStoreNoticeVo> getStoreNoticeVos(String storeId, LocalDateTime nowTime) {
        String rk = GoblinRedisConst.STORE_NOTICE.concat(storeId);
        List<GoblinStoreNoticeVo> vos = (List<GoblinStoreNoticeVo>) redisUtil.get(rk);
        if (CollectionUtils.isEmpty(vos) && !CollectionUtils.isEmpty(vos = goblinMongoUtils.getStoreNoticeVos(storeId, nowTime))) {
//            redisUtil.set(rk, vos);
        }
        return vos;
    }

    public boolean setStoreNoticeVos(String storeId, List<GoblinStoreNoticeVo> vos) {
        return redisUtil.set(GoblinRedisConst.STORE_NOTICE.concat(storeId), vos);
    }

    /* ---------------------------------------- 店铺配置数据源 ---------------------------------------- */

    public List<GoblinStoreConfigVo> getStoreConfigVos(String storeId) {
        String rk = GoblinRedisConst.BASIC_STORE_CONF.concat(storeId);
        List<GoblinStoreConfigVo> vos = (List<GoblinStoreConfigVo>) redisUtil.get(rk);
        if (CollectionUtils.isEmpty(vos) && !CollectionUtils.isEmpty(vos = goblinMongoUtils.getStoreConfigVos(storeId))) {
            redisUtil.set(rk, vos);
        }
        return vos;
    }

    public boolean setStoreConfigVos(String storeId, List<GoblinStoreConfigVo> vos) {
        return redisUtil.set(GoblinRedisConst.BASIC_STORE_CONF.concat(storeId), vos);
    }

    public void delStoreConfigVos(String storeId) {
        redisUtil.del(GoblinRedisConst.BASIC_STORE_CONF.concat(storeId));
    }


    /* ---------------------------------------- 店铺ERP配置数据源 ---------------------------------------- */

    public GoblinStoreErpConfigVo getStoreErpConfigVoByStoreId(String storeId) {
        String rk = GoblinRedisConst.BASIC_STORE_ERP_CONF.concat(storeId);
        GoblinStoreErpConfigVo vo = (GoblinStoreErpConfigVo) redisUtil.get(rk);
        if (null == vo && null != (vo = goblinMongoUtils.getStoreErpConfigVo(storeId))) {
            redisUtil.set(rk, vo);
        }
        return vo;
    }

    public void delStoreErpConfigVo(String storeId) {
        redisUtil.del(GoblinRedisConst.BASIC_STORE_ERP_CONF.concat(storeId));
    }

    public List<String> getStoreErpShopNoList() {
        List<String> storeErpShopNoList = (List<String>) redisUtil.get(GoblinRedisConst.BASIC_STORE_ERPS);
        if (CollectionUtils.isEmpty(storeErpShopNoList) && !CollectionUtils.isEmpty(storeErpShopNoList = goblinMongoUtils.getStoreErpShopNoList())) {
            redisUtil.set(GoblinRedisConst.BASIC_STORE_ERPS, storeErpShopNoList);
        }
        return storeErpShopNoList;
    }

    public void delStoreErpShopNoList() {
        redisUtil.del(GoblinRedisConst.BASIC_STORE_ERPS);
    }

    /* ---------------------------------------- 店铺数据源 ---------------------------------------- */

    private boolean setStoreIds(String uid, List<String> storeIds) {
        return redisUtil.set(GoblinRedisConst.BASIC_USTORE.concat(uid), storeIds);
    }

    public boolean addStoreId(String uid, String storeId) {
        List<String> storeIds = this.getStoreIds(uid);
        if (CollectionUtils.isEmpty(storeIds)) {
            storeIds = CollectionUtil.arrayListString();
        }
        storeIds.add(storeId);
        return this.setStoreIds(uid, storeIds);
    }

    public void delStoreIds(String uid) {
        redisUtil.del(GoblinRedisConst.BASIC_USTORE.concat(uid));
    }

    public void delStoreId(String uid, String storeId) {
        List<String> storeIds = this.getStoreIds(uid);
        if (!CollectionUtils.isEmpty(storeIds)) {
            storeIds.removeIf(r -> r.equals(storeId));
            this.setStoreIds(uid, storeIds);
        }
    }

    public List<String> getStoreIds(String uid) {
//        List<String> list = (List<String>) redisUtil.get(GoblinRedisConst.BASIC_USTORE.concat(uid));
//        return CollectionUtils.isEmpty(list) ? Arrays.asList("1") : list;
        return (List<String>) redisUtil.get(GoblinRedisConst.BASIC_USTORE.concat(uid));
    }

    public boolean hasStoreId(String uid, String storeId) {
        List<String> list = this.getStoreIds(uid);
        return !CollectionUtils.isEmpty(list) && list.contains(storeId);
    }

    public boolean setStoreInfoVo(GoblinStoreInfoVo vo) {
        List<String> storeIds = this.getStoreIds(vo.getUid());
        if (CollectionUtils.isEmpty(storeIds)) {
            storeIds = CollectionUtil.arrayListString();
        }
        storeIds.add(vo.getStoreId());
        this.setStoreIds(vo.getUid(), storeIds);
        return redisUtil.set(GoblinRedisConst.BASIC_STORE.concat(vo.getStoreId()), vo);
    }

    public void delStoreInfoVo(String storeId) {
        redisUtil.del(GoblinRedisConst.BASIC_STORE.concat(storeId));
    }

    public GoblinStoreInfoVo getStoreInfoVo(String storeId) {
        String rk = GoblinRedisConst.BASIC_STORE.concat(storeId);
        GoblinStoreInfoVo vo = (GoblinStoreInfoVo) redisUtil.get(rk);
        if (null == vo && null != (vo = goblinMongoUtils.getStoreInfoVo(storeId))) {
            redisUtil.set(rk, vo);
        }
        return vo;
    }

    public GoblinStoreInfoVo getStoreInfoVoByUid(String uid) {
        List<String> storeIds = this.getStoreIds(uid);
        GoblinStoreInfoVo storeInfoVo = null;
        if (CollectionUtils.isEmpty(storeIds)) {
            List<GoblinStoreInfoVo> vos = goblinMongoUtils.getStoreInfoVoByUid(uid);
            if (!CollectionUtils.isEmpty(vos)) {
                storeIds = CollectionUtil.arrayListString();
                for (GoblinStoreInfoVo vo : vos) {
                    storeIds.add(vo.getStoreId());
                }
                this.setStoreIds(uid, storeIds);
                storeInfoVo = vos.get(0);
            }
        } else {
            storeInfoVo = this.getStoreInfoVo(storeIds.get(0));
        }
        return storeInfoVo;
    }

    /* ---------------------------------------- 商品数据源 ---------------------------------------- */

    public boolean setGoodsInfoVo(GoblinGoodsInfoVo vo) {
        return redisUtil.set(GoblinRedisConst.BASIC_GOODS.concat(vo.getSpuId()), vo);
    }

    public void delGoodsInfoVo(String spuId) {
        redisUtil.del(GoblinRedisConst.BASIC_GOODS.concat(spuId));
    }

    public void delGoodsInfoVoByUnShelves(String spuId) {
        redisUtil.del(GoblinRedisConst.BASIC_GOODS_UNSHELVES.concat(spuId));
    }

    /**
     * 商品基础信息
     *
     * @param spuId 商品ID
     * @return GoblinGoodsInfoVo
     */
    public GoblinGoodsInfoVo getGoodsInfoVo(String spuId) {
        String pre = GoblinStatusConst.MarketPreStatus.getPre(spuId);
        if (pre != null && pre.equals(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue())) {
            String[] spuSplitArr = spuId.split(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue());
            String rk = GoblinRedisConst.BASIC_GOODS.concat(spuSplitArr[0]);
            GoblinGoodsInfoVo vo = (GoblinGoodsInfoVo) redisUtil.get(rk);
            if (null == vo && null != (vo = goblinMongoUtils.getGoodsInfoVo(spuId))) {
                redisUtil.set(rk, vo);
            }
            if (vo == null) {
                return vo;
            }
            String marketrk = GoblinRedisConst.BASIC_GOODS.concat(spuId);
            GoblinGoodsInfoVo marketVo = (GoblinGoodsInfoVo) redisUtil.get(marketrk);
            if (null == marketVo && null != (marketVo = goblinMongoUtils.getGoodsInfoVo(spuId))) {
                redisUtil.set(marketrk, marketVo);
            }
            if (marketVo == null) {
                return marketVo;
            }
            vo.setSpuId(marketVo.getSpuId());
            List<String> skuIdList = CollectionUtil.linkedListString();
            for (String skuIds : vo.getSkuIdList()) {
                skuIdList.add(skuIds.concat(pre).concat(spuSplitArr[1]));
            }
            vo.setSkuIdList(skuIdList);
            vo.setPriceGe(marketVo.getPriceGe());
            vo.setPriceLe(marketVo.getPriceLe());
            vo.setMarketId(marketVo.getMarketId());
            vo.setDelFlg(marketVo.getDelFlg().equals("1") ? marketVo.getDelFlg() : vo.getDelFlg());
            return vo;
        } else {
            String rk = GoblinRedisConst.BASIC_GOODS.concat(spuId);
            GoblinGoodsInfoVo vo = (GoblinGoodsInfoVo) redisUtil.get(rk);
            if (null == vo && null != (vo = goblinMongoUtils.getGoodsInfoVo(spuId))) {
                redisUtil.set(rk, vo);
            }
            return vo;
        }
    }

    public GoblinGoodsInfoVo getGoodsInfoVoByUnShelves(String spuId) {
        String pre = GoblinStatusConst.MarketPreStatus.getPre(spuId);
        if (pre != null && pre.equals(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue())) {
            String[] spuSplitArr = spuId.split(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue());
            String rk = GoblinRedisConst.BASIC_GOODS_UNSHELVES.concat(spuSplitArr[0]);
            GoblinGoodsInfoVo vo = (GoblinGoodsInfoVo) redisUtil.get(rk);
            if (null == vo && null != (vo = goblinMongoUtils.getGoodsInfoVo(spuId))) {
                redisUtil.set(rk, vo);
            }
            if (vo == null) {
                return vo;
            }
            String marketrk = GoblinRedisConst.BASIC_GOODS_UNSHELVES.concat(spuId);
            GoblinGoodsInfoVo marketVo = (GoblinGoodsInfoVo) redisUtil.get(marketrk);
            if (null == marketVo && null != (marketVo = goblinMongoUtils.getGoodsInfoVo(spuId))) {
                redisUtil.set(marketrk, marketVo);
            }
            if (marketVo == null) {
                return marketVo;
            }
            vo.setSpuId(marketVo.getSpuId());
            List<String> skuIdList = CollectionUtil.linkedListString();
            for (String skuIds : vo.getSkuIdList()) {
                skuIdList.add(skuIds.concat(pre).concat(spuSplitArr[1]));
            }
            vo.setSkuIdList(skuIdList);
            vo.setPriceGe(marketVo.getPriceGe());
            vo.setPriceLe(marketVo.getPriceLe());
            vo.setMarketId(marketVo.getMarketId());
            return vo;
        } else {
            String rk = GoblinRedisConst.BASIC_GOODS_UNSHELVES.concat(spuId);
            GoblinGoodsInfoVo vo = (GoblinGoodsInfoVo) redisUtil.get(rk);
            if (null == vo && null != (vo = goblinMongoUtils.getGoodsInfoVo(spuId))) {
                redisUtil.set(rk, vo);
            }
            return vo;
        }
    }

    public boolean setGoodsSkuInfoVo(GoblinGoodsSkuInfoVo vo) {
        return redisUtil.set(GoblinRedisConst.BASIC_GOODS_SKU.concat(vo.getSkuId()), vo);
    }

    public void delGoodsSkuInfoVo(String skuId) {
        redisUtil.del(GoblinRedisConst.BASIC_GOODS_SKU.concat(skuId));
    }

    public void delGoodsSkuInfoVoByUnShelves(String skuId) {
        redisUtil.del(GoblinRedisConst.BASIC_GOODS_SKU_UNSHELVES.concat(skuId));
    }

    /**
     * 单品信息
     *
     * @param skuId 单品ID
     * @return GoblinGoodsSkuInfoVo
     */
    public GoblinGoodsSkuInfoVo getGoodsSkuInfoVo(String skuId) {
        String pre = GoblinStatusConst.MarketPreStatus.getPre(skuId);
        if (pre != null && pre.equals(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue())) {

            String rk = GoblinRedisConst.BASIC_GOODS_SKU.concat(skuId.split(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue())[0]);
            GoblinGoodsSkuInfoVo vo = (GoblinGoodsSkuInfoVo) redisUtil.get(rk);
            if (null == vo && null != (vo = goblinMongoUtils.getGoodsSkuInfoVo(skuId))) {
                redisUtil.set(rk, vo);
            }
            if (vo == null) {
                return vo;
            }
            String marketrk = GoblinRedisConst.BASIC_GOODS_SKU.concat(skuId);
            GoblinGoodsSkuInfoVo marketVo = (GoblinGoodsSkuInfoVo) redisUtil.get(marketrk);
            if (null == marketVo && null != (marketVo = goblinMongoUtils.getGoodsSkuInfoVo(skuId))) {
                redisUtil.set(marketrk, marketVo);
            }
            if (marketVo == null) {
                return marketVo;
            }

            vo.setSpuId(marketVo.getSpuId());
            vo.setSkuId(marketVo.getSkuId());
            vo.setPrice(marketVo.getPrice());
            vo.setPriceMember(marketVo.getPriceMember());
            vo.setSkuStock(marketVo.getSkuStock());
            vo.setBuyLimit(marketVo.getBuyLimit());
            vo.setBuyRoster(marketVo.getBuyRoster());
            vo.setBuyFactor(marketVo.getBuyFactor());
//            vo.setDelFlg("0");
            vo.setDelFlg(marketVo.getDelFlg().equals("1") ? marketVo.getDelFlg() : vo.getDelFlg());
            vo.setMarketId(marketVo.getMarketId());
            vo.setCreatedAt(LocalDateTime.now());
            return vo;
        } else {
            String rk = GoblinRedisConst.BASIC_GOODS_SKU.concat(skuId);
            GoblinGoodsSkuInfoVo vo = (GoblinGoodsSkuInfoVo) redisUtil.get(rk);
            if (null == vo && null != (vo = goblinMongoUtils.getGoodsSkuInfoVo(skuId))) {
                redisUtil.set(rk, vo);
            }
            return vo;
        }
    }

    /**
     * 获取 包含分段购的sku详情 HASHMAP
     *
     * @param now   当前时间
     * @param skuId skuId
     * @return
     */
    public HashMap<String, Object> getGoodsSkuInfoVo(LocalDateTime now, String skuId) {
        GoblinGoodsSkuInfoVo vo = getGoodsSkuInfoVo(skuId);
        if (null == vo) {
            return null;
        }
        GoblinListCollectVo firstCollectVo = getCollectByFirst(skuId);
        HashMap<String, Object> map = CollectionUtil.mapStringObject();
        LocalDateTime nextSaleStartTime = null;
        if (null == vo.getSaleStartTime() || now.isAfter(vo.getSaleStartTime())) {//普通商品已开售
            map.put("vo", vo);
            map.put("tagType", null);
            map.put("listId", null);
            map.put("whiteType", null);
            map.put("baseSaleStartTime", vo.getSaleStartTime());
            map.put("nextSaleStartTime", null);
        } else {//未开售
            GoblinListCollectVo collectVo = getCollectByNow(now, skuId);
            Integer tagType = null;
            Integer whiteType = null;
            String listId = null;
            LocalDateTime baseSaleStartTime = vo.getSaleStartTime();
            if (collectVo != null) {
                vo.setPrice(collectVo.getPrice());
                vo.setPriceV(collectVo.getPriceV());
                vo.setProductId(collectVo.getProductId());
                vo.setSaleStartTime(collectVo.getTimeStart());
                vo.setSaleStopTime(collectVo.getTimeEnd());
                listId = collectVo.getListId();
                whiteType = collectVo.getWhiteType();
                tagType = collectVo.getTagType();
            }
            GoblinListCollectVo collectNext = getCollectByNowNext(now, skuId);
            if (collectNext != null) {
                if (tagType == null) {
                    tagType = collectNext.getTagType();
                }
                //todo 逻辑修改 开售时间
                if (collectVo == null) {
                    vo.setSaleStartTime(collectNext.getTimeStart());
                    vo.setSaleStopTime(collectNext.getTimeEnd());
                }
                nextSaleStartTime = collectNext.getTimeStart();
            }
            map.put("vo", vo);
            map.put("tagType", tagType);
            map.put("listId", listId);
            map.put("whiteType", whiteType);
            map.put("baseSaleStartTime", baseSaleStartTime);
            map.put("nextSaleStartTime", nextSaleStartTime);
        }
        if (firstCollectVo != null) {
            map.put("firstSaleStartTime", firstCollectVo.getTimeStart());
            map.put("firstSaleEndTime", firstCollectVo.getTimeEnd());
        } else {
            map.put("firstSaleStartTime", null);
            map.put("firstSaleEndTime", null);
        }
        return map;
    }

    /**
     * 根据时间获取当前分段购vo
     *
     * @param now
     * @param skuId
     * @return
     */
    public GoblinListCollectVo getCollectByNow(LocalDateTime now, String skuId) {
        GoblinListCollectVo collectVo = null;
        GoblinListCollectVo collectTemp = null;
        List<GoblinListCollectVo> collectVos = getGoblinListCollect(skuId);
        for (int i = 0; i < collectVos.size(); i++) {
            GoblinListCollectVo collectVoItem = collectVos.get(i);
            if (now.isAfter(collectVoItem.getTimeStart()) && collectVoItem.getTimeEnd() == null) {
                if (collectTemp == null || collectTemp.getTimeStart().isBefore(collectVoItem.getTimeStart())) {
                    collectTemp = collectVoItem;
                }
            } else if (now.isAfter(collectVoItem.getTimeStart()) && now.isBefore(collectVoItem.getTimeEnd())) {
                collectVo = collectVoItem;
                break;
            } else if (collectVoItem.getTimeEnd() != null && now.isAfter(collectVoItem.getTimeEnd())) {
                collectTemp = null;
            }
        }
        if (collectVo == null) {
            collectVo = collectTemp;
        }
        return collectVo;
    }

    /**
     * 分批购nft库存回滚
     *
     * @param now
     * @param skuId
     * @return
     */
    public void goblinNftListStock(LocalDateTime now, String skuId, LocalDateTime saleStartTime) {
        GoblinListCollectVo collectVo = null;
        GoblinListCollectVo collectTemp = null;
        List<GoblinListCollectVo> collectVos = getGoblinListCollect(skuId);
        if (now.isAfter(saleStartTime)) {
            lastStockToLastStock(0, collectVos, null, skuId);
        } else {
            for (int i = 0; i < collectVos.size(); i++) {
                GoblinListCollectVo collectVoItem = collectVos.get(i);
                if (now.isAfter(collectVoItem.getTimeStart()) && collectVoItem.getTimeEnd() == null) {
                    if (collectTemp == null || collectTemp.getTimeStart().isBefore(collectVoItem.getTimeStart())) {
                        collectTemp = collectVoItem;
                    }
                } else if (now.isAfter(collectVoItem.getTimeStart()) && now.isBefore(collectVoItem.getTimeEnd())) {
                    collectVo = collectVoItem;
                    break;
                } else if (collectVoItem.getTimeEnd() != null && now.isAfter(collectVoItem.getTimeEnd())) {
                    collectTemp = null;
                }
            }
            if (collectVo == null) {
                collectVo = collectTemp;
            }
            if (collectVo == null) {
                GoblinListCollectVo collectNext = getCollectByNowNext(now, skuId);
                if (collectNext == null) {
                    lastStockToLastStock(0, collectVos, null, skuId);
                } else {
                    lastStockToLastStock(1, collectVos, collectNext, skuId);
                }
            } else {
                lastStockToLastStock(1, collectVos, collectVo, skuId);
            }
        }
//        return collectVo;
    }

    /**
     * 根据时间获取当前分段购vo 如果当前没有返回下一个
     *
     * @param now
     * @param skuId
     * @return
     */
    public GoblinListCollectVo getCollectByNowNext(LocalDateTime now, String skuId) {
        GoblinListCollectVo collectVo = null;
        GoblinListCollectVo collectTemp = null;
        GoblinListCollectVo collectNext = null;
        List<GoblinListCollectVo> collectVos = getGoblinListCollect(skuId);
        for (int i = 0; i < collectVos.size(); i++) {
            GoblinListCollectVo collectVoItem = collectVos.get(i);
            if (now.isAfter(collectVoItem.getTimeStart()) && collectVoItem.getTimeEnd() == null) {
                if (collectTemp == null || collectTemp.getTimeStart().isBefore(collectVoItem.getTimeStart())) {
                    collectTemp = collectVoItem;
                }
            } else if (now.isAfter(collectVoItem.getTimeStart()) && now.isBefore(collectVoItem.getTimeEnd())) {
                collectVo = collectVoItem;
            } else if (now.isBefore(collectVoItem.getTimeStart())) {
                if (collectNext == null || collectNext.getTimeStart().isAfter(collectNext.getTimeStart())) {
                    collectNext = collectVoItem;
                }
            } else if (collectVoItem.getTimeEnd() != null && now.isAfter(collectVoItem.getTimeEnd())) {
                collectTemp = null;
            }
        }
//        if (collectVo == null && collectTemp != null) {
//            collectVo = collectTemp;
//        } else
//        if (collectVo == null) {
//            collectVo = collectNext;
//        }
//        return collectVo;
        return collectNext;
    }


    public GoblinListCollectVo getCollectByFirst(String skuId) {
        GoblinListCollectVo vo = null;
        List<GoblinListCollectVo> collectVos = getGoblinListCollect(skuId);
        for (int i = 0; i < collectVos.size(); i++) {
            GoblinListCollectVo collectVoItem = collectVos.get(i);
            if (vo == null) {
                vo = collectVoItem;
            }
            if (collectVoItem.getTimeStart().isBefore(vo.getTimeStart())) {
                vo = collectVoItem;
            }
        }
        return vo;
    }

    /**
     * 处理上个时间段的库存
     *
     * @param type       类型[0-开售|1-未开售]
     * @param collectVos
     * @param vo
     * @param skuId
     */
    public void lastStockToLastStock(Integer type, List<GoblinListCollectVo> collectVos, GoblinListCollectVo vo, String skuId) {
        if (vo == null && type == 0) {//已开售逻辑
            for (GoblinListCollectVo collectVoItem : collectVos) {
                List<String> skuIds = getGoblinListRelationBox(skuId, collectVoItem.getListId());
                int lastStock;
                if (skuIds.size() > 0) {//盲盒逻辑
                    for (String skuIdItem : skuIds) {
                        lastStock = getSkuStock(collectVoItem.getListId(), skuIdItem);
                        log.debug("all stock = " + lastStock);
                        int restStock = decrSkuStock(collectVoItem.getListId(), skuIdItem, lastStock);
                        if (restStock < 0) {
                            incrSkuStock(collectVoItem.getListId(), skuIdItem, lastStock);
                        } else {
                            incrSkuStock(null, skuIdItem, lastStock);
                        }
                    }
                } else {
                    lastStock = getSkuStock(collectVoItem.getListId(), skuId);
                    log.debug("all stock = " + lastStock);
                    int restStock = decrSkuStock(collectVoItem.getListId(), skuId, lastStock);
                    if (restStock < 0) {
                        incrSkuStock(collectVoItem.getListId(), skuId, lastStock);
                    } else {
                        incrSkuStock(null, skuId, lastStock);
                    }
                }
            }
        } else if (vo != null && type == 1) {
            LocalDateTime st = vo.getTimeStart();
            //获取上个分配购的vo
            List<GoblinListCollectVo> collectVosList = ObjectUtil.getGoblinListCollectVo();
            for (GoblinListCollectVo collectVoItem : collectVos) {
                if (st.isAfter(collectVoItem.getTimeStart()) && collectVoItem.getTimeEnd() == null) {
//                    collectTemp = collectVoItem;
                    collectVosList.add(collectVoItem);
                } else if (collectVoItem.getTimeEnd() != null && st.isAfter(collectVoItem.getTimeEnd())) {
//                    collectVo = collectVoItem;
                    collectVosList.add(collectVoItem);
                } else if (st.isAfter(collectVoItem.getTimeStart()) && st.isBefore(collectVoItem.getTimeEnd())) {
//                    collectVo = collectVoItem;
                    collectVosList.add(collectVoItem);
                    break;
                }
            }
            for (GoblinListCollectVo itemVo : collectVosList) {
                int lastStock;
                List<String> skuIds = getGoblinListRelationBox(skuId, itemVo.getListId());
                if (skuIds.size() > 0) {//盲盒逻辑
                    for (String skuIdItem : skuIds) {
                        lastStock = getSkuStock(itemVo.getListId(), skuIdItem);
                        log.debug("temp stock = " + lastStock);
                        int restStock = decrSkuStock(itemVo.getListId(), skuIdItem, lastStock);
                        if (restStock < 0) {
                            incrSkuStock(itemVo.getListId(), skuIdItem, lastStock);
                        } else {
                            incrSkuStock(vo.getListId(), skuIdItem, lastStock);
                        }
                    }
                } else {
                    //减少上个时间段sku库存
                    lastStock = getSkuStock(itemVo.getListId(), skuId);
                    log.debug("temp stock = " + lastStock);
                    int restStock = decrSkuStock(itemVo.getListId(), skuId, lastStock);
                    if (restStock < 0) {
                        //库存超过销售量 操作失败回滚库存
                        incrSkuStock(itemVo.getListId(), skuId, lastStock);
                    } else {
                        //上个时间段的库存增加到当前时间段
                        incrSkuStock(vo.getListId(), skuId, lastStock);
                    }
                }
            }
        }
    }

    /**
     * 分批购是否可购买
     *
     * @param listId
     * @param skuId
     * @param mobile
     * @param uid
     * @param whiteType
     * @return
     */
    public Boolean getListCanBuy(String listId, String skuId, String mobile, String uid, Integer whiteType) {
        String rdkB = GoblinRedisConst.REDIS_BLACK.concat(listId + ":").concat(skuId + ":").concat(mobile);
        String rdkW = GoblinRedisConst.REDIS_WHITE.concat(listId + ":").concat(skuId + ":").concat(mobile);
        boolean bResult = redisUtil.hasKey(rdkB);//是否黑名单
        boolean wResult = redisUtil.hasKey(rdkW);//是否白名单
        Integer memberStage = getMember(uid);
        if (bResult) {
            return false;
        }
        if (whiteType == -1) {
            return true;
        } else if (whiteType == 0) {//会员
            return memberStage != null;
        } else {//白名单
            return wResult;
        }
    }

    // 1普通会员 2老会员
    public Integer getMember(String uid) {
        String redisKey = GoblinRedisConst.ADAM_IS_MEMBER
                .concat(uid);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return null;
        } else {
            return (Integer) obj;
        }
    }

    public GoblinGoodsSkuInfoVo getGoodsSkuInfoVoByUnShelves(String skuId) {
        String pre = GoblinStatusConst.MarketPreStatus.getPre(skuId);
        if (pre != null && pre.equals(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue())) {
            String rk = GoblinRedisConst.BASIC_GOODS_SKU_UNSHELVES.concat(skuId.split(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue())[0]);
            GoblinGoodsSkuInfoVo vo = (GoblinGoodsSkuInfoVo) redisUtil.get(rk);
            if (null == vo && null != (vo = goblinMongoUtils.getGoodsSkuInfoVo(skuId))) {
                redisUtil.set(rk, vo);
            }
            if (vo == null) {
                return vo;
            }
            String marketrk = GoblinRedisConst.BASIC_GOODS_SKU_UNSHELVES.concat(skuId);
            GoblinGoodsSkuInfoVo marketVo = (GoblinGoodsSkuInfoVo) redisUtil.get(marketrk);
            if (null == marketVo && null != (marketVo = goblinMongoUtils.getGoodsSkuInfoVo(skuId))) {
                redisUtil.set(marketrk, marketVo);
            }
            if (marketVo == null) {
                return marketVo;
            }

            vo.setSpuId(marketVo.getSpuId());
            vo.setSkuId(marketVo.getSkuId());
            vo.setPrice(marketVo.getPrice());
            vo.setPriceMember(marketVo.getPriceMember());
            vo.setSkuStock(marketVo.getSkuStock());
            vo.setBuyLimit(marketVo.getBuyLimit());
            vo.setBuyRoster(marketVo.getBuyRoster());
            vo.setBuyFactor(marketVo.getBuyFactor());
            vo.setMarketId(marketVo.getMarketId());
            vo.setCreatedAt(LocalDateTime.now());
            return vo;
        } else {
            String rk = GoblinRedisConst.BASIC_GOODS_SKU_UNSHELVES.concat(skuId);
            GoblinGoodsSkuInfoVo vo = (GoblinGoodsSkuInfoVo) redisUtil.get(rk);
            if (null == vo && null != (vo = goblinMongoUtils.getGoodsSkuInfoVo(skuId))) {
                redisUtil.set(rk, vo);
            }
            return vo;
        }
    }

//    public GoblinGoodsSkuInfoVo getMgtGoodsSkuInfoVo(String skuId) {
//        String rk = GoblinRedisConst.BASIC_GOODS_SKU.concat(skuId);
//        GoblinGoodsSkuInfoVo vo = (GoblinGoodsSkuInfoVo) redisUtil.get(rk);
//        if (null == vo && null != (vo = goblinMongoUtils.getMgtGoodsSkuInfoVo(skuId))) {
//            redisUtil.set(rk, vo);
//        }
//        return vo;
//    }


    /* ----------------------------------------  ---------------------------------------- */

    /**
     * 覆盖 商铺活动vo
     *
     * @param storeMarketId
     * @param vo
     * @return
     */
    public boolean setGoblinStoreMarketVo(String storeMarketId, GoblinStoreMarketVo vo) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_STORE_MARKET.concat(storeMarketId);
        return redisUtil.set(redisKey, vo);
    }

    /**
     * 获取 商铺活动vo
     *
     * @param storeMarketId
     * @return
     */
    public GoblinStoreMarketVo getGoblinStoreMarketVo(String storeMarketId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_STORE_MARKET.concat(storeMarketId);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            GoblinStoreMarketVo vo = goblinMongoUtils.getStoreMarket(storeMarketId);
            setGoblinStoreMarketVo(storeMarketId, vo);
            return vo;
        } else {
            return (GoblinStoreMarketVo) obj;
        }
    }

    /**
     * 删除 商铺活动vo
     *
     * @param storeMarketId
     * @return
     */
    public void delGoblinStoreMarketVo(String storeMarketId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_STORE_MARKET.concat(storeMarketId);
        redisUtil.del(redisKey);
    }


    /**
     * 获取 配置的商铺id
     *
     * @param marketId
     * @param storeId
     */
    public List<GoblinStoreMarketIsConfigVo> getStoreMarketIsConfig(String marketId, String storeId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_STORE_MARKET_ISCONFIG.concat(marketId).concat(":store_id:" + storeId);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return new ArrayList();
        } else {
            return (List<GoblinStoreMarketIsConfigVo>) obj;
        }
    }

    public void addStoreMarketIsConfig(String marketId, String storeId, String spuId, String marketSpuId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_STORE_MARKET_ISCONFIG.concat(marketId).concat(":store_id:" + storeId);
        List<GoblinStoreMarketIsConfigVo> voList = getStoreMarketIsConfig(marketId, storeId);
        GoblinStoreMarketIsConfigVo vo = GoblinStoreMarketIsConfigVo.getNew();
        vo.setMarketSpuId(marketSpuId);
        vo.setSpuId(spuId);
        voList.add(vo);
        redisUtil.set(redisKey, voList);
    }

    public void delStoreMarketIsConfig(String marketId, String storeId, String spuId, String marketSpuId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_STORE_MARKET_ISCONFIG.concat(marketId).concat(":store_id:" + storeId);
        List<GoblinStoreMarketIsConfigVo> voList = getStoreMarketIsConfig(marketId, storeId);
        for (int i = 0; i < voList.size(); i++) {
            String itemSpuId = voList.get(i).getSpuId();
            if (spuId.equals(itemSpuId)) {
                voList.remove(i);
            }
        }
        redisUtil.set(redisKey, voList);
    }

    /**
     * 添加 活动内商品款式关联关系
     *
     * @param marketPre
     * @param marketId
     * @param vo
     */
    public void addMarketRelation(String marketPre, String marketId, GoblinMarketRelationVo vo) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_MARKET_RELATION.concat(marketPre).concat(marketId);
        List<GoblinMarketRelationVo> voList = getMarketRelation(marketPre, marketId);
        voList.add(vo);
        redisUtil.set(redisKey, voList);
    }

    /**
     * 移除 活动内商品款式关联关系
     *
     * @param marketPre
     * @param marketId
     */
    public void removeMarketRelation(String marketPre, String marketId, String spuId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_MARKET_RELATION.concat(marketPre).concat(marketId);
        List<GoblinMarketRelationVo> voList = getMarketRelation(marketPre, marketId);
        for (GoblinMarketRelationVo item : voList) {
            if (item.getSpuId().equals(spuId)) {
                voList.remove(item);
                break;
            }
        }
        redisUtil.set(redisKey, voList);
    }

    /**
     * 获取 活动内商品款式关联关系
     *
     * @param marketPre
     * @param marketId
     */
    public List<GoblinMarketRelationVo> getMarketRelation(String marketPre, String marketId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_MARKET_RELATION.concat(marketPre).concat(marketId);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return new ArrayList();
        } else {
            return (List<GoblinMarketRelationVo>) obj;
        }
    }

    /**
     * 获取 当前商铺能参与的官方活动id列表
     *
     * @param storeId
     * @return
     */
    public List<String> getStoreZhengzaiRelation(String storeId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_STORE_SELF_RELATION.concat(storeId);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return CollectionUtil.arrayListString();
        } else {
            return (List<String>) obj;
        }
    }

    /**
     * 正在下单 可参加商户关系 详情
     *
     * @param selfMarketId
     * @param storeId
     */
    public GoblinMarketingZhengzaiRelationVo getZhengzaiRelation(String selfMarketId, String storeId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_ZHENGZAI_RELATION.concat(selfMarketId).concat(":store_id:" + storeId);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return null;
        } else {
            return (GoblinMarketingZhengzaiRelationVo) obj;
        }
    }

    /**
     * 正在下单 可参加商户 详情
     *
     * @param selfMarketId
     */
    public GoblinSelfMarketingVo getSelfMarket(String selfMarketId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_SELF_MARKET.concat(selfMarketId);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return null;
        } else {
            return (GoblinSelfMarketingVo) obj;
        }
    }

    //获取全部正在下单的活动
    public List<GoblinSelfMarketingVo> getGoblinSelfMarketingVoList() {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_ZHENGZAI_LIST;
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return goblinMongoUtils.getGoblinSelfMarketingVoList();
        } else {
            return (List<GoblinSelfMarketingVo>) obj;
        }
    }

    //获取 用户sku购买个数
    public Integer getSkuCountByUid(String uid, String skuId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_BUY_COUNT.concat(uid + ":skuId:" + skuId);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return 0;
        } else {
            return (Integer) obj;
        }
    }

    //获取 用户是否可购买
    public boolean getSkuCanBuyByUid(String mobile, String skuId) {
        String redisKey = GoblinRedisConst.REDIS_CAN_BUY.concat(skuId + ":").concat(mobile);
        return redisUtil.hasKey(redisKey);
    }

    // 增加 用户sku购买个数
    public int incrSkuCountByUid(String uid, String skuId, int number) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_BUY_COUNT.concat(uid + ":skuId:" + skuId);
        return (int) redisUtil.incr(redisKey, number);
    }

    // 减少 用户sku购买个数
    public int decrSkuCountByUid(String uid, String skuId, int number) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_BUY_COUNT.concat(uid + ":skuId:" + skuId);
        return (int) redisUtil.decr(redisKey, number);
    }

    //获取 sku销量
    public Integer getSkuSaleCount(String skuId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_SALE_COUNT.concat(skuId);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return null;
        } else {
            return (Integer) obj;
        }
    }

    // 增加 sku销量
    public int incrSkuSaleCount(String spuId, String skuId, int number) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_SALE_COUNT.concat(skuId);
        incrSpuSaleCount(spuId, number);
        return (int) redisUtil.incr(redisKey, number);
    }

    // 减少 sku销量
    public int decrSkuSaleCount(String spuId, String skuId, int number) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_SALE_COUNT.concat(skuId);
        decrSpuSaleCount(spuId, number);
        return (int) redisUtil.decr(redisKey, number);
    }

    //获取 spu销量
    public Integer getSpuSaleCount(String spuId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_SALE_SPU_COUNT.concat(spuId);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return null;
        } else {
            return (Integer) obj;
        }
    }

    // 增加 spu销量
    private int incrSpuSaleCount(String spuId, int number) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_SALE_SPU_COUNT.concat(spuId);
        return (int) redisUtil.incr(redisKey, number);
    }

    // 减少 spu销量
    private int decrSpuSaleCount(String spuId, int number) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_SALE_SPU_COUNT.concat(spuId);
        return (int) redisUtil.decr(redisKey, number);
    }

    // 赋值 订单相关vo
    public void setGoblinOrder(String orderId, GoblinStoreOrderVo vo) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_ORDER.concat(orderId);
        redisUtil.set(redisKey, vo);
    }


    // 赋值 订单相关Skuvo
    public void setGoblinOrderSku(String orderSkuId, GoblinOrderSkuVo vo) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_ORDER_SKU.concat(orderSkuId);
        redisUtil.set(redisKey, vo);
    }

    // 赋值 快递vo
    public void addGoblinMail(String orderId, GoblinMailVo vo) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_MAIL.concat(orderId);
        List<GoblinMailVo> list = getGoblinMail(orderId);
        list.add(vo);
        redisUtil.set(redisKey, list);
    }

    // 修改 快递vo
    public void changeGoblinMail(String orderId, GoblinMailVo vo) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_MAIL.concat(orderId);
        List<GoblinMailVo> list = getGoblinMail(orderId);
        for (GoblinMailVo item : list) {
            if (item.getMailId().equals(vo.getMailId())) {
                item.setMailNo(vo.getMailNo());
                break;
            }
        }
        redisUtil.set(redisKey, list);
    }

    // 获取 快递vo
    public List<GoblinMailVo> getGoblinMail(String orderId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_MAIL.concat(orderId);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return ObjectUtil.goblinMailVo();
        } else {
            return (List<GoblinMailVo>) obj;
        }
    }

    //获取累计充值金额
    public BigDecimal getRechargeAmount(String uid) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_RECHARGE_RECORD.concat(uid);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return BigDecimal.ZERO;
        } else {
            return new BigDecimal(obj.toString());
        }
    }
    // 减少充值金额
    public double decrRechargeRecord(String uid,double amount) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_RECHARGE_RECORD.concat(uid);
        return redisUtil.decrDouble(uid,amount);
    }


    // 获取 订单相关vo
    public GoblinStoreOrderVo getGoblinOrder(String orderId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_ORDER.concat(orderId);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return null;
        } else {
            return (GoblinStoreOrderVo) obj;
        }
    }

    // 获取 nft订单相关vo
    public GoblinNftOrderVo getGoblinNftOrder(String orderId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_NFT_ORDER_INFO.concat(orderId);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return null;
        } else {
            return (GoblinNftOrderVo) obj;
        }
    }

    // 缓存 nft订单相关vo
    public boolean setGoblinNftOrder(GoblinNftOrderVo vo) {
        return redisUtil.set(GoblinRedisConst.REDIS_GOBLIN_NFT_ORDER_INFO.concat(vo.getOrderId()), vo);
    }

    // 获取 订单相关Skuvo
    public GoblinOrderSkuVo getGoblinOrderSkuVo(String orderSkuId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_ORDER_SKU.concat(orderSkuId);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return null;
        } else {
            return (GoblinOrderSkuVo) obj;
        }
    }

    // 获取 未支付订单id列表
    public List<String> getUnPayOrder(String randomKey) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_ORDER_UN_PAY.concat(randomKey);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return CollectionUtil.arrayListString();
        } else {
            return (List<String>) obj;
        }
    }

    // 添加 未支付订单id列表 返回 radomKey
    public int addUnPayOrder(String orderId) {
        int randomKey = RandomUtil.getRandomInt(0, randomMax);
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_ORDER_UN_PAY.concat(randomKey + "");
        List<String> list = getUnPayOrder(randomKey + "");
        list.add(orderId);
        redisUtil.set(redisKey, list);
        return randomKey;
    }

    // 删除 未支付订单id列表
    public void removeGoblinOrder(String randomKey, String orderId) {
        if (randomKey == null) {
            for (int i = 0; i < randomMax; i++) {
                randomKey = i + "";
                String redisKey = GoblinRedisConst.REDIS_GOBLIN_ORDER_UN_PAY.concat(randomKey);
                List<String> list = getUnPayOrder(randomKey);
                if (list.contains(orderId)) {
                    list.remove(orderId);
                    redisUtil.set(redisKey, list);
                    break;
                }
            }
        } else {
            String redisKey = GoblinRedisConst.REDIS_GOBLIN_ORDER_UN_PAY.concat(randomKey + "");
            List<String> list = getUnPayOrder(randomKey);
            list.remove(orderId);
            redisUtil.set(redisKey, list);
        }
    }

    // 获取 订单id列表
    public List<String> getOrderList(String uid) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_ORDER_LIST.concat(uid);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return CollectionUtil.arrayListString();
        } else {
            return (List<String>) obj;
        }
    }

    // 获取 nft订单id列表
    public List<String> getNftOrderList(String uid) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_NFT_ORDER_USER_ID_LIST.concat(uid);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return CollectionUtil.arrayListString();
        } else {
            return (List<String>) obj;
        }
    }

    // 添加 订单id列表
    public void addOrderList(String uid, String orderId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_ORDER_LIST.concat(uid);
        List<String> list = getOrderList(uid);
        list.add(orderId);
        redisUtil.set(redisKey, list);
    }

    // 删除 订单id列表
    public void removeOrderList(String uid, String orderId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_ORDER_LIST.concat(uid);
        List<String> list = getOrderList(uid);
        list.remove(orderId);
        redisUtil.set(redisKey, list);
    }

    // 获取 订单id列表
    public List<String> getZhengzaiOrderList(String uid) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_ORDER_ZHENGZAI_LIST.concat(uid);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return CollectionUtil.arrayListString();
        } else {
            return (List<String>) obj;
        }
    }

    // 添加 订单id列表
    public void addZhengzaiOrderList(String uid, String orderId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_ORDER_ZHENGZAI_LIST.concat(uid);
        List<String> list = getZhengzaiOrderList(uid);
        list.add(orderId);
        redisUtil.set(redisKey, list);
    }

    // 删除 订单id列表
    public void removeZhengzaiOrderList(String uid, String orderId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_ORDER_ZHENGZAI_LIST.concat(uid);
        List<String> list = getZhengzaiOrderList(uid);
        list.remove(orderId);
        redisUtil.set(redisKey, list);
    }


    public String[] getMasterCode(String masterCode) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_ORDER_MASTER.concat(masterCode);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return null;
        } else {
            return ((String) obj).split(",");
        }
    }

    public HashMap<String, String[]> getMixMasterCode(String masterCode) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_ORDER_MIX_MASTER.concat(masterCode);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return null;
        } else {
            String[] a = ((String) obj).split("&&");
            String[] nftA = CollectionUtil.stringArray();
            String[] goblinA = CollectionUtil.stringArray();
            if (a.length > 0) {
                nftA = a[0].split(",");
            }
            if (a.length > 1) {
                goblinA = a[1].split(",");
            }
            HashMap<String, String[]> map = ObjectUtil.mixIdMap();
            map.put("nft", nftA);
            map.put("goblin", goblinA);
            return map;
        }
    }

    //主订单对应的出货吗
    public void setOffCode(String writeOffCode, String masterCode) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_ORDER_OFFCODE.concat(writeOffCode);
        redisUtil.set(redisKey, masterCode);
    }

    public String[] getOffCode(String writeOffCode) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_ORDER_OFFCODE.concat(writeOffCode);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return null;
        } else {
            return getMasterCode((String) obj);
        }
    }

    //覆盖 退款订单vo
    public void setBackOrderVo(String backOrderId, GoblinBackOrderVo vo) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_ORDER_BACK.concat(backOrderId);
        redisUtil.set(redisKey, vo);
    }

    //覆盖 获取订单vo
    public GoblinBackOrderVo getBackOrderVo(String backOrderId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_ORDER_BACK.concat(backOrderId);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return null;
        } else {
            return (GoblinBackOrderVo) obj;
        }
    }

    // 获取 订单id下的退款订单id
    public List<String> getBackOrderByOrderId(String orderId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_BACK_ORDER_ID.concat(orderId);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return CollectionUtil.arrayListString();
        } else {
            return (List<String>) obj;
        }
    }

    // 添加 订单id下的退款订单id
    public void addBackOrderByOrderId(String orderId, String backOrderId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_BACK_ORDER_ID.concat(orderId);
        List<String> list = getBackOrderByOrderId(orderId);
        list.add(backOrderId);
        redisUtil.set(redisKey, list);
    }

    //商品上架、下架、删除 调用的方法
    public void deleteKeyForSelectGoods() {
        redisUtil.del(GoblinRedisConst.SELECT_GOODS_SPUIDS);
        redisUtil.del(GoblinRedisConst.SELECT_GOODS_PAGE1);
        redisUtil.del(GoblinRedisConst.SELECT_GOODS_SPUIDS_ISHAVE);
    }

    // banner 降级
    public List<GoblinFrontBanner> getListBanner() {
        List<GoblinFrontBanner> vo = (List<GoblinFrontBanner>) redisUtil.get(GoblinRedisConst.FRONT_TOP_BANNER);
        if (null == vo) {
            //降级
            return goblinMongoUtils.getListBanner();
        }
        return vo;
    }

    public List<GoblinFrontBanner> getMiddleBanner() {
        List<GoblinFrontBanner> vo = (List<GoblinFrontBanner>) redisUtil.get(GoblinRedisConst.FRONT_MIDDLE_BANNER);
        if (null == vo) {
            //降级
            return goblinMongoUtils.getMiddleBanner();
        }
        return vo;
    }

    // 热词降级
    public List<GoblinFrontHotWord> getHotWord() {
        List<GoblinFrontHotWord> vo = (List<GoblinFrontHotWord>) redisUtil.get(GoblinRedisConst.FRONT_HOTWORD);
        if (null == vo) {
            //降级
            return goblinMongoUtils.getHotWord();
        }
        return vo;
    }

    // 导航栏 降级
    //  List<GoblinFrontNavigation> list = (List<GoblinFrontNavigation>) redisUtil.get(GoblinRedisConst.FRONT_NAVIGATION);
    public List<GoblinFrontNavigation> getNavigation() {
        List<GoblinFrontNavigation> vo = (List<GoblinFrontNavigation>) redisUtil.get(GoblinRedisConst.FRONT_NAVIGATION);
        if (null == vo) {
            //降级
            return goblinMongoUtils.getNavigation();
        }
        return vo;

    }

    /* ---------------------------------------- 商铺活动:优惠券数据源 ---------------------------------------- */

    public GoblinStoreCouponVo getStoreCouponVo(String storeCouponId) {
        String rk = GoblinRedisConst.STORE_COUPON.concat(storeCouponId);
        GoblinStoreCouponVo vo = (GoblinStoreCouponVo) redisUtil.get(rk);
        if (null == vo && null != (vo = goblinMongoUtils.getStoreCouponVo(storeCouponId))) {
            redisUtil.set(rk, vo);
        }
        return vo;
    }

    public List<String> getStoreCouponSpuIds(String storeCouponId) {
        String rk = GoblinRedisConst.STORE_COUPON_RULE.concat(storeCouponId);
        String valStr = (String) redisUtil.get(rk);
        List<String> strs;
        if (StringUtils.isEmpty(valStr)) {
            GoblinStoreCouponBasicVo storeCouponBasicVo = goblinMongoUtils.getMgtStoreCouponBasicVo(storeCouponId);
            strs = null == storeCouponBasicVo ? null : storeCouponBasicVo.getSpuIdList();
            if (!CollectionUtils.isEmpty(strs)) {
                redisUtil.set(rk, JsonUtils.toJson(strs));
            }
        } else {
            strs = JsonUtils.fromJson(valStr, new TypeReference<List<String>>() {
            });
        }
        return strs;
    }

    /* ---------------------------------------- 商铺活动:优惠券剩余库存 ---------------------------------------- */

    public boolean setStoreCouponStock(String storeCouponId, Integer stock) {
        return redisUtil.set(GoblinRedisConst.STORE_COUPON_STOCK.concat(storeCouponId), stock);
    }

    public void delStoreCouponStock(String storeCouponId) {
        redisUtil.del(GoblinRedisConst.STORE_COUPON_STOCK.concat(storeCouponId));
    }

    public int getStoreCouponStock(String storeCouponId) {
        Object valObj = redisUtil.get(GoblinRedisConst.STORE_COUPON_STOCK.concat(storeCouponId));
        return null == valObj ? 0 : (int) valObj;
    }

    public int incrStoreCouponStock(String storeCouponId, Integer operStock) {
        return (int) redisUtil.incr(GoblinRedisConst.STORE_COUPON_STOCK.concat(storeCouponId), operStock);
    }

    public int decrStoreCouponStock(String storeCouponId, Integer operStock) {
        return (int) redisUtil.decr(GoblinRedisConst.STORE_COUPON_STOCK.concat(storeCouponId), operStock);
    }

    /* ---------------------------------------- 商铺活动 ---------------------------------------- */

    public boolean setStoreMarketDtos(String storeId, List<GoblinStoreMarketDto> dtos) {
        return redisUtil.set(GoblinRedisConst.STORE_MARKETS.concat(storeId), JsonUtils.toJson(dtos));
    }

    public List<GoblinStoreMarketDto> getStoreMarketDtos(String storeId) {
        String rk = GoblinRedisConst.STORE_MARKETS.concat(storeId);
        String valStr = (String) redisUtil.get(rk);
        List<GoblinStoreMarketDto> dtos;
        if (StringUtils.isEmpty(valStr)) {
            // TODO: 2022/2/17 zhanggb mongodb 查取该商品所有参与的活动并整理集合
            dtos = ObjectUtil.getGoblinStoreMarketDtoArrayList();
        } else {
            dtos = JsonUtils.fromJson(valStr, new TypeReference<List<GoblinStoreMarketDto>>() {
            });
        }
        return dtos;
    }

    public boolean addStoreMarketDto(String storeId, GoblinStoreMarketDto dto) {
        List<GoblinStoreMarketDto> dtos = this.getStoreMarketDtos(storeId);
        dtos.add(dto);
        return redisUtil.set(GoblinRedisConst.STORE_MARKETS.concat(storeId), JsonUtils.toJson(dtos));
    }

    public void delStoreMarketDto(String storeId) {
        redisUtil.del(GoblinRedisConst.STORE_MARKETS.concat(storeId));
    }

    public void delStoreMarketDto(String storeId, GoblinStoreMarketDto dto) {
        String rk = GoblinRedisConst.STORE_MARKETS.concat(storeId);
        List<GoblinStoreMarketDto> dtos = this.getStoreMarketDtos(storeId);
        if (!CollectionUtils.isEmpty(dtos)) {
            int beforeSize = dtos.size();
            dtos.removeIf(r -> r.getId().equals(dto.getId()) && r.getType().equals(dto.getType()));
            if (beforeSize > dtos.size()) {
                redisUtil.set(GoblinRedisConst.STORE_MARKETS.concat(storeId), JsonUtils.toJson(dtos));
            }
        }
    }

    //获取艺人标签redis
    public List<GoblinGoodsInfoVo> getMusicTagList(String musicTag, String performanceId) {
        List<GoblinGoodsInfoVo> listVo = ObjectUtil.getGoblinGoodsInfoVos();
//        String rk = GoblinRedisConst.REDIS_ZZ_MUSIC_TAG.concat(musicTag + ":").concat(performanceId);
//        Object obj = redisUtil.get(rk);
//        if (obj == null) {
        listVo = goblinMongoUtils.getMusicTagPGoods(musicTag, performanceId);
//            redisUtil.set(rk, listVo, 60 * 30);
        return listVo;
//        } else {
//            return (List<GoblinGoodsInfoVo>) obj;
//        }
    }

    //删除艺人标签redis
    public void delMusicTagList(String musicTag, String performanceId) {
        String rk = GoblinRedisConst.REDIS_ZZ_MUSIC_TAG.concat(musicTag + ":").concat(performanceId);
        redisUtil.del(rk);
    }

    /* ---------------------------------------- 商品活动 ---------------------------------------- */

    public List<GoblinStoreCouponVo> getGoodsMarketsForCoupon(String spuId, String storeId) {
        List<GoblinStoreMarketDto> storeMarketDtos = this.getStoreMarketDtos(storeId);
        if (CollectionUtils.isEmpty(storeMarketDtos)) {
            return ObjectUtil.getGoblinStoreCouponVoArrayList();
        }
        ArrayList<GoblinStoreCouponVo> storeCouponVos = ObjectUtil.getGoblinStoreCouponVoArrayList();
        storeMarketDtos.forEach(dto -> {// 逐个活动筛选优惠券活动处理
            if (dto.getType() == 1) {// 优惠券活动
                GoblinStoreCouponVo storeCouponVo = this.getStoreCouponVo(dto.getId());
                if (null != storeCouponVo) {
                    if ("0".equals(storeCouponVo.getUseScope())) {
                        storeCouponVos.add(storeCouponVo);
                    } else {
                        List<String> storeCouponSpuIds = this.getStoreCouponSpuIds(dto.getId());
                        if (!CollectionUtils.isEmpty(storeCouponSpuIds) && storeCouponSpuIds.contains(spuId)) {
                            storeCouponVos.add(storeCouponVo);
                        }
                    }
                }
            }
        });
        return storeCouponVos;
    }

    /* ---------------------------------------- 商城:用户优惠券 ---------------------------------------- */

    public boolean setUserCouponVos(String uid, List<GoblinUserCouponVo> vos) {
        return redisUtil.set(GoblinRedisConst.USER_COUPON.concat(uid), JsonUtils.toJson(vos));
    }

    public List<GoblinUserCouponVo> getUserCouponVos(String uid) {
        String rk = GoblinRedisConst.USER_COUPON.concat(uid);
//        long s = System.nanoTime();
        String valStr = (String) redisUtil.get(rk);
//        log.info("RDS.G耗时:{}ms", (System.nanoTime() - s) / 1000000);
        List<GoblinUserCouponVo> vos;
        if (StringUtils.isEmpty(valStr)) {
//            if (!CollectionUtils.isEmpty(vos = goblinMongoUtils.getUserCouponVos(uid))) {
//                redisUtil.set(rk, JsonUtils.toJson(vos));
//            }
            return ObjectUtil.getGoblinUserCouponVo();
        } else {
            vos = JsonUtils.fromJson(valStr, new TypeReference<List<GoblinUserCouponVo>>() {
            });
        }
        return vos;
    }

    public boolean addUserCouponVos(String uid, GoblinUserCouponVo vo) {
        if (null == vo) return false;
        List<GoblinUserCouponVo> vos = this.getUserCouponVos(uid);
        vos.add(vo);
        return redisUtil.set(GoblinRedisConst.USER_COUPON.concat(uid), JsonUtils.toJson(vos));
    }

    /* ----------------------------------------  ---------------------------------------- */

    public boolean addMarketTempCoupon(String marketId, String ucouponId) {
        String redisKey = REDIS_GOBLIN_TEMP_COUPON_MARKET.concat(marketId);
        List<String> list = getMarketTempCoupon(marketId);
        list.add(ucouponId);
        return redisUtil.set(redisKey, list, 60 * 60 * 24 * 60);
    }

    /* ----------------------------------------  临时券  ---------------------------------------- */

    public void delMarketTempCoupon(String performanceId) {
        String redisKey = REDIS_GOBLIN_TEMP_COUPON_MARKET.concat(performanceId);
        redisUtil.del(redisKey);
    }

    public List<String> getMarketTempCoupon(String performanceId) {
        String redisKey = REDIS_GOBLIN_TEMP_COUPON_MARKET.concat(performanceId);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return CollectionUtil.arrayListString();
        } else {
            return (List<String>) obj;
        }
    }

    public void setTempCoupon(String ucouponId, TempCouponVo vo) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_TEMP_COUPON.concat(ucouponId);
        redisUtil.set(redisKey, vo, 60 * 60 * 24 * 60);
    }

    public TempCouponVo getTempCoupon(String ucouponId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_TEMP_COUPON.concat(ucouponId);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return null;
        } else {
            return (TempCouponVo) obj;
        }
    }

    public void delGoblinNftGoodsInfoListVo() {
        goblinNftJobService.goodsList();
    }

    /* ---------------------------------------- 我的藏品 ---------------------------------------- */

    /**
     * 获取用户藏品ID集合
     */
    public List<String> getUserDigitalArtworkIds(String uid) {
        return (List<String>) redisUtil.get(GoblinRedisConst.USER_DIGITAL_ARTWORK_IDS.concat(uid));
    }

    /**
     * 缓存用户累计藏品数
     *
     * @param uid 藏品拥有者
     * @param num 增减藏品数量
     * @return 用户剩余藏品数
     */
    public long addSubUserDigitalArtworkCount(String uid, long num) {
        if (num > 0) {
            return redisUtil.incr(GoblinRedisConst.USER_DIGITAL_ARTWORK_CT.concat(uid), num);
        } else {
            return redisUtil.decr(GoblinRedisConst.USER_DIGITAL_ARTWORK_CT.concat(uid), Math.abs(num));
        }
    }

    public long countUserDigitalArtwork(String uid) {
        Object o = redisUtil.get(GoblinRedisConst.USER_DIGITAL_ARTWORK_CT.concat(uid));
        return Objects.isNull(o) ? 0 : Math.max(((int) o), 0);
    }

    public GoblinUserDigitalArtworkVo getUserDigitalArtworkVo(String artworkId) {
        return (GoblinUserDigitalArtworkVo) redisUtil.get(GoblinRedisConst.USER_DIGITAL_ARTWORK.concat(artworkId));
    }

    /**
     * 缓存用户藏品详情
     */
    public boolean setUserDigitalArtworkVo(GoblinUserDigitalArtworkVo vo) {
        return redisUtil.set(GoblinRedisConst.USER_DIGITAL_ARTWORK.concat(vo.getArtworkId()), vo);
    }

    /**
     * 盲盒开启后/来源为转赠的藏品转赠成功后，直接从`我的藏品列表`中移除
     * 此处通过Redis过期删除
     */
    public boolean setexUserDigitalArtworkVo(GoblinUserDigitalArtworkVo vo, long expireSeconds) {
        return redisUtil.set(GoblinRedisConst.USER_DIGITAL_ARTWORK.concat(vo.getArtworkId()), vo, expireSeconds);
    }

    /* ----------------------------------- 我的藏品管理 ----------------------------------- */

    /**
     * 锁定藏品操作
     */
    public boolean lockUserDigitalArtworkVoOperate(String artworkId) {
        return redisUtil.lock(GoblinRedisConst.USER_DIGITAL_ARTWORK.concat("lk").concat(artworkId), 1, 30);
    }

    /**
     * 解锁藏品操作
     */
    public void unlockUserDigitalArtworkVoOperate(String artworkId) {
        redisUtil.uLock(GoblinRedisConst.USER_DIGITAL_ARTWORK.concat("lk").concat(artworkId));
    }

    /**
     * 重置Redis中用户藏品ID集合的缓存（降级Mongo查取藏品ID集合）
     */
    public void resetUserDigitalArtworkIdsByMongo(String uid) {
        List<String> ids = goblinMongoUtils.getPageUserDigitalArtworkIds(uid, 1, 30);
        if (CollectionUtils.isEmpty(ids)) {
            redisUtil.del(GoblinRedisConst.USER_DIGITAL_ARTWORK_IDS.concat(uid));
        } else {
            redisUtil.set(GoblinRedisConst.USER_DIGITAL_ARTWORK_IDS.concat(uid), ids);
        }
    }

    /**
     * 缓存并更新用户藏品ID集合
     */
    public boolean addUserDigitalArtworkIds(String uid, String artworkId) {
        List<String> ids = this.getUserDigitalArtworkIds(uid);
        if (CollectionUtils.isEmpty(ids)) {
            ids = CollectionUtil.arrayListString();
            ids.add(artworkId);
        } else {
            ids.add(0, artworkId);
            int size = ids.size();
            if (size > 30) ids.remove(size - 1);
        }
        return redisUtil.set(GoblinRedisConst.USER_DIGITAL_ARTWORK_IDS.concat(uid), ids);
    }

    /**
     * 开启盲盒：缓存并更新用户藏品ID集合
     */
    public boolean addUserDigitalArtworkIdsForUnbox(String uid, String artworkId, String boxArtworkId) {
        List<String> ids = this.getUserDigitalArtworkIds(uid);
        if (CollectionUtils.isEmpty(ids)) {
            ids = CollectionUtil.arrayListString();
            ids.add(artworkId);
        } else {
            ids.add(0, artworkId);
            ids.remove(boxArtworkId);
            int size = ids.size();
            if (size > 30) ids.remove(size - 1);
        }
        return redisUtil.set(GoblinRedisConst.USER_DIGITAL_ARTWORK_IDS.concat(uid), ids);
    }

    /* ----------------------------------- 受赠藏品管理 ----------------------------------- */

    /**
     * 获取用户受赠藏品ID集合
     */
    public List<String> getUserDigitalArtworkIdsTransfer(String uid) {
        return (List<String>) redisUtil.get(GoblinRedisConst.USER_DIGITAL_ARTWORK_IDS_TRANSFER.concat(uid));
    }

    public boolean addUserDigitalArtworkIdsTransfer(String uid, String artworkId) {
        List<String> ids = this.getUserDigitalArtworkIdsTransfer(uid);
        if (CollectionUtils.isEmpty(ids)) {
            ids = CollectionUtil.arrayListString();
            ids.add(artworkId);
        } else {
            ids.add(0, artworkId);
        }
        return redisUtil.set(GoblinRedisConst.USER_DIGITAL_ARTWORK_IDS_TRANSFER.concat(uid), ids);
    }

    public boolean rmvUserDigitalArtworkIdsTransfer(String uid, String artworkId) {
        List<String> ids = this.getUserDigitalArtworkIdsTransfer(uid);
        if (CollectionUtils.isEmpty(ids)) {
            return false;
        } else {
            ids.remove(artworkId);
            if (CollectionUtils.isEmpty(ids)) {
                redisUtil.del(GoblinRedisConst.USER_DIGITAL_ARTWORK_IDS_TRANSFER.concat(uid));
            } else {
                redisUtil.set(GoblinRedisConst.USER_DIGITAL_ARTWORK_IDS_TRANSFER.concat(uid), ids);
            }
            return true;
        }
    }

    /* ----------------------------------- ---------- ----------------------------------- */

    public List<String> getGoblinNftGoodsInfoListVo(String num) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_NFT_GOODS_LIST.concat(num);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return CollectionUtil.arrayListString();
        } else {
            return (List<String>) obj;
        }
    }

    public void setGoblinNftGoodsListInfoVo(String skuId, GoblinNftGoodsSkuListVo data) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_NFT_GOODS_LIST_INFO.concat(skuId);
        redisUtil.set(redisKey, data);
    }

    public GoblinNftGoodsSkuListVo getGoblinNftGoodsListInfoVo(String skuId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_NFT_GOODS_LIST_INFO.concat(skuId);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return null;
        } else {
            return (GoblinNftGoodsSkuListVo) obj;
        }
    }

    public void setGoblinNftGoodsInfoListVo(List<String> spuList, String num) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_NFT_GOODS_LIST.concat(num);
        redisUtil.set(redisKey, spuList);
    }

    public boolean getNftNumAccount(String userId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_NFT_NUM_ACCOUNT.concat(userId);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return false;
        } else {
            return true;
        }
    }

    public GoblinUserNftAccInfoVo getOpenAccountInfo(String userId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_NFT_NUM_ACCOUNT_INFO.concat(userId);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return null;
        } else {
            return (GoblinUserNftAccInfoVo) obj;
        }
    }

    public void setOpenAccountInfo(String userId, GoblinUserNftAccInfoVo nftAccInfoVo) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_NFT_NUM_ACCOUNT_INFO.concat(userId);
        redisUtil.set(redisKey, nftAccInfoVo);
    }

    public int getIsExchange(String skuId) {
        String redisKey = GoblinRedisConst.ACTIVITY_SKU_TIME.concat(skuId);
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return 1;
        } else {
            GoblinNftExSkuVo exSkuVo = (GoblinNftExSkuVo) obj;
            if ((null == exSkuVo.getExStartTime() || LocalDateTime.now().isAfter(exSkuVo.getExStartTime())) && (null == exSkuVo.getExStopTime() || LocalDateTime.now().isBefore(exSkuVo.getExStopTime()))) {
                return 2;
            } else {
                return 1;
            }
        }
    }

    public int getNotPayNum(String skuId, String listId) {
        String redisKey = GoblinRedisConst.REDIS_GOBLIN_NFT_NOT_PAY_NUM.concat(skuId);
        if (null != listId) {
            redisKey = redisKey.concat(":").concat(listId);
        }
        Object obj = redisUtil.get(redisKey);
        if (obj == null) {
            return 1;
        } else {
            return (int) obj;
        }
    }

    /**
     * private int skuType 商品类型[0-常规｜1-数字藏品｜2-券类商品]
     * private String status 审核状态[0-初始编辑|1-审核中|2-审核不通过|3-审核通过];
     * private String shelvesStatus 单品上架状态[0-待上架|1-下架|2-违规|3-上架];
     * private String skuAppear 是否隐藏[0-默认展示|1-隐藏];
     * private String delFlg 删除标记[0-未删除|1-删除];
     * <p>
     * private LocalDateTime saleStartTime 开售时间;
     * private LocalDateTime saleStopTime 停售时间 预留 暂时不做处理;
     * private String soldoutStatus 是否售罄[0-否|1-是];
     * <p>
     * private String skuCanbuy 是否购买[0-否|1-是] 这个用来预览 前端自己判断;
     * <p>
     * Integer upchain NFT上传声明状态[0-待上传|1-已声明|2-声明失败|9-声明中]
     * <p>
     * String unbox; 是否盲盒[0-否|1-是]
     */
    // 获取盲盒下藏品的库存 各种状态下不能算库存的排除掉
    public int getSkuAllStatusStock(GoblinGoodsSkuInfoVo info, String listId) {
        if (
                info != null
//                        && LocalDateTime.now().isAfter(info.getSaleStartTime())
                        && (null == info.getSoldoutStatus() || info.getSoldoutStatus().equals("0"))
                        && (null == info.getHitRatio() || info.getHitRatio().compareTo(BigDecimal.ZERO) > 0)
                        && (null == info.getSkuCanbuy() || info.getSkuCanbuy().equals("1"))
        ) {// 可以返回库存
            // 外面只有盲盒才能请求进来 里面只有不是分批购才判断盲盒里藏品的开售时间
            if (null == listId) {
//                if (LocalDateTime.now().isAfter(info.getSaleStartTime())) {
                return getSkuStock(listId, info.getSkuId());
//                } else {
//                    return 0;
//                }
            } else {
                return getSkuStock(listId, info.getSkuId());
            }
        } else {// 不计入库存
            return 0;
        }
    }

    // 各种状态下判断藏品总库存
    public Integer getSkuTotalStockShelvesStatus3(GoblinGoodsSkuInfoVo info) {
        if (
                info != null
                        && (null == info.getShelvesStatus() || info.getShelvesStatus().equals("3"))
//                        && LocalDateTime.now().isAfter(info.getSaleStartTime())
//                        && (null == info.getSoldoutStatus() || info.getSoldoutStatus().equals("0"))
//                        && (null == info.getHitRatio() || info.getHitRatio().compareTo(BigDecimal.ZERO) > 0)
        ) {// 可以返回库存
            return info.getSkuStock();
        } else {// 不计入库存
            return 0;
        }
    }

    // 获取盲盒下藏品的库存 各种状态下不能算库存的排除掉
    public int getSkuAllStatusStockType1(GoblinGoodsSkuInfoVo info) {
        if (
                info != null
                        && (null == info.getSoldoutStatus() || info.getSoldoutStatus().equals("0"))
                        && (null == info.getHitRatio() || info.getHitRatio().compareTo(BigDecimal.ZERO) > 0)
                        && (null == info.getSkuCanbuy() || info.getSkuCanbuy().equals("1")
                        && (null == info.getShelvesStatus() || info.getShelvesStatus().equals("3")))
        ) {// 可以返回库存
            return getSkuStock(null, info.getSkuId());
        } else {// 不计入库存
            return 0;
        }
    }

    // 获取盲盒下藏品的库存 各种状态下不能算库存的排除掉
    public int getSkuAllStatusStockStatus4(GoblinGoodsSkuInfoVo info) {
        if (
                info != null
                        && LocalDateTime.now().isBefore(info.getSaleStartTime())
                        && (null == info.getSoldoutStatus() || info.getSoldoutStatus().equals("0"))
                        && (null == info.getHitRatio() || info.getHitRatio().compareTo(BigDecimal.ZERO) > 0)
                        && (null == info.getSkuCanbuy() || info.getSkuCanbuy().equals("1"))
        ) {// 可以返回库存
            return getSkuStock(null, info.getSkuId());
        } else {// 不计入库存
            return 0;
        }
    }

    // 各种状态下判断藏品是否可以展示
    public boolean getSkuAllStatusShow(GoblinGoodsSkuInfoVo info) {
        if (
                info != null
                        && info.getSkuType() == 1
                        && info.getStatus().equals("3")
                        && info.getShelvesStatus().equals("3")
                        && (info.getSkuAppear() == null || info.getSkuAppear().equals("0"))
                        && info.getDelFlg().equals("0")
                        && ((info.getUnbox().equals("0") && info.getUpchain() == 1) || info.getUnbox().equals("1"))
            // && (info.getUnbox().equals("1") || info.getUpchain() == 1)
        ) {
            return true;
        } else {
            return false;
        }
    }

    // 各种状态下判断藏品总库存
    public Integer getSkuTotalStock(GoblinGoodsSkuInfoVo info) {
        if (
                info != null
//                        && LocalDateTime.now().isAfter(info.getSaleStartTime())
//                        && (null == info.getSoldoutStatus() || info.getSoldoutStatus().equals("0"))
//                        && (null == info.getHitRatio() || info.getHitRatio().compareTo(BigDecimal.ZERO) > 0)
        ) {// 可以返回库存
            return info.getSkuStock();
        } else {// 不计入库存
            return 0;
        }
    }

    public Integer getBuyNftTec(String uid) {
        String rdk = GoblinRedisConst.BUY_NFT_TEC.concat(uid);
        Object obj = redisUtil.get(rdk);
        if (obj == null) {
            return null;
        } else {
            return (int) obj;
        }
    }

    /**
     * 设置 技术部nft特效开关
     *
     * @param uid
     * @param status
     */
    public void setOpenNftTec(String uid, Integer status) {
        String rdk = GoblinRedisConst.OPEN_NFT_TEC.concat(uid);
        if (!(status == 0 || status == 1)) {
            status = 0;
        }
        Integer data = getBuyNftTec(uid);
        if (data == null) {
            redisUtil.set(rdk, 0);
        } else if (data == 1) {
            redisUtil.set(rdk, status);
        } else {
            redisUtil.set(rdk, 0);
        }
    }

    /**
     * 获取 技术部nft特效开关
     *
     * @param uid
     * @return
     */
    public Integer getOpenNftTec(String uid) {
        String rdk = GoblinRedisConst.OPEN_NFT_TEC.concat(uid);
        Object obj = redisUtil.get(rdk);
        if (obj == null) {
            Integer data = getBuyNftTec(uid);
            if (data == null) {
                return null;
            } else if (data == 1) {
                setOpenNftTec(uid, 1);
                return 1;
            } else {
                return null;
            }
        } else {
            return (int) obj;
        }
    }

    /**
     * 设置 名单详情
     */
    public void setGoblinListDetailsVo(GoblinListDetailsVo vo) {
        redisUtil.set(GoblinRedisConst.LIST_DETAILS.concat(vo.getListId()), vo);
    }

    public void delGoblinListDetailsVo(String listId) {
        redisUtil.del(GoblinRedisConst.LIST_DETAILS.concat(listId));
    }

    public GoblinListDetailsVo getGoblinListDetailsVo(String listId) {
        Object obj = redisUtil.get(GoblinRedisConst.LIST_DETAILS.concat(listId));
        if (obj == null) {
            return null;
        } else {
            return (GoblinListDetailsVo) obj;
        }
    }

    /**
     * 设置 分批购数据
     */
    public void setGoblinListCollect(String skuId, List<GoblinListCollectVo> vo) {
        redisUtil.set(GoblinRedisConst.LIST_COLLECT.concat(skuId), vo);
    }

    public void delGoblinListCollect(String skuId, String listId) {
        List<GoblinListCollectVo> vos = getGoblinListCollect(skuId);
        for (GoblinListCollectVo vo : vos) {
            if (vo.getListId().equals(listId)) {
                vos.remove(vo);
                break;
            }
        }
        setGoblinListCollect(skuId, vos);
    }

    public List<GoblinListCollectVo> getGoblinListCollect(String skuId) {
        Object obj = redisUtil.get(GoblinRedisConst.LIST_COLLECT.concat(skuId));
        if (obj == null) {
            return ObjectUtil.getGoblinListCollectVo();
        } else {
            List<GoblinListCollectVo> list = (List<GoblinListCollectVo>) obj;
            list = list.stream().sorted(Comparator.comparing(GoblinListCollectVo::getTimeStart)).collect(Collectors.toList());
            return list;
        }
    }

    /**
     * 设置 盲盒skuId 关联 的skuId
     */
    public void addGoblinListRelationBox(String skuId, String listId, String relationSkuId) {
        String rdk = GoblinRedisConst.LIST_RELATION_BOX.concat(skuId).concat(":" + listId);
        ArrayList<String> list = getGoblinListRelationBox(skuId, listId);
        if (!list.contains(relationSkuId)) {
            list.add(relationSkuId);
            redisUtil.set(rdk, list);
        }
    }

    /**
     * 获取 盲盒skuId 关联 的skuId
     */
    public ArrayList<String> getGoblinListRelationBox(String skuId, String listId) {
        String rdk = GoblinRedisConst.LIST_RELATION_BOX.concat(skuId).concat(":" + listId);
        Object obj = redisUtil.get(rdk);
        if (obj == null) {
            return CollectionUtil.arrayListString();
        } else {
            return (ArrayList<String>) obj;
        }
    }

    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | NFT三要素认证缓存的<ID_TYPE+ID_NO, "ID_NAME,MOBILE"> */

    public boolean setCertmetaJunk(int idType, String idNo, String idName, String mobile) {
        return redisUtil.set(GoblinRedisConst.REDIS_GOBLIN_NFT_CERTMETA_JUNK + idType + idNo, idName.concat(",").concat(mobile), 604800);
    }

    public boolean isCertmetaJunk(int idType, String idNo, String idName, String mobile) {
        String val = (String) redisUtil.get(GoblinRedisConst.REDIS_GOBLIN_NFT_CERTMETA_JUNK + idType + idNo);
        return !StringUtils.isEmpty(val) && val.equals(idName.concat(",").concat(mobile));
    }

    public boolean setCertmeta(int idType, String idNo, String idName, String mobile) {
        return redisUtil.set(GoblinRedisConst.REDIS_GOBLIN_NFT_CERTMETA + idType + idNo, idName.concat(",").concat(mobile));
    }

    public int isCertmeta(int idType, String idNo, String idName, String mobile) {
        String o = (String) redisUtil.get(GoblinRedisConst.REDIS_GOBLIN_NFT_CERTMETA + idType + idNo);
        if (StringUtils.isEmpty(o)) {
            return -1;
        }
        return o.equals(idName.concat(",").concat(mobile)) ? 1 : 0;
    }

    // 设置 组合售数据
    public void setMixDetails(String mixId, GoblinMixDetailsVo vo) {
        String rdk = GoblinRedisConst.GOBLIN_MIX_DETAILS.concat(mixId);
        redisUtil.set(rdk, vo);
    }

    // 获取 组合售数据
    public GoblinMixDetailsVo getMixDetails(String mixId) {
        String rdk = GoblinRedisConst.GOBLIN_MIX_DETAILS.concat(mixId);
        Object obj = redisUtil.get(rdk);
        if (obj == null) {
            return GoblinMixDetailsVo.getNew();
        } else {
            return (GoblinMixDetailsVo) obj;
        }
    }

    /**
     * 设置 盲盒skuId 关联 的skuId
     */
    public void addGoblinMixRelationBox(String skuId, String mixId, String relationSkuId) {
        String rdk = GoblinRedisConst.GOBLIN_MIX_RELATION_BOX.concat(skuId).concat(":" + mixId);
        ArrayList<String> list = getGoblinMixRelationBox(skuId, mixId);
        list.add(relationSkuId);
        redisUtil.set(rdk, list);
    }

    /**
     * 删除 盲盒skuId 关联 的skuId
     */
    public void removeGoblinMixRelationBox(String skuId, String mixId, String relationSkuId) {
        String rdk = GoblinRedisConst.GOBLIN_MIX_RELATION_BOX.concat(skuId).concat(":" + mixId);
        ArrayList<String> list = getGoblinMixRelationBox(skuId, mixId);
        for (String item : list) {
            if (item.equals(relationSkuId)) {
                list.remove(item);
                break;
            }
        }
        redisUtil.set(rdk, list);
    }

    /**
     * 获取 盲盒skuId 关联 的skuId
     */
    public ArrayList<String> getGoblinMixRelationBox(String skuId, String mixId) {
        String rdk = GoblinRedisConst.GOBLIN_MIX_RELATION_BOX.concat(skuId).concat(":" + mixId);
        Object obj = redisUtil.get(rdk);
        if (obj == null) {
            return CollectionUtil.arrayListString();
        } else {
            return (ArrayList<String>) obj;
        }
    }

    // 设置 组合售 nft列表
    public void setGoblinMixNftList(List<String> mixId) {
        String rdk = GoblinRedisConst.GOBLIN_MIX_NFT_LIST;
        redisUtil.set(rdk, mixId);
    }

    // 获取 组合售 nft列表
    public List<String> getGoblinMixNftList() {
        String rdk = GoblinRedisConst.GOBLIN_MIX_NFT_LIST;
        Object obj = redisUtil.get(rdk);
        if (obj == null) {
            return CollectionUtil.linkedListString();
        } else {
            return (List<String>) obj;
        }
    }

    public void addGoblinMixNftList(String mixId) {
        List<String> mixIds = getGoblinMixNftList();
        mixIds.add(mixId);
        setGoblinMixNftList(mixIds);
    }

    public void removeGoblinMixNftList(String mixId) {
        List<String> mixIds = getGoblinMixNftList();
        for (String item : mixIds) {
            if (item.equals(mixId)) {
                mixIds.remove(mixId);
                break;
            }
        }
        setGoblinMixNftList(mixIds);
    }

    // 设置 组合售 sku列表
    public void setGoblinMixSkuList(List<String> mixId) {
        String rdk = GoblinRedisConst.GOBLIN_MIX_SKU_LIST;
        redisUtil.set(rdk, mixId);
    }

    // 获取 组合售 sku列表
    public List<String> getGoblinMixSkuList() {
        String rdk = GoblinRedisConst.GOBLIN_MIX_SKU_LIST;
        Object obj = redisUtil.get(rdk);
        if (obj == null) {
            return CollectionUtil.linkedListString();
        } else {
            return (List<String>) obj;
        }
    }

    public void addGoblinMixSkuList(String mixId) {
        List<String> mixIds = getGoblinMixSkuList();
        mixIds.add(mixId);
        setGoblinMixSkuList(mixIds);
    }

    public void removeGoblinMixSkuList(String mixId) {
        List<String> mixIds = getGoblinMixSkuList();
        for (String item : mixIds) {
            if (item.equals(mixId)) {
                mixIds.remove(mixId);
                break;
            }
        }
        setGoblinMixSkuList(mixIds);
    }

    // 设置 组合售 sku列表
    public void setGoblinMixNftStockList(List<String> mixId) {
        String rdk = GoblinRedisConst.GOBLIN_MIX_NFT_STOCK_LIST;
        redisUtil.set(rdk, mixId);
    }

    // 设置 组合售 sku列表
    public void setGoblinMixNftStartList(List<String> mixId) {
        String rdk = GoblinRedisConst.GOBLIN_MIX_NFT_START_LIST;
        redisUtil.set(rdk, mixId);
    }

    // 设置 组合售 sku列表
    public void setGoblinMixSkuStockList(List<String> mixId) {
        String rdk = GoblinRedisConst.GOBLIN_MIX_SKU_STOCK_LIST;
        redisUtil.set(rdk, mixId);
    }

    // 设置 组合售 sku列表
    public void setGoblinMixSkuStartList(List<String> mixId) {
        String rdk = GoblinRedisConst.GOBLIN_MIX_SKU_START_LIST;
        redisUtil.set(rdk, mixId);
    }

    public List<String> getGoblinMixNftStockList() {
        String rdk = GoblinRedisConst.GOBLIN_MIX_NFT_STOCK_LIST;
        Object obj = redisUtil.get(rdk);
        if (obj == null) {
            return CollectionUtil.linkedListString();
        } else {
            return (List<String>) obj;
        }
    }

    public List<String> getGoblinMixNftStartList() {
        String rdk = GoblinRedisConst.GOBLIN_MIX_NFT_START_LIST;
        Object obj = redisUtil.get(rdk);
        if (obj == null) {
            return CollectionUtil.linkedListString();
        } else {
            return (List<String>) obj;
        }
    }

    public List<String> getGoblinMixSkuStockList() {
        String rdk = GoblinRedisConst.GOBLIN_MIX_SKU_STOCK_LIST;
        Object obj = redisUtil.get(rdk);
        if (obj == null) {
            return CollectionUtil.linkedListString();
        } else {
            return (List<String>) obj;
        }
    }

    public List<String> getGoblinMixSkuStartList() {
        String rdk = GoblinRedisConst.GOBLIN_MIX_SKU_START_LIST;
        Object obj = redisUtil.get(rdk);
        if (obj == null) {
            return CollectionUtil.linkedListString();
        } else {
            return (List<String>) obj;
        }
    }

    public void addGoblinMixNftStockList(String mixId) {
        List<String> mixIds = getGoblinMixNftStockList();
        mixIds.add(mixId);
        setGoblinMixNftStockList(mixIds);
    }

    public void addGoblinMixNftStartList(String mixId) {
        List<String> mixIds = getGoblinMixNftStartList();
        mixIds.add(mixId);
        setGoblinMixNftStartList(mixIds);
    }

    public void addGoblinMixSkuStockList(String mixId) {
        List<String> mixIds = getGoblinMixSkuStockList();
        mixIds.add(mixId);
        setGoblinMixSkuStockList(mixIds);
    }

    public void addGoblinMixSkuStartList(String mixId) {
        List<String> mixIds = getGoblinMixSkuStartList();
        mixIds.add(mixId);
        setGoblinMixSkuStartList(mixIds);
    }

    //保存用户预约
    public void setReserveMixByUid(GoblinMixReserveVo goblinMixReserveVo) {
        String rdk = GoblinRedisConst.GOBLIN_MIX_RESERVE_UID.concat(goblinMixReserveVo.getMixId()).concat(":").concat(goblinMixReserveVo.getUid());
        redisUtil.set(rdk, goblinMixReserveVo);
    }

    //根据用户uid和混合mixId查询用户预约
    public GoblinMixReserveVo getReserveMixByUid(String uid, String mixId) {
        Object obj = redisUtil.get(GoblinRedisConst.GOBLIN_MIX_RESERVE_UID.concat(mixId).concat(":").concat(uid));
        if (obj == null) {
            return null;
        } else {
            return (GoblinMixReserveVo) obj;
        }
    }

    /* ---------------------------------------- NFT用户安全配置 ---------------------------------------- */

    public boolean setUserSafeConfigDto(String uid, GoblinUserSafeConfigDto dto) {
        return redisUtil.set(GoblinRedisConst.USER_SAFE_CONFIG.concat(uid), dto);
    }

    public GoblinUserSafeConfigDto getUserSafeConfigDto(String uid) {
        return (GoblinUserSafeConfigDto) redisUtil.get(GoblinRedisConst.USER_SAFE_CONFIG.concat(uid));
    }

    /**
     * 校验安全密码
     *
     * @param inputPasswd       用户输入密码
     * @param userSafeConfigDto 用户设置密码
     * @return ResponseDto<String>
     */
    public ResponseDto<String> validUserSafePasswd(String inputPasswd, GoblinUserSafeConfigDto userSafeConfigDto, String uid) {
        long expire = redisUtil.getExpire(GoblinRedisConst.USER_SAFE_LK_PASSWDTL.concat(uid));
        ErrorMapping.ErrorMessage errorMessage;
        if (expire > 0) {
            errorMessage = ErrorMapping.get("140117");
            return ResponseDto.failure(errorMessage.getCode(), String.format(errorMessage.getMessage(), this.getUserSafeLkPasswdtlTimelimit()));
        }
        long validFailedNum = redisUtil.incr(GoblinRedisConst.USER_SAFE_LK_PASSWD.concat(uid), 1);
        if (validFailedNum <= 5) {
            if (userSafeConfigDto.getPasswd().equals(DigestUtils.md5DigestAsHex(inputPasswd.concat(passwdSalt).getBytes(StandardCharsets.UTF_8)))) {
                redisUtil.del(GoblinRedisConst.USER_SAFE_LK_PASSWD.concat(uid));
                return ResponseDto.success();
            }
        }
        Integer passwdtlTimelimit;
        LocalDateTime currentDateTime, tomorrowStartDateTime;
        switch (Math.toIntExact(validFailedNum)) {
            case 1:
                currentDateTime = LocalDateTime.now();
                tomorrowStartDateTime = currentDateTime.plusDays(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
                redisUtil.expireSet(GoblinRedisConst.USER_SAFE_LK_PASSWD, ChronoUnit.SECONDS.between(currentDateTime, tomorrowStartDateTime));
            case 2:
                passwdtlTimelimit = this.getUserSafeLkPasswdtlTimelimit();
                errorMessage = ErrorMapping.get("140116");
                return ResponseDto.failure(errorMessage.getCode(), String.format(errorMessage.getMessage(), 3 - validFailedNum, passwdtlTimelimit));
            case 3:
                passwdtlTimelimit = this.getUserSafeLkPasswdtlTimelimit();
                redisUtil.set(GoblinRedisConst.USER_SAFE_LK_PASSWDTL.concat(uid), 1, passwdtlTimelimit * 60);// 30分钟后可继续尝试第4、5次
                errorMessage = ErrorMapping.get("140113");
                return ResponseDto.failure(errorMessage.getCode(), String.format(errorMessage.getMessage(), passwdtlTimelimit));
            case 4:
                return ResponseDto.failure(ErrorMapping.get("140114"));
            case 5:
                redisUtil.set(GoblinRedisConst.USER_SAFE_LK_PASSWD.concat(uid), 5);
            default:
                return ResponseDto.failure(ErrorMapping.get("140115"));
        }
    }

    private Integer getUserSafeLkPasswdtlTimelimit() {
        Integer passwdtlTimelimit = (Integer) redisUtil.get(GoblinRedisConst.USER_SAFE_LK_PASSWDTL_TIMELIMIT);
        if (null == passwdtlTimelimit) {
            redisUtil.set(GoblinRedisConst.USER_SAFE_LK_PASSWDTL_TIMELIMIT, passwdtlTimelimit = 30);
        }
        return passwdtlTimelimit;
    }

    /* ----------------------------------------  ---------------------------------------- */

    /**
     * NFT转赠约束配置（首次转赠）
     * <p>
     * Redis未配置或配置格式有误时，默认返回180天对应15552000秒
     * {"xuper":15552000,"zxinchain":15552000}
     * </p>
     *
     * @return Map<String, Long>
     */
    public Map<String, Long> getUserDigitalArtworkTransferConfMap() {
        return getUserDigitalArtworkTransferConfMap(null);
    }

    /**
     * NFT转赠约束配置（区分首次转赠、二次转赠）
     * <p>
     * Redis未配置或配置格式有误时，默认返回180天对应15552000秒
     * {"xuper":15552000,"zxinchain":15552000}
     * </p>
     *
     * @param artworkSource 藏品来源，为空或不等于`6`时为首次转赠配置
     * @return Map<String, Long>
     */
    public Map<String, Long> getUserDigitalArtworkTransferConfMap(Integer artworkSource) {
        String key = null != artworkSource && artworkSource == 6 ? GoblinRedisConst.NFT_TRANSFER_CONF_AGAIN : GoblinRedisConst.NFT_TRANSFER_CONF;
        String val = (String) redisUtil.get(key);
        Map<String, Long> map;
        if (StringUtils.isEmpty(val)) {
            map = CollectionUtil.mapStringLong();
            for (GalaxyEnum.RouterTypeEnum routerTypeEnum : GalaxyEnum.RouterTypeEnum.values()) {
                map.put(routerTypeEnum.getCode(), 15552000L);
            }
            redisUtil.set(key, JsonUtils.toJson(map));
        } else {
            try {
                map = JsonUtils.fromJson(val, new TypeReference<Map<String, Long>>() {
                });
            } catch (Exception ignored) {
                map = CollectionUtil.mapStringLong();
                for (GalaxyEnum.RouterTypeEnum routerTypeEnum : GalaxyEnum.RouterTypeEnum.values()) {
                    map.put(routerTypeEnum.getCode(), 15552000L);
                }
            }
        }
        return map;
    }

    public List<CouponOutLineVo> getOutLineCoupon() {
        Object obj = redisUtil.get(GoblinRedisConst.STORE_OUT_LINE_COUPON);
        if (obj == null) {
            List<CouponOutLineVo> list = ObjectUtil.couponOutLineVo();
            CouponOutLineVo vo = CouponOutLineVo.getNew();
            vo.setName("95折券");
            vo.setStoreCouponId("ccoupon95");
            vo.setDiscount(95);
            vo.setDesc("95折券");
            vo.setCouType("2");
            list.add(vo);
            redisUtil.set(GoblinRedisConst.STORE_OUT_LINE_COUPON, list);
            return list;
        } else {
            return (List<CouponOutLineVo>) obj;
        }
    }


    //获取erp订单
    public List<String> getRange(int index) {
        String rdk = GoblinRedisConst.ERP_GOBLIN_GOODS_LIST.concat(index + "");
        List<Object> list = redisUtil.getRange(rdk);
        List<String> data = CollectionUtil.arrayListString();
        for (Object str : list) {
            data.add((String) str);
        }
        return data;
    }

    public String erpLeftPop(String shopNo) {
        String rdk = GoblinRedisConst.ERP_GOBLIN_GOODS_LIST.concat(shopNo);
        Object obj = redisUtil.leftPop(rdk);
        if (obj == null) {
            return null;
        } else {
            return (String) obj;
        }
    }

    //添加erp订单
    public int erpAddErrorPush(String shopNo, String orderId) {
        String rdk = GoblinRedisConst.ERP_GOBLIN_GOODS_LIST.concat("error:" + shopNo);
        return (int) redisUtil.rightPush(rdk, orderId);
    }

    /* ----------------------------------------  ---------------------------------------- */
    /* ----------------------------------------  ---------------------------------------- */
    /* ----------------------------------------  ---------------------------------------- */
    /* ----------------------------------------  ---------------------------------------- */
}
