【golang】动态生成微信小程序二维码实战下:golang 生成 小程序二维码图片 并通过s3协议上传到对象存储桶 | 腾讯云 cos
项目背景
在自研的系统,需要实现类似草料二维码的功能
将我们自己的小程序,通过代码生成相想要的小程序二维码
代码已经上传到 Github 需要的朋友可以自取
https://github.com/ctra-wang/wechat-mini-qrcode
一、生成Qrcode并提交到对象存储
通过源生API实现对小程序二维码的生成
1、s3上传多云对象存储桶
感谢
suyuan32
同学对代码的开源: https://github.com/suyuan32/simple-admin-file

让我们一起支持群主维护simple-admin 社群吧!!!
不能加入星球的朋友记得来点个Star!!
https://github.com/suyuan32/simple-admin-core
2、源码
下面为示意代码,
需要的package如下:
- github.com/silenceper/wechat/v2
- github.com/aws/aws-sdk-go/aws
func NewVerifyRaceSignTeamLogic(ctx context.Context, svcCtx *svc.ServiceContext) *VerifyRaceSignTeamLogic {return &VerifyRaceSignTeamLogic{Logger: logx.WithContext(ctx),ctx: ctx,svcCtx: svcCtx}
}func (l *VerifyRaceSignTeamLogic) VerifyRaceSignTeam(req *types.RaceSignTeamInfo) (resp *types.BaseMsgResp, err error) {deptId := ctxdata.GetIntParamFromJwt(l.ctx, "deptId")// 根据具体赛事id查询raceSignTeam, err := l.svcCtx.CtraGoRaceRpc.GetRaceSignTeamById(l.ctx, &ctragorace.IDReq{Id: *req.Id,})if err != nil {return nil, err}flag := falseif int(deptId) != constant.ORG_TYPE_ADMIN {// 根据 deptid 换 orgInfoorgRes, err := l.svcCtx.CtraGoRaceRpc.GetRaceOrgInfoList(l.ctx, &ctragorace.RaceOrgInfoListReq{DeptId: &deptId,})if err != nil {return nil, err}if orgRes.Total > 0 {// 非管理员,查看该权限下所有赛事raceList, err := l.svcCtx.CtraGoRaceRpc.GetRaceInfoList(l.ctx, &ctragorace.RaceInfoListReq{RaceOrgInfoId: *orgRes.Data[0].Id,})if err != nil {return nil, err}if raceList.Total > 0 {for _, datum := range raceList.Data {if *datum.Id == *raceSignTeam.RaceInfoId {flag = truebreak}}}}} else {flag = true}if !flag {return nil, errorx.NewCodeAbortedError("该用户暂无权限进行审核!")}// ----------------------- 生成 微信小程序二维码 使用:github.com/silenceper/wechat/v2 -----------------------// 初始化 Wechat 实例wc := wechat.NewWechat()//这里本地内存保存access_token,也可选择redis,memcache或者自定cachememory := cache.NewMemory()cfg := &miniConfig.Config{AppID: constant.MINI_APP_LATEST_ID,AppSecret: constant.MINI_APP_LATEST_SECRET,Cache: memory,}mini := wc.GetMiniProgram(cfg)qr := mini.GetQRCode()qrRes, err := qr.CreateWXAQRCode(qrcode.QRCoder{Page: l.svcCtx.Config.QrCode.Page,Path: fmt.Sprintf(l.svcCtx.Config.QrCode.Path, raceSignTeam.RaceInfoId),//CheckPath: nil,Width: l.svcCtx.Config.QrCode.Width,//Scene: "pathName=/race/pages/group&id=58",//AutoColor: false,//LineColor: nil,//IsHyaline: false,//EnvVersion: "",})if err != nil {return nil, errorx.NewCodeAbortedError("通过微信小程序API生成小程序二维码失败!")}// ----------------------- 将 微信小程序二维码 生成为本地文件用于存入对象存储cos -----------------------// 拼接文件路径fileDir := fmt.Sprintf("/upload/race-info/%s/", time.Now().Format("2006_01"))newFileName := generatoruuid.GetUuid() + ".jpg"// 获取当前 Pod 的工作目录pwd, err := os.Getwd()if err != nil {l.Logger.Errorf(err.Error())return nil, errorx.NewCodeAbortedError("os创建文件夹失败!")}// 创建文件路径err = os.MkdirAll(pwd+fileDir, 0755)if err != nil {l.Logger.Errorf(err.Error())return nil, errorx.NewCodeAbortedError("os创建文件夹失败!")}// 复制文件(空文件)到该路径qrcodeFile, err := os.Create(pwd + fileDir + newFileName)if err != nil {l.Logger.Errorf(err.Error())return nil, errorx.NewCodeAbortedError("os创建文件失败!")}// 将通过API生成小程序二维码->写入到文件中_, err = qrcodeFile.Write(qrRes)if err != nil {l.Logger.Errorf(err.Error())return nil, errorx.NewCodeAbortedError("os创建文件失败!")}defer qrcodeFile.Close()// 删除文件defer os.RemoveAll(pwd + fileDir + newFileName)// ----------------------- 推送文件到tencent对象存储cos -----------------------// 创建s3实例sess := session.Must(session.NewSession(&aws.Config{Region: aws.String(l.svcCtx.Config.QrCode.Region),Credentials: credentials.NewStaticCredentials(l.svcCtx.Config.QrCode.SecretId, l.svcCtx.Config.QrCode.SecretKey, ""),Endpoint: aws.String(l.svcCtx.Config.QrCode.EndPoint),},))CloudStorage := s3.New(sess)qrFile, err := os.Open(pwd + fileDir + newFileName)if err != nil {l.Logger.Errorf(err.Error())return nil, errorx.NewCodeAbortedError("读取新创建qrcode失败!")}defer qrFile.Close()// 处理存放cos的路径// - C 端// - 赛事报名:race-sign/赛事id/// - 赛事信息:race-info/赛事id/ ✅// - 用户里程碑:member-moment/用户id/// - 用户个人信息: member-info/用户id/// - B 端 (不在这里使用)// - banner:banner/relativeSrc := fmt.Sprintf("%s/%s/%d/%s",l.svcCtx.Config.QrCode.Folder,"race-info",*raceSignTeam.RaceInfoId,newFileName)// 发送到tencent-cos_, err = CloudStorage.PutObjectWithContext(context.Background(), &s3.PutObjectInput{Bucket: aws.String(l.svcCtx.Config.QrCode.BucketName),Key: aws.String(relativeSrc),Body: qrFile,})if err != nil {l.Logger.Errorf(err.Error())return nil, errorx.NewCodeAbortedError("文件上传到tencent-cos失败!")}fmt.Println("QR code upload tencent cos successfully!")// ----------------------- 更新数据库表 race_sign_team -----------------------// 更新团报状态res1, err := l.svcCtx.CtraGoRaceRpc.UpdateRaceSignTeam(l.ctx,&ctragorace.RaceSignTeamInfo{Id: req.Id,IsValidate: pointy.GetPointer(int32(constant.SIGN_TEAM_IS_VALIDATE_ACCESS)),TeamQrcode: &relativeSrc,})if err != nil {return nil, err}return &types.BaseMsgResp{Msg: res1.Msg}, nil}
3、源码分析
3.1、拿到qrcode二进制
qrRes 为拿到的图片二进制
// ----------------------- 生成 微信小程序二维码 使用:github.com/silenceper/wechat/v2 -----------------------// 初始化 Wechat 实例wc := wechat.NewWechat()//这里本地内存保存access_token,也可选择redis,memcache或者自定cachememory := cache.NewMemory()cfg := &miniConfig.Config{AppID: constant.MINI_APP_LATEST_ID,AppSecret: constant.MINI_APP_LATEST_SECRET,Cache: memory,}mini := wc.GetMiniProgram(cfg)qr := mini.GetQRCode()qrRes, err := qr.CreateWXAQRCode(qrcode.QRCoder{Page: l.svcCtx.Config.QrCode.Page,Path: fmt.Sprintf(l.svcCtx.Config.QrCode.Path, raceSignTeam.RaceInfoId),//CheckPath: nil,Width: l.svcCtx.Config.QrCode.Width,//Scene: "pathName=/race/pages/group&id=58",//AutoColor: false,//LineColor: nil,//IsHyaline: false,//EnvVersion: "",})if err != nil {return nil, errorx.NewCodeAbortedError("通过微信小程序API生成小程序二维码失败!")}
3.2、二维码存为本地文件
将 微信小程序二维码 生成为本地文件用于存入对象存储cos
// ----------------------- 将 微信小程序二维码 生成为本地文件用于存入对象存储cos -----------------------// 拼接文件路径fileDir := fmt.Sprintf("/upload/contracts/%s/", time.Now().Format("2006_01"))newFileName := generatoruuid.GetUuid() + ".jpg"// 获取当前 Pod 的工作目录pwd, err := os.Getwd()if err != nil {l.Logger.Errorf(err.Error())return nil, errorx.NewCodeAbortedError("os创建文件夹失败!")}// 创建文件路径err = os.MkdirAll(pwd+fileDir, 0755)if err != nil {l.Logger.Errorf(err.Error())return nil, errorx.NewCodeAbortedError("os创建文件夹失败!")}// 复制文件(空文件)到该路径qrcodeFile, err := os.Create(pwd + fileDir + newFileName)if err != nil {l.Logger.Errorf(err.Error())return nil, errorx.NewCodeAbortedError("os创建文件失败!")}// 将通过API生成小程序二维码->写入到文件中_, err = qrcodeFile.Write(qrRes)if err != nil {l.Logger.Errorf(err.Error())return nil, errorx.NewCodeAbortedError("os创建文件失败!")}defer qrcodeFile.Close()// 删除文件defer os.RemoveAll(pwd + fileDir + newFileName)
3.3、推送文件到tencent对象存储cos
通过s3协议上传到对象存储桶 | 腾讯云 cos
这里注意要将刚才保存的图片再次打开os.Open()
// ----------------------- 推送文件到tencent对象存储cos -----------------------// 创建s3实例sess := session.Must(session.NewSession(&aws.Config{Region: aws.String(l.svcCtx.Config.QrCode.Region),Credentials: credentials.NewStaticCredentials(l.svcCtx.Config.QrCode.SecretId, l.svcCtx.Config.QrCode.SecretKey, ""),Endpoint: aws.String(l.svcCtx.Config.QrCode.EndPoint),},))CloudStorage := s3.New(sess)qrFile, err := os.Open(pwd + fileDir + newFileName)if err != nil {l.Logger.Errorf(err.Error())return nil, errorx.NewCodeAbortedError("读取新创建qrcode失败!")}defer qrFile.Close()// 处理存放cos的路径// - C 端// - 赛事报名:race-sign/赛事id/// - 赛事信息:race-info/赛事id/ ✅// - 用户里程碑:member-moment/用户id/// - 用户个人信息: member-info/用户id/// - B 端 (不在这里使用)// - banner:banner/relativeSrc := fmt.Sprintf("%s/%s/%d/%s",l.svcCtx.Config.QrCode.Folder,"race-info",*raceSignTeam.RaceInfoId,newFileName)// 发送到tencent-cos_, err = CloudStorage.PutObjectWithContext(context.Background(), &s3.PutObjectInput{Bucket: aws.String(l.svcCtx.Config.QrCode.BucketName),Key: aws.String(relativeSrc),Body: qrFile,})if err != nil {l.Logger.Errorf(err.Error())return nil, errorx.NewCodeAbortedError("文件上传到tencent-cos失败!")}fmt.Println("QR code upload tencent cos successfully!")
相关文章:

【golang】动态生成微信小程序二维码实战下:golang 生成 小程序二维码图片 并通过s3协议上传到对象存储桶 | 腾讯云 cos
项目背景 在自研的系统,需要实现类似草料二维码的功能 将我们自己的小程序,通过代码生成相想要的小程序二维码 代码已经上传到 Github 需要的朋友可以自取 https://github.com/ctra-wang/wechat-mini-qrcode 一、生成Qrcode并提交到对象存储 通过源生A…...
kubeadm k8s 1.24之后版本安装,带cri-dockerd
最后编辑时间:2024/3/26 适用于1.24之后的版本 单节点配置 检查是否已经安装kubectl, kubelet, kubeadm直接输入命令确定,如果提示没有该指令则正确 kubectl kubelet kubeadm如果之前安装,首先reset,然后使用apt remove和snap r…...

13-pyspark的共享变量用法总结
目录 前言广播变量广播变量的作用 广播变量的使用方式 累加器累加器的作用累加器的优缺点累加器的使用方式 PySpark实战笔记系列第四篇 10-用PySpark建立第一个Spark RDD(PySpark实战笔记系列第一篇)11-pyspark的RDD的变换与动作算子总结(PySpark实战笔记系列第二篇))12-pysp…...

