Bläddra i källkod

fix:游客登陆接口幂等处理

hidewnd 1 månad sedan
förälder
incheckning
358678eb16

+ 2 - 0
yt-common/src/main/java/com/ytpm/app/param/LoginParam.java

@@ -47,5 +47,7 @@ public class LoginParam {
     @ApiModelProperty(value = "设备ID", required = false)
     private String deviceId;
 
+    @ApiModelProperty(value = "幂等性ID")
+    private String requestId;
 
 }

+ 2 - 0
yt-common/src/main/java/com/ytpm/handle/LoginServiceFactory.java

@@ -53,6 +53,8 @@ public class LoginServiceFactory {
             return Result.resultOk(RepMessage.LOGIN_SUCCESS, ytDyzUser);
         } catch (CommonException e) {
             return new Result<>(StatusCode.ACCESS_ERR, e.getMessage());
+        } catch (IllegalArgumentException e) {
+            return new Result<>(StatusCode.PARAMETER_CHECK_ERR, e.getMessage());
         }
     }
 

+ 22 - 0
yt-question/yt-question-service/src/main/java/com/ytpm/question/controller/VisitorController.java

@@ -1,11 +1,14 @@
 package com.ytpm.question.controller;
 
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.StrUtil;
 import com.ytpm.app.enums.LoginType;
 import com.ytpm.app.model.YtDyzUser;
 import com.ytpm.app.param.VisitorLoginParam;
 import com.ytpm.general.Result;
 import com.ytpm.handle.LoginServiceFactory;
 import com.ytpm.question.dao.AppUserMapper;
+import com.ytpm.question.redis.RedisService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.cloud.context.config.annotation.RefreshScope;
@@ -38,6 +41,25 @@ public class VisitorController {
     @Resource
     private LoginServiceFactory loginServiceFactory;
 
+    @Resource
+    private RedisService redisService;
+
+    @ApiOperation("获取游客登陆幂等Token")
+    @GetMapping("/get/requestId")
+    public Result<String> getRequestId(@RequestParam("ditchId") String ditchId, @RequestParam("appType") String appType,
+                                       @RequestParam("deviceId") String deviceId){
+        String redisKey = StrUtil.format("visitor:requestId:{}:{}:{}", ditchId, appType, deviceId);
+        String requestId = "";
+        if (redisService.hasKey(redisKey)) {
+            requestId = redisService.getStr(redisKey);
+        }
+        if (StrUtil.isEmpty(requestId)) {
+            requestId = IdUtil.fastSimpleUUID();
+            redisService.setTimeOutMinutesStr(redisKey, requestId, 1);
+        }
+        return Result.resultObjOk(requestId);
+    }
+
     @PostMapping("/login")
     @ApiOperation("游客登录")
     @Transactional(rollbackFor = Exception.class)

+ 1 - 1
yt-question/yt-question-service/src/main/java/com/ytpm/question/monitor/RedisKeyExpirationListener.java

@@ -47,7 +47,7 @@ public class RedisKeyExpirationListener extends KeyExpirationEventMessageListene
     @Override
     public void onMessage(Message message, byte[] pattern) {
         String key = String.valueOf(message);
-        log.error("App-Service 发现预定风控用户:{}", key);
+        log.info("App-Service 发现预定风控用户:{}", key);
         if (!key.endsWith(applicationName)) {
             return;
         }

+ 13 - 1
yt-question/yt-question-service/src/main/java/com/ytpm/question/service/impl/VisitorLoginServiceImpl.java

@@ -95,7 +95,19 @@ public class VisitorLoginServiceImpl extends AbstractLoginService {
 
     @Override
     protected void validateParams(LoginParam loginParam, HttpServletRequest request) {
-
+        if (StrUtil.isNotEmpty(loginParam.getRequestId())) {
+            // 游客登陆幂等校验
+            String redisKey = StrUtil.format("visitor:requestId:{}:{}:{}", loginParam.getDitchId(),
+                    loginParam.getAppType(), loginParam.getDeviceId());
+            if (!redisService.hasKey(redisKey)) {
+                throw new IllegalArgumentException("重复请求");
+            }
+            String cacheKey = redisService.getStr(redisKey);
+            if (!StrUtil.equals(cacheKey, loginParam.getRequestId())) {
+                throw new IllegalArgumentException("重复请求");
+            }
+            redisService.del(redisKey);
+        }
     }
 
     @Override