微信公众号 注册的时候不关注 后期关注 获取 这个人是谁

为用户生成二维码

    @PostMapping("/generate")
    public AjaxResult generateQrcode(@RequestParam Long userId) {
        try {
            SysUser user = userService.generateUserQrcode(userId);
            return AjaxResult.success(user);
        } catch (Exception e) {
            return AjaxResult.error("Failed to generate QR code: " + e.getMessage());
        }
    }
  SysUser generateUserQrcode(Long userId) throws JsonProcessingException;


    @Override
    public SysUser generateUserQrcode(Long userId) throws JsonProcessingException {
        // 使用合适的 scene_id
        int sceneId = (int)(userId % 100000); // 确保在范围内

        // 1. 获取用户信息
        SysUser user = userMapper.selectUserById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 2. 调用微信接口生成永久二维码
        String accessToken = getAccessToken();  // 获取 access_token
        String qrcodeUrl = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" + accessToken;

        // 创建永久二维码的请求
        Map<String, Object> scene = new HashMap<>();
        scene.put("scene_id", sceneId);  // 使用合法的 sceneId

        Map<String, Object> actionInfo = new HashMap<>();
        actionInfo.put("scene", scene);

        Map<String, Object> requestBodyMap = new HashMap<>();
        requestBodyMap.put("action_name", "QR_LIMIT_SCENE");
        requestBodyMap.put("action_info", actionInfo);

        ObjectMapper objectMapper = new ObjectMapper();
        String requestBody = objectMapper.writeValueAsString(requestBodyMap);

        RestTemplate restTemplate = new RestTemplate();
        String response = restTemplate.postForObject(qrcodeUrl, requestBody, String.class);

        // 使用 Jackson 解析返回的 JSON 字符串
        JsonNode jsonResponse = objectMapper.readTree(response);

        if (!jsonResponse.has("ticket")) {
            throw new RuntimeException("生成二维码失败,微信接口返回异常:" + jsonResponse.toString());
        }

        // 3. 获取二维码的 URL 和 Ticket
        String ticket = jsonResponse.get("ticket").asText();
        System.out.println(""+ticket);
        String qrCodeUrl = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=" + ticket;

        // 4. 更新用户表中的二维码信息
        user.setQrUrl(qrCodeUrl);  // 假设用户表中有 qrCodeUrl 字段

        // 更新用户表
        userMapper.updatesUserQrcode(userId, qrCodeUrl);

        // 5. 返回更新后的用户信息
        return user;
    }
    @Update("UPDATE sys_user SET qr_url = #{qrUrl} WHERE user_id = #{userId}")
    void updatesUserQrcode(@Param("userId") Long userId, @Param("qrUrl") String qrUrl);