BI数据分析软件:行业趋势与功能特点剖析
随着数据量的爆炸性增长,企业对于数据的需求也日益迫切。BI数据分析软件作为帮助企业实现数据驱动决策的关键工具,在当前的商业环境中扮演着不可或缺的角色。本文将从行业趋势、功能特点以及适用场景等方面,深入剖析BI数据分析软件࿰…...

centos7上docker搭建vulhub靶场
1 vulhub靶场概述 VulHub是一个在线靶场平台,提供了丰富的漏洞环境供安全爱好者学习和实践。 该平台主要面向网络安全初学者和进阶者,通过模拟真实的漏洞环境,帮助用户深入了解漏洞的成因、利用方式以及防范措施。 此外,VulHub还…...
Flutter入门指南
文章目录 一、环境搭建二、基本概念三、创建一个简单的Flutter应用四、常用组件及代码示例五、总结推荐阅读 笔者项目中使用Flutter的模块并不多。虽然笔者还没有机会在项目中正式使用Flutter,但是也在学习Flutter的一些基本用法。本文就是一篇Flutter的入门介绍&am…...

keepalived脑裂问题
脑裂问题产生的原因 就是vip同时存在 master和backup 就叫做脑裂 比如说 backup 机器的防火墙没关,并且没有允许vrrp通过,backup 没有收到master的心跳数据,就会抢夺资源,发生脑裂问题测试 我们打开test3的防火墙,此…...
【Linux笔记】编mysql库
说明当前编译条件:使用cmake 进行编译<当前编译为Ubuntu PC 版本 在虚拟机上面使用> 一、 cmake 库 【 cmake version 3.16.3 】 二、 openssl 库 【 libopenssl-1.1.1K 】 三、mysql 库 【mysql-5.7.36 】 四、boost 库 【boost_1_59_0 】 一、安装cmake 1.1…...

