Jelajahi Sumber

提现失败自动补偿一次

wujiefeng 9 bulan lalu
induk
melakukan
8a933a8294

+ 5 - 0
RewardServer/pom.xml

@@ -104,6 +104,11 @@
 			<version>${project.version}</version>
 		</dependency>
 
+		<dependency>
+			<groupId>redis.clients</groupId>
+			<artifactId>jedis</artifactId>
+			<version>4.4.2</version>
+		</dependency>
 
 <!--		<dependency>-->
 <!--			<groupId>org.redisson</groupId>-->

+ 8 - 1
RewardServer/src/main/java/com/zhongshu/reward/server/core/controller/wallet/WalletController.java

@@ -73,10 +73,17 @@ public class WalletController {
 //    @ResourceAuth(value = "user", type = AuthType.User)
     @PostMapping (value = "transfer", consumes = MediaType.APPLICATION_JSON_VALUE)
     public Object transfer(@RequestBody WalletTransferParam param){
-        return wxTransferService.transfer(param);
+        return wxTransferService.transferLock(param);
     }
 
 
+    @Operation(summary = "发起提现lock", description = "发起提现")
+    @ResourceAuth(value = "user", type = AuthType.User)
+    @PostMapping (value = "transferLock", consumes = MediaType.APPLICATION_JSON_VALUE)
+    public Object transferLock(@RequestBody WalletTransferParam param){
+        return wxTransferService.transferLock(param);
+    }
+
     @Operation(summary = "查询提现列表", description = "查询提现列表")
     @ResourceAuth(value = "user", type = AuthType.User)
     @PostMapping (value = "queryTransfer", consumes = MediaType.APPLICATION_JSON_VALUE)

+ 22 - 7
RewardServer/src/main/java/com/zhongshu/reward/server/core/service/WxTransferService.java

@@ -2,13 +2,9 @@ package com.zhongshu.reward.server.core.service;
 
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.lang.Snowflake;
-import com.github.microservice.auth.client.content.ResultContent;
-import com.github.microservice.auth.client.content.ResultState;
+import com.zhongshu.reward.client.ret.ResultContent;
 import com.github.microservice.auth.security.helper.AuthHelper;
 import com.github.microservice.components.data.mongo.mongo.helper.DBHelper;
-import com.wechat.pay.java.core.exception.HttpException;
-import com.wechat.pay.java.core.exception.MalformedMessageException;
-import com.wechat.pay.java.core.exception.ServiceException;
 import com.wechat.pay.java.service.transferbatch.model.InitiateBatchTransferResponse;
 import com.wechat.pay.java.service.transferbatch.model.TransferBatchEntity;
 import com.wechat.pay.java.service.transferbatch.model.TransferDetailInput;
@@ -17,6 +13,7 @@ import com.zhongshu.reward.client.model.wallet.TransferModel;
 import com.zhongshu.reward.client.model.wallet.TransferStatusModel;
 import com.zhongshu.reward.client.model.wallet.WxTransferBatchModel;
 import com.zhongshu.reward.client.ret.CommentException;
+import com.zhongshu.reward.client.ret.ResultState;
 import com.zhongshu.reward.client.type.OperateType;
 import com.zhongshu.reward.client.type.TimeUnitType;
 import com.zhongshu.reward.client.type.TransferChannel;
@@ -31,12 +28,16 @@ import com.zhongshu.reward.server.core.domain.TransferRuler;
 import com.zhongshu.reward.server.core.domain.Wallet;
 import com.zhongshu.reward.server.core.domain.WxTransferBatch;
 import com.zhongshu.reward.server.core.util.DateUtils;
+import com.zhongshu.reward.server.core.util.JedisUtil;
+import com.zhongshu.reward.server.core.util.RedisDistributedLock;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
 import org.springframework.data.mongodb.core.aggregation.DateOperators;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import redis.clients.jedis.Jedis;
 
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
@@ -81,14 +82,28 @@ public class WxTransferService {
     @Autowired
     DBHelper dbHelper;
 
-//    private final ReentrantLock lock = new ReentrantLock();
+    @Autowired
+    JedisUtil jedisUtil;
+    private static final String TRANSFER = "com:zswl:reward:wxtransfer";
+
+    @Transactional
+    public ResultContent transferLock(WalletTransferParam param){
+        String userId = authHelper.getCurrentUser().getUserId();
+        if (jedisUtil.lock(userId + TRANSFER, 30L)){
+            log.info("发起提现");
+            return transfer(param);
+        }else {
+            log.info("获取锁失败");
+            return ResultContent.buildFail("请勿重复操作");
+        }
+    }
+
 
     /**
      * 发起提现
      * @param param
      * @return
      */
-    @Transactional
     public ResultContent transfer(WalletTransferParam param){
         String userId = authHelper.getCurrentUser().getUserId();
         OperateDisable operateDisable = operateDisableDao.findTopByUserIdAndType(userId, OperateType.TRANSFER);

+ 964 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/util/JedisUtil.java

@@ -0,0 +1,964 @@
+package com.zhongshu.reward.server.core.util;
+
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.extra.spring.SpringUtil;
+import com.alibaba.fastjson.JSON;
+import com.zhongshu.reward.server.core.util.ext.GeoRadiusResponseExt;
+import com.zhongshu.reward.server.core.util.ext.RedisExtProperties;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+import redis.clients.jedis.*;
+import redis.clients.jedis.args.GeoUnit;
+import redis.clients.jedis.params.GeoRadiusParam;
+import redis.clients.jedis.params.ScanParams;
+import redis.clients.jedis.params.SetParams;
+import redis.clients.jedis.resps.GeoRadiusResponse;
+import redis.clients.jedis.resps.ScanResult;
+import redis.clients.jedis.util.Pool;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @Author: wy
+ * @Date: 2023/6/8 15:51
+ */
+@Slf4j
+@Component
+public class JedisUtil {
+
+    private static final String LOCK_SUCCESS = "OK";
+
+    private static final Long RELEASE_SUCCESS = 1L;
+
+    private final Pool<Jedis> jedisPool;
+
+    private static Map<Integer, JedisUtil> map = new ConcurrentHashMap<>();
+
+    public JedisUtil(Pool<Jedis> jedisPool){
+        this.jedisPool = jedisPool;
+    }
+
+    public boolean lock(String lockKey, long expireTime) {
+        try (Jedis jedis = getRedisClient()){
+            long expires = System.currentTimeMillis() + expireTime + 1;
+            String expiresStr = String.valueOf(expires); // 锁到期时间
+
+            if (jedis.setnx(lockKey, expiresStr) == 1) {
+                // 获取锁成功
+                jedis.expire(lockKey, expireTime); // 设置锁的过期时间
+                return true;
+            }
+
+            String currentValueStr = jedis.get(lockKey); // Redis里面的时间
+            if (currentValueStr != null && Long.parseLong(currentValueStr) < System.currentTimeMillis()) {
+                // 锁已经存在,但已经过期,可以尝试获取锁
+                String oldValueStr = jedis.getSet(lockKey, expiresStr);
+                if (oldValueStr != null && oldValueStr.equals(currentValueStr)) {
+                    // 获取锁成功
+                    jedis.expire(lockKey, expireTime); // 设置锁的过期时间
+                    return true;
+                }
+            }
+            // 其他情况,无法获取锁
+            return false;
+        }catch (Exception e){
+            log.error("jedis执行异常......", e);
+            return false;
+        }
+
+    }
+
+    public Set<String> keys(final String pattern) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.keys(pattern);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        }
+    }
+
+    public String get(final String key) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.get(key);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        }
+    }
+
+    public String set(final String key, final String value) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.set(key, value);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        }
+    }
+
+    public String setex(final String key, final String value, final int seconds) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.setex(key, seconds, value);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        }
+    }
+
+    public long expire(final String key, final int seconds) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.expire(key, seconds);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return 0L;
+        }
+
+    }
+
+    public List<String> mget(final String... keys) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.mget(keys);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        }
+
+    }
+
+    public String hget(final String key, final String field) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.hget(key, field);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        }
+    }
+
+    public long hset(final String key, final String field, final String value) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.hset(key, field, value);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return 0;
+        }
+    }
+
+    public String hmset(final String key, final Map<String, String> map) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.hmset(key, map);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        }
+    }
+
+    public String hmsetex(final String key, final Map<String, String> map, final int seconds) {
+        try (Jedis jedis = getRedisClient()) {
+            String hmset = jedis.hmset(key, map);
+            jedis.expire(key, seconds);
+            return hmset;
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        }
+    }
+
+    public Map<String, String> hmget(final String key) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.hgetAll(key);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        }
+    }
+
+    public Long del(final String key) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.del(key);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        }
+    }
+
+    public Long del(final String... keys) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.del(keys);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        }
+    }
+
+    public Long hdel(final String key, final String... fields) {
+        Jedis jedis = null;
+        try {
+            if (null == fields || fields.length == 0) {
+                return 0L;
+            }
+            List<String> array = new ArrayList<>();
+            for (String field : fields) {
+                if (null != field && !field.isEmpty()) {
+                    array.add(field);
+                }
+            }
+            if (array.size() <= 0) {
+                return 0L;
+            }
+            jedis = getRedisClient();
+            String[] a = new String[array.size()];
+            return jedis.hdel(key, array.toArray(a));
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        } finally {
+            if (null != jedis) {
+                jedis.close();
+            }
+        }
+    }
+
+    public Long lpush(final String key, final String... values) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.lpush(key, values);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        }
+    }
+
+    public List<String> lrange(final String key, final Long start, final Long end) {
+        try (Jedis jedis = getRedisClient()) {
+            Long startTemp = start, endTemp = end;
+            if (null == startTemp) {
+                startTemp = 0L;
+            }
+            if (null == endTemp) {
+                endTemp = -1L;
+            }
+            return jedis.lrange(key, startTemp, endTemp);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        }
+    }
+
+    public String ltrim(String key, Long start, Long stop) {
+        try (Jedis jedis = getRedisClient()) {
+            Long startTemp = start, endTemp = stop;
+            if (null == startTemp) {
+                startTemp = 0L;
+            }
+            if (null == endTemp) {
+                endTemp = -1L;
+            }
+            return jedis.ltrim(key, startTemp, endTemp);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        }
+    }
+
+    public List<String> scan(final int cursor, final String pattern, final Integer count) {
+        Jedis jedis = null;
+        try {
+            ScanParams scanParams = new ScanParams();
+            int defaultCount = 100;
+            boolean queryAll = false;
+            if (null != count) {
+                defaultCount = count;
+            } else {
+                queryAll = true;
+            }
+            scanParams.count(defaultCount);
+            scanParams.match(pattern);
+            ScanResult<String> result;
+            jedis = getRedisClient();
+            result = jedis.scan(String.valueOf(cursor), scanParams);
+            if (!queryAll) {
+                return result.getResult();
+            }
+            // 模拟查询所有的数据
+            String i = result.getCursor();
+            List<String> all = new ArrayList<>(result.getResult());
+            while (!"0".equals(i)) {
+                result = jedis.scan(i, scanParams);
+                i = result.getCursor();
+                all.addAll(result.getResult());
+            }
+            return all;
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        } finally {
+            if (null != jedis) {
+                jedis.close();
+            }
+        }
+    }
+
+    public String mset(Map<String, String> map) {
+        if (null == map || map.isEmpty()) {
+            return null;
+        }
+        int len = map.size() * 2;
+        String[] keysvalues = new String[len];
+        List<String> keyvalueList = new ArrayList<>(len);
+        for (Map.Entry<String, String> entry : map.entrySet()) {
+            keyvalueList.add(entry.getKey());
+            keyvalueList.add(entry.getValue());
+        }
+        return mset(keyvalueList.toArray(keysvalues));
+    }
+
+    public String mset(String... keysvalues) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.mset(keysvalues);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        }
+    }
+
+    public Long msetnx(Map<String, String> map) {
+        if (null == map || map.isEmpty()) {
+            return null;
+        }
+        int len = map.size() * 2;
+        String[] keysvalues = new String[len];
+        List<String> keyvalueList = new ArrayList<>(len);
+        for (Map.Entry<String, String> entry : map.entrySet()) {
+            keyvalueList.add(entry.getKey());
+            keyvalueList.add(entry.getValue());
+        }
+        return msetnx(keyvalueList.toArray(keysvalues));
+    }
+
+    public Long msetnx(String... keysvalues) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.msetnx(keysvalues);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        }
+    }
+
+    public boolean distributedLock(String lockKey, String requestId, long expireTime) {
+        try (Jedis jedis = getRedisClient()) {
+            SetParams params = SetParams.setParams().nx().ex((int) expireTime);
+            String ret = jedis.set(lockKey, requestId, params);
+            return LOCK_SUCCESS.equals(ret);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return false;
+        }
+    }
+
+    public boolean releaseDistributedLock(String lockKey, String requestId) {
+        try (Jedis jedis = getRedisClient()) {
+            String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
+            Object obj = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
+            return RELEASE_SUCCESS.equals(obj);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return false;
+        }
+    }
+
+    public Long zrem(String key, String member) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.zrem(key, member);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        }
+    }
+
+    public Long geoadd(String key, double longitude, double latitude, String member) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.geoadd(key, longitude, latitude, member);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        }
+    }
+
+    
+    public Long incr(String key) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.incr(key);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        }
+    }
+
+    public Long lrem(String key, int count, String value) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.lrem(key, count, value);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        }
+    }
+
+    public Long hincrBy(String key, String field, Long value) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.hincrBy(key, field, value);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        }
+    }
+
+    public List<String> get(String... keys) {
+        if (null == keys || keys.length == 0) {
+            return null;
+        }
+        try (Jedis jedis = getRedisClient()) {
+            Pipeline pipelined = jedis.pipelined();
+            for (String key : keys) {
+                pipelined.get(key);
+            }
+            List<Object> responses = pipelined.syncAndReturnAll();
+            List<String> results = new ArrayList<>(responses.size());
+            for (Object o : responses) {
+                results.add(o == null ? null : o.toString());
+            }
+            return results;
+        }
+    }
+
+    public void set(String[]... kvs) {
+        setKeyValueExpire(null, kvs);
+    }
+
+    public void setex(String[]... kvs) {
+        if (null == kvs || kvs.length == 0) {
+            return;
+        }
+        try (Jedis jedis = getRedisClient()) {
+            Pipeline pipelined = jedis.pipelined();
+            for (String[] kv : kvs) {
+                if (kv == null || kv.length < 3) {
+                    continue;
+                }
+                pipelined.setex(kv[0], Integer.parseInt(kv[1]), kv[2]);
+            }
+            pipelined.sync();
+        }
+    }
+
+    public void expire(int seconds, String... ks) {
+        if (null == ks || ks.length == 0) {
+            return;
+        }
+        List<String[]> list = new ArrayList<>(ks.length);
+        for (String k : ks) {
+            list.add(new String[]{k, String.valueOf(seconds)});
+        }
+        expire(list);
+    }
+
+    public void expire(String[]... ks) {
+        if (null == ks || ks.length == 0) {
+            return;
+        }
+        List<String[]> list = new ArrayList<>(ks.length);
+        list.addAll(Arrays.asList(ks));
+        expire(list);
+    }
+
+    public void expireAt(long unixTime, String... ks) {
+        if (null == ks || ks.length == 0) {
+            return;
+        }
+        List<String[]> list = new ArrayList<>(ks.length);
+        for (String k : ks) {
+            list.add(new String[]{k, unixTime + ""});
+        }
+        expireAt(list);
+    }
+
+    public void expireAt(String[]... ks) {
+        if (null == ks || ks.length == 0) {
+            return;
+        }
+        List<String[]> list = new ArrayList<>(ks.length);
+        Collections.addAll(list, ks);
+        expireAt(list);
+    }
+
+    public List<String> hget(String key, String... fields) {
+        if (null == key || fields == null || fields.length == 0) {
+            return null;
+        }
+        try (Jedis jedis = getRedisClient()) {
+            Pipeline pipelined = jedis.pipelined();
+            for (String field : fields) {
+                pipelined.hget(key, field);
+            }
+            List<Object> retList = pipelined.syncAndReturnAll();
+            List<String> list = new ArrayList<>(retList.size());
+            for (Object o : retList) {
+                list.add(o == null ? null : o.toString());
+            }
+            return list;
+        }
+    }
+
+    public Map<String, String> hgetAll(String key) {
+        if (null == key) {
+            return null;
+        }
+        try (Jedis jedis = getRedisClient()) {
+            Pipeline pipeline = jedis.pipelined();
+            Response<Map<String, String>> hgetAll = pipeline.hgetAll(key);
+            pipeline.sync();
+            return hgetAll.get();
+        }
+    }
+
+    public void hset(String key, String[]... kvs) {
+        if (null == key || null == kvs || kvs.length == 0) {
+            return;
+        }
+        try (Jedis jedis = getRedisClient()) {
+            Pipeline pipelined = jedis.pipelined();
+            for (String[] kv : kvs) {
+                if (kv.length < 2) {
+                    continue;
+                }
+                pipelined.hset(key, kv[0], kv[1]);
+            }
+            pipelined.sync();
+        }
+    }
+
+    public <T> T getConfigStrToObj(String key, Class<T> clazz, T defaultValue) {
+        try {
+            T re;
+            String value = get(key);
+            if (StringUtils.isEmpty(value)) {
+                re = defaultValue;
+                if (defaultValue != null) {
+                    set(key, JSON.toJSONString(defaultValue));
+                }
+            } else {
+                re = JSON.parseObject(value, clazz);
+            }
+            return re;
+        } catch (Exception e) {
+            log.error("执行异常", e);
+            return defaultValue;
+        }
+    }
+
+    public Integer getConfigStrToInteger(String key, Integer defaultValue) {
+        try {
+            Integer re;
+            String value = get(key);
+            if (StringUtils.isBlank(value)) {
+                re = defaultValue;
+                if (defaultValue != null) {
+                    set(key, defaultValue + "");
+                }
+            } else {
+                re = Integer.parseInt(value);
+            }
+            return re;
+        } catch (Exception e) {
+            log.error("执行异常", e);
+            return defaultValue;
+        }
+    }
+
+    public long expireAt(String key, long unixTime) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.expireAt(key, unixTime);
+        } catch (Exception e) {
+            log.error("执行异常", e);
+            return 0;
+        }
+    }
+
+    public boolean exists(String key) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.exists(key);
+        } catch (Exception e) {
+            log.error("执行异常", e);
+            return false;
+        }
+
+    }
+
+    public String getSet(String key, String value) {
+        if (null == key || key.trim().isEmpty() || null == value) {
+            return null;
+        }
+        try (Jedis jedis = this.getRedisClient()) {
+            return jedis.getSet(key, value);
+        } catch (Exception e) {
+            log.error("执行异常", e);
+            return null;
+        }
+    }
+
+    protected Jedis getRedisClient() {
+        return jedisPool.getResource();
+    }
+
+    private void expire(List<String[]> ks) {
+        if (null == ks || ks.size() == 0) {
+            return;
+        }
+        try (Jedis jedis = getRedisClient()) {
+            Pipeline pipeline = jedis.pipelined();
+            for (String[] key : ks) {
+                if (key.length < 2) {
+                    continue;
+                }
+                pipeline.expire(key[0], Integer.parseInt(key[1]));
+            }
+            pipeline.sync();
+        }
+    }
+
+    private void expireAt(List<String[]> ks) {
+        if (null == ks || ks.size() == 0) {
+            return;
+        }
+        try (Jedis jedis = getRedisClient()) {
+            Pipeline pipeline = jedis.pipelined();
+            for (String[] key : ks) {
+                if (key.length < 2) {
+                    continue;
+                }
+                pipeline.expireAt(key[0], Long.parseLong(key[1]));
+            }
+            pipeline.sync();
+        }
+    }
+
+    private void setKeyValueExpire(Integer seconds, String[]... kvs) {
+        if (null == kvs || kvs.length == 0) {
+            return;
+        }
+        try (Jedis jedis = getRedisClient()) {
+            Pipeline pipelined = jedis.pipelined();
+            for (String[] kv : kvs) {
+                if (kv == null) {
+                    continue;
+                }
+                if (kv.length < 2) {
+                    if (null == seconds) {
+                        pipelined.set(kv[0], "");
+                    } else {
+                        pipelined.setex(kv[0], seconds, "");
+                    }
+                } else {
+                    if (null == seconds) {
+                        pipelined.set(kv[0], kv[1]);
+                    } else {
+                        pipelined.setex(kv[0], seconds, kv[1]);
+                    }
+                }
+            }
+            pipelined.sync();
+        }
+    }
+
+    
+    public Long geoAdd(String key, Map<String, GeoCoordinate> memberCoordinateMap) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.geoadd(key, memberCoordinateMap);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return 0L;
+        }
+    }
+
+    
+    public Double geoDist(String key, String member1, String member2, GeoUnit geoUnit) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.geodist(key, member1, member2, geoUnit);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return 0.00D;
+        }
+    }
+
+    
+    public List<String> geoHash(String key, String... members) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.geohash(key, members);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return new ArrayList<>();
+        }
+    }
+
+    
+    public List<GeoCoordinate> geoPos(String key, String... members) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.geopos(key, members);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return new ArrayList<>();
+        }
+    }
+
+    
+    public List<GeoRadiusResponseExt> geoRadius(String key, GeoCoordinate coordinate, double radius, int count) {
+        try (Jedis jedis = getRedisClient()) {
+            List<GeoRadiusResponse> georadius = jedis.georadius(key,
+                    coordinate.getLongitude(),
+                    coordinate.getLatitude(),
+                    radius,
+                    GeoUnit.KM,
+                    GeoRadiusParam.geoRadiusParam().withDist().withCoord().count(count).sortAscending());
+            return GeoRadiusResponseExt.toExt(georadius);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return new ArrayList<>();
+        }
+    }
+
+    
+    public List<GeoRadiusResponseExt> geoRadiusByMember(String key, String member, double radius) {
+        try (Jedis jedis = getRedisClient()) {
+            List<GeoRadiusResponse> georadius = jedis.georadiusByMember(key,
+                    member,
+                    radius,
+                    GeoUnit.KM,
+                    GeoRadiusParam.geoRadiusParam().withDist().withCoord().sortAscending());
+            return GeoRadiusResponseExt.toExt(georadius);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return new ArrayList<>();
+        }
+    }
+
+    /**
+     * 获取指定key的所有set信息
+     */
+    public List<String> zRange(String key) {
+        try (Jedis jedis = getRedisClient()) {
+
+            return jedis.zrange(key, 0, -1);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return new ArrayList<>();
+        }
+    }
+
+    public long zadd(String key, Long score, String topicId) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.zadd(key, Double.valueOf(score), topicId);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return -1;
+        }
+    }
+
+    public long zrem(String key, String... members) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.zrem(key, members);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return -1;
+        }
+    }
+
+    public long zremrangeByRank(String key, long start, long stop) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.zremrangeByRank(key, start, stop);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return -1;
+        }
+    }
+
+    public List<String> zrevrange(String key, long start, long stop) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.zrevrange(key, start, stop);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return new ArrayList<>();
+        }
+    }
+
+    /**
+     * 查询小于等于当前权重的值
+     */
+    public List<String> zrangeByScore(String key, Long score) {
+        try (Jedis jedis = getRedisClient()) {
+            List<String> strings = jedis.zrangeByScore(key, Double.valueOf(0), Double.valueOf(score));
+            /* jedis.zremrangeByScore(key,"0",score+"");*/
+            return strings;
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return new ArrayList<>();
+        }
+    }
+
+    public String bLpop(Integer timeOut, String key) {
+        try (Jedis jedis = getRedisClient()) {
+            List<String> blpop = jedis.blpop(timeOut, key);
+            String result = CollectionUtils.isEmpty(blpop) ? null : ArrayUtil.isEmpty(blpop.get(1)) ? null : StringUtils.strip(blpop.get(1), "[]");
+            log.info("redis获取消费队列数据" + result);
+            return result;
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        }
+    }
+
+
+    public Long rpush(String key, String values) {
+        try (Jedis jedis = getRedisClient()) {
+            Long rpush = jedis.rpush(key, values);
+            return rpush;
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        }
+    }
+
+    public String brpop(int i, String callBackRdListTopicPre) {
+        try (Jedis jedis = getRedisClient()) {
+            List<String> brpop = jedis.brpop(i, callBackRdListTopicPre);
+            String result = CollectionUtils.isEmpty(brpop) ? null : ArrayUtil.isEmpty(brpop.get(1)) ? null : StringUtils.strip(brpop.get(1), "[]");
+            return result;
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        }
+    }
+
+    public String rpop(String key) {
+        try (Jedis jedis = getRedisClient()) {
+            String value = jedis.rpop(key);
+            return value;
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        }
+    }
+
+    public Long sadd(String key, String... value) {
+        try (Jedis jedis = getRedisClient()) {
+            Long sadd = jedis.sadd(key, value);
+            return sadd;
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        }
+    }
+
+    public Set<String> smembers(String key) {
+        try (Jedis jedis = getRedisClient()) {
+            Set<String> smembers = jedis.smembers(key);
+            return smembers;
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        }
+    }
+
+    public Boolean sismember(String key, String Value) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.sismember(key, Value);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        }
+    }
+
+    public Long srem(String key,String... val){
+        try (Jedis jedis = getRedisClient()) {
+            Long srem = jedis.srem(key, val);
+            return srem;
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        }
+    }
+
+    public String spop(String key){
+        try (Jedis jedis = getRedisClient()) {
+            String spop = jedis.spop(key);
+            return spop;
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        }
+    }
+
+    public Long scard(String key){
+        try (Jedis jedis = getRedisClient()) {
+            Long scard = jedis.scard(key);
+            return scard;
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return null;
+        }
+    }
+
+    /**
+     * 减少指定的值(核减)
+     * @param key
+     * @param num
+     * @return long
+     **/
+    public long decrby(String key, long num) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.decrBy(key,num);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return 0L;
+        }
+    }
+
+    /**
+     * 增加指定的值(核增)
+     *
+     * @param key
+     * @param num
+     * @return long
+     **/
+    public long incrby(String key, long num) {
+        try (Jedis jedis = getRedisClient()) {
+            return jedis.incrBy(key,num);
+        } catch (Exception e) {
+            log.error("jedis执行异常......", e);
+            return 0L;
+        }
+    }
+
+    /**
+     * 指定db
+     * @param db
+     */
+    public JedisUtil assignDb(int db) {
+        if (Objects.nonNull(map.get(db))) {
+            return map.get(db);
+        }
+        RedisExtProperties redisExtProperties = SpringUtil.getBean(RedisExtProperties.class);
+        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
+        jedisPoolConfig.setMaxTotal(redisExtProperties.getMaxActive());
+        jedisPoolConfig.setMaxIdle(redisExtProperties.getMaxIdle());
+        jedisPoolConfig.setMinIdle(redisExtProperties.getMinIdle());
+        JedisPool jedisPool = new JedisPool(jedisPoolConfig, redisExtProperties.getHost()
+                , redisExtProperties.getPort()
+                , redisExtProperties.getTimeout()
+                , null
+                , db);
+        JedisUtil jedis = new JedisUtil(jedisPool);
+        map.put(db, jedis);
+        return jedis;
+    }
+
+}

