【golang】动态生成微信小程序二维码实战上:golang整合github.com/silenceper/wechat/v2 实现生成 小程序二维码图片

项目背景

在自研的系统,需要实现类似草料二维码的功能

将我们自己的小程序,通过代码生成相想要的小程序二维码

代码已经上传到 Github 需要的朋友可以自取
https://github.com/ctra-wang/wechat-mini-qrcode

一、源生实现

通过源生API实现对小程序二维码的生成

1、官方API

官方文档地址:https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/qrcode-link/qr-code/createQRCode.html

下面是三个官方的API 可以根据需求进行调用

CreateWXAQRCodeURL   = "https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=%s"
GetWXACodeURL        = "https://api.weixin.qq.com/wxa/getwxacode?access_token=%s"
GetWXACodeUnlimitURL = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%s"

2、golang 实现源码

go 复制代码
package main

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"log"
	"net/http"
	"net/url"
	"os"
)

const (
	CreateWXAQRCodeURL   = "https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=%s"
	GetWXACodeURL        = "https://api.weixin.qq.com/wxa/getwxacode?access_token=%s"
	GetWXACodeUnlimitURL = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%s"
)

const (
	// 替换成你的小程序 appiId 和 secretKey
	MINI_APP_LATEST_ID     string = "wxxxxf6"
	MINI_APP_LATEST_SECRET string = "7dfxxx64a"
)

// 通过 普通的源生请求
func main() {
	// 要生成二维码的路径和参数
	_, err := GetQRCode(58)
	if err != nil {
		fmt.Println("Error getting QR code:", err)
		return
	}

}

func GetQRCode(id int) ([]byte, error) {
	//上面生成的access code 判断为空时重新请求
	accessToken, err := requestToken(MINI_APP_LATEST_ID, MINI_APP_LATEST_SECRET)
	if err != nil {
		return nil, err
	}
	strUrl := fmt.Sprintf(CreateWXAQRCodeURL, accessToken)

	// todo: 这里有bug待完善
	parm := make(map[string]string)
	// path 要以?开始
	parm["path"] = fmt.Sprintf("?pathName=/race/pages/group&id=%d", id)
	// page 起始位置不需要 /
	parm["page"] = fmt.Sprintf("pages/home/index")
	jsonStr, err := json.Marshal(parm)
	if err != nil {
		return nil, errors.New("json Marshal QRCode paramter err :" + err.Error())
	}
	req, err := http.NewRequest("POST", strUrl, bytes.NewBuffer([]byte(jsonStr)))
	if err != nil {
		return nil, errors.New("get QRCode err :" + err.Error())
	}
	// 发起 post 请求
	req.Header.Set("Content-Type", "application/json")
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return nil, errors.New("get QRCode err :" + err.Error())
	}

	defer resp.Body.Close()
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, errors.New("get QRCode err :" + err.Error())
	}

	// 生成图片
	png, err := os.Create("data.png")
	_, err2 := png.Write(body)

	if err2 != nil {
		log.Fatal(err2)
	}
	fmt.Println("QR code saved successfully!")
	return nil, nil
}

func requestToken(appid, secret string) (string, error) {
	u, err := url.Parse("https://api.weixin.qq.com/cgi-bin/token")
	if err != nil {
		log.Fatal(err)
	}
	paras := &url.Values{}
	//设置请求参数
	paras.Set("appid", appid)
	paras.Set("secret", secret)
	paras.Set("grant_type", "client_credential")
	u.RawQuery = paras.Encode()
	resp, err := http.Get(u.String())
	//关闭资源
	if resp != nil && resp.Body != nil {
		defer resp.Body.Close()
	}
	if err != nil {
		return "", errors.New("request token err :" + err.Error())
	}

	jMap := make(map[string]interface{})
	err = json.NewDecoder(resp.Body).Decode(&jMap)
	if err != nil {
		return "", errors.New("request token response json parse err :" + err.Error())
	}
	if jMap["errcode"] == nil || jMap["errcode"] == 0 {
		accessToken, _ := jMap["access_token"].(string)
		return accessToken, nil
	} else {
		//返回错误信息
		errcode := jMap["errcode"].(string)
		errmsg := jMap["errmsg"].(string)
		err = errors.New(errcode + ":" + errmsg)
		return "", err
	}
}

