Browse Source

fix: 重定向测试1

wrj 11 months ago
parent
commit
5cc7cd4360

+ 383 - 0
nightFragrance-admin/src/main/java/com/ylx/web/controller/massage/WeSqController.java

@@ -0,0 +1,383 @@
+package com.ylx.web.controller.massage;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.extra.qrcode.QrCodeUtil;
+import cn.hutool.extra.qrcode.QrConfig;
+import cn.hutool.json.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.ylx.common.annotation.Log;
+import com.ylx.common.config.RuoYiConfig;
+import com.ylx.common.constant.Constants;
+import com.ylx.common.core.controller.BaseController;
+import com.ylx.common.core.domain.AjaxResult;
+import com.ylx.common.core.domain.model.WxLoginUser;
+import com.ylx.common.enums.BusinessType;
+import com.ylx.common.utils.MessageUtils;
+import com.ylx.common.utils.file.FileUploadUtils;
+import com.ylx.framework.manager.AsyncManager;
+import com.ylx.framework.manager.factory.AsyncFactory;
+import com.ylx.framework.web.service.WxTokenService;
+import com.ylx.massage.domain.CouponReceive;
+import com.ylx.massage.domain.TWxUser;
+import com.ylx.massage.service.CouponReceiveService;
+import com.ylx.massage.service.TWxUserService;
+import com.ylx.massage.service.TbFileService;
+import com.ylx.massage.utils.StringUtilsMassage;
+import com.ylx.massage.utils.WeChatUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import static com.ylx.massage.utils.OtherUtil.verification;
+
+/**
+ * @author b16mt
+ */
+@Slf4j
+@Controller
+@Api(tags = {"微信公众号sq"})
+@RequestMapping("/sq")
+public class WeSqController extends BaseController {
+
+    private final static String TOKEN = "abcd1234";
+    private final static String ENCODING = "UTF-8";
+    private final static String ACCESS_TOKEN = "access_token";
+    private final static String REFRESH_TOKEN = "refresh_token";
+    private final static String OPEN_ID = "openid";
+
+    /**
+     * 二维码保存路径
+     */
+    private String IMG_PATH = "D:\\Users\\";
+
+
+    @Resource
+    private WeChatUtil weChatUtil;
+
+    @Resource
+    private TWxUserService wxUserService;
+
+    @Resource(name = "commonAsyncExecutor")
+    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
+
+    @Autowired
+    private CouponReceiveService couponReceiveService;
+
+    @Resource
+    private WxTokenService wxTokenService;
+
+    @Autowired
+    private TbFileService tbFileService;
+
+    /**
+     * 微信Token验证
+     *
+     * @param signature 微信加密签名
+     * @param timestamp 时间戳
+     * @param nonce     随机数
+     * @param echostr   随机字符串
+     * @param response  HTTP响应对象
+     * @throws Exception 如果处理过程中出现错误
+     */
+    @GetMapping("/verifyToken")
+    @Log(title = "公众号pverifyToken", businessType = BusinessType.OTHER)
+    public void verifyToken(@RequestParam(value = "signature") String signature,
+                            @RequestParam(value = "timestamp") String timestamp,
+                            @RequestParam(value = "nonce") String nonce,
+                            @RequestParam(value = "echostr") String echostr, HttpServletResponse response) throws Exception {
+
+        log.info("微信Token验证 入参: signature:{},timestamp:{},nonce:{},echostr:{},", signature, timestamp, nonce, echostr);
+        // 参数排序
+        String[] params = new String[]{timestamp, nonce, TOKEN};
+        Arrays.sort(params);
+
+        // 校验成功则响应 echostr,失败则不响应
+        if (verification(params, signature) && echostr != null) {
+            response.setCharacterEncoding(ENCODING);
+            response.getWriter().write(echostr);
+            response.getWriter().flush();
+            response.getWriter().close();
+        }
+    }
+
+    @GetMapping("/setMenu")
+    @Log(title = "公众号pverifyToken", businessType = BusinessType.OTHER)
+    public Map<?,?> setMenu() {
+
+        //获取access_token
+        String token = weChatUtil.getToken();
+        //获取的二维码ticket
+        return weChatUtil.menuUtil(token);
+
+    }
+
+//    @PostMapping("/verifyToken")
+//    @Log(title = "公众号pverifyToken", businessType = BusinessType.OTHER)
+//    public void pverifyToken(@RequestParam(value = "signature") String signature,
+//                             @RequestParam(value = "timestamp") String timestamp,
+//                             @RequestParam(value = "nonce") String nonce) {
+//
+//        log.info("11111111111111111111111111111111111111111111");
+//        // 参数排序
+//        String[] params = new String[]{timestamp, nonce, TOKEN};
+//        Arrays.sort(params);
+//
+////        {
+////            "signature": "63c8f3e1fb23d0d18f6d7ddf8019dc8a8737a04b",
+////                "openid": "oPYgb6qoOUXYIQLbB7f6zOF40kwk",
+////                "nonce": "1376426761",
+////                "timestamp": "1717569593"
+////        }
+//
+//    }
+
+    /**
+     * 处理微信公众号请求信息
+     *
+     * @param request
+     * @return
+     */
+    @RequestMapping("/verifyToken")
+    @ResponseBody
+    @Log(title = "处理微信公众号请求信息", businessType = BusinessType.OTHER)
+    public String handlePublicMsg(HttpServletRequest request) throws Exception {
+        log.info("处理微信公众号请求信息:{}", request.toString());
+        // 获得微信端返回的xml数据
+        InputStream is = null;
+        InputStreamReader isr = null;
+        BufferedReader br = null;
+        try {
+            is = request.getInputStream();
+            isr = new InputStreamReader(is, "utf-8");
+            br = new BufferedReader(isr);
+            String str = null;
+            StringBuffer returnXml = new StringBuffer();
+            while ((str = br.readLine()) != null) {
+                //返回的是xml数据
+                returnXml.append(str);
+            }
+            log.info("微信端返回的xml数据:{}", returnXml);
+            Map<String, String> encryptMap = WeChatUtil.xmlToMap(returnXml.toString());
+            // 得到公众号传来的加密信息并解密,得到的是明文xml数据
+//            String decryptXml = WXPublicUtils.decrypt(encryptMap.get("Encrypt"));
+            // 将xml数据转换为map
+//            Map<String, String> decryptMap = WeChatUtil.xmlToMap(decryptXml);
+
+            // 区分消息类型
+            String msgType = encryptMap.get("MsgType");
+            // 普通消息
+            if ("text".equals(msgType)) { // 文本消息
+                // todo 处理文本消息
+            } else if ("image".equals(msgType)) { // 图片消息
+                // todo 处理图片消息
+            } else if ("voice".equals(msgType)) { //语音消息
+                // todo 处理语音消息
+            } else if ("video".equals(msgType)) { // 视频消息
+                // todo 处理视频消息
+            } else if ("shortvideo".equals(msgType)) { // 小视频消息
+                // todo 处理小视频消息
+            } else if ("location".equals(msgType)) { // 地理位置消息
+                // todo 处理地理位置消息
+            } else if ("link".equals(msgType)) { // 链接消息
+                // todo 处理链接消息
+            }
+            // 事件推送
+            else if ("event".equals(msgType)) { // 事件消息
+                // 区分事件推送
+                String event = encryptMap.get("Event");
+                if ("subscribe".equals(event)) { // 订阅事件 或 未关注扫描二维码事件
+                    return getString(encryptMap);
+                } else if ("unsubscribe".equals(event)) { // 取消订阅事件
+                    // todo 处理取消订阅事件
+                } else if ("SCAN".equals(event)) { // 已关注扫描二维码事件
+                    return getString(encryptMap);
+                } else if ("LOCATION".equals(event)) { // 上报地理位置事件
+                    // todo 处理上报地理位置事件
+                } else if ("CLICK".equals(event)) { // 点击菜单拉取消息时的事件推送事件
+                    // todo 处理点击菜单拉取消息时的事件推送事件
+                } else if ("VIEW".equals(event)) { // 点击菜单跳转链接时的事件推送
+                    // todo 处理点击菜单跳转链接时的事件推送
+                }
+            }
+        } catch (Exception e) {
+            logger.error("处理微信公众号请求信息,失败", e);
+        } finally {
+            if (null != is) {
+                is.close();
+            }
+            if (null != isr) {
+                isr.close();
+            }
+            if (null != br) {
+                br.close();
+            }
+        }
+        return null;
+    }
+
+    private String getString(Map<String, String> encryptMap) throws Exception {
+        // 返回消息时ToUserName的值与FromUserName的互换
+        Map<String, String> returnMap = new HashMap<>();
+
+        //添加新用户
+        TWxUser fromUserName = wxUserService.getByOpenId(encryptMap.get("FromUserName"));
+        if (fromUserName == null) {
+            fromUserName = new TWxUser();
+        }
+        fromUserName.setcOpenid(encryptMap.get("FromUserName"));
+        fromUserName.setcUpUser(StringUtilsMassage.afterString(encryptMap.get("EventKey"), "qrscene_"));
+        wxUserService.saveOrUpdate(fromUserName);
+
+        returnMap.put("ToUserName", encryptMap.get("FromUserName"));
+        returnMap.put("FromUserName", encryptMap.get("ToUserName"));
+        returnMap.put("CreateTime", new Date().getTime() + "");
+        returnMap.put("MsgType", "text");
+        returnMap.put("Content", "欢迎来到舒压乐园");
+        String encryptMsg = weChatUtil.mapToXml(returnMap).toString();
+        return encryptMsg;
+    }
+    /**
+     * 获取微信code
+     *
+     * @param state 状态参数
+     */
+    @ApiOperation("获取微信code")
+    @Log(title = "获取微信code", businessType = BusinessType.OTHER)
+    @GetMapping("/getCode")
+    public String weiXinLogin(String state) {
+//        QrConfig config = new QrConfig(300, 300);
+        // 设置边距,即二维码和背景之间的边距
+//        config.setMargin(1);
+        // 生成二维码到文件,也可以到流
+        String code = weChatUtil.getCode(state);
+        log.info("code:{}", code);
+//        QrCodeUtil.generate(code, config,
+//                FileUtil.file(IMG_PATH));
+        return code;
+    }
+
+    /**
+     * 获取token和userInfo
+     *
+     * @param code 微信授权码
+     * @return 访问令牌
+     */
+    @GetMapping("/getAccessToken")
+    @Log(title = "公众号网页登录", businessType = BusinessType.OTHER)
+    public String getAccessToken(@RequestParam String code) {
+
+        // 发送get请求获取 AccessToken
+        Map<?, ?> result = weChatUtil.getAccessToken(code);
+        String accessToken = result.get(ACCESS_TOKEN).toString();
+        String refreshToken = result.get(REFRESH_TOKEN).toString();
+        String openid = result.get(OPEN_ID).toString();
+
+        // 如果用户是第一次进行微信公众号授权
+        // 进行这一步时用户应点击了同意授权按钮
+        String userInfoJsom = weChatUtil.getUserInfo(accessToken, openid);
+        // 解析JSON数据
+        JSONObject jsonObject = new JSONObject(userInfoJsom);
+        log.info("公众号网页登录,{}",jsonObject);
+        // 将用户信息保存到数据库中
+        LambdaQueryWrapper<TWxUser> objectLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        objectLambdaQueryWrapper.eq(TWxUser::getcOpenid, openid);
+        TWxUser user = wxUserService.getOne(objectLambdaQueryWrapper);
+        if (user == null || user.getcNickName() == null) {
+            user = new TWxUser();
+            user.setcOpenid(openid);
+            user.setcNickName(jsonObject.get("nickname").toString());
+            user.setcIcon(jsonObject.get("headimgurl").toString());
+            user.setcSessionKey(refreshToken);
+//            user.setcPhone(phoneNumber);
+            wxUserService.save(user);
+            //异步 添加新人优惠卷
+            TWxUser finalUser = user;
+            threadPoolTaskExecutor.submit(() -> couponReceiveService.submit(new CouponReceive().setOpenid(finalUser.getcOpenid()).setCouponId("1")));
+            user.setId(user.getId());
+        }
+
+        WxLoginUser wxUser = new WxLoginUser();
+        BeanUtils.copyProperties(user, wxUser);
+        // 生成并返回令牌
+        String token = wxTokenService.createToken(wxUser);
+        if (token == null || token.isEmpty()) {
+            return null;
+        }
+        wxUser.setToken(token);
+        // 返回用户信息
+        // 记录登录信息
+        AsyncManager.me().execute(AsyncFactory.recordLogininfor(wxUser.getCOpenid(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
+//        return R.ok(wxUser);
+
+        return "redirect:" + "https://test.baoxianzhanggui.com/fragrance/#/pages/my/wxLogin" + "?openid=" + openid;
+    }
+
+
+    /**
+     * 刷新token,微信提供的token是有限时间的,但是对于财务报销系统仅需授权一次的情况下一般不需要进行更新
+     *
+     * @return accessToken
+     */
+    @GetMapping("/refreshToken")
+    public String refreshToken() {
+
+        WxLoginUser wxLoginUser = this.getWxLoginUser();
+        TWxUser user = wxUserService.getByOpenId(wxLoginUser.getCOpenid());
+        if (user == null) {
+            throw new RuntimeException("用户不存在");
+        }
+        // 发送get请求获取 RefreshToken
+        Map<?, ?> result = weChatUtil.refreshToken(user.getcSessionKey());
+        String accessToken = result.get(ACCESS_TOKEN).toString();
+        String refreshToken = result.get(REFRESH_TOKEN).toString();
+        // 更新用户信息
+        user.setcSessionKey(refreshToken);
+        // 存储数据库
+        wxUserService.updateById(user);
+        return accessToken;
+    }
+
+    @ApiOperation("获取公众号二维码")
+    @RequestMapping(value = "getwxQrCode", method = RequestMethod.GET)
+    public Map<?, ?> getWxQrCodeUtil(@RequestParam String openId) {
+
+        //获取access_token
+        String token = weChatUtil.getToken();
+        //获取的二维码ticket
+        return weChatUtil.getTicket(token, openId);
+    }
+
+    @ApiOperation("获取公众号网页二维码")
+    @GetMapping("/getweQrCode")
+    public AjaxResult weiXinLogin1(String openId) {
+        QrConfig config = new QrConfig(300, 300);
+        // 设置边距,即二维码和背景之间的边距
+        config.setMargin(1);
+        // 生成二维码到文件,也可以到流
+        String code = "https://www.baidu.com?openId=" + openId;
+        log.info("code:{}", code);
+        String str = IMG_PATH;
+        File generate = QrCodeUtil.generate(code, config, FileUtil.file(RuoYiConfig.getUploadPath() + "/code.png"));
+
+        MultipartFile multipartFile = FileUploadUtils.getMultipartFile(generate);
+        return tbFileService.uploadFile(multipartFile);
+    }
+}

+ 1 - 1
nightFragrance-admin/src/main/resources/application-test.yml

@@ -235,7 +235,7 @@ wechat:
   # 获取code
   get-code-url: https://open.weixin.qq.com/connect/oauth2/authorize
   # 回调地址
-  redirect-url: https://test.baoxianzhanggui.com/nightFragrance/weChat/getAccessToken
+  redirect-url: https://test.baoxianzhanggui.com/nightFragrance/sq/getAccessToken
   # 回调地址
   access-token-url: https://api.weixin.qq.com/sns/oauth2/access_token
 # 防止XSS攻击

+ 1 - 1
nightFragrance-framework/src/main/java/com/ylx/framework/config/SecurityConfig.java

@@ -114,7 +114,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
                 .antMatchers("/login", "/register", "/captchaImage","/wx/login",
                         "/api/lbt/v1/getAll", "/api/js/v1/select", "/api/xiangmu/v1/wx/getAll", "/api/order/v1/getStatus",
                         "/api/xiangmu/v1/getByid", "/api/js/v1/wx/getByid","/api/js/v1/wx/select", "/api/recharge/v1/test",
-                        "/wx/pay/payNotify","/wx/pay/refundNotify","/weChat/getAccessToken","/weChat/getCode","/weChat/verifyToken").permitAll()
+                        "/wx/pay/payNotify","/wx/pay/refundNotify","/weChat/getAccessToken","/weChat/getCode","/weChat/verifyToken","/sq/getAccessToken").permitAll()
                 // 静态资源,可匿名访问
                 .antMatchers(HttpMethod.GET, "/", "/*.txt","/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
                 .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()