Forráskód Böngészése

小程序一键登录修改

hxd 3 hónapja
szülő
commit
7c20bc0cd5

+ 2 - 2
portal-service-application/src/main/java/com/hfln/portal/application/controller/wap/UserController.java

@@ -131,9 +131,9 @@ public class UserController {
 
     @GetMapping("/getUserPhone")
     @ApiOperation(value = "获取用户手机号码")
-    public ApiResult<Map<String, String>> getUserPhone(@RequestParam String code) {
+    public ApiResult<Map<String, String>> getUserPhone(@RequestParam String code, String accessToken) {
         Map<String, String> result = new HashMap<>();
-        result.put("phone", userGateway.getUserPhone(code));
+        result.put("phone", userGateway.getUserPhone(code, accessToken));
         return ApiResult.success(result);
     }
 

+ 14 - 12
portal-service-application/src/test/java/com/hfln/portal/application/controller/wap/UserControllerTest.java

@@ -489,16 +489,17 @@ class UserControllerTest {
     void getUserPhone_Success() {
         // 准备测试数据
         String code = "valid_code";
+        String accessToken = "valid_access_token";
         String expectedPhone = TEST_PHONE;
         
         // 模拟UserGateway的行为
-        when(userGateway.getUserPhone(code)).thenReturn(expectedPhone);
+        when(userGateway.getUserPhone(code, accessToken)).thenReturn(expectedPhone);
         
         // 执行测试
-        ApiResult<Map<String, String>> result = userController.getUserPhone(code);
+        ApiResult<Map<String, String>> result = userController.getUserPhone(code, accessToken);
         
         // 验证交互
-        verify(userGateway, times(1)).getUserPhone(code);
+        verify(userGateway, times(1)).getUserPhone(code, accessToken);
         
         // 验证结果
         assertEquals(SUCCESS_CODE, ReflectionTestUtils.getField(result, "code"));
@@ -513,37 +514,38 @@ class UserControllerTest {
     void getUserPhone_Failed() {
         // 准备测试数据
         String invalidCode = "invalid_code";
+        String invalidAccessToken = "invalid_access_token";
 
         // 模拟UserGateway的行为 - 返回空字符串表示获取失败
-        when(userGateway.getUserPhone(invalidCode))
+        when(userGateway.getUserPhone(invalidCode, invalidAccessToken))
                 .thenThrow((new BizException(
                         ErrorEnum.WECHAT_CODE_ISNULL.getErrorCode(),
                         ErrorEnum.WECHAT_CODE_ISNULL.getErrorMessage())));
 
         // 执行测试并验证应抛出异常
-       BizException exception = assertThrows(BizException.class, () -> userController.getUserPhone(invalidCode));
+       BizException exception = assertThrows(BizException.class, () -> userController.getUserPhone(invalidCode, invalidAccessToken));
 
         // 验证异常内容
         assertEquals(ErrorEnum.WECHAT_CODE_ISNULL.getErrorCode(), exception.getErrCode());
         assertEquals(ErrorEnum.WECHAT_CODE_ISNULL.getErrorMessage(), exception.getMessage());
 
         // 验证交互
-        verify(userGateway, times(1)).getUserPhone(invalidCode);
+        verify(userGateway, times(1)).getUserPhone(invalidCode, invalidAccessToken);
     }
 
     @Test
     void getUserPhone_Exception() {
         // 准备测试数据
         String code = "invalid_code";
+        String accessToken = "invalid_access_token";
         
         // 模拟UserGateway抛出异常
-        when(userGateway.getUserPhone(code)).thenThrow(new BizException(ErrorEnum.WECHAT_CODE_ISNULL.getErrorCode(), ErrorEnum.WECHAT_CODE_ISNULL.getErrorMessage()));
-        
+        when(userGateway.getUserPhone(code, accessToken)).thenThrow(new BizException(ErrorEnum.ERROR_BIZ_FAIL.getErrorCode(), "code或者token有问题"));
         // 执行测试 - 验证异常被正确传播
-        assertThrows(BizException.class, () -> userController.getUserPhone(code));
+        assertThrows(BizException.class, () -> userController.getUserPhone(code, accessToken));
         
         // 验证交互
-        verify(userGateway, times(1)).getUserPhone(code);
+        verify(userGateway, times(1)).getUserPhone(code, accessToken);
     }
 
     @Test
@@ -676,9 +678,9 @@ class UserControllerTest {
     }
 
     // 辅助方法
-    private PhoneLoginParams createTestPhoneLoginParams(String phone, String openId, String unionId) {
+    private PhoneLoginParams createTestPhoneLoginParams(String code, String openId, String unionId) {
         PhoneLoginParams params = new PhoneLoginParams();
-        params.setPhone(phone);
+        params.setCode(code);
         params.setOpenId(openId);
         params.setUnionId(unionId);
         return params;

+ 3 - 3
portal-service-common/src/main/java/com/hfln/portal/common/request/user/PhoneLoginParams.java

@@ -14,9 +14,9 @@ import javax.validation.constraints.NotEmpty;
 @ApiModel(description = "电话登录入参")
 public class PhoneLoginParams extends BaseVO {
 
-    @NotEmpty(message = "手机号不能为空!")
-    @ApiModelProperty("手机号")
-    private String phone;
+    @NotEmpty(message = "code不能为空!")
+    @ApiModelProperty("微信用户code")
+    private String code;
 
     @NotEmpty(message = "openId不能为空!")
     @ApiModelProperty("小程序openId")

+ 50 - 4
portal-service-domain/src/main/java/com/hfln/portal/domain/customer/util/WxOfficeAccountClient.java

@@ -1,8 +1,10 @@
 package com.hfln.portal.domain.customer.util;
 
+import cn.hfln.framework.common.redis.service.RedisService;
 import com.alibaba.fastjson2.JSON;
 import com.google.gson.Gson;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.http.HttpEntity;
 import org.apache.http.client.methods.CloseableHttpResponse;
 import org.apache.http.client.methods.HttpGet;
@@ -11,8 +13,11 @@ import org.apache.http.entity.StringEntity;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClients;
 import org.apache.http.util.EntityUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
 
 import javax.validation.constraints.NotBlank;
 import java.io.IOException;
@@ -20,14 +25,24 @@ import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
 
 /**
  * 微信公众号客户端
  */
 @Slf4j
+@Service
 @Component
 public class WxOfficeAccountClient {
 
+    private final RedisService redisService;
+
+    @Autowired
+    private StringRedisTemplate stringRedisTemplate;
+
+    private static final String ACCESS_TOKEN_KEY = "wx:access_token";
+
     @NotBlank
     @Value("${lnxx.wechat.office.account.appId}")
     private String appId;
@@ -42,6 +57,10 @@ public class WxOfficeAccountClient {
 
     private static final Gson gson = new Gson();
 
+    public WxOfficeAccountClient(RedisService redisService) {
+        this.redisService = redisService;
+    }
+
     public void sendMsg(String devId, String devName, String phoneNo, String fwhOpenId, String msg) {
         // 1. 获取 access_token
         String accessToken = getAccessToken();
@@ -83,6 +102,13 @@ public class WxOfficeAccountClient {
     }
 
     private String getAccessToken() {
+        //1.尝试从Redis中获取access_token
+        String cachedToken = stringRedisTemplate.opsForValue().get(ACCESS_TOKEN_KEY);
+        if (StringUtils.isNotEmpty(cachedToken)) {
+            log.info("从Redis中获取access_token成功: {}", cachedToken);
+            return cachedToken;
+        }
+        //2.如果Redis中没有,则调用微信接口获取
         String url = "https://api.weixin.qq.com/cgi-bin/token" +
                 "?grant_type=client_credential" +
                 "&appid=" + appId +
@@ -94,13 +120,27 @@ public class WxOfficeAccountClient {
                 HttpEntity entity = response.getEntity();
                 String result = EntityUtils.toString(entity);
                 Map<String, Object> map = gson.fromJson(result, Map.class);
-                log.info("access_token:{}",map.get("access_token"));
-                return (String) map.get("access_token");
+
+                //3.判断是否有错误码返回
+                if (map.containsKey("errcode")) {
+                    log.error("微信接口返回错误码:{}", result);
+                    return null;
+                }
+                if (map.containsKey("access_token")) {
+                    String accessToken = (String) map.get("access_token");
+
+                    //4.写入redis,有效期7080秒
+                    stringRedisTemplate.opsForValue().set(ACCESS_TOKEN_KEY, accessToken, 7080, TimeUnit.SECONDS);
+                    log.info("从微信中获取 access_token 并写入Redis:{}", accessToken);
+                    return accessToken;
+                } else {
+                    log.error("微信接口未返回 access_token, 原始响应:{}", result);
+                }
             }
         } catch (IOException e) {
-            log.error("获取accessToke失败", e);
-            return null;
+            log.error("调用微信接口异常,获取 access_token 失败", e);
         }
+        return null;
     }
 
     private boolean sendTemplateMessage(String accessToken, String openid,
@@ -130,4 +170,10 @@ public class WxOfficeAccountClient {
             return false;
         }
     }
+
+    //调用getaccess_token方法,给一键获取手机号登录使用
+    public String fetchAccessToken() {
+        return getAccessToken();
+            }
+
 }

+ 1 - 1
portal-service-domain/src/main/java/com/hfln/portal/domain/gateway/UserGateway.java

@@ -34,7 +34,7 @@ public interface UserGateway {
     UserDto loginByPassword(UserLoginParams request);
 
 
-    String getUserPhone(String code);
+    String getUserPhone(String code, String accessToken);
 
 
     void test();

+ 15 - 9
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/gateway/impl/UserGatewayImpl.java

@@ -18,6 +18,7 @@ import com.hfln.portal.common.response.user.UserInfoWxRes;
 import com.hfln.portal.domain.customer.DeviceType;
 import com.hfln.portal.domain.customer.OssBusiType;
 import com.hfln.portal.domain.customer.util.PasswordUtil;
+import com.hfln.portal.domain.customer.util.WxOfficeAccountClient;
 import com.hfln.portal.domain.exception.ErrorEnum;
 import com.hfln.portal.domain.gateway.UserGateway;
 import com.hfln.portal.infrastructure.oss.OssClient;
@@ -102,7 +103,10 @@ public class UserGatewayImpl implements UserGateway {
     @Autowired
     private OssFileService ossFileService;
 
-    public static String WXX_CX_ACCESS_TOKEN = "";
+//    public static String WXX_CX_ACCESS_TOKEN = "";
+
+    @Autowired
+    private WxOfficeAccountClient wxOfficeAccountClient;
 
     @Override
     public String getOpenId(String code) {
@@ -150,20 +154,22 @@ public class UserGatewayImpl implements UserGateway {
     @Override
     public Boolean loginByPhone(PhoneLoginParams params) {
 
-        // todo 这里的电话号码,不能由前端 传过来,根据下面的获取电话号码 方法来获取 参照老代码 loginByPhone 方法
-
         // 1 校验当前用户是否已注册
-        UserInfo userInfo = userService.queryByPhone(params.getPhone());
+        UserInfo userInfo = userService.queryByOpenId(params.getOpenId());
         if (userInfo == null) {
+            //调用微信获取accessToken
+            String accessToken = wxOfficeAccountClient.fetchAccessToken();
+            //获取用户手机号
+            String phone = getUserPhone(params.getCode(), accessToken);
             // 未注册的手机号直接注册用户
             userInfo = new UserInfo();
             userInfo.setOpenid(params.getOpenId());
-            userInfo.setPhone(params.getPhone());
+            userInfo.setPhone(phone);
             userInfo.setUnionId(params.getUnionId());
             userInfo.setAvatarUrl(params.getAvatarUrl());
             userService.save(userInfo);
         } else {
-            log.info("当前用户已注册:{}", params.getPhone());
+            log.info("当前用户已注册:{}", params.getOpenId());
         }
 
         // 2 校验当前用户是否已登录
@@ -182,7 +188,7 @@ public class UserGatewayImpl implements UserGateway {
             wxSession.set(UserConstants.SA_USER_OPEN_ID, userInfo.getOpenid());
             wxSession.set(UserConstants.SA_USER_UNION_ID, userInfo.getUnionId());
         } else {
-            log.info("当前用户已登录:{}", params.getPhone());
+            log.info("当前用户已登录:{}",params.getOpenId());
         }
 
         return true;
@@ -295,12 +301,12 @@ public class UserGatewayImpl implements UserGateway {
 
 
     @Override
-    public String getUserPhone(String code) {
+    public String getUserPhone(String code, String accessToken) {
         if (StringUtils.isEmpty(code)) {
             throw new BizException(ErrorEnum.WECHAT_CODE_ISNULL.getErrorCode(), ErrorEnum.WECHAT_CODE_ISNULL.getErrorMessage());
         }
         try {
-            String url = String.format("https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=%s", WXX_CX_ACCESS_TOKEN);
+            String url = String.format("https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=%s", accessToken);
 
             // 构建请求体
             JSONObject param = new JSONObject();