uniapp生成微信小程序码踩坑记录

107 阅读2分钟

背景

在做微信小程序开发中,微信小程序码是营销的一个重要功能。 经常和海报一起结合使用。 如下:
小程序码官方文档

DiTPxG90XSJGa4192dd0e11b5f6a44644888f74646b7.png

代码

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.本地调试的时候, 用了没有发布的页面进行使用