【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(..…...
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...
2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
