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

为用户生成二维码

    @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;
    @Overridepublic SysUser generateUserQrcode(Long userId) throws JsonProcessingException {// 使用合适的 scene_idint sceneId = (int)(userId % 100000); // 确保在范围内// 1. 获取用户信息SysUser user = userMapper.selectUserById(userId);if (user == null) {throw new RuntimeException("用户不存在");}// 2. 调用微信接口生成永久二维码String accessToken = getAccessToken();  // 获取 access_tokenString qrcodeUrl = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" + accessToken;// 创建永久二维码的请求Map<String, Object> scene = new HashMap<>();scene.put("scene_id", sceneId);  // 使用合法的 sceneIdMap<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 和 TicketString 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_")) {// 提取场景值中的 userIdString 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 更新openIdboolean 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);  // 提取用户IDSystem.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);}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/147724.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

最佳植树距离 - 华为OD统一考试(E卷)

2024华为OD机试&#xff08;C卷D卷E卷&#xff09;最新题库【超值优惠】Java/Python/C合集 题目描述 按照环保公司要求&#xff0c;小明需要在沙化严重的地区进行植树防沙工作&#xff0c;初步目标是种植一条直线的树带。由于有些区域目前不适合种植树木&#xff0c;所以只能在…

电脑提示找不到msvcp110.dll怎么办?全方面详细解答

msvcp110.dll 是 Microsoft Visual C 2012 Redistributable Package 中的一个动态链接库文件。它是运行使用 Visual C 2012 开发的应用程序所必需的&#xff0c;包含了许多 C 标准库函数的实现。这些函数主要用于支持字符串处理、内存管理、输入输出流、异常处理等功能。 1.ms…

Clion使用vcpkg管理C/C++包

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、Clion安装vcpkg二、使用步骤1.切换到清单模式2.开始安装包 三、测试代码总结 前言 Linux上的库基本都可以通过apt或yum等包管理工具来在线安装包&#xff…

C语言深入理解指针(四)

目录 字符指针变量数组指针变量数组指针变量是什么数组指针变量怎么初始化 二维数组传参的本质函数指针变量函数指针变量的创建函数指针变量的使用代码typedef关键字 函数指针数组转移表 字符指针变量 字符指针在之前我们有提到过&#xff0c;&#xff08;字符&#xff09;&am…

NLP 文本分类核心问题

解决思路 分解为多个独立二分类任务将多标签分类转化为多分类问题更换 loss 直接由模型进行多标签分类 数据稀疏问题 标注更多数据&#xff0c;核心解决方案&#xff1a; 自己构造训练样本 数据增强&#xff0c;如使用 chatGPT 来构造数据更换模型 减少数据需求增加规则弥补…

MELON的难题- 华为OD统一考试(E卷)

2024华为OD机试&#xff08;C卷D卷&#xff09;最新题库【超值优惠】Java/Python/C合集 题目描述 MELON 有一堆精美的雨花石&#xff08;数量为 n&#xff0c;重量各异&#xff09;&#xff0c;准备送给 S和 W&#xff0c;MELON 希望送给俩人的雨花石重量是一致的。请你设计一…

爬虫 ----hook

目录 定义&#xff1a; 了解什么是hook? 举例 hook XHR请求 XMLHttpRequest 案例地址&#xff1a; Interceptors-拦截器 HOOK cookie操作 cookie 示范 常见的hook代码总结 1.Hook Cookie 2.Hook Header 3.Hook URL 4.Hook JSON.stringify 5.Hook JSON.parse 6.Ho…

Mac使用gradle编译springboot-2.7.x源码

1 开发环境&#xff1a; JDK8 ideaIU-2024.2.2 gradle-7.6.3 代理网络 2 下载springboot源码 代码仓库网址 git clone -b 2.7.x https://github.com/spring-projects/spring-boot.git3 安装gradle gradle下载网址 https://services.gradle.org/distributions/ 安装此文件指…

C语言 | Leetcode C语言题解之第415题字符串相加

题目&#xff1a; 题解&#xff1a; char* addStrings(char* num1, char* num2) {int i strlen(num1) - 1, j strlen(num2) - 1, add 0;char* ans (char*)malloc(sizeof(char) * (fmax(i, j) 3));int len 0;while (i > 0 || j > 0 || add ! 0) {int x i > 0 ?…

lsof可以查看当前系统中正在被使用的文件,包括动态库

lsof的英文是 list open files lsof直接回车&#xff0c;会显示很多&#xff0c;可以配合more命令查看 lsof | more -10 sudo lsof | more -20 lsof查看正在使用某个动态库的进程 lsof /lib/x86_64-linux-gnu/libc.so.6 lsof /usr/lib/x86_64-linux-gnu/libc.so.6 l…

如何优化苹果CMS 泛目录的缓存管理?

在使用苹果CMS进行内容管理时&#xff0c;缓存管理是提升网站性能的重要环节。随着技术的不断发展&#xff0c;泛目录插件的缓存机制也逐渐变得不再必要。&#xff08;maccmscn&#xff09;本文将探讨如何在不使用缓存的情况下&#xff0c;优化苹果CMS泛目录的性能&#xff0c;…

(学习记录)使用 STM32CubeMX——配置时钟(入门)

使用STM32CubeMX配置STM32F103C8T6时钟部分 选择芯片 ①&#xff1a;选择MCU型号 ①&#xff1a;这里使用英文输入法&#xff0c;输入你想要的芯片型号&#xff0c;我这里采用STM32F103C8T6 ②&#xff1a;这里能看到搜索后出来的芯片具体型号&#xff0c;选择匹配度最高的一个…

MySQL-排名函数ROW_NUMBER(),RANK(),DENSE_RANK()函数的异同

MySQL-排名函数ROW_NUMBER()&#xff0c;RANK()&#xff0c;DENSE_RANK()函数的异同 前言 假设有如下表结构与数据&#xff0c;class_id表示班级&#xff0c;需求&#xff1a;现在要按照班级分组&#xff0c;每个班级的学生进行年龄从小到大排序 一、ROW_NUMBER()函数 ROW_NUM…

Linux中的调度算法

nice值的范围有限&#xff0c;即为[-20, 19]&#xff0c;也就是40个数字&#xff0c;优先级为[60, 99]即一共40个优先级 目前谈论的Linux操作系统叫做分时操作系统&#xff0c;调度的时候主要强调公平&#xff0c;还有一种是实时操作系统&#xff0c;比如智能汽车里面必须装有这…

【面经】查找中常见的树数据结构

查找中常见的树数据结构 一、二叉排序&#xff08;搜索、查找&#xff09;树&#xff08;BST&#xff0c;Binary Search Tree&#xff09;&#xff08;1&#xff09;二叉排序树的查找、插入和删除过程&#xff08;2&#xff09;叉树排序树的缺陷&#xff08;3&#xff09;二叉排…

Spark原理及调优

spark官档 hints&#xff1a;https://spark.apache.org/docs/3.0.0/sql-ref-syntax-qry-select-hints.html调优参数&#xff1a;https://spark.apache.org/docs/latest/sql-performance-tuning.html#join-strategy-hints-for-sql-queries作者几乎把所有的RDD API查了个遍&…

【服务器入门】Linux系统基础知识

【服务器入门】Linux系统基础知识 远程登录与文件传输基础命令与文本编辑vi/vim使用shell脚本基本命令1、目录操作2、文件创建与删改3、文件连接与查看 参考 目前超算使用的系统以Linux系统为主&#xff0c;肯定需要了解一些相关知识。本博客就以本人运行WRF模型所需&#xff0…

7-50 畅通工程之局部最小花费问题 (kruskal)

输入样例: 4 1 2 1 1 1 3 4 0 1 4 1 1 2 3 3 0 2 4 2 1 3 4 5 0输出样例: 3 代码&#xff1a; #include<iostream> #include<queue> using namespace std; const int N110; struct node{int x,y,w;bool operator <(const node &n1)const{if(wn1.w) retur…

提升编程效率的秘诀:多数人竟然忽略了它!

在编程学习的过程中&#xff0c;许多人会专注于算法、数据结构、编程语言的学习&#xff0c;而往往忽略了一个至关重要的基础技能——键盘盲打。虽然看似与编程能力无关&#xff0c;但盲打不仅可以显著提高编程效率&#xff0c;还能帮助编程者更好地集中注意力。本文将深入探讨…

数字图像面积计算一般方法及MATLAB实现

一、引言 在数字图像处理中&#xff0c;经常需要获取感兴趣区域的面积属性&#xff0c;下面给出图像处理的一般步骤。 1.读入的彩色图像 2.将彩色图像转化为灰度图像 3.灰度图像转化为二值图像 4.区域标记 5.对每个区域的面积进行计算和显示 二、程序代码 %面积计算 cle…