微信小程序中引导用户关注公众号实现方案详细说明

news/2024/5/17 16:14:29/文章来源:https://blog.csdn.net/weixin_43401380/article/details/127171766

前言

    之前讲过如何利用公众号针对指定用户完成业务操作之后实时发送消息.就好比在线医院公众号中看病挂号,挂号预约成功之后微信列表中会新增一条关注的公众号预约成功消息.具体实现步骤可以看下文章如何实现:手把手教你微信公众号如何给指定用户发送消息提醒,有兴趣的可以看下。现在要从小程序中要加入引导关注公众号并授权的功能,用于使用公众号发送业务消息提醒,注意这里不是订阅消息。
    参考过很多其他同学的实现方案,总感觉有些繁琐,并且接口有调用次数的限制。结合业务场景梳理了一下流程,并对具体的实现做了详细说明,希望对有同样需求的同学有所帮助,下面详细说下整个流程。

业务流程说明

    用户登录小程序进入到消息模块之后,对于没有关注公众号的用户或是已经关注公众号但是没有授权的用户显示引导关注公众号提示信息,已经关注公众号并授权处理的不显示(授权逻辑主要是指将用户关注公众号的openID与用户信息进行绑定,下文会详细讲)业务截图如下:
图1

    点击进入关注公众号页面,这里进入的是公众号发布的一篇公众号关注文章,业务截图如下:在这里插入图片描述

    没有关注公众号的进入到关注页面。在这里插入图片描述
    对于已关注公众号的用户,直接进入公众号聊天页面,设置默认回复为授权链接(进入到此页面的为已关注公众号但是没有授权的用户)。截图如下:
在这里插入图片描述

    点击开通消息之后进入到授权页面进行授权即可,授权成功之后跳转到小程序完成授权操作。在这里插入图片描述

    以上是对小程序中引导关注公众号的流程梳理,下面说下如何进行实现,主要侧重于服务端讲解实现原理!

实现方案说明

    这里需要用户进入到小程序之后获取一下用户的unionId,unionId可以说是同一个用户在微信开放平台下各个产品中的唯一标识.openId在微信平台下每个产品是唯一的.两个都需要后端进行入表操作.unionId可以放到用户注册登录中实现.openId入表逻辑可以放到授权操作中(这里使用的是公众号的openID,因为官方提供的公众号发送消息接口中需要获取关注公众号用户的唯一标识openID).主要说下本文重点:如何判断用户是否关注过公众号.梳理逻辑如下:
在这里插入图片描述

    判断的主要逻辑是看用户表信息中是否有维护过公众号的openId,如果有则说明之前关注过,但考虑到关注的用户可能会取消关注但是表中还保存着之前的公众号openId,所以这里调用官方的获取用户基本信息接口根据subscribe进行判断现在用户是否处于关注状态.subscribe表示用户是否订阅该公众号标识,值为0时,代表此用户没有关注该公众号,拉取不到其余信息。官方接口截图如下:
在这里插入图片描述
    这里再贴一下公众号网页授权流程:
在这里插入图片描述
需要在授权操作中维护一下用户在公众号下面的唯一标识:openId.

代码以及表结构实现

用户表结构设计如下:

CREATE TABLE `user` (`user_id` bigint(20) NOT NULL AUTO_INCREMENT,`login` varchar(20) NOT NULL COMMENT '用户唯一标识',`union_id` varchar(30) NOT NULL COMMENT '用户unionId',`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`update_time` datetime DEFAULT NULL COMMENT '更新时间',`gzh_open_id` varchar(60) DEFAULT '' COMMENT '用户关注的公众号openId',PRIMARY KEY (`user_id`),UNIQUE KEY `unique` (`login`),UNIQUE KEY `unionId_unique` (`union_id`)
) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8mb4 COMMENT='用户信息表';

    主要提供两个接口,一个是判断用户数是否关注公众号并授权,另一个是用户授权接口(主要逻辑是引导用户关注公众号后将公众号openid绑定用户信息入表)。现提供两个接口的实现逻辑。

1.判断用户是否关注公众号并授权

@ApiOperation(value = "判断用户是否关注公众号并授权:true表示关注且授权,false表示未关注或已关注未授权",notes = "返回true表示已关注公众号并已进行授权(用户信息中维护openId),页面不做引导处理.返回false表示没有关注公众号或是关注公众号之后没有授权,可引导关注并授权")
@ApiImplicitParams({@ApiImplicitParam(name = "unionId", value = "unionId", required = true, dataType = "Boolean", paramType = "query",example = "1")})
@GetMapping("/checkIsFollowGzg")
public ResultVo checkIsFollowGzg(@NotBlank(message = "unionId不允许为空!") String unionId){boolean returnFlag = userService.checkIsFollowGzg(unionId);return  ResultVoUtil.success(returnFlag);
}

service层实现具体逻辑:

 @Overridepublic boolean checkIsFollowGzg(String unionId) {boolean returnFlag=false;// 根据unionId查询用户关注公众号的openIdUser userBasicInfo = userMapper.findUserBasicInfo(unionId,null);if(ObjectUtil.isNull(userBasicInfo)) throw new BussinessExcption(ApiCode.SYSTEM_EXCEPTION.getMessage());String gzhOpenId = userBasicInfo.getGzhOpenId();if(StrUtil.isBlank(gzhOpenId)) return returnFlag;// 根据公众号的openId和accessToken判断用户是否关注(subscribe为1表示关注)// 获取微信认证信息String wxgAccessToken = getWxgAccessToken();if (checkIsGzhUer(gzhOpenId, wxgAccessToken)) return true;return false;}/*** @Author: txm* @Description: 获取公众号认证AccessToken* @Param: []* @return: java.lang.String* @Date:  2022/10/5 10:47**/public String getWxgAccessToken() {String returnMsg="";JSONObject accessTokenObject = null;String gzhAppId =jobConfig.getGzhAppId();String gzhSecret=jobConfig.getGzhSecrect();String requestUrl = StrUtil.format(Constants.GZH_ACCESS_TOKEN_URL, gzhAppId, gzhSecret);try {returnMsg=HttpUtil.get(requestUrl);accessTokenObject = JSON.parseObject(returnMsg);log.info("错误信息:{}",accessTokenObject);} catch (Exception e) {log.error("获取用户AccessToken认证信息失败:{}",e.getMessage());}String accessToken = accessTokenObject.getString("access_token");if(StrUtil.isBlank(accessToken)) throw new BussinessExcption("响应异常:获取accessToken信息为空!");return accessToken;}/*** @Author: txm* @Description: 校验是否是关注过公众号用户,返回false表示没有关注公众号;返回true表示关注过公众号* @Param: [gzhOpenId, wxgAccessToken]* @return: boolean* @Date:  2022/10/8 16:06**/private boolean checkIsGzhUer(String gzhOpenId, String wxgAccessToken) {// 根据获取公众号用户基本信息String responBasicUserInfo="";JSONObject basicUserInfo = null;String reqUrl = StrUtil.format(Constants.USER_BASIC_INFO_URL, wxgAccessToken, gzhOpenId);try {responBasicUserInfo= HttpUtil.get(reqUrl);basicUserInfo = JSON.parseObject(responBasicUserInfo);} catch (Exception e) {log.error("获取用户公众号基本信息失败:{}",e.getMessage());}if(ObjectUtil.isNull(basicUserInfo)) throw new BussinessExcption(ApiCode.SYSTEM_EXCEPTION.getMessage());// 用户是否订阅该公众号标识,1表示关注,值为0时,代表此用户没有关注该公众号,拉取不到其余信息。if(StrUtil.isBlank(basicUserInfo.getString("subscribe")) || StrUtil.equals("0",basicUserInfo.getString("subscribe"),true)) return false;return true;}

2.用户授权操作

@ApiOperation("公众号授权操作:判断是否关注公众号:返回true表示已经关注公众号用户并绑定公众号openId,返回false表示没有关注公众号")@PostMapping("/getWxgUserInfo")public ResultVo getWxgUserInfo(@RequestBody @Validated WxgUserInfoDto wxgUserInfoDto){userService.getWxgUserInfo(wxgUserInfoDto);return  ResultVoUtil.success();}

service层实现逻辑:

/*** @Author: txm* @Description: 授权处理* @Param: [wxgUserInfoDto]* @return: void* @Date:  2022/10/5 9:08**/
@Overridepublic void getWxgUserInfo(WxgUserInfoDto wxgUserInfoDto) {// 网页授权根据code获取access_tokenJSONObject accessTokenInfo = getWxgAccessTokenInfo(wxgUserInfoDto.getCode());String accessToken = accessTokenInfo.getString("access_token");String openid = accessTokenInfo.getString("openid");if(StrUtil.isBlank(accessToken)|| StrUtil.isBlank(openid)) throw new BussinessExcption("获取用户信息失败:accessToken或openId获取为空!");// 根据公众号的openId和accessToken判断用户是否关注(subscribe为1表示关注)// 获取微信认证信息access_tokenString wxgAccessToken = getWxgAccessToken();// 校验用户是否已经关注公众号,已经关注公众号需要查询是否维护过公众号的openIdif (checkIsGzhUer(openid, wxgAccessToken)){// 根据unionId查询用户是否已经维护过公众号openId,没有的话需要更新用户关注公众号的openIdString login = wxgUserInfoDto.getLogin();User userBasicInfo = userMapper.findUserBasicInfo(null,login);if(ObjectUtil.isNull(userBasicInfo)) throw new BussinessExcption(ApiCode.SYSTEM_EXCEPTION.getMessage());// 更新用户公众号openIdint i = userMapper.updateUserOpenId(openid, login);if(i == 0) throw new BussinessExcption("操作失败:更新信息为空!");}}/*** @Author: txm* @Description: 获取AccessToken* @Param: [code]* @return: com.alibaba.fastjson.JSONObject* @Date:  2022/10/5 9:08**/public JSONObject getWxgAccessTokenInfo(String code) {String accessTokenInfo = "";JSONObject accessTokenObject = null;String gzhAppId =jobConfig.getGzhAppId();String gzhSecret=jobConfig.getGzhSecrect();String reqUrl = StrUtil.format(Constants.ACCESS_TOKEN_URL, gzhAppId, gzhSecret, code);try {accessTokenInfo=HttpUtil.get(reqUrl);log.info("错误信息:{}",accessTokenInfo);accessTokenObject = JSON.parseObject(accessTokenInfo);} catch (Exception e) {log.error("获取用户AccessToken认证信息失败:{}",e.getMessage());}return accessTokenObject;}

用户信息操作接口:

public interface UserMapper {// 根据unionId查询用户基本信息User findUserBasicInfo(String unionId);}

用户信息持久层配置文件:

<!-- 获取用户基本信息,实体类暂不提供可自行自定义--><select id="findUserBasicInfo" resultType="com.kawa.job.api.wanted.user.entity.User">select user_id,login,gzh_open_id from job_user where union_id=#{unionId} limit 1</select>

    以上是处理小程序中引导关注公众号的处理方案,如果看完感觉有所帮助,欢迎评论区留言或点赞,每个赞美都是对自己最大的鼓励和支持!

官方文档链接:公众号官方文档

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

瑞吉外卖06-分页查询

瑞吉外卖06-分页查询 需求分析 问题描述 解决方案 对于createTime、updateTime字段 对于createUser、updateUser字段 代码实现 知识点分析 ThreadLocal 本次功能代码实现&#xff08;免费&#xff09; 瑞吉外卖06-分页查询 需求分析 问题描述 前面我们已经完成了…

嵌入式分享合集76

一、推挽、开漏、OC、OD 与推挽输出相对的是开漏输出&#xff0c;而开漏输出分为OC、OD两种&#xff0c;下文分别详细介绍。 推挽输出 推挽输出&#xff08;Push-Pull Output&#xff09;是由两个MOS或者三极管受到互补控制信号的控制&#xff0c;两个管子始终处在一个导通另一…

解决github分支提交冲突

一、背景 github上fork了base仓库 648540858/wvp-GB28181-pro 到自己仓库&#xff0c;并进行了个性化更改。base仓进行了代码更新&#xff0c;此时我和base仓有了冲突如何解决&#xff1f; 思路&#xff1a;自己仓库的代码合并到主仓是Pull Requests&#xff0c;两个不同仓库or…

PDF怎么转图片?建议收藏这些方法

PDF是我们在传输文件的时候&#xff0c;经常会使用到的一种格式。它可以帮助我们在不同的设备上&#xff0c;打开文件并且不会影响到文件内容的文字结构。而jpg是一种常见的图片格式&#xff0c;有时我们可能会遇到PDF转jpg的情况&#xff0c;那你们知道PDF转jpg怎么转吗&#…

git push 所有分支到新仓库地址

例&#xff1a;从gitee上拉取test-code代码&#xff0c;到自己新仓库地址,test-code仓库有master和test两个分支&#xff1b;具体命令和结果如下 xxxxxxxxopen02:~/src/code/tmp$ git clone gitgitee.com:striver-wy/test-code.git //从gitee下载代码 Cloning into test-code..…

CVPR2022-Rethinking Efficient Lane Detection via Curve Modeling

概述 总结分析了当前&#xff08;图像&#xff09;车道线检测的三类方法&#xff0c;为了解决现有多项式曲线方法的优化困难&#xff0c;提出了使用参数贝塞尔曲线拟合车道线的方案。此外还提出了基于变形卷积的特征翻转融合&#xff0c;以利用驾驶场景中车道的对称特性。 Pape…

Mysql基于binlog日志恢复数据

Mysql基于binlog日志恢复数据 1.Linux安装mysql https://blog.csdn.net/qq_44981526/article/details/126717005 可能遇到的问题 1.net-tools未安装&#xff0c;执行yum install net-tools 2.远程连接工具连接不上mysql grant all privileges on *.* to root% identified…

R语言caret机器学习(四):数据拆分

【R语言数据科学】 🌸个人主页:JOJO数据科学📝个人介绍:统计学top3高校统计学硕士在读💌如果文章对你有帮助,欢迎✌关注、👍点赞、✌收藏、👍订阅专栏✨本文收录于【R语言数据科学】本系列主要介绍R语言在数据科学领域的应用包括: R语言编程基础、R语言可视化、R…

垃圾分类查询管理系统

垃圾分类查询管理系统1.介绍1.1 功能点2.软件架构3.安装启动4.运行截图参考网站&#xff1a;https://lajifenleiapp.com/ 1.介绍 垃圾分类查询管理系统&#xff0c;对不懂的垃圾进行查询进行分类并可以预约上门回收垃圾。 让用户自己分类垃圾&#xff0c; 按国家标准自己分类&…

【最详细最全】Github的jenkins的自动化部署

1>创建项目 2>General 设置 3>配置源码管理 1>勾选Git选项之后&#xff0c;就会出现相关的填写项&#xff0c;根据下图的指引来填写就行了 填写项目的 git 地址, eg&#xff1a; GitHub - Leader755/leader755.github.io: github 博客&#xff08;hexo一键搭建博…

(附源码)计算机毕业设计SSM基于Java的图书馆座位预约系统

&#xff08;附源码&#xff09;计算机毕业设计SSM基于Java的图书馆座位预约系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 …

Torch网络结构/训练过程可视化

一、网络结构的可视化 我们训练神经网络时&#xff0c;除了随着step或者epoch观察损失函数的走势&#xff0c;从而建立对目前网络优化的基本认知外&#xff0c;也可以通过一些额外的可视化库来可视化我们的神经网络结构图。这将更加地高效地向读者展现目前的网络结构。 为了可…

ARM接口技术:汇编语言实现1~100的累加,1+2+3+4+...+99+100=?还有汇编语言程序的编译和运行步骤

进入正题&#xff1a; 在终端输入&#xff1a;vi sum.S&#xff0c;建立文件 1、编写代码&#xff1a;定义两个变量&#xff0c;r0、r1 .global _start _start:mov r0,#1mov r1,#0 sum:add r1,r0add r0,#1cmp r0,#100bgt endb sumend:mov r2,r1nopnopnop2、编译建立一个makefi…

客流管控系统可以协助博物馆进行人数管理

进入21世纪&#xff0c;我国的博物馆建设迎来了新的高潮&#xff0c;无论是数量&#xff0c;还是规模&#xff0c;都前所未有。目前&#xff0c;全国的博物馆总数已经达到5 000多座&#xff0c;为了管控博物馆的人数&#xff0c;很多博物馆都安装了客流管控系统。客流管控系统可…

Android 开发学习(一)

文章目录1. Android 安装2. 创建第一个Android项目3. 什么是Gradle&#xff1f;4. 运行第一个Android程序5. Android架构 介绍6. 控件 之 textView(文本)6.1 textView 基础语法6.2 带阴影的textView6.3 跑马灯效果的 textView7. 控件 之 Butto(按钮)7.1 Button 的 基本属性 和 …

电源纹波,有这样几种测试方法,值得收藏

【嵌入式学习资料】V/ X 公/众/号 https://pan.baidu.com/s/1K8_EKVtOaN42IvuFSj8vJA tiquma&#xff1a;6666 纹波测试在电源质量检测中十分重要&#xff0c;虽然看似简单&#xff0c;但却包含诸多细节。这些细节在您测试的时候是否面面俱到&#xff1f;我们又如何把一项简单…

上海雷卯推出SOD123HE封装肖特基,帮工程师解决发热问题

为何肖特基二极管会发热&#xff1f; 肖特基二极管在工作时发热量不可小视&#xff0c;发热量大小与实际工作电流大小有关&#xff0c;与肖特基二极管实际压降大小有关。这是可以通过测量和计算得到&#xff0c;很方便。 方法是&#xff1a;测得二极管两端实际压降假如为0.5V…

浅谈C语言文件操作以及对先前通讯录的简单改造

文章目录前言1.为什么要使用文件以及文件简单介绍文件的简单介绍2.文件的相关操作1.文件的打开和关闭2.文件的顺序读写文件的顺序写文件的顺序读总结3.文件的随机读写4.文本文件和二进制文件介绍以及文件的读取结束的判定3.文件缓冲区4.对先前通讯录的改造5总结前言 之前简单的…

一家公司需要多少名产品经理?从这三个角度评估

扩张你的产品团队前应当考虑的一件事情是&#xff0c;当前阶段问题的根源是否真的在于人手不足——毕竟只有在适当的发展时机扩张团队&#xff0c;才能起到良好的作用。 当你开始考虑是否要扩张产品团队时&#xff0c;你就会面临所谓的“高质量问题”。 对更多产品管理资源的需…

C# 连接 MySQL 数据库

一、需求 C# 使用 MySQL 数据库的情况还是比较少的&#xff0c;大部分使用 Windows 平台一般使用 SQL Server&#xff0c;在两年前我买过100元一年的学生服务器&#xff0c;当时也是买着玩的&#xff0c;装 MySQL 数据库使用起来就非常卡&#xff0c;也不知道为什么&#xff0…