+ 74 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/util/RedisDistributedLock.java

@@ -0,0 +1,74 @@
+package com.zhongshu.reward.server.core.util;
+
+import org.springframework.stereotype.Component;
+import redis.clients.jedis.Jedis;
+
+/**
+ * @author wjf
+ * @date 2024/8/19
+ */
+
+public class RedisDistributedLock {
+    private Jedis jedis;
+    private String lockKey;
+    private int expireTime; // 锁的超时时间
+
+    public RedisDistributedLock(Jedis jedis, String lockKey, int expireTime) {
+        this.jedis = jedis;
+        this.lockKey = lockKey;
+        this.expireTime = expireTime;
+    }
+
+    public boolean lock() {
+        long expires = System.currentTimeMillis() + expireTime + 1;
+        String expiresStr = String.valueOf(expires); // 锁到期时间
+
+        if (jedis.setnx(lockKey, expiresStr) == 1) {
+            // 获取锁成功
+            jedis.expire(lockKey, expireTime); // 设置锁的过期时间
+            return true;
+        }
+
+        String currentValueStr = jedis.get(lockKey); // Redis里面的时间
+        if (currentValueStr != null && Long.parseLong(currentValueStr) < System.currentTimeMillis()) {
+            // 锁已经存在,但已经过期,可以尝试获取锁
+            String oldValueStr = jedis.getSet(lockKey, expiresStr);
+            if (oldValueStr != null && oldValueStr.equals(currentValueStr)) {
+                // 获取锁成功
+                jedis.expire(lockKey, expireTime); // 设置锁的过期时间
+                return true;
+            }
+        }
+        // 其他情况,无法获取锁
+        return false;
+    }
+
+    public void unlock() {
+        // 确保是该用户持有的锁才能释放
+        String currentValueStr = jedis.get(lockKey);
+        if (currentValueStr != null && Long.parseLong(currentValueStr) == System.currentTimeMillis()) {
+            jedis.del(lockKey); // 释放锁
+        }
+    }
+
+    public static void main(String[] args) {
+        Jedis jedis = new Jedis("localhost");
+        RedisDistributedLock lock = new RedisDistributedLock(jedis, "user_1001", 1000);
+
+        try {
+            if (lock.lock()) {
+                // 执行业务逻辑
+                System.out.println("执行业务逻辑...");
+                // 模拟耗时操作
+                Thread.sleep(2000);
+            } else {
+                System.out.println("未获取到锁,其他实例可能正在操作...");
+            }
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        } finally {
+            lock.unlock();
+            jedis.close();
+        }
+    }
+}

