package com.cyksj.redis;

import com.cyksj.common.util.StringUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;


/**
 * @description 定义常用的 Redis操作
 * @author chan
 * @date 2021-03-31 5:34 下午
 */
@Service
@SuppressWarnings("all")
public class RedisService {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    public static String env = "dev";


    /**
     * 指定缓存失效时间
     *
     * @param key  键
     * @param time 时间(秒)
     * @return Boolean
     */
    public Boolean expire(String key, Long time) {
        try {
            if (time > 0) {
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据key获取过期时间
     *
     * @param key 键 不能为 null
     * @return 时间(秒) 返回 0代表为永久有效
     */
    public Long getExpire(String key) {
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }

    /**
     * 判断 key是否存在
     *
     * @param key 键
     * @return true 存在 false不存在
     */
    public Boolean hasKey(String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 删除缓存
     *
     * @param key 可以传一个值 或多个
     */
    public void del(String... key) {
        if (key != null && key.length > 0) {
            if (key.length == 1) {
                redisTemplate.delete(key[0]);
            } else {
                redisTemplate.delete(Arrays.asList(key));
            }
        }
    }

    /**
     * 普通缓存获取
     *
     * @param key 键
     * @return 值
     */
    public Object get(String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }

    /**
     * String缓存获取
     * @param key 键
     * @return 值
     */
    public String getStr(String key) {
            return key == null ? null : StringUtil.getString(redisTemplate.opsForValue().get(key));
    }

    /**
     * 普通缓存放入
     *
     * @param key   键
     * @param value 值
     * @return true成功 false失败
     */
    public Boolean set(String key, Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 普通缓存放入并设置时间
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期
     * @return true成功 false 失败
     */
    public Boolean set(String key, Object value, Long time) {
        try {
            if (time > 0) {
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            } else {
                set(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 递增
     *
     * @param key   键
     * @param delta 要增加几(大于0)
     * @return Long
     */
    public Long incr(String key, Long delta) {
        if (delta < 0) {
            throw new RuntimeException("递增因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }

    /**
     * 递减
     *
     * @param key   键
     * @param delta 要减少几
     * @return Long
     */
    public Long decr(String key, Long delta) {
        if (delta < 0) {
            throw new RuntimeException("递减因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, -delta);
    }

    /**
     * HashGet
     *
     * @param key  键 不能为 null
     * @param item 项 不能为 null
     * @return 值
     */
    public Object hget(String key, String item) {
        return redisTemplate.opsForHash().get(key, item);
    }

    /**
     * 获取 hashKey对应的所有键值
     *
     * @param key 键
     * @return 对应的多个键值
     */
    public Map<Object, Object> hmget(String key) {
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * HashSet
     *
     * @param key 键
     * @param map 对应多个键值
     * @return true 成功 false 失败
     */
    public Boolean hmset(String key, Map<String, Object> map) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * HashSet 并设置时间
     *
     * @param key  键
     * @param map  对应多个键值
     * @param time 时间(秒)
     * @return true成功 false失败
     */
    public Boolean hmset(String key, Map<String, Object> map, Long time) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 向一张hash表中放入数据,如果不存在将创建
     *
     * @param key   键
     * @param item  项
     * @param value 值
     * @return true 成功 false失败
     */
    public Boolean hset(String key, String item, Object value) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 向一张hash表中放入数据,如果不存在将创建
     *
     * @param key   键
     * @param item  项
     * @param value 值
     * @param time  时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
     * @return true 成功 false失败
     */
    public Boolean hset(String key, String item, Object value, Long time) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 删除hash表中的值
     *
     * @param key  键 不能为 null
     * @param item 项 可以使多个不能为 null
     */
    public void hdel(String key, Object... item) {
        redisTemplate.opsForHash().delete(key, item);
    }

    /**
     * 判断hash表中是否有该项的值
     *
     * @param key  键 不能为 null
     * @param item 项 不能为 null
     * @return true 存在 false不存在
     */
    public Boolean hHasKey(String key, String item) {
        return redisTemplate.opsForHash().hasKey(key, item);
    }

    /**
     * hash递增 如果不存在,就会创建一个 并把新增后的值返回
     *
     * @param key  键
     * @param item 项
     * @param by   要增加几(大于0)
     * @return Double
     */
    public Double hincr(String key, String item, Double by) {
        return redisTemplate.opsForHash().increment(key, item, by);
    }

    /**
     * hash递减
     *
     * @param key  键
     * @param item 项
     * @param by   要减少记(小于0)
     * @return Double
     */
    public Double hdecr(String key, String item, Double by) {
        return redisTemplate.opsForHash().increment(key, item, -by);
    }

    /**
     * 根据 key获取 Set中的所有值
     *
     * @param key 键
     * @return Set
     */
    public Set<Object> sGet(String key) {
        try {
            return redisTemplate.opsForSet().members(key);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 根据value从一个set中查询,是否存在
     *
     * @param key   键
     * @param value 值
     * @return true 存在 false不存在
     */
    public Boolean sHasKey(String key, Object value) {
        try {
            return redisTemplate.opsForSet().isMember(key, value);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将数据放入set缓存
     *
     * @param key    键
     * @param values 值 可以是多个
     * @return 成功个数
     */
    public Long sSet(String key, Object... values) {
        try {
            return redisTemplate.opsForSet().add(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0L;
        }
    }

    /**
     * 将set数据放入缓存
     *
     * @param key    键
     * @param time   时间(秒)
     * @param values 值 可以是多个
     * @return 成功个数
     */
    public Long sSetAndTime(String key, Long time, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().add(key, values);
            if (time > 0) {
                expire(key, time);
            }
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0L;
        }
    }

    /**
     * 获取set缓存的长度
     *
     * @param key 键
     * @return Long
     */
    public Long sGetSetSize(String key) {
        try {
            return redisTemplate.opsForSet().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0L;
        }
    }

    /**
     * 移除值为value的
     *
     * @param key    键
     * @param values 值 可以是多个
     * @return 移除的个数
     */
    public Long setRemove(String key, Object... values) {
        try {
            return redisTemplate.opsForSet().remove(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0L;
        }
    }

    /**
     * 获取list缓存的内容
     *
     * @param key   键
     * @param start 开始
     * @param end   结束 0 到 -1代表所有值
     * @return List
     */
    public List<Object> lGet(String key, Long start, Long end) {
        try {
            return redisTemplate.opsForList().range(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取list缓存的长度
     *
     * @param key 键
     * @return Long
     */
    public Long lGetListSize(String key) {
        try {
            return redisTemplate.opsForList().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0L;
        }
    }

    /**
     * 通过索引 获取list中的值
     *
     * @param key   键
     * @param index 索引 index>=0时， 0 表头，1 第二个元素，依次类推；
     *              index<0时，-1，表尾，-2倒数第二个元素，依次类推
     * @return Object
     */
    public Object lGetIndex(String key, Long index) {
        try {
            return redisTemplate.opsForList().index(key, index);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @return Boolean
     */
    public Boolean lSet(String key, Object value) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒)
     * @return Boolean
     */
    public Boolean lSet(String key, Object value, Long time) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @return Boolean
     */
    public Boolean lSet(String key, List<Object> value) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒)
     * @return Boolean
     */
    public Boolean lSet(String key, List<Object> value, Long time) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据索引修改list中的某条数据
     *
     * @param key   键
     * @param index 索引
     * @param value 值
     * @return Boolean
     */
    public Boolean lUpdateIndex(String key, Long index, Object value) {
        try {
            redisTemplate.opsForList().set(key, index, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 移除N个值为value
     *
     * @param key   键
     * @param count 移除多少个
     * @param value 值
     * @return 移除的个数
     */
    public Long lRemove(String key, Long count, Object value) {
        try {
            return redisTemplate.opsForList().remove(key, count, value);
        } catch (Exception e) {
            e.printStackTrace();
            return 0L;
        }
    }

    public boolean setNx(String key, Object value, Long time) {
        if (time > 0) {
            return redisTemplate.opsForValue().setIfAbsent(key, value, time, TimeUnit.SECONDS);
        }
        return false;
    }


    /**
     * 添加元素到ZSet
     */
    public Boolean zAdd(String key, double score, Object value) {
        try {
            return redisTemplate.opsForZSet().add(key, value, score);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    // 增加ZSet元素的分数
    public Double zIncrementScore(String key, String value, double delta) {
        try {
            return redisTemplate.opsForZSet().incrementScore(key, value, delta);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    // 封装获取ZSet分数操作
    public Double zScore(String key, Object value) {
        try {
            return redisTemplate.opsForZSet().score(key, value);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    // 封装ZSet添加或更新分数操作
    public Boolean zAddOrUpdateScore(String key, Object value, double score) {
        try {
            return redisTemplate.opsForZSet().add(key, value, score);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 获取ZSet的大小
     */
    public Long zCard(String key) {
        try {
            return redisTemplate.opsForZSet().zCard(key);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 获取ZSet的大小
     */
    public Long zCount(String key, long start, long end) {
        try {
            return redisTemplate.opsForZSet().count(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    // 封装获取ZSet范围内成员的方法
    public Set<Object> zRange(String key, long start, long end) {
        try {
            ZSetOperations<String, Object> zSetOperations = redisTemplate.opsForZSet();
            return zSetOperations.range(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 删除ZSet中分数范围内的元素
     */
    public Long zRemoveRangeByScore(String key, double min, double max) {
        try {
            return redisTemplate.opsForZSet().removeRangeByScore(key, min, max);
        } catch (Exception e) {
            e.printStackTrace();
            return 0L;
        }
    }

    /**
     * 返回有序集 key 中，所有分数介于 min 和 max 之间（包括等于 min 或 max）的成员。
     * 有序集成员按分数值递增（从小到大）次序排列。
     * 此方法还支持限制返回的元素数量。
     *
     * @param key 有序集合的key
     * @param min 分数范围的最小值
     * @param max 分数范围的最大值
     * @param offset 开始返回的索引位置
     * @param count 返回的最大元素数量
     * @return 介于最小值和最大值之间的成员的集合
     */
    public Set<Object> zRangeByScore(String key, double min, double max, long offset, long count) {
        return redisTemplate.opsForZSet().rangeByScore(key, min, max, offset, count);
    }

    /**
     * 从ZSet获取所有成员及其分数
     * @param key ZSet的键
     * @return ZSet中所有成员及其分数的集合
     */
    public Set<ZSetOperations.TypedTuple<Object>> zRangeWithScores(String key, long start, long end){
        return redisTemplate.opsForZSet().rangeWithScores(key, start, end);
    }

    /**
     * 检查指定值是否存在于有序集合中
     * @param key
     * @param value
     * @return
     */
    public boolean checkValueExistsInZSet(String key, String value) {
        // 检查指定值是否存在于有序集合中
        return redisTemplate.opsForZSet().score(key, value) != null;
    }

    /**
     * 从ZSet中删除指定的成员
     *
     * @param key ZSet的键
     * @param value 要删除的成员值
     * @return 被成功移除的成员数量
     */
    public Long zRemove(String key, Object value) {
        try {
            return redisTemplate.opsForZSet().remove(key, value);
        } catch (Exception e) {
            e.printStackTrace();
            return 0L;
        }
    }




    public Set<String> keys(String name) {
        return redisTemplate.keys(name);
    }

    @AllArgsConstructor
    @Getter
    public enum key {

	    CORP_AUTH_MAPPING_KEY("mapping:corp:", "企业微信授权跳转", 60 * 60 * 24L),
	    CORP_ACCESSO_TOKEN_KEY("corp:access_token:", "corp_access_token", 60 * 30L),
	    MAPPING_INDEX_KEY("mapper:index:", "授权跳转", 60 * 10L),
        WX_LOGIN_AUTH_URI("wx_login_auth_uri:%s:%s", "微信网页授权登录uri", 60 * 60 * 24L),
        RECOMMEND_COUPON_DAY("recommend_coupon_day:%s", "推荐优惠券弹窗", 60 * 60 * 24L),
        EMAIL_CODE_KEY("email_code_key:%s", "邮箱验证码", 60 * 3),
        PHONE_CODE_KEY("phone_code_key:", "短信验证码", 60 * 3),
        PHONE_CODE_USER_NUM_KEY_DAY("phone_code_user_num_key:", "近一天获取验证码次数", 60 * 60 * 24l),
        PHONE_CODE_BALCK_KEY("phone_code_balck_key:", "手机黑名单", -1l),
        PHONE_CODE_RETRY_TIME_KEY("phone_code_retry_time_key:", "手机登录重试key", 60 * 3),
        BALCK_USER_IP_KEY("balck_user_ip_key:", "拉黑用户ip", 60 * 60 * 24),
        LOTTERY_KEY("lottery_key:%s", "抽奖key", 60 * 60 * 24l),
        TASK_TIME_LIMIT_KEY("task_time_limit:%s", "一次性任务key", 30),
        WX_GZH_QRCODE_LOGIN("wx_gzh_qrcode_login:%s", "微信公众号扫码登录key", 60),
        WX_GZH_QRCODE_BIND("wx_gzh_qrcode_bind:%s", "pc手机用户购买车票绑定wx", 60),
        WX_GZH_QRCODE_SHARED_LOGIN("wx_gzh_qrcode_shared_login:%s", "微信公众号扫码分享邀请key", 60),
        EQUIPMENT_DISTRIBUTE_COUPON_KEY("equipment_distribute_coupon_key:%s", "实物设备分销新用户优惠券展示key", 60),
        CMS_USER_KEY("cms:user:%s:", "user缓存前缀", 60 * 60 * 24L * 7),
        CMS_USER_ROLE_KEY("cms:user:role:%s:", "user角色缓存前缀", 60 * 60 * 24L * 7),
        CMS_USER_PERMISSION_KEY("cms:user:permission:%s:", "user权限缓存前缀", 60 * 60 * 24L * 7),
        REPEAT_USER_KEY("repeat_user_key:%s:", "重复用户插入key", 60l),
        BUSINESS_FIRST_ORDER_USER_KEY("business_first_order_user_key:%s:", "商务分销首单提成key", 60l),
        PC_WEB_CACHE("pc_web_cache", "首页平台缓存", 10 * 60),
        H5_WEB_CACHE("h5_web_cache", "h5首页平台缓存", 10 * 60),
        YH_HOME_PAGHE_CACHE("yh_home_paghe_cache:", "银河首页缓存", 30 * 60),
        YH_HOME_PAGHE_CACHE_SHOP("yh_home_paghe_cache:shop:", "银河首页店铺缓存", 40 * 60),
        YH_GOODS_QUESTIONS_DETAIL("yh_goods_questions_detail:%s:%s", "平台售后问题", 60 * 60 * 24),
        REGISTER_HOME_PAGE_CACHE("register_home_page_cache:", "注册首页缓存", 10 * 60),
        CPS_BACK_LOGIN_KEY("cps_back_login:", "cps商务后台登录key", 3 * 60),
        CPS_AUTH_SUCCESS_KEY("cps_auth_success_key:%s", "cps后台微信授权", 60 * 10),
        YH_SHOP_BACK_LOGIN_KEY("yh_shop_back_login:", "店铺主后台key", 3 * 60),
        YH_SHOP_AUTH_SUCCESS_KEY("yh_shop_auth_success_key:%s", "店铺主后台微信授权", 60 * 10),
        QUESTION_RESPONSE_KEY("question_response_key:%s", "问卷回答key", 60 * 60 * 24L),
        IMPORT_ACCOUNT_CACHE_KEY("import_account_cache_key:%s", "导入缓存key", 60 * 10L),
        MAKERTING_MSG_KEY("makerting_msg_key", "营销短信", 60 * 60 * 24 * 30),
        PHONE_AREA_CODE("phone_area_code:key", "国家或地区码", 60 * 60 * 24 * 15),
        CORP_CHAT_GROUP_CODE("corp_chat_group_code:", "企业微信群动态码", 60 * 60 * 24 * 15),
        CORP_SERVICE_QR_CODE("corp_service_qr_code:", "企业微信客服活码", 60 * 60 * 24 * 15),
        GENERAL_POPULARIZE_CODE("general_popularize_code:", "普通推广者关联优惠券", 10l),
        //企业微信欢迎语 临时素材 mediaId
        CORP_WECLOME_MEDIA("corp:%s:weclome:media:","临时素材 mediaId",60*60*24*3 - 60*60*1L),
        CORP_UPLOAD_ATTACHMENTS("corp:%s:upload:attachments:","临时附件",60*60*24*3 - 60*60*1L),
        CORP_DYNAMIC_RULE_TAG_KEY("corp_dynamic_rule_tag_key:", "企业微信动态标签key", 60 * 60L),
        ORDER_DON_POST_DATA_USER_KEY("order_don_post_data_user_key:", "用户订单回传缓存key", -1L),
        ABROAD_SUCCESS_URL("abroad:pay:success_url:","海外支付成功页",60 * 60 * 24L),
        CHAT_GPT_TOKEN_KEY("chat_gpt_token_key:", "chatGPT直连token key", 60 * 10l),
        CHAT_GPT_TOKEN_EXCEPTION_KEY("chat_gpt_token_exception_key:", "chatGPT直连token异常 key", -1l),
        ORDER_COMMENT_KEY("order_comment_key:", "订单评价", 10l),
        USER_BIND_ACCOUNT_INFO_KEY("user_bind_account_info_key:", "用户绑定其他账号key", 10l),
        TASK_RECEIVED_KEY("task_received_key:%s:%s", "领取任务奖励key", 10l),
        CORP_GROUP_CHAT_LIST("corp_group_chat_list:%s", "企业微信客户群列表", 60 * 60 * 24),
        PLUS_GOODS_ADDRESS_KEY("plus_goods_address_key:", "优惠加购实物地址key", 10 * 60l),
        GROUPS_TRIPS_OUTSIDE_RELATION("groups_trips_outside_relation:key:%s:%s", "额外车位", 30l),
        DISTRIBUTE_RULE_TIME_KEY("DISTRIBUTE_RULE_TIME_KEY", "渠道规格记录时间key", 5 * 60L),

        //巨量广告平台临时存储 callback
        OCEANENGINE_MONITOR_CALLBCAK("oceanengine:monitor:callback","巨量广告投放临时数据",60L*60L*24L),
        CORP_FOLLOW_ACTIVE_CODE_KEY("corp_follow_active_code_key:%s:%s", "活动客服活码key", 60 * 61),
        CORP_FOLLOW_ACTIVE_CODE_CLEAN_KEY("corp_follow_active_code_key:%s", "活动客服活码清除key", -1),
        REAL_GOODS_BENEFITS_KEY("real_goods_benefits_key:%s", "实物权益key", 60 * 5l),
        USER_DISTRIBUTE_ADD_KEY("user_distribute_add_key:%s", "分销用户新增key", 30l),

        CORP_CUSTOMER_ACQUISTION_CLICKID("corp:customer:post:%s","巨量投放，获客链接 跳转存储点击id",60*60*24),

        CORP_CUSTOMER_ACQUISTION_START_CHAT("corp:customer:post:start_chat","获客链接 发起回话存储点击id",60*60*24),

        CORP_CUSTOMER_ACQUISTION_START_CHAT_COUNT("corp:customer:post:start_chat:count:%s","获客链接 发起回话回传计数",60*60*24),

        CORP_CUSTOMER_ACQUISTION_START_CHAT_SET("corp:customer:post:start_chat_set","获客链接 发起回话待回传set",60*60*24),

        //获客链接 到企业微信内将平台标识与unionId 对应
        CORP_CUSTOMER_ACQUISTION_UNIONID_CLICKID("corp:customer:unionId:%s","unionid 对应的clickId",60*60*24),

        WEEKEND_DUTY_UNDERSTAFFED_NOTIFY("weekend_duty_understaffed_notify","周末值班人员不足短信通知key",60*60),
        DOUBLE_VERIFY_CODE_VIEW_MINUTES_KEY("double_verify_code_view_minutes_key","双重验证码查看同时间段人数限制",60),

        WX_INDENT_BIND_KEY("wx_indent_bind:key:", "微信身份授权绑定key", 60 * 60 * 24),
        EQUIPMENT_USER_SERVICE_RECORD("equipment_user_service_record:", "用户设备客服获取记录key", 60 * 60 * 24),
        INFORMATION_KEY("information_key:", "文章", 30 * 60L),
        CLOSE_ORDER_TIME_KEY("close_order_time_key:", "关闭订单key", 3 * 60),
        CLOSE_UPGRADE_ORDER_TIME_KEY("close_upgrade_order_time_key:", "关闭订单key", 3 * 60),
        CHATGPT_CONVERSATION_LIMIT("chatgpt:conversation:limit:", "chatGpt 对话限制", 3 * 60 * 60L),

        CHATGPT_CAR_SCORES("chatgpt:car:scores","chatGpt 车队分数", 48 * 60 * 60L),
        CHATGPT_CAR_HIGH_CHAT("chatgpt:car:high:chat:","chatGpt gpt4 对话次数", 48 * 60 * 60L),
        CHATGPT_CAR_LOW_CHAT("chatgpt:car:low:chat:","chatGpt 3.5 对话次数", 48 * 60 * 60L),

        //claude
        CLAUDE_CONVERSATION_LIMIT("claude:conversation:limit:", "claude 对话限制", 3 * 60 * 60L),
        CLAUDE_CAR_CHAT("claude:car:chat:","claude 对话次数", 48 * 60 * 60L),
        CLAUDE_CAR_SCORES("claude:car:scores","claude 车队分数", 48 * 60 * 60L),

        //车票到期前每日通知key
        TICKET_EXPIRY_NOTIFY_DAY("ticket_expiry_notify_day:%s:%s", "车票到期前每日通知key", 60 * 60 * 24L),
        MIDJOURNEY_FAST_LIMIT("midjourney:fast:limit:", "midjourney fast次数", 60 * 60 * 48L),
        MIDJOURNEY_UPGRADE_LIMIT("midjourney:upgrade:limit:", "midjourney upgrade次数", 60 * 60 * 48L),
        MIDJOURNEY_RELAX_LIMIT("midjourney:relax:limit:", "midjourney relax次数", 60 * 60 * 48L),
        MIDJOURNEY_EXPIRE_TIME("midjourney:expire:time:", "midjourney expire time", 60 * 60 * 48L),
        MIDJOURNEY_USER("midjourney:user:", "midjourney user", 60 * 60 * 2L),
        MIDJOURNEY_ACCOUNT("midjourney:account:", "midjourney account", 60 * 60 * 48L),
        APPLY_MONEY_DAY_LIMIT_KEY("apply_money_day_limit_key:%s:%s:%s", "每日提现次数限制", 60 * 60 * 24L * 2),
        NETFLIX_UPDATE_LIMIT_TIME("netflix_update_limit_time", "奈飞同步更新", 30l),
        NETFLIX_SET_LIMIT_TIME("netflix_set_limit_time", "奈飞设置限制", 30l),
        MIDJOURNEY_CAR_TASK("midjourney:car:task","midjourney car 任务数", 48 * 60 * 60L),
        SYS_CONFIG_CACHE_KEY("sys_config_cache_key:", "系统配置缓存key", 60 * 60 * 23L),
        NF_UPGRAD_USER_LIMIT_KEY("nf_upgrad_user_limit_key:%s:%s:%s", "奈飞同步装置key", 60 * 60L),

        LUMA_USER("luma_user:", "luma_user", 60 * 60 * 2L),
        LUMA_NUM_LIMIT("luma_num_limit:", "luma次数", 60 * 60 * 48L),
        NF_SET_TIME_LIMIT("nf_set_time_limit:", "设置pin码", 60l),
        NF_KICKOUT_TIME_LIMIT("nf_kickout_time_limit:", "踢出奈飞设备", 60l),
        GOODS_WHOLESALE_KEY("yh_home_paghe_cache:wholesale_key", "平台批发", 60 * 60 * 4L),
        USER_BENEFITS_KEY("yh_home_paghe_cache:user_benefits_key", "用户权益", 60 * 60 * 12L),
        USER_MIRROR_SHOP_BACK_LOGIN_KEY("user_mirror_shop_back_login:", "镜像店铺主后台key", 3 * 60),
        USER_MIRROR_SHOP_AUTH_SUCCESS_KEY("user_mirror_shop_auth_success_key:%s", "镜像店铺主后台微信授权", 60 * 10),
        USER_MIRROR_SHOP_ADVERTISE_CACHE_KEY("user_mirror_shop_advertise_cache_key:", "用户镜像店铺广告缓存key", 60 * 60 * 12),
        NETFLIX_CHANGE_TICKET_KEY("netflix_change_ticket_key:", "奈飞更换车票key", 60l),
        CORP_KF_ACCOUNT_URL("corp_kf_account_url:", "微信客服url:", 60 * 60 * 6),
        CORP_WX_YL_KEY("corp_wx_yl_key:", "企业微信引流", 60 * 30),
        TG_MINI_USER_SAHRE_COUNT_KEY("mini_popualrize_user_sahre_count_key:", "推广小程序用户分享次数key", 60 * 60 * 24l),
        GPT_RECHARGE_KEY("gpt_recharge_key:", "gpt代充", 60),
        GPT_RECHARGE_RECOVER_KEY("gpt_recharge_recover_key:", "gpt代充恢复key", 60 * 5l),
        CLAUDE_CODE_TY_DAY_CARD_KEY("claude_code_ty_day_card_key:", "claude_code体验天卡key", 30L),
        NANO_TY_DAY_CARD_KEY("nano_ty_day_card_key:", "nano体验天卡key", 30L),
        ;

        private String name;

        private String desc;

        private long timeout;

        public String getNameFormat(Object ... str) {
            return String.format(this.getName(), str);
        }

    }
}