Bladeren bron

feat: "微信登录"
当前为1.0版本,一个微信账号仅可绑定一个平台账号。

ritchie 2 jaren geleden
bovenliggende
commit
8a6a13c5df

+ 167 - 80
src/main/java/com/szwl/controller/TWechatController.java

@@ -13,6 +13,7 @@ import com.szwl.model.bo.R;
 //import com.szwl.model.dto.WechatDTO;
 import com.szwl.model.entity.TAdmin;
 import com.szwl.model.entity.TWechat;
+import com.szwl.model.param.WxBindParam;
 import com.szwl.model.utils.DateUtils;
 import com.szwl.model.utils.HttpClientUtils;
 import com.szwl.service.TAdminService;
@@ -84,115 +85,201 @@ public class TWechatController {
     private String http;
 
     @ApiOperation(value = "绑定微信")
-    @PostMapping("/bindWechat")
-    public Map<String, Object> bindWechat(@RequestBody Map<String, Object> params) throws Exception {
-        Long adminId = (Long) params.get("adminId");
-        Map<String, Object> result = new HashMap<>();
-        if (adminId==null) {
-            result.put("code", 400);
-            result.put("msg", "参数为空");
-            return result;
-        }
-        TAdmin tAdmin = tAdminService.getById(adminId);
-        TWechat tWechat = new TWechat();
-        if (tAdmin != null) {
-            List<TWechat> list = tWechatService
-                    .lambdaQuery()
-                    .eq(TWechat::getAdminId, adminId)
-                    .list();
-            if (!list.isEmpty()) {
-                tWechat = list.get(0);
-                tWechatService.updateById(tWechat);
-            } else {
-                tWechat.setAdminId(String.valueOf(adminId));
-                tWechatService.save(tWechat);
-            }
-        } else {
-            throw new MyException("用户不存在!");
-        }
-//        String path = http + "/tWechat/callback?";
-        String path = http + "/SZWL-SERVER/tWechat/callback?";
+    @GetMapping("/bindWechat")
+    public R bindWechat(@RequestParam Long adminId) {
 
+        if (adminId == null) {
+            throw new MyException("参数为空");
+        }
+        String path = http + "/SZWL-SERVER/tWechat/callback";
+//        String path = http + "/tWechat/callback";
         try {
-            path = URLEncoder.encode(path, "UTF-8");
+            // redirectUrl 用于处理微信授权回调请求的页面
+            String redirectUrl = URLEncoder.encode(path, "UTF-8");
+            // 第一步:用户同意授权,获取code
+            String url = "http://szwlh.sunzee.com.cn/openWeixin/connect/oauth2/authorize?"
+//            String url = "http://szwltest.sunzee.com.cn/openWeixin/connect/oauth2/authorize?"
+//            String url = "https://open.weixin.qq.com/connect/oauth2/authorize?"
+                    + "appid=" + appid
+                    + "&redirect_uri=" + redirectUrl
+                    + "&response_type=code"
+                    + "&scope=snsapi_userinfo"
+                    + "&state=" + adminId
+                    + "#wechat_redirect";
+            return R.ok(url);
+
         } catch (UnsupportedEncodingException e) {
             throw new RuntimeException(e);
         }
-
-        // 第一步:用户同意授权,获取code
-        String url = "http://szwltest.sunzee.com.cn/openWeixin/connect/oauth2/authorize?"
-//        String url = "https://open.weixin.qq.com/connect/oauth2/authorize?"
-                + "appid=" + appid
-                + "&redirect_uri=" + path
-                + "&response_type=code"
-                + "&scope=snsapi_userinfo"
-                + "&state=" + adminId
-                + "#wechat_redirect";
-//        response.sendRedirect(url);
-        result.put("code", 200);
-        result.put("msg", "success");
-        result.put("data", url);
-        return result;
     }
 
-
     @ApiOperation(value = "绑定微信回调")
     @GetMapping("/callback")
-    public void oauthCallback(HttpServletRequest request, HttpServletResponse response) throws IOException {
+    public R oauthCallback(HttpServletRequest request, HttpServletResponse response) throws IOException {
         // 获取code
         String code = request.getParameter("code");
         String adminId = request.getParameter("state");
 
-        // 第二步:通过code换取网页授权access_token
-        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?" +
+        // 第二步:通过 code 换取网页授权 access_token 和 openid
+        String openUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?" +
                 "appid=" + appid +
                 "&secret=" + appsecret +
                 "&code=" + code +
                 "&grant_type=authorization_code";
-        JSONObject jsonObject = HttpClientUtils.get(url);
+
+        JSONObject jsonObject = HttpClientUtils.get(openUrl);
         String openid = jsonObject.getString("openid");
         String accessToken = jsonObject.getString("access_token");
         // 第三步:刷新access_token(如果需要)
         // 第四步:拉取用户信息(需scope为 snsapi_userinfo)
-        url = "https://api.weixin.qq.com/sns/userinfo?" +
+        String userUrl = "https://api.weixin.qq.com/sns/userinfo?" +
                 "access_token=" + accessToken +
                 "&openid=" + openid +
                 "&lang=zh_CN";
-        JSONObject userInfo = HttpClientUtils.get(url);
+        JSONObject userInfo = HttpClientUtils.get(userUrl);
+        String nickname = userInfo.getString("nickname");
+        String headimgurl = userInfo.getString("headimgurl");
 
-        LambdaQueryWrapper<TWechat> wrapper = new LambdaQueryWrapper<>();
-        wrapper.eq(TWechat::getAdminId, adminId);
-        TWechat tWechat = tWechatService.getOne(wrapper);
-
-        if (Objects.isNull(tWechat)) {
-            response.sendError(HttpServletResponse.SC_NOT_FOUND, "tWechat is null"); // 返回错误状态码和错误信息给前端
-            return;
-        }
-        String openId = tWechat.getOpenId();
-
-        if (Objects.nonNull(openId)) {
-            tWechat.setOpenId(userInfo.getString("openid"));
-            tWechat.setNickName(userInfo.getString("nickname"));
-            tWechat.setAvatarUrl(userInfo.getString("headimgurl"));
-            tWechat.setModifyDate(new Date());
-            tWechatService.updateById(tWechat);
+        if (StringUtils.isNotEmpty(openid)) {
+            TWechat list0 = tWechatService
+                    .lambdaQuery()
+                    .eq(TWechat::getOpenId, openid)
+                    .one();
+            if (Objects.isNull(list0)) {
+                if (StringUtils.isNotEmpty(adminId)) {
+                    TWechat wechat = tWechatService
+                            .lambdaQuery()
+                            .eq(TWechat::getAdminId, adminId)
+                            .one();
+                    if (Objects.isNull(wechat)) {
+                        // 当前 adminId 首次绑定微信
+                        TWechat tWechat = new TWechat();
+                        tWechat.setOpenId(openid);
+                        tWechat.setAdminId(adminId);
+                        tWechat.setNickName(nickname);
+                        tWechat.setAvatarUrl(headimgurl);
+                        tWechat.setCreateDate(new Date());
+                        tWechatService.save(tWechat);
+                    } else {
+                        // 更新绑定在当前 adminId 上的微信号
+                        wechat.setOpenId(openid);
+                        wechat.setAdminId(adminId);
+                        wechat.setNickName(nickname);
+                        wechat.setAvatarUrl(headimgurl);
+                        wechat.setModifyDate(new Date());
+                        tWechatService.updateById(wechat);
+                    }
+                } else {
+                    throw new MyException("用户不存在!");
+                }
+            } else {
+                String userId = list0.getAdminId();
+                if (Objects.equals(userId, adminId)) {
+                    TWechat one = tWechatService
+                            .lambdaQuery()
+                            .eq(TWechat::getAdminId, userId)
+                            .one();
+                    one.setOpenId(openid);
+                    one.setAdminId(adminId);
+                    one.setNickName(nickname);
+                    one.setAvatarUrl(headimgurl);
+                    one.setModifyDate(new Date());
+                    tWechatService.updateById(one);
+                } else {
+                    return R.fail("当前微信号已绑定<" + userId + ">账户");
+                }
+            }
         } else {
-            tWechat.setOpenId(userInfo.getString("openid"));
-            tWechat.setNickName(userInfo.getString("nickname"));
-            tWechat.setAvatarUrl(userInfo.getString("headimgurl"));
-            tWechat.setCreateDate(new Date());
-            tWechatService.updateById(tWechat);
+            // 获取微信授权失败
+            return R.fail("微信授权失败,没有openid");
         }
-        Map<String, Object> result = new HashMap<>();
-        result.put("code", 200);
-        result.put("msg", "success");
-        // 跳转到用户页面
-        String userPageUrl = "http://szwltest.sunzee.com.cn/shenze/#/user";
-        result.put("data", userPageUrl);
-        response.setContentType("application/json;charset=UTF-8");
-        response.getWriter().write(JSON.toJSONString(result));
+        String redirectUrl = http + "/shenze/#/user";
+        response.sendRedirect(redirectUrl);
+        return R.ok(userInfo);
     }
 
+    @ApiOperation(value = "获取用户头像")
+    @GetMapping("/getAvatar")
+    public R getAvatar(@RequestParam("adminId") Long adminId) {
+        String avatarUrl = "";
+        if (adminId != null) {
+            TWechat wechat = tWechatService.lambdaQuery()
+                    .eq(TWechat::getAdminId, adminId)
+                    .one();
+            if (wechat != null) {
+                avatarUrl = wechat.getAvatarUrl();
+            }
+        }
+        return R.ok(avatarUrl);
+    }
+
+    @ApiOperation(value = "绑定微信回调2")
+    @PostMapping("/auth")
+    public Map<String, Object> auth(@RequestBody WxBindParam wxBindParam) {
+        String adminId = wxBindParam.getState();
+        String code = wxBindParam.getCode();
+        Map<String, Object> result = new HashMap<>();
+        try {
+            // 第二步:通过 code 换取网页授权 access_token 和 openid
+            String openUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?" +
+                    "appid=" + appid +
+                    "&secret=" + appsecret +
+                    "&code=" + code +
+                    "&grant_type=authorization_code";
+            System.out.println(openUrl);
+
+            JSONObject jsonObject = HttpClientUtils.get(openUrl);
+            String openid = jsonObject.getString("openid");
+            String accessToken = jsonObject.getString("access_token");
+            // 第三步:刷新access_token(如果需要)
+            // 第四步:拉取用户信息(需scope为 snsapi_userinfo)
+            String userUrl = "https://api.weixin.qq.com/sns/userinfo?" +
+                    "access_token=" + accessToken +
+                    "&openid=" + openid +
+                    "&lang=zh_CN";
+            JSONObject userInfo = HttpClientUtils.get(userUrl);
+            String nickname = userInfo.getString("nickname");
+            String headimgurl = userInfo.getString("headimgurl");
+
+
+            if (StringUtils.isNotEmpty(openid)) {
+                if (StringUtils.isNotEmpty(adminId)) {
+                    TWechat wechat = tWechatService
+                            .lambdaQuery()
+                            .eq(TWechat::getAdminId, adminId)
+                            .one();
+                    if (Objects.isNull(wechat)) {
+                        // 当前 adminId 首次绑定微信
+                        TWechat tWechat = new TWechat();
+                        tWechat.setOpenId(openid);
+                        tWechat.setAdminId(adminId);
+                        tWechat.setNickName(nickname);
+                        tWechat.setAvatarUrl(headimgurl);
+                        tWechat.setCreateDate(new Date());
+                        tWechatService.save(tWechat);
+                    } else {
+                        // 更新绑定在当前 adminId 上的微信号
+                        wechat.setOpenId(openid);
+                        wechat.setAdminId(adminId);
+                        wechat.setNickName(nickname);
+                        wechat.setAvatarUrl(headimgurl);
+                        wechat.setModifyDate(new Date());
+                        tWechatService.updateById(wechat);
+                    }
+                } else {
+                    throw new MyException("用户不存在!");
+                }
+            } else {
+                // 获取微信授权失败
+                result.put("message", "微信授权失败,没有openid");
+            }
+            result.put("success", true);
+        } catch (Exception e) {
+            result.put("success", false);
+            result.put("message", e.getMessage());
+        }
+        return result;
+    }
 
 }
 

+ 64 - 3
src/main/java/com/szwl/controller/WxLoginController.java

@@ -4,25 +4,44 @@ import cn.hutool.http.HttpRequest;
 import cn.hutool.http.HttpResponse;
 import com.alibaba.fastjson.JSON;
 import com.szwl.exception.MyException;
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.IdUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.rabbitmq.http.client.domain.UserInfo;
+import com.szwl.annotation.Audit;
+import com.szwl.constant.AuditEnum;
+import com.szwl.constant.ResponseCodesEnum;
+import com.szwl.exception.BizException;
+import com.szwl.manager.TokenManager;
 import com.szwl.model.bo.R;
+import com.szwl.model.bo.ResponseModel;
 import com.szwl.model.bo.UserDetailBO;
 import com.szwl.model.entity.TAdmin;
 import com.szwl.model.entity.TWechat;
+import com.szwl.model.utils.AdminUtils;
+import com.szwl.model.utils.HttpClientUtils;
+import com.szwl.service.SysRoleService;
 import com.szwl.service.TAdminService;
 import com.szwl.service.TWechatService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
 import com.alibaba.fastjson.JSONObject;
+import org.apache.commons.lang.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
-import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
+import java.util.Optional;
+import java.util.Set;
+
 @Slf4j
 @Api(value = "/WxLoginController", tags = {"微信登录接口"})
 @RestController
@@ -30,6 +49,11 @@ import java.net.URLEncoder;
 public class WxLoginController {
 
     @Autowired
+    SysRoleService sysRoleService;
+
+    @Autowired
+    TokenManager tokenManager;
+    @Autowired
     private TAdminService tAdminService;
 
     @Autowired
@@ -48,14 +72,20 @@ public class WxLoginController {
     @ApiOperation(value = "用户默认授权,获取code")
     @GetMapping("/menuOauth")
     public R<String> getOpenid() {
+        // 针对test服务器
         // 带shenzeVue 的url 会经nginx 重定向到 http://szwltest.sunzee.com.cn/shenze/#/xxx
         // openWeixin 的url 会经nginx 重定向到 https://open.weixin.qq.com/xxx
         // SZWL-SERVER 的url 会经nginx 重定向到 http://szwltest.sunzee.com.cn:49011 (即该应用)
+
+        // 针对正式服务器
+        // 带shenzeVue 的url 会经nginx 重定向到 http://szwlh.sunzee.com.cn/shenze/#/xxx
+        // openWeixin 的url 会经nginx 重定向到 https://open.weixin.qq.com/xxx
         String path = http + "/shenzeVue/wxLogin";
         try {
             String redirectUrl = URLEncoder.encode(path, "UTF-8");
             // 第一步:用户静默授权,获取code
-            String authUrl = "http://szwltest.sunzee.com.cn/openWeixin/connect/oauth2/authorize?"
+            String authUrl = "http://szwlh.sunzee.com.cn/openWeixin/connect/oauth2/authorize?"
+//            String authUrl = "http://szwltest.sunzee.com.cn/openWeixin/connect/oauth2/authorize?"
 //            String authUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?"
                     + "appid=" + appid
                     + "&redirect_uri=" + redirectUrl
@@ -74,7 +104,7 @@ public class WxLoginController {
     }
     @ApiOperation(value = "用微信code 获取openid,再获取用户信息")
     @GetMapping("/getUserDetailByWxCode")
-    public R getUserDetailByWxCode(String code) throws IOException {
+    public R getUserDetailByWxCode(String code) {
         // 第二步:使用code换取access_token和openid
         String url = "https://api.weixin.qq.com/sns/oauth2/access_token?"
                 + "appid=" + appid
@@ -96,4 +126,35 @@ public class WxLoginController {
         return R.ok(userDetailBO);
     }
 
+    @ApiOperation(value = "使用 Openid 登录")
+    @PostMapping("/loginWithOpenid")
+    @Audit(type = AuditEnum.LOGIN,content = "#username + '请求登录'")
+    public ResponseModel<UserDetailBO> loginWithOpenid(String username) {
+        if(StringUtils.isEmpty(username)){
+            return R.fail(ResponseCodesEnum.A0001,"参数有空");
+        }
+
+        //验证用户名登录
+        LambdaQueryWrapper<TAdmin> query = Wrappers.lambdaQuery();
+        query.eq(TAdmin::getUsername, username);
+        TAdmin tAdmin = Optional.ofNullable(tAdminService.getOnly(query))
+                .orElseThrow(() -> new BizException(ResponseCodesEnum.L0002));
+        if(StringUtils.isEmpty(tAdmin.getManagerId())){
+            String managerId = AdminUtils.encrypt(false, tAdmin.getId());
+            tAdmin.setManagerId(managerId);
+            tAdminService.getById(tAdmin);
+        }
+        UserDetailBO userDetailBO = BeanUtil.copyProperties(tAdmin,UserDetailBO.class);
+
+        String token = IdUtil.simpleUUID();
+        userDetailBO.setCurrentToken(token);
+        // 获取拥有的权限菜单
+        Set<String> menuList = sysRoleService.listAuthMenuByUserId(userDetailBO.getId());
+        userDetailBO.setMenuCodeList(CollUtil.newArrayList(menuList));
+        // 抹除密码
+        userDetailBO.setPassword(null);
+        // 保存到redis
+        tokenManager.saveAuthentication(token,userDetailBO);
+        return R.ok(userDetailBO);
+    }
 }

+ 16 - 0
src/main/java/com/szwl/model/param/WxBindParam.java

@@ -0,0 +1,16 @@
+package com.szwl.model.param;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+@Accessors(chain = true)
+@ApiModel(description = "绑定微信获取 openid 参数")
+@Data
+public class WxBindParam {
+    private String code;
+
+    @ApiModelProperty("传入 adminId ")
+    private String state;
+}