微信公众平台的 GET 请求,用于验证 token

    private static final String TOKEN = "X4yZ7k9B3mVfD1nQ5tG8wL2pR7";  // 与微信公众号后台配置的 Token 保持一致


    // 微信公众平台的 GET 请求,用于验证 token
    @GetMapping("/event")
    public void verifyToken(@RequestParam String signature,
                            @RequestParam String timestamp,
                            @RequestParam String nonce,
                            @RequestParam String echostr,
                            HttpServletResponse response) {
        System.out.println("微信官方回调了我的这个接口");
        try {
            // 1. 将 token, timestamp, nonce 按字典序排序
            String[] arr = {TOKEN, timestamp, nonce};
            Arrays.sort(arr);

            // 2. 将三个参数拼接成字符串并进行 SHA1 加密
            StringBuilder content = new StringBuilder();
            for (String s : arr) {
                content.append(s);
            }
            String tempSignature = DigestUtils.sha1Hex(content.toString());

            // 3. 校验签名是否来自微信
            if (tempSignature.equals(signature)) {
                response.getWriter().write(echostr);  // 验证成功,返回 echostr
            } else {
                response.getWriter().write("fail");  // 验证失败
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

微信公众平台的 POST 请求,接收事件推送

 @PostMapping("/event")
    public void handleWechatEvents(@RequestBody String xmlData, HttpServletResponse response) {
        try {
            // 解析微信推送的XML数据
            Document document = DocumentHelper.parseText(xmlData);
            Element root = document.getRootElement();

            // 获取消息类型和事件类型
            String msgType = root.elementText("MsgType");
            String event = root.elementText("Event");
            String openId = root.elementText("FromUserName");  // 提取用户的 OpenID

            // 处理事件推送
            if ("event".equals(msgType)) {
                if ("subscribe".equals(event)) {
                    // 处理用户首次关注公众号事件
                    String eventKey = root.elementText("EventKey");
                    if (eventKey != null && eventKey.startsWith("qrscene_")) {
                        // 提取场景值中的 userId
                        String userId = eventKey.replace("qrscene_", "");
                        System.out.println("用户通过二维码关注公众号,OpenID: " + openId + ", 用户ID: " + userId);
                        handleSubscribeEvent(openId, userId);

                        //根据userId 更新openId
                        // 使用 MyBatis 查询后四位匹配的用户
                        SysUser user = userService.queryByUserIdSuffix(userId);
                        if(user != null){
                            Long userIds = user.getUserId();
                            //根据userId 更新openId

                            boolean flag =   userService.updateByuserId(userIds,openId);
                            System.out.println("userId1"+userIds);
                        }




                    } else {
                        System.out.println("用户直接关注了公众号,OpenID: " + openId);
                        handleSubscribeEvent(openId, null);  // 如果没有场景值,userId 为 null
                    }

                } else if ("unsubscribe".equals(event)) {
                    // 处理用户取消关注事件
                    System.out.println("用户取消关注公众号,OpenID: " + openId);
                    handleUnsubscribeEvent(openId);

                } else if ("SCAN".equals(event)) {
                    // 处理已关注用户扫描二维码事件
                    String eventKey = root.elementText("EventKey");
                    System.out.println("已关注用户扫描二维码,OpenID: " + openId + ", 场景值: " + eventKey);
                    handleScanEvent(openId, eventKey);
                }
            }

            // 回复微信服务器,防止重试
            response.getWriter().write("success");

        } catch (Exception e) {
            e.printStackTrace();
            try {
                response.getWriter().write("fail");
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
        }
    }

    // 处理首次关注事件(附带二维码参数)
    private void handleSubscribeEvent(String openId, String userId) {
        if (userId != null) {
            // 处理通过带参数二维码关注的用户
            System.out.println("欢迎通过二维码关注的用户,OpenID: " + openId + ", 用户ID: " + userId);



            // 在这里可以将 openId 和 userId 保存到数据库,或者发送欢迎消息
            saveUserInfo(openId, userId);
        } else {
            // 处理直接关注的用户
            System.out.println("欢迎直接关注的用户,OpenID: " + openId);
            saveUserInfo(openId, null);  // 如果没有场景值,可以不保存 userId
        }
        // 在这里可以发送欢迎消息
    }

    // 处理取消关注事件
    private void handleUnsubscribeEvent(String openId) {
        System.out.println("用户取消关注,OpenID: " + openId);
        // 在这里更新数据库,记录用户的取消关注行为
        updateUserStatus(openId, false);
    }

    // 处理已关注用户扫描二维码事件
    private void handleScanEvent(String openId, String eventKey) {
        String userId = extractUserIdFromEventKey(eventKey);  // 提取用户ID
        System.out.println("已关注用户扫描二维码,OpenID: " + openId + ", 场景值: " + eventKey);
        System.out.println("已关注用户,场景值中提取的用户ID: " + userId);

        // 根据场景值和用户ID执行相应的业务逻辑
        saveScanEventInfo(openId, userId);
    }

    // 提取 userId 方法
    private String extractUserIdFromEventKey(String eventKey) {
        if (eventKey != null && !eventKey.isEmpty()) {
            try {
                // 尝试提取 userId (假设 eventKey 是数字形式的用户ID)
                return eventKey.replace("qrscene_", "");
            } catch (Exception e) {
                System.out.println("提取 userId 时发生错误: " + e.getMessage());
            }
        }
        return "未知用户ID";
    }

    // 模拟保存用户信息到数据库
    private void saveUserInfo(String openId, String userId) {
        // 在这里执行将 openId 和 userId 保存到数据库的操作
        System.out.println("保存用户信息到数据库,OpenID: " + openId + ", 用户ID: " + userId);
    }

    // 模拟更新用户状态(取消关注)
    private void updateUserStatus(String openId, boolean isActive) {
        // 在这里执行更新数据库中用户状态的操作
        System.out.println("更新用户状态为 " + (isActive ? "活跃" : "取消关注") + ",OpenID: " + openId);
    }

    // 保存二维码扫描事件的信息
    private void saveScanEventInfo(String openId, String userId) {
        // 在这里执行保存已关注用户扫描二维码后的事件信息的操作
        System.out.println("保存二维码扫描事件信息,OpenID: " + openId + ", 用户ID: " + userId);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值