【微信】公众号扫码点餐功能(附源码)

【标题】微信-推送公众号扫码关注信息(附源码)

 

【前言】

最近在做一个需求,也是公众号常用的功能-《扫码点餐》。

在店铺桌子贴一张固定二维码,用户扫码后进入公众号窗口①,推送模板消息(点餐消息)给用户②。

① 用户已关注公众号,则到关注页面;已关注则直接进入公众号窗口。

② 使用openId和模板消息id推送信息给用户。

这样可以收集用户的openId,绑定店铺,后期也能推送其他模板消息、帮助用户和店铺静默开通会员卡等操作。

【概览】

 

 


一、实现步骤

1、生成带参数的二维码

2、服务器接入指南

3、接收事件推送

4、与3同

【概览】

 

 

 


二、部分代码:

1、qrauth_wx.jsp(显示二维码)

<noscript>
	<h3 class="tips">您的浏览器不支持JavaScript,请更改浏览器参数!</h3>
</noscript>
<%
	String key = "key_" + System.currentTimeMillis();
	String url = QRauthAction.getQRCodeByCache(storeName);
	session.setAttribute("xxx_eqcode_url_" + key, url);
%>
<div class="mydiv" id="opacity"></div>
<div style="margin: auto; width: 100%; padding: 0px;" id="ecode_div">
	<img alt="二维码" src="<%=serviceUrl%>/qrauth_wx_img.jsp?key=<%=key%>&width=<%=width%>&height=<%=height%>" title="扫码关注" style="max-width: 600px; max-height: 600px;" id="qrCode" />
</div>

2、获取access_token:

/**
 * TODO 请求微信获取token
 * 
 * @param appId
 * @return
 */
protected static String getAccess_token(String appId, String secret) {
	String rs = null;
	try {
		String mainUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" + secret;
		rs = NetUtils.getHtmlSource(mainUrl, 5000);
		JSONObject json = new JSONObject(rs);
		return json.getString("access_token");
	} catch (Exception e) {
		LogUtils.error(rs, e);
		return "";
	}
}

3、生成二维码:

/**
 * 创建二维码
 * 
 * @param access_token
 * @param qrCodeType
 * @return
 */
public static String createQRCode(String access_token, String parames, String qrCodeType) {
	try {
		Json json = new Json();
		JSONObject jsonObject = new JSONObject();
		JSONObject jsonObject1 = new JSONObject();
		if (StringUtils.isNotBlank(qrCodeType) && "1".equals(qrCodeType)) {
			// 生成永久二维码
			jsonObject1.put("scene_str", parames);
			jsonObject.put("scene", jsonObject1);
			json.add("action_name", "QR_LIMIT_STR_SCENE");
			json.add("action_info", jsonObject);
		} else {
			jsonObject1.put("scene_str", parames);
			jsonObject.put("scene", jsonObject1);
			json.add("expire_seconds", String.valueOf(1000 * 60 * 60 * 24)); // 有效期:秒
			json.add("action_name", "QR_STR_SCENE");
			json.add("action_info", jsonObject);
		}
		String createRS = WeiXinNetUtil.postJsonDataToServer(WeiXinUrl.QRCODE_CREATE + "?access_token=" + access_token, json.toString());
		LogUtils.debug(createRS);
		JSONObject creJson = new JSONObject(createRS);
		if (!creJson.has("url")) {
			return null;
		}
		return creJson.getString("url");
	} catch (Exception e) {
		e.printStackTrace();
		return null;
	}
}

4、接收推送消息:

if ("event".equalsIgnoreCase(msgType)) {
	String event = map.containsKey("Event") ? map.get("Event") : null;
	if (event != null) {
		String eventKey = map.containsKey("EventKey") ? map.get("EventKey") : null;
		// 关注/取消关注事件:
		if ("subscribe".equalsIgnoreCase(event)) {
			if (StringUtils.isNotBlank(eventKey)) {
				eventKey = eventKey.replaceAll("qrscene_", "");

				Update update = new Update("Account");
				update.setKey("storeName", eventKey);
				update.setValue("openid", openId);
				update.execute(true);
			}
			new WeiXinMethod().message_custom_send(openId, "感谢你的关注,我与你同在!!!");

			SendMessageDing sendMessageDing = new SendMessageDing();
			sendMessageDing.setTitle("用户关注公众号");
			sendMessageDing.setLogType("微信");
			sendMessageDing.setLogInfo("用户{" + openId + "}关注了公众号,绑定了{" + eventKey + "}账号");
			sendMessageDing.sendAsyn();
		}
		if ("unsubscribe".equalsIgnoreCase(event)) {
			String storeName = DBUtils.getString("select storeName from Account where openId=? limit 1 ", new String[] { openId });

			SendMessageDing sendMessageDing = new SendMessageDing();
			sendMessageDing.setTitle("取消关注公众号");
			sendMessageDing.setLogType("微信");
			sendMessageDing.setLogInfo("用户{" + openId + "}取消关注公众号,为{" + storeName + "}账号;");
			sendMessageDing.sendAsyn();

			DBUtils.execute("update Account set openId=null where openId=? ", new String[] { openId });
		}
		if ("scan".equalsIgnoreCase(event)) {
			if (StringUtils.isNotBlank(eventKey)) {
				eventKey = eventKey.replaceAll("qrscene_", "");

				Update update = new Update("SYCM_Account");
				update.setKey("storeName", eventKey);
				update.setValue("openid", openId);
				update.execute(true);
			}
			SendMessageDing sendMessageDing = new SendMessageDing();
			sendMessageDing.setTitle("用户重新扫码进公众号");
			sendMessageDing.setLogType("微信");
			sendMessageDing.setLogInfo("用户{" + openId + "}已关注公众号,为{" + eventKey + "}账号!");
			sendMessageDing.sendAsyn();
		}
		if ("click".equalsIgnoreCase(event)) {
			// @-菜单点击,菜单id匹配:
			if ("NIUCM_V1001_DOWN".equalsIgnoreCase(eventKey)) {
				String msg = "地址:https://www.baidu.com/";
				out.println(WeiXinMethod.getSendPlainMsgXml(openId, toUserId, msg));
			}
		}
	}
}

5、推送模板消息给用户:

/**
 * TODO 模板推送
 * 
 * @param map
 * 
 */
public static boolean queueReminderPush(Map<String, Object> map) {
	String openId = map.get("openId").toString();
	if (openId == null)
		return false;
	String title = map.get("title") == null ? "" : map.get("title").toString();
	String keyword1 = map.get("keyword1") == null ? "" : map.get("keyword1").toString();
	String keyword2 = map.get("keyword2") == null ? "" : map.get("keyword2").toString();
	String detailUrl = map.get("detailUrl") == null ? "" : map.get("detailUrl").toString();
	String remark = map.get("remark") == null ? "" : map.get("remark").toString();
	try {
		String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + AccessTokenUtil.getTokenByDB();
		Json json = new Json();
		Json data = new Json();
		json.add("template_id", WX_APP_TEMPLATE_ID);
		json.add("url", detailUrl);
		json.add("topcolor", "#000000");
		json.add("touser", openId);
		data.put("first", newWeixinJson(title));
		data.put("keyword1", newWeixinJson(keyword1));// 商家名称
		data.put("keyword2", newWeixinJson(keyword2));// 评测结果
		data.put("remark", newWeixinJson(remark, "#993366"));
		json.put("data", data);
		String strRes = NetUtils.getHtmlSourcePost(url, json.toString());
		LogUtils.debug(strRes);
		JSONObject obj = new JSONObject(strRes);
		if (obj.has("errcode") && !"0".equalsIgnoreCase(obj.getString("errcode"))) {
			return false;
		}
		return true;
	} catch (Exception e) {
		return false;
	}
}

 


三、附件-代码:

代码地址:https://download.csdn.net/download/qq_26599807/12107121 密码:lcl20200116

如遇代码不能用,麻烦给作者留言,百忙之中尽量给以回复。

Ⅰ、可能原因:

1、尚未更新地址(最后编辑:2020-01-19 14:13:11)

2、资源未审核通过,一个小时后重试

3、资源被和谐了

4、not other...

Ⅱ、代码说明:

1、SendMessageDing类为推送服务消息日志类,可忽略。

2、QRImageUtils和qrauth_wx_img.jsp是二维码java生成方式,可自行度娘。

3、类似DBUtils和Update的是数据库操作封装类,可使用自己项目传统方式。

4、CacheUtils缓存、StringUtils字符串判断及转型。

 

 

作者附言:如果本文章帮到了您,劳烦动动贵手点个赞,关注一下,谢谢^_^

 

  • 7
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值