vscode远程免密登录ssh
vscode远程免密登录ssh 1. 安装vscode2. 安装ssh3. 本地vscode配置免密登录远端开发机1. 本地配置秘钥2. 远程开发机配置秘钥 4. vscode常用小工具1. vscode怎么设置ctrl加滚轮放大字体 1. 安装vscode 2. 安装ssh 设置符号打开config配置文件,点击符号ssh连接新的远…...

2024年MathorCup数模竞赛C题详解
C题持续更新中 问题一问题二代码混合ARIMA-LSTM模型构建完整数据与代码第一问第二问 问题一 问题一要求对未来30天每天及每小时的货量进行预测。首先,利用混合ARIMA-LSTM模型进行时间序列预测。ARIMA模型擅长捕捉线性特征和趋势,而LSTM模型处理非线性关…...

【简单讲解如何安装与配置Composer】
🎥博主:程序员不想YY啊 💫CSDN优质创作者,CSDN实力新星,CSDN博客专家 🤗点赞🎈收藏⭐再看💫养成习惯 ✨希望本文对您有所裨益,如有不足之处,欢迎在评论区提出…...

深入理解Apache ZooKeeper与Kafka的协同工作原理
目录 引言 一、ZooKeeper基础概念 (一)ZooKeeper简介 (二)ZooKeeper数据结构 (三)ZooKeeper特点 (四)应用场景 二、ZooKeeper工作模式 (一)工作机制 …...