3、代码分析 io.ReadAll 文件流

通过接口返回的 resp中的body,通过 io.ReadAll() 方法返回的body为二进制

go 复制代码
body, err := io.ReadAll(resp.Body)
if err != nil {
	return nil, errors.New("get QRCode err :" + err.Error())
}

我们需要通过文件去接收这个文件流

go 复制代码
// 生成图片
png, err := os.Create("data.png")
_, err2 := png.Write(body)

这样我们就可以看到一个data.png的文件产生

二、框架实现

1、官方API

作者: silenceper/wechat

github地址:https://github.com/silenceper/wechat/v2

文档地址:https://silenceper.com/wechat/miniprogram/qrcode.html

2、golang 实现源码

go 复制代码
package main

import (
	"fmt"
	"github.com/silenceper/wechat/v2"
	"github.com/silenceper/wechat/v2/cache"
	miniConfig "github.com/silenceper/wechat/v2/miniprogram/config"
	"github.com/silenceper/wechat/v2/miniprogram/qrcode"
	"log"
	"os"
)

const (

	// 替换成你的小程序 appiId 和 secretKey
	MINI_APP_LATEST_ID     string = "wxxxxf6"
	MINI_APP_LATEST_SECRET string = "7dfxxx64a"
)

func main() {
	// 初始化 Wechat 实例
	wc := wechat.NewWechat()
	//这里本地内存保存access_token,也可选择redis,memcache或者自定cache
	memory := cache.NewMemory()
	//token, _ := requestToken(MINI_APP_LATEST_ID, MINI_APP_LATEST_SECRET)
	cfg := &miniConfig.Config{
		AppID:     MINI_APP_LATEST_ID,
		AppSecret: MINI_APP_LATEST_SECRET,
		Cache:     memory,
	}

	//officialAccount := wc.GetOfficialAccount(cfg)
	mini := wc.GetMiniProgram(cfg)
	fmt.Println("------------")
	qcode := mini.GetQRCode()
	res, err := qcode.CreateWXAQRCode(qrcode.QRCoder{
		Page: "pages/home/index",
		Path: "?pathName=/race/pages/group&id=58",
		//CheckPath:  nil,
		Width: 300,
		//Scene: "pathName=/race/pages/group&id=58",
		//AutoColor:  false,
		//LineColor:  nil,
		//IsHyaline:  false,
		//EnvVersion: "",
	})
	if err != nil {
		return
	}
	// 生成图片
	png, err := os.Create("race.png")
	_, err2 := png.Write(res)

	if err2 != nil {
		log.Fatal(err2)
	}

	fmt.Println("QR code saved successfully!")

}
相关推荐
liupenglove1 小时前
golang操作mysql利器-gorm
mysql·golang
风等雨归期1 小时前
【python】【绘制小程序】动态爱心绘制
开发语言·python·小程序
Rookie_explorers2 小时前
Linux下go环境安装、环境配置并执行第一个go程序
linux·运维·golang
做技术的Pandaer2 小时前
Go 第二期
开发语言·golang
李宥小哥3 小时前
微信小程序07-开发进阶
微信小程序·小程序·notepad++
wn5313 小时前
【Go - 类型断言】
服务器·开发语言·后端·golang
艾小逗4 小时前
uniapp快速入门教程,内容来源于官方文档,仅仅记录快速入门需要了解到的知识点
小程序·uni-app·app·es6
程序员阿龙4 小时前
【2025】儿童疫苗接种预约小程序(源码+文档+解答)
小程序·毕业设计·小程序开发·预约小程序·疫苗管理小程序·出勤数据分析·智能考勤
818源码资源站4 小时前
表情包创作、取图小程序端(带流量主)
小程序
GoppViper4 小时前
golang学习笔记29——golang 中如何将 GitHub 最新提交的版本设置为 v1.0.0
笔记·git·后端·学习·golang·github·源代码管理