GO语言实现二维码扫码的示例代码

 更新时间:2023年06月14日 10:26:11   作者:虾滑虾滑  
你对二维码扫码的流程有困惑吗,这篇文章就结合笔者自身的开发经验进行分享,让大家熟悉并掌握此功能,感兴趣的小伙伴快跟随小编一起学习一下吧

笔者在学校开发的时候就对很多流程并不太熟悉,你对二维码扫码的流程有困惑吗?本篇文章就结合笔者自身的开发经验进行分享,让你熟悉并掌握此功能~

场景: 笔者的功能是分享二维码给他人扫码加入到组织中

分享二维码加入组织流程图

二维码状态

根据业务二维码状态大致分为4种

  • 待扫码
  • 已扫码待确认
  • 已过期
  • 使用次数限制

注:状态可以自定义,笔者的功能点在邀请他人加入组织,所以有次数限制

创建二维码

小程序二维码官方文档

笔者是小程序二维码跳转普通的二维码是不支持的要采用官方获取不限制二维码的包,因为使用官方的接口我们都需要去维护他的access_token,这里笔者采用go官网提供的包。

微信小程序服务端

第一步: 安装包

go get -u github.com/medivhzhan/weapp/v3

第二步: 引入包

import(
    "github.com/medivhzhan/weapp/v3"
    "github.com/medivhzhan/weapp/v3/wxacode"
)
func main() {
    var key = strings.ReplaceAll(uuid.NewString(), "-", "")
    newWxaCode := weapp.NewClient(appid, secret).NewWXACode()
    httpResponse, cmdErr, err := newWxaCode.GetUnlimited(&wxacode.UnlimitedQRCode{
        Scene:     key,
        Page:      "pages/organization/receive/QR",
        Width:     300,
        AutoColor: false,
        LineColor: wxacode.Color{
            R: "0",
            G: "0",
            B: "0",
        },
        IsHyaline:  false,
        EnvVersion: "",
        CheckPath:  false,
    })
    if err != nil {
        // 这是我们内部的返回异常,请替换成自己项目的进行返回
        web.NewErrorResponse(c, QrcodeException.SetMsg(err.Error()).Return(http.StatusBadRequest)
        return
    }
    // 检验生成是否有错误
    if cmdErr.ErrCode != 0 {
        response := web.NewErrorResponse(c, QrcodeException.SetMsg(cmdErr.ErrMSG), "")
        response.Return(http.StatusBadRequest)
        return
    }
    // 我们读取数据要关闭,否则会导致链接池错误
    defer httpResponse.Body.Close()
    // qrCode就是[]byte类型的二维码了,通过json返回就可以在页面上展示了
    qrCode, err := io.ReadAll(code.Body)
    if err != nil {
        web.NewErrorResponse(c, QrcodeException.SetMsg(err.Error()).Return(http.StatusBadRequest)
        return
    }
    // 代码未结束...查看下面文章并且拼接到此位置
}

内存配置

type QRCodeKey string
var (
    QRToken          QRCodeKey = "token"
    QRScene          QRCodeKey = "scene"
    QRExpire         QRCodeKey = "expire"
    QRTokenExpire    QRCodeKey = "token_expire"
    QRUser           QRCodeKey = "user"
    QRLimit          QRCodeKey = "limit"
    QROwner          QRCodeKey = "owner"
    QRIsNeedApproval QRCodeKey = "is_need_approval"
    QRCreate         QRCodeKey = "create"
)
var MemoryQRCodeLoginStorage = make(map[string]map[QRCodeKey]any)

二维码状态

生成了二维码就应该保存二维码状态,稍后提供接口查询二维码状态,让pc端轮询这个接口,就能实现扫码之后会更改二维码状态为已扫码。

因为架构师让笔者使用内存的方式存储这个数据,并没有采用redis的方式存储,所以下面的例子是采用内存的方式进行存储

currentTime := time.Now()
data := make(map[QRCodeKey]any)
data[QRExpire] = currentTime.Add(time.Minute * time.Duration(params.EffectiveTime))
data[QRLimit] = params.Count
data[QRUser] = gin.H{
    "id":   user.ID,
    "name": user.Nickname,
}
data[QROwner] = gin.H{
    "id":   owner.ID,
    "name": owner.Name,
}
data[QRCreate] = currentTime.Format(time.DateTime)
data[QRIsNeedApproval] = params.IsNeedApproval
cache := MemoryQRCodeLoginStorage
cache[key] = data
web.NewSingleResponse(c, gin.H{
        "createAt": currentTime.Format(time.DateTime),
        "qrCode":   qrCodeData,
}).Return(http.StatusOK)

获取二维码状态

func (api ownerApi) QrCodeInformation(c *gin.Context) {
    var params OwnerInformationRequest
    if err := c.ShouldBindQuery(&params); err != nil {
        web.NewErrorResponse(c, ErrorParams, err.Error()).Return(http.StatusBadRequest)
        return
    }
    cache := MemoryQRCodeLoginStorage
    m := cache[params.Key]
    expire := m[v1.QRExpire]
    if t, ok := expire.(time.Time); ok {
        expire = t.Format(time.DateTime)
    }
    web.NewSingleResponse(c, gin.H{
        "expire":   expire,
        "limit":    m[v1.QRLimit],
        "owner":    m[v1.QROwner],
        "user":     m[v1.QRUser],
        "createAt": m[v1.QRCreate],
    }).Return(http.StatusOK)
}

总结

二维码扫码并不难,只是在没做过的时候需要捋清楚流程,重要的是维护二维码的状态,以及怎么存储他。扫码本质就是扫码获取二维码需要携带的信息再去请求其他接口,扫码只是为了方便操作,希望刚刚入门的朋友不要像我一样惧怕一些陌生的业务,实际上他真的很简单只是需要我们多思考。

到此这篇关于GO语言实现二维码扫码的示例代码的文章就介绍到这了,更多相关GO二维码扫码内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 深入了解Go的interface{}底层原理实现

    深入了解Go的interface{}底层原理实现

    本文主要介绍了Go的interface{}底层原理实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • 关于go语言编码需要放到src 文件夹下的问题

    关于go语言编码需要放到src 文件夹下的问题

    这篇文章主要介绍了go语言编码需要放到src 文件夹下的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • Go gRPC服务客户端流式RPC教程

    Go gRPC服务客户端流式RPC教程

    这篇文章主要为大家介绍了Go gRPC服务客户端流式RPC教程示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • Go语言单元测试的实现及用例

    Go语言单元测试的实现及用例

    在日常开发中,我们通常需要针对现有的功能进行单元测试,以验证开发的正确性,本文主要介绍了Go语言单元测试的实现及用例,具有一定的参考价值,感兴趣的可以了解一下
    2024-01-01
  • Go时间操作常用方法(推荐!)

    Go时间操作常用方法(推荐!)

    平时开发过程中,时间相关的操作用的还是很多的,下面这篇文章主要给大家介绍了关于Go时间操作常用方法的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-06-06
  • Windows系统中搭建Go语言开发环境图文详解

    Windows系统中搭建Go语言开发环境图文详解

    GoLand 是 JetBrains 公司推出的商业 Go 语言集成开发环境(IDE),这篇文章主要介绍了Windows系统中搭建Go语言开发环境详解,需要的朋友可以参考下
    2022-10-10
  • GoLang切片相关问题梳理讲解

    GoLang切片相关问题梳理讲解

    这篇文章主要介绍了GoLang切片相关的七个问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-10-10
  • 一文详解Go语言中对象池的正确打开方式

    一文详解Go语言中对象池的正确打开方式

    对象池是一种设计模式,它维护一组已经创建好的对象,当需要使用对象时,直接从对象池中获取,使用完毕后再放回对象池,而不是频繁地创建和销毁对象,下面我们就来看看Go语言中对象池的具体使用吧
    2025-02-02
  • go语言reflect.Type 和 reflect.Value 应用示例详解

    go语言reflect.Type 和 reflect.Value 应用示例详解

    这篇文章主要为大家介绍了go语言reflect.Type 和 reflect.Value 应用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • 一文带你了解Go语言中方法的调用

    一文带你了解Go语言中方法的调用

    这篇文章主要和大家分享一下Go语言中的方法的调用,文中的示例代码讲解详细,对我们学习Go语言有一定的帮助,需要的小伙伴可以参考一下
    2022-12-12

最新评论