js解密心得,记录一次抓包vue解密过程
背景 有个抓包结果被加密了 1、寻找入口,打断点 先正常请求一次,找到需要的请求接口。 寻找入口,需要重点关注几个关键字:new Promise 、new XMLHttpRequest、onreadystatechange、.interceptors.response.use、.interceptors.r…...

redis-哨兵模式
一,哨兵的作用: 通过发送命令,让Redis服务器返回监控其运行状态,包括主服务器和从服务器。当哨兵监测到master宕机,会自动将slave切换成master,然后通过发布订阅模式通知其他的从服务器,修改配…...

自动化测试中的SOLID原则
自动化测试在软件质量保障手段中愈显重要 。但是随着自动化测试代码的规模和复杂性不断扩大,它也很容易出现测试代码重复、紧耦合等问题。而SOLID原则可以解决这一问题,作为自动化用例开发的指导原则。 探索SOLID原则 SOLID原则是一组指导软件开发人员…...
tencentcloud-sdk-python-iotexplorer和tencent-iot-device有什么区别
1. tencent-iot-device tencent-iot-device 是腾讯云提供的物联网设备 SDK,用于在物联网场景中开发和连接设备。这个 SDK 提供了丰富的功能和接口,可以帮助开发者快速构建稳定、高效的物联网应用。 主要功能和特点: 设备连接管理࿱…...
Spring day1
day01_eesy_01jdbc pom.xml<packaging>jar</packaging> <dependencies><!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --><!--依赖--><dependency><groupId>mysql</groupId><artifactId>mysql-…...
设计模式: 行为型之中介者模式(18)
中介者模式概述 中介者模式(Mediator Pattern)是一种行为设计模式,它用于减少对象之间的直接交互,从而使其可以松散耦合中介者模式通过引入一个中介者对象来协调多个对象之间的交互,使得这些对象不需要知道彼此的具体…...
计算机网络的起源与发展历程
文章目录 前言时代背景ARPANET 的诞生TCP/IP 协议簇与 Internet 的诞生HTTP 协议与 Web 世界结语 前言 在当今数字化时代,计算机网络已经成为我们生活中不可或缺的一部分。无论是在家庭、学校、还是工作场所,我们都能感受到网络的巨大影响。随着互联网的…...

2024-4-12-实战:商城首页(下)
个人主页:学习前端的小z 个人专栏:HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结,欢迎大家在评论区交流讨论! 文章目录 作业小结 作业 .bg-backward {width: 60px; height: 60px;background: url(..…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...

STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...

苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...

网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...

C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...