背景
在做微信小程序开发中,微信小程序码是营销的一个重要功能。 经常和海报一起结合使用。 如下:
小程序码官方文档
代码
uniapp
- 发起请求生成小程序码
generateQrCode(){
var reqData ={
"path": 'pages/index/index',
"params": "id=1"
}
this.http.post(this.$url.poster.generateQrCodeUrl,
{data: reqData, showLoading: true}).then(res => {
if(res.code === 200){
//改变海报的二维码图
this.posterSimpleData.posterCodeUrl = res.data
//改变海报背景图
this.posterSimpleData.posterBgUrl = this.posterUrl
//封装数据展示简版海报
this.posterObj = this.posterSimpleData
this.simpleFlag = true
//显示弹窗
this.deliveryFlag = true
}
}).catch(e => {
console.log(e)
})
},
- 小程序码扫码进入页面的处理
onLoad(options) {
const scene = decodeURIComponent(options.scene)
if(util.isNotEmpty(scene)){
//从海报进入
let idParam = scene.split("=")[1];
this.getById(idParam);
}else{
//其他渠道
this.getById(options.id);
}
},
boot后端代码
//controller
@ApiOperation(value = "/generateQrCodeUrl", notes = "生成微信分享二维码")
@PostMapping("generateQrCodeUrl")
public Result<String> generateQrCodeUrl(@RequestBody QrCodeUrlReq qrCodeUrlReq) {
log.info("generateQrCodeUrl:{}", qrCodeUrlReq);
ValidatorUtils.validateEntity(qrCodeUrlReq);
String qrCodeUrl = fileService.generateQrCode(qrCodeUrlReq.getPath(), qrCodeUrlReq.getParams());
return Results.newSuccessResult(qrCodeUrl);
}
//service
@Override
public String generateQrCode(String page, String certNumber) {
String fileDir = "qrCode/customer/" + DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN) + ".png";
return WxUtil.downloadMiniCode(fileDir, page, certNumber, appId, appSecret);
}
- WxUtil
package com.jeecg.camunda.gateway.common.util;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.jeecg.camunda.gateway.common.oss.OssBootUtil;
import lombok.extern.slf4j.Slf4j;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
/**
* 微信小程序辅助工具类 https://developers.weixin.qq.com/miniprogram/dev/api-backend/
*
* @Author zhengkai.blog.csdn.net
*/
@Slf4j
public class WxUtil {
public static String GET_MINICODE_URL = "https://api.weixin.qq.com/wxa/getwxacodeunlimit";
public static String getAccessTokenAsUrl(String appId, String appSecret) {
String tokenStr = HttpUtil.get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" + appSecret + "");
log.info(tokenStr);
JSONObject jsonObject = JSONObject.parseObject(tokenStr);
return "?access_token=" + jsonObject.getString("access_token");
}
/**
* 下载带参数的小程序二维码
* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/qr-code/wxacode.getUnlimited.html
* by zhengkai.blog.csdn.net
*
* @param path 保存图片的的path(该路径一定要线上发布之后的,否则会生成失败)
* @param certNumber 带过去小程序的参数,一般为你的业务参数,建议是id或者number,scene可以多个参数=分隔符 :"1_2_3_4"
*/
public static String downloadMiniCode(String path, String page, String certNumber, String appId, String appSecret) {
Map<String, Object> paramMap = new HashMap<>(12);
paramMap.put("page", page);
paramMap.put("scene", certNumber);
paramMap.put("is_hyaline", true);
try {
String buildUrl = GET_MINICODE_URL + getAccessTokenAsUrl(appId, appSecret);
URL url = new URL(buildUrl);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
// 提交模式
httpURLConnection.setRequestMethod("POST");
//连接超时 单位毫秒
httpURLConnection.setConnectTimeout(10000);
//读取超时 单位毫秒
httpURLConnection.setReadTimeout(10000);
// 发送POST请求必须设置如下两行
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
// 获取URLConnection对象对应的输出流
PrintWriter printWriter = new PrintWriter(httpURLConnection.getOutputStream());
printWriter.write(JSON.toJSONString(paramMap));
// flush输出流的缓冲
printWriter.flush();
//开始获取数据
String qrCodeUrl = OssBootUtil.upload(httpURLConnection.getInputStream(), path);
return qrCodeUrl;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
踩坑记录
paramMap.put("page", page);
paramMap.put("scene", certNumber);
// 小程序码设置的page路径,一定是线上发布的路径,线上发布的路径,线上发布的路径!!!
// 否则生成出异常, 找了好久才发现这个问题, 希望大家一定注意!!!!
//出现异常的场景描述
//1.版本迭代的时候,删除了某一个用于生成的页面
//2.本地调试的时候, 用了没有发布的页面进行使用