当前位置: 首页 > news >正文

【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

Your Image Description

让我们一起支持群主维护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数据分析软件&#xff0…...

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库

说明当前编译条件&#xff1a;使用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配置文件&#xff0c;点击符号ssh连接新的远…...

2024年MathorCup数模竞赛C题详解

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

【简单讲解如何安装与配置Composer】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…...

深入理解Apache ZooKeeper与Kafka的协同工作原理

目录 引言 一、ZooKeeper基础概念 &#xff08;一&#xff09;ZooKeeper简介 &#xff08;二&#xff09;ZooKeeper数据结构 &#xff08;三&#xff09;ZooKeeper特点 &#xff08;四&#xff09;应用场景 二、ZooKeeper工作模式 &#xff08;一&#xff09;工作机制 …...

js解密心得,记录一次抓包vue解密过程

背景 有个抓包结果被加密了 1、寻找入口&#xff0c;打断点 先正常请求一次&#xff0c;找到需要的请求接口。 寻找入口&#xff0c;需要重点关注几个关键字&#xff1a;new Promise 、new XMLHttpRequest、onreadystatechange、.interceptors.response.use、.interceptors.r…...

redis-哨兵模式

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

自动化测试中的SOLID原则

自动化测试在软件质量保障手段中愈显重要 。但是随着自动化测试代码的规模和复杂性不断扩大&#xff0c;它也很容易出现测试代码重复、紧耦合等问题。而SOLID原则可以解决这一问题&#xff0c;作为自动化用例开发的指导原则。 探索SOLID原则 SOLID原则是一组指导软件开发人员…...

tencentcloud-sdk-python-iotexplorer和tencent-iot-device有什么区别

1. tencent-iot-device tencent-iot-device 是腾讯云提供的物联网设备 SDK&#xff0c;用于在物联网场景中开发和连接设备。这个 SDK 提供了丰富的功能和接口&#xff0c;可以帮助开发者快速构建稳定、高效的物联网应用。 主要功能和特点&#xff1a; 设备连接管理&#xff1…...

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)

中介者模式概述 中介者模式&#xff08;Mediator Pattern&#xff09;是一种行为设计模式&#xff0c;它用于减少对象之间的直接交互&#xff0c;从而使其可以松散耦合中介者模式通过引入一个中介者对象来协调多个对象之间的交互&#xff0c;使得这些对象不需要知道彼此的具体…...

计算机网络的起源与发展历程

文章目录 前言时代背景ARPANET 的诞生TCP/IP 协议簇与 Internet 的诞生HTTP 协议与 Web 世界结语 前言 在当今数字化时代&#xff0c;计算机网络已经成为我们生活中不可或缺的一部分。无论是在家庭、学校、还是工作场所&#xff0c;我们都能感受到网络的巨大影响。随着互联网的…...

2024-4-12-实战:商城首页(下)

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; 文章目录 作业小结 作业 .bg-backward {width: 60px; height: 60px;background: url(..…...

一、flask入门和视图

run启动参数 模板渲染 后端给前端页面传参 前端页面设置css from flask import Flask, render_template,jsonify# 创建flask对象 app Flask(__name__)# 视图函数 路由route app.route("/") def hello_world():# 响应&#xff0c;返回给前端的数据return "h…...

Selenium+Chrome Driver 爬取搜狐页面信息

进行selenium包和chromedriver驱动的安装 安装selenium包 在命令行或者anaconda prompt 中输入 pip install Selenium 安装 chromedriver 先查看chrome浏览器的版本 这里是 123.0.6312.106 版 然后在http://npm.taobao.org/mirrors/chromedriver/或者https://googlechrom…...

SpringBoot:一个注解就能帮你下载任意对象

介绍 下载功能应该是比较常见的功能了&#xff0c;虽然一个项目里面可能出现的不多&#xff0c;但是基本上每个项目都会有&#xff0c;而且有些下载功能其实还是比较繁杂的&#xff0c;倒不是难&#xff0c;而是麻烦。 所以结合之前的下载需求&#xff0c;我写了一个库来简化…...

oracle全量、增量备份

采用0221222增量备份策略,7天一个轮回 也就是周日0级备份&#xff0c;周1 2 4 5 6 采用2级增量备份&#xff0c;周3采用1级增量备份 打开控制文件自动备份 CONFIGURE CONTROLFILE AUTOBACKUP ON; 配置控制文件备份路径 CONFIGURE CONTROLFILE AUTOBACKUP FORMAT FOR DEVI…...

React Router 5 vs 6:使用上的主要差异与升级指南

React Router 5 的一些API 在 React Router 6 上有时可能找不到&#xff0c;可能会看到如下画面&#xff1a;export ‘useHistory’ was not found in ‘react-router-dom’ … React Router目前有两个大的版本&#xff0c;即React Router 5、6。React Router 6 在设计上更加简…...

基于LNMP部署wordpress

目录 一.环境准备 二.配置源并安装 三.配置Nginx 四.配置数据库 五.上传源码并替换 六.打开浏览器&#xff0c;输入虚拟机ip访问安装部署 七.扩展增加主题 一.环境准备 centos7虚拟机 关闭防火墙和seliunx stop firewalld #关闭防火墙 setenforce 0 …...

openGauss_5.1.0 企业版快速安装及数据库连接:单节点容器化安装

目录 &#x1f4da;第一章 官网信息&#x1f4da;第二章 安装&#x1f4d7;下载源码&#x1f4d7;下载安装包&#x1f4d7;修改版本&#x1f4d7;解压安装包&#x1f4d7;运行buildDockerImage.sh脚本&#x1f4d7;docker操作&#x1f4d5;查看docker镜像&#x1f4d5;启动dock…...

微信小程序 uniapp+vue城市公交线路查询系统dtjl3

小程序Android端运行软件 微信开发者工具/hbuiderx uni-app框架&#xff1a;使用Vue.js开发跨平台应用的前端框架&#xff0c;编写一套代码&#xff0c;可编译到Android、小程序等平台。 前端&#xff1a;HTML5,CSS3 VUE 后端&#xff1a;java(springbootssm)/python(flaskdja…...

2024年MathorCup数模竞赛B题问题一二三+部分代码分享

inputFolderPath E:\oracle\images\; outputFolderPath E:\oracle\process\; % 获取文件夹中所有图片的文件列表 imageFiles dir(fullfile(inputFolderPath, *.jpg)); % 设置colorbar范围阈值 threshold 120; % 遍历每个图片文件 for i 1:length(imageFiles) % 读…...

Ubuntu日常配置

目录 修改网络配置 xshell连不上怎么办 解析域名失败 永久修改DNS方法 临时修改DNS方法 修改网络配置 1、先ifconfig确认本机IP地址&#xff08;刚装的机子没有ifconfig&#xff0c;先apt install net-tools&#xff09; 2、22.04版本的ubuntu网络配置在netplan目录下&…...