+ 39 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/util/ext/GeoRadiusResponseExt.java

@@ -0,0 +1,39 @@
+package com.zhongshu.reward.server.core.util.ext;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.util.CollectionUtils;
+import redis.clients.jedis.GeoCoordinate;
+import redis.clients.jedis.resps.GeoRadiusResponse;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @Author: wy
+ * @Date: 2023/6/8 16:02
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class GeoRadiusResponseExt {
+
+    private String member;
+    private double distance;
+    private GeoCoordinate coordinate;
+
+    public static List<GeoRadiusResponseExt> toExt(List<GeoRadiusResponse> params) {
+        List<GeoRadiusResponseExt> result = new ArrayList<>();
+        if (!CollectionUtils.isEmpty(params)) {
+            for (GeoRadiusResponse param : params) {
+                GeoRadiusResponseExt ext = new GeoRadiusResponseExt();
+                ext.setCoordinate(param.getCoordinate());
+                ext.setDistance(param.getDistance());
+                ext.setMember(param.getMemberByString());
+                result.add(ext);
+            }
+        }
+        return result;
+    }
+}

+ 53 - 0
RewardServer/src/main/java/com/zhongshu/reward/server/core/util/ext/RedisExtProperties.java

@@ -0,0 +1,53 @@
+package com.zhongshu.reward.server.core.util.ext;
+
+import lombok.Data;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import redis.clients.jedis.JedisPool;
+import redis.clients.jedis.JedisPoolConfig;
+
+/**
+ * @Author: wy
+ * @Date: 2023/6/8 16:15
+ */
+@Data
+@Configuration
+public class RedisExtProperties {
+
+    @Value("${spring.redis.host}")
+    private String host;
+
+    @Value("${spring.redis.port}")
+    private int port;
+
+    @Value("${spring.redis.password}")
+    private String password;
+
+    @Value("${spring.redis.database}")
+    private Integer database;
+
+    @Value("${spring.redis.timeout}")
+    private int timeout;
+
+    @Value("${spring.redis.jedis.pool.max-active}")
+    private Integer maxActive;
+
+    @Value("${spring.redis.jedis.pool.max-idle}")
+    private Integer maxIdle;
+
+    @Value("${spring.redis.jedis.pool.min-idle}")
+    private Integer minIdle;
+
+    @Bean
+    public JedisPool jedisPool() {
+        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
+        jedisPoolConfig.setMinIdle(minIdle);
+        jedisPoolConfig.setMaxIdle(maxIdle);
+        jedisPoolConfig.setMaxTotal(maxActive);
+        jedisPoolConfig.setJmxEnabled(false);
+        return new JedisPool(jedisPoolConfig, host, port, timeout, null, database);
+    }
+
+
+}