package com.cyksj.redis; import com.cyksj.common.util.StringUtil; import lombok.AllArgsConstructor; import lombok.Getter; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ZSetOperations; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; 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 redisTemplate; public static String env = "dev"; @Value("${spring.profiles.active}") private String active; @PostConstruct public void init(){ env = active + ":"; } /** * 指定缓存失效时间 * * @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 hmget(String key) { return redisTemplate.opsForHash().entries(key); } /** * HashSet * * @param key 键 * @param map 对应多个键值 * @return true 成功 false 失败 */ public Boolean hmset(String key, Map 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 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 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 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 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 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 zRange(String key, long start, long end) { try { ZSetOperations 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 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> 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 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_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), NETFLIX_SET_LIMIT_TIME("netflix_set_limit_time", "奈飞设置限制", 30l), ; private String name; private String desc; private long timeout; public String getEnvName() { return this.name + env; } public String getNameFormat(Object ... str) { return String.format(this.getEnvName(), str); } } }